OpenCores
URL https://opencores.org/ocsvn/spi_master_slave/spi_master_slave/trunk

Subversion Repositories spi_master_slave

[/] [spi_master_slave/] [trunk/] [syn/] [spi_master_atlys_top.vhd] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 jdoin
----------------------------------------------------------------------------------
2 12 jdoin
-- Author:          Jonny Doin, jdoin@opencores.org, jonnydoin@gmail.com
3 5 jdoin
-- 
4
-- Create Date:     01:21:32 06/30/2011 
5
-- Design Name: 
6
-- Module Name:     spi_master_atlys_top
7
-- Project Name:    spi_master_slave
8
-- Target Devices:  Spartan-6 LX45
9
-- Tool versions:   ISE 13.1
10
-- Description: 
11 10 jdoin
--          This is a verification project for the Digilent Atlys board, to test the SPI_MASTER, SPI_SLAVE and GRP_DEBOUNCE cores.
12 5 jdoin
--          It uses the board's 100MHz clock input, and clocks all sequential logic at this clock.
13
--
14 10 jdoin
--          See the "spi_master_atlys.ucf" file for pin assignments.
15 5 jdoin
--          The test circuit uses the VHDCI connector on the Atlys to implement a 16-pin debug port to be used
16
--          with a Tektronix MSO2014. The 16 debug pins are brought to 2 8x2 headers that form a umbilical
17
--          digital pod port.
18
--
19
------------------------------ REVISION HISTORY -----------------------------------------------------------------------
20
--
21
-- 2011/07/02   v0.01.0010  [JD]    implemented a wire-through from switches to LEDs, just to test the toolchain. It worked!
22
-- 2011/07/03   v0.01.0020  [JD]    added clock input, and a simple LED blinker for each LED. 
23
-- 2011/07/03   v0.01.0030  [JD]    added clear input, and instantiated a SPI_MASTER from my OpenCores project. 
24
-- 2011/07/04   v0.01.0040  [JD]    changed all clocks to clock enables, and use the 100MHz board gclk_i to clock all registers.
25
--                                  this change made the design go up to 288MHz, after synthesis.
26
-- 2011/07/07   v0.03.0050  [JD]    implemented a 16pin umbilical port for the MSO2014 in the Atlys VmodBB board, and moved all
27
--                                  external monitoring pins to the VHDCI ports.
28
-- 2011/07/10   v1.10.0075  [JD]    verified spi_master_slave at 50MHz, 25MHz, 16.666MHz, 12.5MHz, 10MHz, 8.333MHz, 7.1428MHz, 
29
--                                  6.25MHz, 1MHz and 500kHz 
30 12 jdoin
-- 2011/07/29   v1.12.0105  [JD]    spi_master.vhd and spi_slave_vhd changed to fix CPHA='1' bug.
31 13 jdoin
-- 2011/08/02   v1.13.0110  [JD]    testbed for continuous transfer in FPGA hardware.
32 5 jdoin
--
33
--
34
----------------------------------------------------------------------------------
35
library ieee;
36
use ieee.std_logic_1164.all;
37 11 jdoin
use ieee.std_logic_arith.all;
38 5 jdoin
 
39
entity spi_master_atlys_top is
40
    Port (
41 12 jdoin
        gclk_i : in std_logic := 'X';                           -- board clock input 100MHz
42
        --- SPI interface ---           
43
        spi_ssel_o : out std_logic;                             -- spi port SSEL
44
        spi_sck_o : out std_logic;                              -- spi port SCK
45
        spi_mosi_o : out std_logic;                             -- spi port MOSI
46
        spi_miso_o : out std_logic;                             -- spi port MISO
47
        --- input slide switches ---            
48
        sw_i : in std_logic_vector (7 downto 0);                -- 8 input slide switches
49
        --- input buttons ---           
50
        btn_i : in std_logic_vector (5 downto 0);               -- 6 input push buttons
51
        --- output LEDs ----            
52
        led_o : out std_logic_vector (7 downto 0);              -- output leds
53 5 jdoin
        --- debug outputs ---
54 20 jdoin
        s_do_o : out std_logic_vector (7 downto 0);
55
        m_do_o : out std_logic_vector (7 downto 0);
56 13 jdoin
        m_state_o : out std_logic_vector (3 downto 0);          -- master spi fsm state
57
        s_state_o : out std_logic_vector (3 downto 0);          -- slave spi fsm state
58 12 jdoin
        dbg_o : out std_logic_vector (11 downto 0)              -- 12 generic debug pins
59 5 jdoin
    );
