Line 6... |
Line 6... |
-- Module Name: spi_master_atlys_top
|
-- Module Name: spi_master_atlys_top
|
-- Project Name: spi_master_slave
|
-- Project Name: spi_master_slave
|
-- Target Devices: Spartan-6 LX45
|
-- Target Devices: Spartan-6 LX45
|
-- Tool versions: ISE 13.1
|
-- Tool versions: ISE 13.1
|
-- Description:
|
-- Description:
|
-- This is a test project for the Atlys board, to test the spi_master and grp_debounce cores.
|
-- This is a verification project for the Digilent Atlys board, to test the SPI_MASTER, SPI_SLAVE and GRP_DEBOUNCE cores.
|
-- It uses the board's 100MHz clock input, and clocks all sequential logic at this clock.
|
-- It uses the board's 100MHz clock input, and clocks all sequential logic at this clock.
|
--
|
--
|
-- See the "spi_master_atlys.ucf" file for pin assignments.
|
-- See the "spi_master_atlys.ucf" file for pin assignments.
|
-- The test circuit uses the VHDCI connector on the Atlys to implement a 16-pin debug port to be used
|
-- The test circuit uses the VHDCI connector on the Atlys to implement a 16-pin debug port to be used
|
-- with a Tektronix MSO2014. The 16 debug pins are brought to 2 8x2 headers that form a umbilical
|
-- with a Tektronix MSO2014. The 16 debug pins are brought to 2 8x2 headers that form a umbilical
|
-- digital pod port.
|
-- digital pod port.
|
|
-- The board switches are used to set the SPI_MASTER transmit data, and the SPI_SLAVE receive data drives the switch LEDs.
|
|
-- The pushbuttons drive the slave transmit data, and the master received data drives the parallel debug port.
|
--
|
--
|
------------------------------ REVISION HISTORY -----------------------------------------------------------------------
|
------------------------------ REVISION HISTORY -----------------------------------------------------------------------
|
--
|
--
|
-- 2011/07/02 v0.01.0010 [JD] implemented a wire-through from switches to LEDs, just to test the toolchain. It worked!
|
-- 2011/07/02 v0.01.0010 [JD] implemented a wire-through from switches to LEDs, just to test the toolchain. It worked!
|
-- 2011/07/03 v0.01.0020 [JD] added clock input, and a simple LED blinker for each LED.
|
-- 2011/07/03 v0.01.0020 [JD] added clock input, and a simple LED blinker for each LED.
|
Line 40... |
Line 42... |
clear_i : in std_logic := '0'; -- btn used as clear signal
|
clear_i : in std_logic := '0'; -- btn used as clear signal
|
--- SPI interface ---
|
--- SPI interface ---
|
spi_ssel_o : out std_logic; -- spi port SSEL
|
spi_ssel_o : out std_logic; -- spi port SSEL
|
spi_sck_o : out std_logic; -- spi port SCK
|
spi_sck_o : out std_logic; -- spi port SCK
|
spi_mosi_o : out std_logic; -- spi port MOSI
|
spi_mosi_o : out std_logic; -- spi port MOSI
|
|
spi_miso_o : out std_logic; -- spi port MISO
|
--- input slide switches ---
|
--- input slide switches ---
|
sw_i : in std_logic_vector (7 downto 0); -- 8 input slide switches
|
sw_i : in std_logic_vector (7 downto 0); -- 8 input slide switches
|
--- input buttons ---
|
--- input buttons ---
|
btn_i : in std_logic_vector (5 downto 0); -- 6 input push buttons
|
btn_i : in std_logic_vector (5 downto 0); -- 6 input push buttons
|
--- output LEDs ----
|
--- output LEDs ----
|
led_o : out std_logic_vector (7 downto 0); -- output leds
|
led_o : out std_logic_vector (7 downto 0); -- output leds
|
--- debug outputs ---
|
--- debug outputs ---
|
dbg_o : out std_logic_vector (9 downto 0); -- 10 generic debug pins
|
dbg_o : out std_logic_vector (7 downto 0); -- 10 generic debug pins
|
--- spi debug pins ---
|
--- spi debug pins ---
|
|
spi_rx_bit_m_o : out std_logic; -- master rx bit feedback
|
|
spi_rx_bit_s_o : out std_logic; -- slave rx bit feedback
|
|
spi_do_valid_o : out std_logic; -- spi data valid
|
spi_di_req_o : out std_logic; -- spi data request
|
spi_di_req_o : out std_logic; -- spi data request
|
spi_wren_o : out std_logic; -- spi write enable
|
spi_wren_o : out std_logic; -- spi write enable
|
spi_wren_ack_o : out std_logic -- spi write enable ack
|
spi_wren_ack_o : out std_logic -- spi write enable ack
|
);
|
);
|
end spi_master_atlys_top;
|
end spi_master_atlys_top;
|
Line 62... |
Line 68... |
--=============================================================================================
|
--=============================================================================================
|
-- Constants
|
-- Constants
|
--=============================================================================================
|
--=============================================================================================
|
-- clock divider count values from gclk_i (100MHz board clock)
|
-- clock divider count values from gclk_i (100MHz board clock)
|
-- these constants shall not be zero
|
-- these constants shall not be zero
|
constant FSM_CE_DIV : integer := 1;
|
constant FSM_CE_DIV : integer := 1; -- fsm operates at 100MHz
|
constant SPI_2X_CLK_DIV : integer := 1; -- 50MHz SPI clock
|
constant SPI_2X_CLK_DIV : integer := 1; -- 50MHz SPI clock
|
constant SAMP_CE_DIV : integer := 1;
|
constant SAMP_CE_DIV : integer := 1; -- board signals sampled at 100MHz
|
-- spi port generics
|
-- spi port generics
|
constant N : integer := 8; -- 8 bits
|
constant N : integer := 8; -- 8 bits
|
|
|
-- button definitions
|
-- button definitions
|
constant btRESET : integer := 0; -- these are constants to use as btn_i(x)
|
constant btRESET : integer := 0; -- these are constants to use as btn_i(x)
|
Line 91... |
Line 97... |
signal state_next : fsm_state_type := st_reset;
|
signal state_next : fsm_state_type := st_reset;
|
|
|
--=============================================================================================
|
--=============================================================================================
|
-- Signals for internal operation
|
-- Signals for internal operation
|
--=============================================================================================
|
--=============================================================================================
|
-- clock signals
|
--- clock enable signals ---
|
signal core_clk : std_logic := '0'; -- core clock, direct copy of board clock
|
|
signal spi_2x_clk : std_logic := '0'; -- spi_2x clock, 50% clock divided-down from board clock
|
|
-- clock enable signals
|
|
signal samp_ce : std_logic := '1'; -- clock enable for sample inputs
|
signal samp_ce : std_logic := '1'; -- clock enable for sample inputs
|
signal fsm_ce : std_logic := '1'; -- clock enable for fsm logic
|
signal fsm_ce : std_logic := '1'; -- clock enable for fsm logic
|
-- switch debouncer signals
|
--- switch debouncer signals ---
|
signal sw_data : std_logic_vector (7 downto 0) := (others => '0'); -- debounced switch data
|
signal sw_data : std_logic_vector (7 downto 0) := (others => '0'); -- debounced switch data
|
signal sw_reg : std_logic_vector (7 downto 0) := (others => '0'); -- registered switch data
|
signal sw_reg : std_logic_vector (7 downto 0) := (others => '0'); -- registered switch data
|
signal sw_next : std_logic_vector (7 downto 0) := (others => '0'); -- combinatorial switch data
|
signal sw_next : std_logic_vector (7 downto 0) := (others => '0'); -- combinatorial switch data
|
signal new_switch : std_logic := '0'; -- detector for new switch data
|
signal new_switch : std_logic := '0'; -- detector for new switch data
|
-- pushbutton debouncer signals
|
--- pushbutton debouncer signals ---
|
signal btn_data : std_logic_vector (5 downto 0) := (others => '0'); -- debounced state of pushbuttons
|
signal btn_data : std_logic_vector (5 downto 0) := (others => '0'); -- debounced state of pushbuttons
|
signal btn_reg : std_logic_vector (5 downto 0) := (others => '0'); -- registered button data
|
signal btn_reg : std_logic_vector (5 downto 0) := (others => '0'); -- registered button data
|
signal btn_next : std_logic_vector (5 downto 0) := (others => '0'); -- combinatorial button data
|
signal btn_next : std_logic_vector (5 downto 0) := (others => '0'); -- combinatorial button data
|
signal new_button : std_logic := '0'; -- detector for new button data
|
signal new_button : std_logic := '0'; -- detector for new button data
|
-- spi port signals
|
--- spi port signals ---
|
|
-- spi bus wires
|
signal spi_ssel : std_logic;
|
signal spi_ssel : std_logic;
|
signal spi_sck : std_logic;
|
signal spi_sck : std_logic;
|
signal spi_mosi : std_logic;
|
signal spi_mosi : std_logic;
|
signal spi_di_req : std_logic;
|
signal spi_miso : std_logic;
|
signal spi_ssel_reg : std_logic;
|
-- spi master port control signals
|
signal spi_wr_ack : std_logic;
|
|
signal spi_rst_reg : std_logic := '1';
|
signal spi_rst_reg : std_logic := '1';
|
signal spi_rst_next : std_logic := '1';
|
signal spi_rst_next : std_logic := '1';
|
signal spi_di_reg : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal spi_ssel_reg : std_logic;
|
signal spi_di_next : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal spi_wren_reg_m : std_logic := '0';
|
signal spi_wren_reg : std_logic := '0';
|
signal spi_wren_next_m : std_logic := '0';
|
signal spi_wren_next : std_logic := '0';
|
-- spi master port flow control flags
|
|
signal spi_di_req_m : std_logic;
|
|
signal spi_do_valid_m : std_logic;
|
|
-- spi master port parallel data bus
|
|
signal spi_di_reg_m : std_logic_vector (N-1 downto 0) := (others => '0');
|
|
signal spi_di_next_m : std_logic_vector (N-1 downto 0) := (others => '0');
|
|
signal spi_do_m : std_logic_vector (N-1 downto 0);
|
|
-- spi master port debug flags
|
|
signal spi_rx_bit_m : std_logic;
|
|
signal spi_wr_ack_m : std_logic;
|
|
-- spi slave port control signals
|
|
signal spi_wren_reg_s : std_logic := '1';
|
|
signal spi_wren_next_s : std_logic := '0';
|
|
-- spi slave port flow control flags
|
|
signal spi_di_req_s : std_logic;
|
|
signal spi_do_valid_s : std_logic;
|
|
-- spi slave port parallel data bus
|
|
signal spi_di_reg_s : std_logic_vector (N-1 downto 0) := (7 => '1', 6 => '0', 5 => '1', others => '0');
|
|
signal spi_di_next_s : std_logic_vector (N-1 downto 0) := (others => '0');
|
|
signal spi_do_s : std_logic_vector (N-1 downto 0);
|
|
-- spi slave port debug flags
|
|
signal spi_rx_bit_s : std_logic;
|
|
signal spi_wr_ack_s : std_logic;
|
-- other signals
|
-- other signals
|
signal clear : std_logic := '0';
|
signal clear : std_logic := '0';
|
-- output signals
|
-- debug output signals
|
signal leds_reg : std_logic_vector (7 downto 0) := (others => '0'); -- registered led outputs
|
signal leds_reg : std_logic_vector (7 downto 0) := (others => '0');
|
signal dbg : std_logic_vector (9 downto 0) := (others => '0'); -- we have 10 debug pins available
|
signal dbg : std_logic_vector (7 downto 0) := (others => '0');
|
begin
|
begin
|
|
|
--=============================================================================================
|
--=============================================================================================
|
-- Component instantiation for the SPI port
|
-- COMPONENT INSTANTIATIONS FOR THE CORES UNDER TEST
|
--=============================================================================================
|
--=============================================================================================
|
-- spi_port is the spi output port
|
-- spi master port:
|
Inst_spi_port: entity work.spi_master(rtl)
|
-- receives parallel data from the slide switches, transmits to slave port.
|
|
-- receives serial data from slave port, sends to 8bit parallel debug port.
|
|
Inst_spi_master_port: entity work.spi_master(rtl)
|
generic map (N => N, CPOL => '0', CPHA => '0', PREFETCH => 3, SPI_2X_CLK_DIV => SPI_2X_CLK_DIV)
|
generic map (N => N, CPOL => '0', CPHA => '0', PREFETCH => 3, SPI_2X_CLK_DIV => SPI_2X_CLK_DIV)
|
port map(
|
port map(
|
sclk_i => core_clk, -- system clock is used for serial and parallel ports
|
sclk_i => gclk_i, -- system clock is used for serial and parallel ports
|
pclk_i => core_clk,
|
pclk_i => gclk_i,
|
rst_i => spi_rst_reg,
|
rst_i => spi_rst_reg,
|
spi_ssel_o => spi_ssel,
|
spi_ssel_o => spi_ssel,
|
spi_sck_o => spi_sck,
|
spi_sck_o => spi_sck,
|
spi_mosi_o => spi_mosi,
|
spi_mosi_o => spi_mosi,
|
di_req_o => spi_di_req,
|
spi_miso_i => spi_miso,
|
di_i => spi_di_reg,
|
di_req_o => spi_di_req_m,
|
wren_i => spi_wren_reg,
|
di_i => spi_di_reg_m,
|
|
do_valid_o => spi_do_valid_m,
|
|
do_o => spi_do_m,
|
|
rx_bit_reg_o => spi_rx_bit_m,
|
|
wren_i => spi_wren_reg_m,
|
wren_o => spi_wren_o,
|
wren_o => spi_wren_o,
|
wren_ack_o => spi_wr_ack, -- monitor wren ack from inside spi port
|
wren_ack_o => spi_wr_ack_m -- monitor wren ack from inside spi port
|
core_ce_o => dbg(8), -- monitor the internal core clock enable lines
|
|
core_n_ce_o => dbg(9)
|
|
);
|
);
|
|
|
spi_di_req_o <= spi_di_req; -- monitor data request
|
dbg(7 downto 0) <= spi_do_m(7 downto 0); -- connect master received data to 8bit debug port
|
spi_wren_ack_o <= spi_wr_ack;
|
spi_rx_bit_m_o <= spi_rx_bit_m; -- connect rx_bit monitor for master port
|
|
|
|
-- spi slave port
|
|
-- receives parallel data from the pushbuttons, transmits to master port.
|
|
-- receives serial data from master port, sends to the 8 LEDs.
|
|
Inst_spi_slave_port: entity work.spi_slave(rtl)
|
|
generic map (N => N, CPOL => '0', CPHA => '0', PREFETCH => 3)
|
|
port map(
|
|
clk_i => gclk_i,
|
|
spi_ssel_i => spi_ssel, -- generated by the spi master
|
|
spi_sck_i => spi_sck, -- generated by the spi master
|
|
spi_mosi_i => spi_mosi,
|
|
spi_miso_o => spi_miso,
|
|
di_req_o => spi_di_req_s,
|
|
di_i => spi_di_reg_s,
|
|
wren_i => spi_wren_reg_s,
|
|
rx_bit_reg_o => spi_rx_bit_s,
|
|
do_valid_o => spi_do_valid_s,
|
|
do_o => spi_do_s
|
|
);
|
|
|
|
spi_di_reg_s(7 downto 5) <= B"101"; -- get the slave transmit data from pushbuttons
|
|
spi_di_reg_s(4 downto 0) <= btn_data(5 downto 1);
|
|
spi_wren_reg_s <= '1'; -- fix wren to '1', for continuous load of transmit data
|
|
spi_rx_bit_s_o <= spi_rx_bit_s; -- connect rx_bit monitor for slave port
|
|
|
-- debounce for the input switches, with new data strobe output
|
-- debounce for the input switches, with new data strobe output
|
Inst_sw_debouncer: entity work.grp_debouncer(rtl)
|
Inst_sw_debouncer: entity work.grp_debouncer(rtl)
|
generic map (N => 8, CNT_VAL => 10000) -- debounce 8 inputs with 100 us settling time
|
generic map (N => 8, CNT_VAL => 10000) -- debounce 8 inputs with 100 us settling time
|
port map(
|
port map(
|
clk_i => core_clk, -- system clock
|
clk_i => gclk_i, -- system clock
|
data_i => sw_i, -- noisy input data
|
data_i => sw_i, -- noisy input data
|
data_o => sw_data, -- registered stable output data
|
data_o => sw_data -- registered stable output data
|
strb_o => dbg(0) -- monitor the debounced data strobe
|
-- strb_o => dbg(0) -- monitor the debounced data strobe
|
);
|
);
|
|
|
-- debounce for the input pushbuttons, with new data strobe output
|
-- debounce for the input pushbuttons, with new data strobe output
|
Inst_btn_debouncer: entity work.grp_debouncer(rtl)
|
Inst_btn_debouncer: entity work.grp_debouncer(rtl)
|
generic map (N => 6, CNT_VAL => 50000) -- debounce 6 inputs with 500 us settling time
|
generic map (N => 6, CNT_VAL => 50000) -- debounce 6 inputs with 500 us settling time
|
port map(
|
port map(
|
clk_i => core_clk, -- system clock
|
clk_i => gclk_i, -- system clock
|
data_i => btn_i, -- noisy input data
|
data_i => btn_i, -- noisy input data
|
data_o => btn_data, -- registered stable output data
|
data_o => btn_data -- registered stable output data
|
strb_o => dbg(3) -- monitor the debounced data strobe
|
-- strb_o => dbg(3) -- monitor the debounced data strobe
|
);
|
);
|
|
|
dbg1_proc: dbg(1) <= new_switch; -- monitor new_switch signal
|
|
dbg2_proc: dbg(2) <= sw_i(0); -- monitor raw input (rightmost switch)
|
|
dbg4_proc: dbg(4) <= new_button; -- monitor new_button signal
|
|
dbg5_proc: dbg(5) <= btn_i(5); -- monitor raw input (center btn)
|
|
|
|
--=============================================================================================
|
--=============================================================================================
|
-- CONSTANTS CONSTRAINTS CHECKING
|
-- CONSTANTS CONSTRAINTS CHECKING
|
--=============================================================================================
|
--=============================================================================================
|
-- clock dividers shall not be zero
|
-- clock dividers shall not be zero
|
assert FSM_CE_DIV > 0
|
assert FSM_CE_DIV > 0
|
Line 201... |
Line 249... |
-- The clock generation block derives 3 internal clocks, divided down from the 100MHz input clock
|
-- The clock generation block derives 3 internal clocks, divided down from the 100MHz input clock
|
-- core clock,
|
-- core clock,
|
-- spi 2x base clock,
|
-- spi 2x base clock,
|
-- fsm clock,
|
-- fsm clock,
|
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
-- generate the core clock from the 100MHz board input clock
|
|
core_clock_gen_proc: core_clk <= gclk_i;
|
|
-- generate the sampling clock enable from the 100MHz board input clock
|
-- generate the sampling clock enable from the 100MHz board input clock
|
samp_ce_gen_proc: process (gclk_i) is
|
samp_ce_gen_proc: process (gclk_i) is
|
variable clk_cnt : integer range SAMP_CE_DIV-1 downto 0 := 0;
|
variable clk_cnt : integer range SAMP_CE_DIV-1 downto 0 := 0;
|
begin
|
begin
|
if gclk_i'event and gclk_i = '1' then
|
if gclk_i'event and gclk_i = '1' then
|
Line 231... |
Line 277... |
fsm_ce <= '0';
|
fsm_ce <= '0';
|
clk_cnt := clk_cnt + 1;
|
clk_cnt := clk_cnt + 1;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process fsm_ce_gen_proc;
|
end process fsm_ce_gen_proc;
|
-- generate the spi base clock from the 100MHz board input clock
|
|
-- spi_2x_clk_div_proc: spi_2x_clk <= gclk_i; -- generate 50MHz SPI SCK
|
|
|
|
spi_2x_clk_div_proc: process (gclk_i) is
|
|
variable clk_cnt : integer range SPI_2X_CLK_DIV-1 downto 0:= 0;
|
|
begin
|
|
if gclk_i'event and gclk_i = '1' then
|
|
if clk_cnt = SPI_2X_CLK_DIV-1 then
|
|
spi_2x_clk <= not spi_2x_clk;
|
|
clk_cnt := 0;
|
|
else
|
|
clk_cnt := clk_cnt + 1;
|
|
end if;
|
|
end if;
|
|
end process spi_2x_clk_div_proc;
|
|
|
|
--=============================================================================================
|
--=============================================================================================
|
-- INPUTS LOGIC
|
-- INPUTS LOGIC
|
--=============================================================================================
|
--=============================================================================================
|
-- registered inputs
|
-- registered inputs
|
samp_inputs_proc: process (core_clk) is
|
samp_inputs_proc: process (gclk_i) is
|
begin
|
begin
|
if core_clk'event and core_clk = '1' then
|
if gclk_i'event and gclk_i = '1' then
|
if samp_ce = '1' then
|
if samp_ce = '1' then
|
-- clear <= btn_data(btRESET); -- sample reset input
|
clear <= btn_data(btUP); -- clear is button UP
|
leds_reg <= sw_data; -- update LEDs with debounced switches
|
leds_reg <= spi_do_s; -- update LEDs with spi_slave received data
|
end if;
|
end if;
|
end if;
|
end if;
|
end process samp_inputs_proc;
|
end process samp_inputs_proc;
|
|
|
--=============================================================================================
|
--=============================================================================================
|
-- FSM REGISTER PROCESSES
|
-- REGISTER TRANSFER PROCESSES
|
--=============================================================================================
|
--=============================================================================================
|
-- fsm state and data registers: synchronous to the spi base reference clock
|
-- fsm state and data registers: synchronous to the spi base reference clock
|
fsm_reg_proc : process (core_clk) is
|
fsm_reg_proc : process (gclk_i) is
|
begin
|
begin
|
-- FFD registers clocked on rising edge and cleared on sync 'clear'
|
-- FFD registers clocked on rising edge and cleared on sync 'clear'
|
if core_clk'event and core_clk = '1' then
|
if gclk_i'event and gclk_i = '1' then
|
if clear = '1' then -- sync reset
|
if clear = '1' then -- sync reset
|
state_reg <= st_reset; -- only provide local reset for the state register
|
state_reg <= st_reset; -- only provide local reset for the state register
|
else
|
else
|
if fsm_ce = '1' then
|
if fsm_ce = '1' then
|
state_reg <= state_next; -- state register
|
state_reg <= state_next; -- state register
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
-- FFD registers clocked on rising edge, with no reset
|
-- FFD registers clocked on rising edge, with no reset
|
if core_clk'event and core_clk = '1' then
|
if gclk_i'event and gclk_i = '1' then
|
if fsm_ce = '1' then
|
if fsm_ce = '1' then
|
spi_wren_reg <= spi_wren_next;
|
spi_wren_reg_m <= spi_wren_next_m;
|
spi_di_reg <= spi_di_next;
|
spi_di_reg_m <= spi_di_next_m;
|
|
-- spi_wren_reg_s <= spi_wren_next_s;
|
|
-- spi_di_reg_s <= spi_di_next_s;
|
spi_rst_reg <= spi_rst_next;
|
spi_rst_reg <= spi_rst_next;
|
spi_ssel_reg <= spi_ssel;
|
spi_ssel_reg <= spi_ssel;
|
sw_reg <= sw_next;
|
sw_reg <= sw_next;
|
btn_reg <= btn_next;
|
btn_reg <= btn_next;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process fsm_reg_proc;
|
end process fsm_reg_proc;
|
|
|
--=============================================================================================
|
--=============================================================================================
|
-- FSM COMBINATORIAL NEXT-STATE LOGIC PROCESSES
|
-- COMBINATORIAL NEXT-STATE LOGIC PROCESSES
|
--=============================================================================================
|
--=============================================================================================
|
-- edge detector for new switch data
|
-- edge detector for new switch data
|
new_switch_proc: new_switch <= '1' when sw_data /= sw_reg else '0'; -- '1' for difference
|
new_switch_proc: new_switch <= '1' when sw_data /= sw_reg else '0'; -- '1' for difference
|
-- edge detector for new button data
|
-- edge detector for new button data
|
new_button_proc: new_button <= '1' when btn_data /= btn_reg else '0'; -- '1' for difference
|
new_button_proc: new_button <= '1' when btn_data /= btn_reg else '0'; -- '1' for difference
|
-- fsm state and combinatorial logic
|
-- fsm state and combinatorial logic
|
-- the sequencer will wait for a new switch combination, and send the switch data to the spi port
|
-- the sequencer will wait for a new switch combination, and send the switch data to the spi port
|
fsm_combi_proc: process ( state_reg, spi_wren_reg, spi_di_reg, spi_di_req, spi_wr_ack,
|
fsm_combi_proc: process ( state_reg, spi_wren_reg_m, spi_di_reg_m, spi_di_req_m, spi_wr_ack_m, -- spi_di_reg_s,
|
spi_ssel_reg, spi_rst_reg, sw_data, sw_reg, new_switch,
|
spi_wren_reg_s, spi_ssel_reg, spi_rst_reg, sw_data,
|
btn_data, btn_reg, new_button) is
|
sw_reg, new_switch, btn_data, btn_reg, new_button) is
|
begin
|
begin
|
spi_di_next <= spi_di_reg;
|
|
spi_rst_next <= spi_rst_reg;
|
spi_rst_next <= spi_rst_reg;
|
spi_wren_next <= spi_wren_reg;
|
spi_di_next_m <= spi_di_reg_m;
|
|
spi_wren_next_m <= spi_wren_reg_m;
|
|
-- spi_di_next_s <= spi_di_reg_s;
|
|
-- spi_wren_next_s <= spi_wren_reg_s;
|
sw_next <= sw_reg;
|
sw_next <= sw_reg;
|
btn_next <= btn_reg;
|
btn_next <= btn_reg;
|
state_next <= state_reg;
|
state_next <= state_reg;
|
case state_reg is
|
case state_reg is
|
when st_reset =>
|
when st_reset =>
|
spi_rst_next <= '1'; -- place spi interface on reset
|
spi_rst_next <= '1'; -- place spi interface on reset
|
spi_di_next <= (others => '0'); -- clear spi data port
|
spi_di_next_m <= (others => '0'); -- clear spi data port
|
spi_wren_next <= '0'; -- deassert write enable
|
spi_di_next_s <= (others => '0'); -- clear spi data port
|
|
spi_wren_next_m <= '0'; -- deassert write enable
|
|
spi_wren_next_s <= '0'; -- deassert write enable
|
state_next <= st_wait_spi_idle;
|
state_next <= st_wait_spi_idle;
|
|
|
when st_wait_spi_idle =>
|
when st_wait_spi_idle =>
|
if spi_ssel_reg = '1' then
|
if spi_ssel_reg = '1' then
|
spi_rst_next <= '0'; -- remove reset when interface is idle
|
spi_rst_next <= '0'; -- remove reset when interface is idle
|
Line 328... |
Line 365... |
if new_switch = '1' then -- wait for new stable switch data
|
if new_switch = '1' then -- wait for new stable switch data
|
sw_next <= sw_data; -- load new switch data (end the mismatch condition)
|
sw_next <= sw_data; -- load new switch data (end the mismatch condition)
|
state_next <= st_send_spi_data;
|
state_next <= st_send_spi_data;
|
elsif new_button = '1' then
|
elsif new_button = '1' then
|
btn_next <= btn_data; -- load new button data (end the mismatch condition)
|
btn_next <= btn_data; -- load new button data (end the mismatch condition)
|
if btn_data /= (5 downto 0 => '0') then
|
if btn_data /= B"000001" then
|
state_next <= st_send_spi_data;
|
state_next <= st_send_spi_data;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
when st_send_spi_data =>
|
when st_send_spi_data =>
|
spi_di_next <= sw_reg; -- load switch register to the spi port
|
spi_di_next_m <= sw_reg; -- load switch register to the spi port
|
spi_wren_next <= '1'; -- write data on next clock
|
spi_wren_next_m <= '1'; -- write data on next clock
|
state_next <= st_wait_spi_ack;
|
state_next <= st_wait_spi_ack;
|
|
|
when st_wait_spi_ack => -- the actual write happens on this state
|
when st_wait_spi_ack => -- the actual write happens on this state
|
spi_di_next <= sw_reg; -- load switch register to the spi port
|
spi_di_next_m <= sw_reg; -- load switch register to the spi port
|
if spi_wr_ack = '1' then -- wait acknowledge
|
if spi_wr_ack_m = '1' then -- wait acknowledge
|
spi_wren_next <= '0'; -- remove write strobe on next clock
|
spi_wren_next_m <= '0'; -- remove write strobe on next clock
|
state_next <= st_wait_spi_finish;
|
state_next <= st_wait_spi_finish;
|
end if;
|
end if;
|
|
|
when st_wait_spi_finish =>
|
when st_wait_spi_finish =>
|
if spi_ssel_reg = '1' then
|
if spi_ssel_reg = '1' then
|
Line 362... |
Line 399... |
--=============================================================================================
|
--=============================================================================================
|
-- connect the spi output wires
|
-- connect the spi output wires
|
spi_ssel_o_proc: spi_ssel_o <= spi_ssel;
|
spi_ssel_o_proc: spi_ssel_o <= spi_ssel;
|
spi_sck_o_proc: spi_sck_o <= spi_sck;
|
spi_sck_o_proc: spi_sck_o <= spi_sck;
|
spi_mosi_o_proc: spi_mosi_o <= spi_mosi;
|
spi_mosi_o_proc: spi_mosi_o <= spi_mosi;
|
-- connect leds_reg signal to LED outputs
|
spi_miso_o_proc: spi_miso_o <= spi_miso;
|
leds_out_proc: led_o <= leds_reg;
|
spi_do_valid_o_proc: spi_do_valid_o <= spi_do_valid_m;
|
|
spi_di_req_o_proc: spi_di_req_o <= spi_di_req_m;
|
|
spi_wren_ack_o_proc: spi_wren_ack_o <= spi_wr_ack_m;
|
|
led_o_proc: led_o <= leds_reg; -- connect leds_reg signal to LED outputs
|
|
|
--=============================================================================================
|
--=============================================================================================
|
-- DEBUG LOGIC PROCESSES
|
-- DEBUG LOGIC PROCESSES
|
--=============================================================================================
|
--=============================================================================================
|
-- connect the debug vector outputs
|
-- connect the debug vector outputs
|