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 13

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

powered by: WebSVN 2.1.0

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