60
end spi_master_atlys_top;
61
 
62
architecture behavioral of spi_master_atlys_top is
63
 
64
    --=============================================================================================
65
    -- Constants
66
    --=============================================================================================
67
    -- clock divider count values from gclk_i (100MHz board clock)
68
    -- these constants shall not be zero
69 10 jdoin
    constant FSM_CE_DIV         : integer := 1;     -- fsm operates at 100MHz
70 5 jdoin
    constant SPI_2X_CLK_DIV     : integer := 1;     -- 50MHz SPI clock
71 10 jdoin
    constant SAMP_CE_DIV        : integer := 1;     -- board signals sampled at 100MHz
72 5 jdoin
    -- spi port generics
73 11 jdoin
    constant N      : integer   := 8;               -- 8 bits
74 20 jdoin
    constant CPOL   : std_logic := '0';
75
    constant CPHA   : std_logic := '0';
76 5 jdoin
 
77
    -- button definitions
78
    constant btRESET    : integer := 0;             -- these are constants to use as btn_i(x)
79
    constant btUP       : integer := 1;
80
    constant btLEFT     : integer := 2;
81
    constant btDOWN     : integer := 3;
82
    constant btRIGHT    : integer := 4;
83
    constant btCENTER   : integer := 5;
84
 
85
    --=============================================================================================
86
    -- Type definitions
87
    --=============================================================================================
88 13 jdoin
    type fsm_master_write_state_type is
89
            (st_reset, st_wait_spi_idle, st_wait_new_switch, st_send_spi_data_sw, st_wait_spi_ack_sw,
90
            st_send_spi_data_1, st_wait_spi_ack_1, st_wait_spi_di_req_2, st_wait_spi_ack_2,
91
            st_wait_spi_di_req_3, st_wait_spi_ack_3);
92 5 jdoin
 
93 13 jdoin
    type fsm_slave_write_state_type is
94 20 jdoin
            (st_reset, st_wait_spi_start, st_wait_spi_di_req_2, st_wait_spi_ack_2, st_wait_spi_do_valid_1,
95 13 jdoin
            st_wait_spi_di_req_3, st_wait_spi_ack_3, st_wait_spi_end);
96
 
97
    type fsm_slave_read_state_type is
98
            (st_reset, st_wait_spi_do_valid_1, st_wait_spi_n_do_valid_1, st_wait_spi_do_valid_2,
99
            st_wait_spi_n_do_valid_2, st_wait_spi_do_valid_3, st_wait_spi_n_do_valid_3);
100
 
101 5 jdoin
    --=============================================================================================
102
    -- Signals for state machine control
103
    --=============================================================================================
104 13 jdoin
    signal m_wr_st_reg  : fsm_master_write_state_type := st_reset;
105
    signal m_wr_st_next : fsm_master_write_state_type := st_reset;
106
    signal s_wr_st_reg  : fsm_slave_write_state_type := st_reset;
107
    signal s_wr_st_next : fsm_slave_write_state_type := st_reset;
108
    signal s_rd_st_reg  : fsm_slave_read_state_type := st_reset;
109
    signal s_rd_st_next : fsm_slave_read_state_type := st_reset;
110 5 jdoin
 
111
    --=============================================================================================
112
    -- Signals for internal operation
113
    --=============================================================================================
114 10 jdoin
    --- clock enable signals ---
115
    signal samp_ce          : std_logic := '1';         -- clock enable for sample inputs
116
    signal fsm_ce           : std_logic := '1';         -- clock enable for fsm logic
117
    --- switch debouncer signals ---
118
    signal sw_data          : std_logic_vector (7 downto 0) := (others => '0'); -- debounced switch data
119
    signal sw_reg           : std_logic_vector (7 downto 0) := (others => '0'); -- registered switch data 
120
    signal sw_next          : std_logic_vector (7 downto 0) := (others => '0'); -- combinatorial switch data
121
    signal new_switch       : std_logic := '0';                                 -- detector for new switch data
122
    --- pushbutton debouncer signals ---
123
    signal btn_data         : std_logic_vector (5 downto 0) := (others => '0'); -- debounced state of pushbuttons
124
    signal btn_reg          : std_logic_vector (5 downto 0) := (others => '0'); -- registered button data 
125
    signal btn_next         : std_logic_vector (5 downto 0) := (others => '0'); -- combinatorial button data
126
    signal new_button       : std_logic := '0';                                 -- detector for new button data
127
    --- spi port signals ---
128
    -- spi bus wires
129
    signal spi_ssel         : std_logic;
130
    signal spi_sck          : std_logic;
131
    signal spi_mosi         : std_logic;
132
    signal spi_miso         : std_logic;
133
    -- spi master port control signals
134
    signal spi_rst_reg      : std_logic := '1';
135
    signal spi_rst_next     : std_logic := '1';
136
    signal spi_ssel_reg     : std_logic;
137
    signal spi_wren_reg_m   : std_logic := '0';
138
    signal spi_wren_next_m  : std_logic := '0';
139
    -- spi master port flow control flags
140
    signal spi_di_req_m     : std_logic;
141
    signal spi_do_valid_m   : std_logic;
142
    -- spi master port parallel data bus
143
    signal spi_di_reg_m     : std_logic_vector (N-1 downto 0) := (others => '0');
144
    signal spi_di_next_m    : std_logic_vector (N-1 downto 0) := (others => '0');
145
    signal spi_do_m         : std_logic_vector (N-1 downto 0);
146
    signal spi_wr_ack_m     : std_logic;
147
    -- spi slave port control signals
148
    signal spi_wren_reg_s   : std_logic := '1';
149 12 jdoin
    signal spi_wren_next_s  : std_logic := '1';
150 10 jdoin
    -- spi slave port flow control flags
151
    signal spi_di_req_s     : std_logic;
152
    signal spi_do_valid_s   : std_logic;
153
    -- spi slave port parallel data bus
154 12 jdoin
    signal spi_di_reg_s     : std_logic_vector (N-1 downto 0) := (others => '0');
155 10 jdoin
    signal spi_di_next_s    : std_logic_vector (N-1 downto 0) := (others => '0');
156
    signal spi_do_s         : std_logic_vector (N-1 downto 0);
157 13 jdoin
    signal spi_wr_ack_s     : std_logic;
158 10 jdoin
    signal spi_rx_bit_s     : std_logic;
159 20 jdoin
    -- spi debug data --
160
    signal spi_state_m      : std_logic_vector (3 downto 0);
161
    signal spi_state_s      : std_logic_vector (3 downto 0);
162 13 jdoin
    -- slave data output regs --
163
    signal s_do_1_reg       : std_logic_vector (N-1 downto 0) := (others => '0');
164
    signal s_do_1_next      : std_logic_vector (N-1 downto 0) := (others => '0');
165
    signal s_do_2_reg       : std_logic_vector (N-1 downto 0) := (others => '0');
166
    signal s_do_2_next      : std_logic_vector (N-1 downto 0) := (others => '0');
167
    signal s_do_3_reg       : std_logic_vector (N-1 downto 0) := (others => '0');
168
    signal s_do_3_next      : std_logic_vector (N-1 downto 0) := (others => '0');
169 5 jdoin
    -- other signals
170 10 jdoin
    signal clear            : std_logic := '0';
171
    -- debug output signals
172 13 jdoin
    signal leds_reg         : std_logic_vector (7 downto 0);
173
    signal leds_next        : std_logic_vector (7 downto 0) := (others => '0');
174 12 jdoin
    signal dbg              : std_logic_vector (11 downto 0) := (others => '0');
175 5 jdoin
begin
176
 
177
    --=============================================================================================
178 10 jdoin
    -- COMPONENT INSTANTIATIONS FOR THE CORES UNDER TEST
179 5 jdoin
    --=============================================================================================
180 13 jdoin
    -- spi master port: data and control signals driven by the master fsm
181 10 jdoin
    Inst_spi_master_port: entity work.spi_master(rtl)
182 11 jdoin
        generic map (N => N, CPOL => CPOL, CPHA => CPHA, PREFETCH => 3, SPI_2X_CLK_DIV => SPI_2X_CLK_DIV)
183 5 jdoin
        port map(
184 10 jdoin
            sclk_i => gclk_i,                   -- system clock is used for serial and parallel ports
185
            pclk_i => gclk_i,
186 5 jdoin
            rst_i => spi_rst_reg,
187
            spi_ssel_o => spi_ssel,
188
            spi_sck_o => spi_sck,
189
            spi_mosi_o => spi_mosi,
190 13 jdoin
            spi_miso_i => spi_miso,             -- driven by the spi slave 
191 10 jdoin
            di_req_o => spi_di_req_m,
192
            di_i => spi_di_reg_m,
193 12 jdoin
            wren_i => spi_wren_reg_m,
194 13 jdoin
            wr_ack_o => spi_wr_ack_m,
195 10 jdoin
            do_valid_o => spi_do_valid_m,
196 20 jdoin
            do_o => spi_do_m,
197 12 jdoin
            ------------ debug pins ------------
198 20 jdoin
            state_dbg_o => spi_state_m          -- debug: internal state register
199 5 jdoin
        );
200
 
201 13 jdoin
    -- spi slave port: data and control signals driven by the slave fsm
202 10 jdoin
    Inst_spi_slave_port: entity work.spi_slave(rtl)
203 11 jdoin
        generic map (N => N, CPOL => CPOL, CPHA => CPHA, PREFETCH => 3)
204 10 jdoin
        port map(
205
            clk_i => gclk_i,
206 13 jdoin
            spi_ssel_i => spi_ssel,             -- driven by the spi master
207
            spi_sck_i => spi_sck,               -- driven by the spi master
208
            spi_mosi_i => spi_mosi,             -- driven by the spi master
209 10 jdoin
            spi_miso_o => spi_miso,
210
            di_req_o => spi_di_req_s,
211
            di_i => spi_di_reg_s,
212
            wren_i => spi_wren_reg_s,
213 13 jdoin
            wr_ack_o => spi_wr_ack_s,
214 10 jdoin
            do_valid_o => spi_do_valid_s,
215 20 jdoin
            do_o => spi_do_s,
216 12 jdoin
            ------------ debug pins ------------
217 20 jdoin
            state_dbg_o => spi_state_s          -- debug: internal state register
218 10 jdoin
        );
219
 
220 5 jdoin
    -- debounce for the input switches, with new data strobe output
221
    Inst_sw_debouncer: entity work.grp_debouncer(rtl)
222 20 jdoin
        generic map (N => 8, CNT_VAL => 200)  -- debounce 8 inputs with 200 us settling time
223 5 jdoin
        port map(
224 10 jdoin
            clk_i => gclk_i,                    -- system clock
225 5 jdoin
            data_i => sw_i,                     -- noisy input data
226 10 jdoin
            data_o => sw_data                   -- registered stable output data
227 12 jdoin
        );
228 5 jdoin
 
229
    -- debounce for the input pushbuttons, with new data strobe output
230
    Inst_btn_debouncer: entity work.grp_debouncer(rtl)
231 20 jdoin
        generic map (N => 6, CNT_VAL => 200)  -- debounce 6 inputs with 200 us settling time
232 5 jdoin
        port map(
233 10 jdoin
            clk_i => gclk_i,                    -- system clock
234 5 jdoin
            data_i => btn_i,                    -- noisy input data
235 10 jdoin
            data_o => btn_data                  -- registered stable output data
236 12 jdoin
        );
237 5 jdoin
 
238
    --=============================================================================================
239
    --  CONSTANTS CONSTRAINTS CHECKING
240
    --=============================================================================================
241
    -- clock dividers shall not be zero
242 11 jdoin
    assert FSM_CE_DIV > 0
243
    report "Constant 'FSM_CE_DIV' should not be zero"
244 5 jdoin
    severity FAILURE;
245
    -- minimum prefetch lookahead check
246 11 jdoin
    assert SPI_2X_CLK_DIV > 0
247
    report "Constant 'SPI_2X_CLK_DIV' should not be zero"
248 5 jdoin
    severity FAILURE;
249
    -- maximum prefetch lookahead check
250 11 jdoin
    assert SAMP_CE_DIV > 0
251
    report "Constant 'SAMP_CE_DIV' should not be zero"
252 5 jdoin
    severity FAILURE;
253
 
254
    --=============================================================================================
255
    --  CLOCK GENERATION
256
    --=============================================================================================
257 13 jdoin
    -- All registers are clocked directly from the 100MHz system clock.
258
    -- The clock generation block derives 2 clock enable signals, divided down from the 100MHz input 
259
    -- clock. 
260
    --      input sample clock enable, 
261
    --      fsm clock enable,
262 5 jdoin
    -----------------------------------------------------------------------------------------------
263
    -- generate the sampling clock enable from the 100MHz board input clock 
264
    samp_ce_gen_proc: process (gclk_i) is
265
        variable clk_cnt : integer range SAMP_CE_DIV-1 downto 0 := 0;
266
    begin
267
        if gclk_i'event and gclk_i = '1' then
268
            if clk_cnt = SAMP_CE_DIV-1 then
269 13 jdoin
                samp_ce <= '1';                 -- generate a single pulse every SAMP_CE_DIV clocks
270 5 jdoin
                clk_cnt := 0;
271
            else
272
                samp_ce <= '0';
273
                clk_cnt := clk_cnt + 1;
274
            end if;
275
        end if;
276
    end process samp_ce_gen_proc;
277
    -- generate the fsm clock enable from the 100MHz board input clock 
278
    fsm_ce_gen_proc: process (gclk_i) is
279
        variable clk_cnt : integer range FSM_CE_DIV-1 downto 0 := 0;
280
    begin
281
        if gclk_i'event and gclk_i = '1' then
282
            if clk_cnt = FSM_CE_DIV-1 then
283 13 jdoin
                fsm_ce <= '1';                  -- generate a single pulse every FSM_CE_DIV clocks
284 5 jdoin
                clk_cnt := 0;
285
            else
286
                fsm_ce <= '0';
287
                clk_cnt := clk_cnt + 1;
288
            end if;
289
        end if;
290
    end process fsm_ce_gen_proc;
291
 
292
    --=============================================================================================
293
    -- INPUTS LOGIC
294
    --=============================================================================================
295
    -- registered inputs
296 10 jdoin
    samp_inputs_proc: process (gclk_i) is
297 5 jdoin
    begin
298 10 jdoin
        if gclk_i'event and gclk_i = '1' then
299 5 jdoin
            if samp_ce = '1' then
300 10 jdoin
                clear <= btn_data(btUP);        -- clear is button UP
301 13 jdoin
                leds_reg <= leds_next;          -- update LEDs with spi_slave received data
302 5 jdoin
            end if;
303
        end if;
304
    end process samp_inputs_proc;
305
 
306
    --=============================================================================================
307 10 jdoin
    --  REGISTER TRANSFER PROCESSES
308 5 jdoin
    --=============================================================================================
309 13 jdoin
    -- fsm state and data registers: synchronous to the system clock
310 10 jdoin
    fsm_reg_proc : process (gclk_i) is
311 5 jdoin
    begin
312
        -- FFD registers clocked on rising edge and cleared on sync 'clear'
313 10 jdoin
        if gclk_i'event and gclk_i = '1' then
314 13 jdoin
            if clear = '1' then                     -- sync reset
315
                m_wr_st_reg <= st_reset;            -- only provide local reset for the state registers
316 5 jdoin
            else
317
                if fsm_ce = '1' then
318 13 jdoin
                    m_wr_st_reg <= m_wr_st_next;    -- master write state register update
319 5 jdoin
                end if;
320
            end if;
321
        end if;
322 13 jdoin
        -- FFD registers clocked on rising edge and cleared on ssel = '1'
323
        if gclk_i'event and gclk_i = '1' then
324
            if spi_ssel = '1' then                  -- sync reset
325
                s_wr_st_reg <= st_reset;            -- only provide local reset for the state registers
326
                s_rd_st_reg <= st_reset;
327
            else
328
                if fsm_ce = '1' then
329
                    s_wr_st_reg <= s_wr_st_next;    -- slave write state register update
330
                    s_rd_st_reg <= s_rd_st_next;    -- slave read state register update
331
                end if;
332
            end if;
333
        end if;
334 5 jdoin
        -- FFD registers clocked on rising edge, with no reset
335 10 jdoin
        if gclk_i'event and gclk_i = '1' then
336 5 jdoin
            if fsm_ce = '1' then
337 13 jdoin
                --------- master write fsm signals -----------
338 10 jdoin
                spi_wren_reg_m <= spi_wren_next_m;
339
                spi_di_reg_m <= spi_di_next_m;
340 5 jdoin
                spi_rst_reg <= spi_rst_next;
341
                spi_ssel_reg <= spi_ssel;
342
                sw_reg <= sw_next;
343
                btn_reg <= btn_next;
344 13 jdoin
                --------- slave write fsm signals -----------
345
                spi_wren_reg_s <= spi_wren_next_s;
346
                spi_di_reg_s <= spi_di_next_s;
347
                --------- slave read fsm signals -----------
348
                s_do_1_reg <= s_do_1_next;
349
                s_do_2_reg <= s_do_2_next;
350
                s_do_3_reg <= s_do_3_next;
351 5 jdoin
            end if;
352
        end if;
353
    end process fsm_reg_proc;
354
 
355
    --=============================================================================================
356 10 jdoin
    --  COMBINATORIAL NEXT-STATE LOGIC PROCESSES
357 5 jdoin
    --=============================================================================================
358
    -- edge detector for new switch data
359 13 jdoin
    new_switch_proc: new_switch <= '1' when sw_data /= sw_reg else '0';     -- '1' for edge
360
 
361 5 jdoin
    -- edge detector for new button data
362 13 jdoin
    new_button_proc: new_button <= '1' when btn_data /= btn_reg else '0';   -- '1' for edge
363
 
364
    -- master port fsm state and combinatorial logic
365
    fsm_m_wr_combi_proc: process ( m_wr_st_reg, spi_wren_reg_m, spi_di_reg_m, spi_di_req_m, spi_wr_ack_m,
366
                                spi_ssel_reg, spi_rst_reg, sw_data, sw_reg, new_switch, btn_data, btn_reg,
367 20 jdoin
                                new_button, clear) is
368 5 jdoin
    begin
369
        spi_rst_next <= spi_rst_reg;
370 10 jdoin
        spi_di_next_m <= spi_di_reg_m;
371
        spi_wren_next_m <= spi_wren_reg_m;
372 5 jdoin
        sw_next <= sw_reg;
373
        btn_next <= btn_reg;
374 13 jdoin
        m_wr_st_next <= m_wr_st_reg;
375
        case m_wr_st_reg is
376 5 jdoin
            when st_reset =>
377
                spi_rst_next <= '1';                        -- place spi interface on reset
378 10 jdoin
                spi_di_next_m <= (others => '0');           -- clear spi data port
379
                spi_wren_next_m <= '0';                     -- deassert write enable
380 13 jdoin
                m_wr_st_next <= st_wait_spi_idle;
381 5 jdoin
 
382
            when st_wait_spi_idle =>
383 12 jdoin
                spi_wren_next_m <= '0';                     -- remove write strobe on next clock
384 5 jdoin
                if spi_ssel_reg = '1' then
385
                    spi_rst_next <= '0';                    -- remove reset when interface is idle
386 13 jdoin
                    m_wr_st_next <= st_wait_new_switch;
387 5 jdoin
                end if;
388
 
389
            when st_wait_new_switch =>
390
                if new_switch = '1' then                    -- wait for new stable switch data
391
                    sw_next <= sw_data;                     -- load new switch data (end the mismatch condition)
392 13 jdoin
                    m_wr_st_next <= st_send_spi_data_sw;
393 5 jdoin
                elsif new_button = '1' then
394
                    btn_next <= btn_data;                   -- load new button data (end the mismatch condition)
395 20 jdoin
                    if clear = '0' then
396 13 jdoin
                        if btn_data(btDOWN) = '1' then
397
                            m_wr_st_next <= st_send_spi_data_sw;
398
                        elsif btn_data(btLEFT) = '1' then
399
                            m_wr_st_next <= st_send_spi_data_1;
400
                        elsif btn_data(btCENTER) = '1' then
401
                            m_wr_st_next <= st_send_spi_data_1;
402
                        elsif btn_data(btRIGHT) = '1' then
403
                            m_wr_st_next <= st_send_spi_data_1;
404
                        end if;
405 5 jdoin
                    end if;
406
                end if;
407
 
408 13 jdoin
            when st_send_spi_data_sw =>
409 10 jdoin
                spi_di_next_m <= sw_reg;                    -- load switch register to the spi port
410
                spi_wren_next_m <= '1';                     -- write data on next clock
411 13 jdoin
                m_wr_st_next <= st_wait_spi_ack_sw;
412 5 jdoin
 
413 13 jdoin
            when st_wait_spi_ack_sw =>                      -- the actual write happens on this state
414
                if spi_wr_ack_m = '1' then
415
                    spi_wren_next_m <= '0';                 -- remove write strobe on next clock
416
                    m_wr_st_next <= st_wait_spi_di_req_2;
417
                end if;
418
 
419
            when st_send_spi_data_1 =>
420
                spi_di_next_m <= X"A1";                     -- load switch register to the spi port
421
                spi_wren_next_m <= '1';                     -- write data on next clock
422
                m_wr_st_next <= st_wait_spi_ack_1;
423
 
424
            when st_wait_spi_ack_1 =>                       -- the actual write happens on this state
425
                if spi_wr_ack_m = '1' then
426
                    spi_wren_next_m <= '0';                 -- remove write strobe on next clock
427
                    m_wr_st_next <= st_wait_spi_di_req_2;
428
                end if;
429
 
430
            when st_wait_spi_di_req_2 =>
431
                if spi_di_req_m = '1' then
432
                    spi_di_next_m <= X"A2";
433
                    spi_wren_next_m <= '1';
434
                    m_wr_st_next <= st_wait_spi_ack_2;
435
                end if;
436 5 jdoin
 
437 13 jdoin
            when st_wait_spi_ack_2 =>                       -- the actual write happens on this state
438
                if spi_wr_ack_m = '1' then
439
                    spi_wren_next_m <= '0';                 -- remove write strobe on next clock
440
                    m_wr_st_next <= st_wait_spi_di_req_3;
441
                end if;
442
 
443
            when st_wait_spi_di_req_3 =>
444
                if spi_di_req_m = '1' then
445
                    spi_di_next_m <= X"A3";
446
                    spi_wren_next_m <= '1';
447
                    m_wr_st_next <= st_wait_spi_ack_3;
448
                end if;
449
 
450
            when st_wait_spi_ack_3 =>                       -- the actual write happens on this state
451
                if spi_wr_ack_m = '1' then
452
                    spi_wren_next_m <= '0';                 -- remove write strobe on next clock
453
                    m_wr_st_next <= st_wait_spi_idle;       -- wait transmission end
454
                end if;
455
 
456 5 jdoin
            when others =>
457 13 jdoin
                m_wr_st_next <= st_reset;                   -- state st_reset is safe state
458
 
459 5 jdoin
        end case;
460 13 jdoin
    end process fsm_m_wr_combi_proc;
461 5 jdoin
 
462 13 jdoin
    -- slave port fsm state and combinatorial logic
463 20 jdoin
    fsm_s_wr_combi_proc: process (  s_wr_st_reg, spi_di_req_s, spi_wr_ack_s, spi_do_valid_s,
464 13 jdoin
                                    spi_di_reg_s, spi_wren_reg_s, spi_ssel_reg) is
465
    begin
466
        spi_wren_next_s <= spi_wren_reg_s;
467
        spi_di_next_s <= spi_di_reg_s;
468
        s_wr_st_next <= s_wr_st_reg;
469
        case s_wr_st_reg is
470
            when st_reset =>
471
                spi_di_next_s <= X"D1";                     -- write first data word
472
                spi_wren_next_s <= '1';                     -- set write enable
473
                s_wr_st_next <= st_wait_spi_start;
474
 
475
            when st_wait_spi_start =>
476
                if spi_ssel_reg = '0' then                  -- wait for slave select
477
                    spi_wren_next_s <= '0';                 -- remove write enable
478
                    s_wr_st_next <= st_wait_spi_di_req_2;
479
                end if;
480
 
481
            when st_wait_spi_di_req_2 =>
482
                if spi_di_req_s = '1' then
483 20 jdoin
--                    spi_di_next_s <= X"D2";               -- do not write on this cycle (cycle miss)
484
--                    spi_wren_next_s <= '1';
485
                    s_wr_st_next <= st_wait_spi_do_valid_1;
486 13 jdoin
                end if;
487
 
488
            when st_wait_spi_ack_2 =>                       -- the actual write happens on this state
489
                if spi_wr_ack_s = '1' then
490
                    spi_wren_next_s <= '0';                 -- remove write strobe on next clock
491
                    s_wr_st_next <= st_wait_spi_di_req_3;
492
                end if;
493
 
494 20 jdoin
            when st_wait_spi_do_valid_1 =>
495
                if spi_do_valid_s = '1' then
496
                    s_wr_st_next <= st_wait_spi_di_req_3;
497
                end if;
498
 
499 13 jdoin
            when st_wait_spi_di_req_3 =>
500
                if spi_di_req_s = '1' then
501
                    spi_di_next_s <= X"D3";
502
                    spi_wren_next_s <= '1';
503
                    s_wr_st_next <= st_wait_spi_ack_3;
504
                end if;
505
 
506
            when st_wait_spi_ack_3 =>                       -- the actual write happens on this state
507
                if spi_wr_ack_s = '1' then
508
                    spi_wren_next_s <= '0';                 -- remove write strobe on next clock
509
                    s_wr_st_next <= st_wait_spi_end;        -- wait transmission end
510
                end if;
511
 
512
            when st_wait_spi_end =>                         -- wait interface to be deselected
513
                if spi_ssel_reg = '1' then
514
                    s_wr_st_next <= st_reset;               -- wait transmission start
515
                end if;
516
 
517
            when others =>
518
                s_wr_st_next <= st_reset;                   -- state st_reset is safe state
519
 
520
        end case;
521
    end process fsm_s_wr_combi_proc;
522
 
523
    -- slave port fsm state and combinatorial logic
524
    fsm_s_rd_combi_proc: process ( s_rd_st_reg, spi_do_valid_s, spi_do_s, s_do_1_reg, s_do_2_reg, s_do_3_reg) is
525
    begin
526
        s_do_1_next <= s_do_1_reg;
527
        s_do_2_next <= s_do_2_reg;
528
        s_do_3_next <= s_do_3_reg;
529
        s_rd_st_next <= s_rd_st_reg;
530
        case s_rd_st_reg is
531
            when st_reset =>
532
                s_rd_st_next <= st_wait_spi_do_valid_1;
533
 
534
            when st_wait_spi_do_valid_1 =>
535
                if spi_do_valid_s = '1' then                -- wait for receive data ready
536
                    s_do_1_next <= spi_do_s;                -- read data from output port
537
                    s_rd_st_next <= st_wait_spi_n_do_valid_1;
538
                end if;
539
 
540
            when st_wait_spi_n_do_valid_1 =>
541
                if spi_do_valid_s = '0' then
542
                    s_rd_st_next <= st_wait_spi_do_valid_2;
543
                end if;
544
 
545
            when st_wait_spi_do_valid_2 =>
546
                if spi_do_valid_s = '1' then                -- wait for receive data ready
547
                    s_do_2_next <= spi_do_s;                -- read data from output port
548
                    s_rd_st_next <= st_wait_spi_n_do_valid_2;
549
                end if;
550
 
551
            when st_wait_spi_n_do_valid_2 =>
552
                if spi_do_valid_s = '0' then
553
                    s_rd_st_next <= st_wait_spi_do_valid_3;
554
                end if;
555
 
556
            when st_wait_spi_do_valid_3 =>
557
                if spi_do_valid_s = '1' then                -- wait for receive data ready
558
                    s_do_3_next <= spi_do_s;                -- read data from output port
559
                    s_rd_st_next <= st_wait_spi_n_do_valid_3;
560
                end if;
561
 
562
            when st_wait_spi_n_do_valid_3 =>
563
                if spi_do_valid_s = '0' then
564
                    s_rd_st_next <= st_reset;
565
                end if;
566
 
567
            when others =>
568
                s_rd_st_next <= st_reset;                   -- state st_reset is safe state
569
 
570
        end case;
571
    end process fsm_s_rd_combi_proc;
572
 
573
    leds_combi_proc: process (btn_data, leds_reg, s_do_1_reg, s_do_2_reg, s_do_3_reg) is
574
    begin
575
        leds_next <= leds_reg;
576
        if btn_data(btRIGHT) = '1' then
577
            leds_next <= s_do_3_reg;
578
        elsif btn_data(btCENTER) = '1' then
579
            leds_next <= s_do_2_reg;
580
        elsif btn_data(btLEFT) = '1' then
581
            leds_next <= s_do_1_reg;
582
        elsif btn_data(btDOWN) = '1' then
583
            leds_next <= s_do_1_reg;
584
        end if;
585
    end process leds_combi_proc;
586
 
587 5 jdoin
    --=============================================================================================
588
    --  OUTPUT LOGIC PROCESSES
589
    --=============================================================================================
590
    -- connect the spi output wires
591 10 jdoin
    spi_ssel_o_proc:        spi_ssel_o      <= spi_ssel;
592
    spi_sck_o_proc:         spi_sck_o       <= spi_sck;
593
    spi_mosi_o_proc:        spi_mosi_o      <= spi_mosi;
594
    spi_miso_o_proc:        spi_miso_o      <= spi_miso;
595 12 jdoin
    -- connect leds_reg signal to LED outputs
596 13 jdoin
    led_o_proc:             led_o           <= leds_reg;
597 5 jdoin
 
598
    --=============================================================================================
599
    --  DEBUG LOGIC PROCESSES
600
    --=============================================================================================
601
    -- connect the debug vector outputs
602 10 jdoin
    dbg_o_proc:             dbg_o <= dbg;
603 13 jdoin
 
604
    -- connect debug port pins to spi ports instances interface signals
605
    -- master signals mapped on dbg
606
    dbg(11) <= spi_wren_reg_m;
607
    dbg(10) <= spi_wr_ack_m;
608
    dbg(9)  <= spi_di_req_m;
609
    dbg(8)  <= spi_do_valid_m;
610 20 jdoin
--    dbg(11 downto 8) <= spi_state_s;
611 13 jdoin
    -- slave signals mapped on dbg
612
    dbg(7)  <= spi_wren_reg_s;
613
    dbg(6)  <= spi_wr_ack_s;
614
    dbg(5)  <= spi_di_req_s;
615
    dbg(4)  <= spi_do_valid_s;
616 20 jdoin
    -- specific ports to test on testbench
617
    s_do_o <= spi_do_s;
618
    m_do_o <= spi_do_m;
619
    m_state_o <= spi_state_m;  -- master spi fsm state
620
    s_state_o <= spi_state_s;  -- slave spi fsm state
621 10 jdoin
 
622 5 jdoin
end behavioral;
623
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.