Line 49... |
Line 49... |
--- 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 ---
|
|
s_do_o : out std_logic_vector (7 downto 0);
|
|
m_do_o : out std_logic_vector (7 downto 0);
|
m_state_o : out std_logic_vector (3 downto 0); -- master spi fsm state
|
m_state_o : out std_logic_vector (3 downto 0); -- master spi fsm state
|
s_state_o : out std_logic_vector (3 downto 0); -- slave spi fsm state
|
s_state_o : out std_logic_vector (3 downto 0); -- slave spi fsm state
|
dbg_o : out std_logic_vector (11 downto 0) -- 12 generic debug pins
|
dbg_o : out std_logic_vector (11 downto 0) -- 12 generic debug pins
|
);
|
);
|
end spi_master_atlys_top;
|
end spi_master_atlys_top;
|
Line 67... |
Line 69... |
constant FSM_CE_DIV : integer := 1; -- fsm operates at 100MHz
|
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; -- board signals sampled at 100MHz
|
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
|
constant CPOL : std_logic := '1';
|
constant CPOL : std_logic := '0';
|
constant CPHA : std_logic := '1';
|
constant CPHA : std_logic := '0';
|
|
|
-- 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)
|
constant btUP : integer := 1;
|
constant btUP : integer := 1;
|
constant btLEFT : integer := 2;
|
constant btLEFT : integer := 2;
|
Line 87... |
Line 89... |
(st_reset, st_wait_spi_idle, st_wait_new_switch, st_send_spi_data_sw, st_wait_spi_ack_sw,
|
(st_reset, st_wait_spi_idle, st_wait_new_switch, st_send_spi_data_sw, st_wait_spi_ack_sw,
|
st_send_spi_data_1, st_wait_spi_ack_1, st_wait_spi_di_req_2, st_wait_spi_ack_2,
|
st_send_spi_data_1, st_wait_spi_ack_1, st_wait_spi_di_req_2, st_wait_spi_ack_2,
|
st_wait_spi_di_req_3, st_wait_spi_ack_3);
|
st_wait_spi_di_req_3, st_wait_spi_ack_3);
|
|
|
type fsm_slave_write_state_type is
|
type fsm_slave_write_state_type is
|
(st_reset, st_wait_spi_start, st_wait_spi_di_req_2, st_wait_spi_ack_2,
|
(st_reset, st_wait_spi_start, st_wait_spi_di_req_2, st_wait_spi_ack_2, st_wait_spi_do_valid_1,
|
st_wait_spi_di_req_3, st_wait_spi_ack_3, st_wait_spi_end);
|
st_wait_spi_di_req_3, st_wait_spi_ack_3, st_wait_spi_end);
|
|
|
type fsm_slave_read_state_type is
|
type fsm_slave_read_state_type is
|
(st_reset, st_wait_spi_do_valid_1, st_wait_spi_n_do_valid_1, st_wait_spi_do_valid_2,
|
(st_reset, st_wait_spi_do_valid_1, st_wait_spi_n_do_valid_1, st_wait_spi_do_valid_2,
|
st_wait_spi_n_do_valid_2, st_wait_spi_do_valid_3, st_wait_spi_n_do_valid_3);
|
st_wait_spi_n_do_valid_2, st_wait_spi_do_valid_3, st_wait_spi_n_do_valid_3);
|
Line 152... |
Line 154... |
signal spi_di_reg_s : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal spi_di_reg_s : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal spi_di_next_s : std_logic_vector (N-1 downto 0) := (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);
|
signal spi_do_s : std_logic_vector (N-1 downto 0);
|
signal spi_wr_ack_s : std_logic;
|
signal spi_wr_ack_s : std_logic;
|
signal spi_rx_bit_s : std_logic;
|
signal spi_rx_bit_s : std_logic;
|
|
-- spi debug data --
|
|
signal spi_state_m : std_logic_vector (3 downto 0);
|
|
signal spi_state_s : std_logic_vector (3 downto 0);
|
-- slave data output regs --
|
-- slave data output regs --
|
signal s_do_1_reg : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal s_do_1_reg : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal s_do_1_next : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal s_do_1_next : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal s_do_2_reg : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal s_do_2_reg : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal s_do_2_next : std_logic_vector (N-1 downto 0) := (others => '0');
|
signal s_do_2_next : std_logic_vector (N-1 downto 0) := (others => '0');
|
Line 186... |
Line 191... |
di_req_o => spi_di_req_m,
|
di_req_o => spi_di_req_m,
|
di_i => spi_di_reg_m,
|
di_i => spi_di_reg_m,
|
wren_i => spi_wren_reg_m,
|
wren_i => spi_wren_reg_m,
|
wr_ack_o => spi_wr_ack_m,
|
wr_ack_o => spi_wr_ack_m,
|
do_valid_o => spi_do_valid_m,
|
do_valid_o => spi_do_valid_m,
|
do_o => spi_do_m
|
do_o => spi_do_m,
|
------------ debug pins ------------
|
------------ debug pins ------------
|
|
state_dbg_o => spi_state_m -- debug: internal state register
|
);
|
);
|
|
|
-- spi slave port: data and control signals driven by the slave fsm
|
-- spi slave port: data and control signals driven by the slave fsm
|
Inst_spi_slave_port: entity work.spi_slave(rtl)
|
Inst_spi_slave_port: entity work.spi_slave(rtl)
|
generic map (N => N, CPOL => CPOL, CPHA => CPHA, PREFETCH => 3)
|
generic map (N => N, CPOL => CPOL, CPHA => CPHA, PREFETCH => 3)
|
Line 204... |
Line 210... |
di_req_o => spi_di_req_s,
|
di_req_o => spi_di_req_s,
|
di_i => spi_di_reg_s,
|
di_i => spi_di_reg_s,
|
wren_i => spi_wren_reg_s,
|
wren_i => spi_wren_reg_s,
|
wr_ack_o => spi_wr_ack_s,
|
wr_ack_o => spi_wr_ack_s,
|
do_valid_o => spi_do_valid_s,
|
do_valid_o => spi_do_valid_s,
|
do_o => spi_do_s
|
do_o => spi_do_s,
|
------------ debug pins ------------
|
------------ debug pins ------------
|
|
state_dbg_o => spi_state_s -- debug: internal state register
|
);
|
);
|
|
|
-- 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 => 20000) -- debounce 8 inputs with 200 us settling time
|
generic map (N => 8, CNT_VAL => 200) -- debounce 8 inputs with 200 us settling time
|
port map(
|
port map(
|
clk_i => gclk_i, -- 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
|
);
|
);
|
|
|
-- 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 => 20000) -- debounce 6 inputs with 200 us settling time
|
generic map (N => 6, CNT_VAL => 200) -- debounce 6 inputs with 200 us settling time
|
port map(
|
port map(
|
clk_i => gclk_i, -- 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
|
);
|
);
|
Line 355... |
Line 362... |
new_button_proc: new_button <= '1' when btn_data /= btn_reg else '0'; -- '1' for edge
|
new_button_proc: new_button <= '1' when btn_data /= btn_reg else '0'; -- '1' for edge
|
|
|
-- master port fsm state and combinatorial logic
|
-- master port fsm state and combinatorial logic
|
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,
|
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,
|
spi_ssel_reg, spi_rst_reg, sw_data, sw_reg, new_switch, btn_data, btn_reg,
|
spi_ssel_reg, spi_rst_reg, sw_data, sw_reg, new_switch, btn_data, btn_reg,
|
new_button) is
|
new_button, clear) is
|
begin
|
begin
|
spi_rst_next <= spi_rst_reg;
|
spi_rst_next <= spi_rst_reg;
|
spi_di_next_m <= spi_di_reg_m;
|
spi_di_next_m <= spi_di_reg_m;
|
spi_wren_next_m <= spi_wren_reg_m;
|
spi_wren_next_m <= spi_wren_reg_m;
|
sw_next <= sw_reg;
|
sw_next <= sw_reg;
|
Line 383... |
Line 390... |
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)
|
m_wr_st_next <= st_send_spi_data_sw;
|
m_wr_st_next <= st_send_spi_data_sw;
|
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(btUP) = '0' then
|
if clear = '0' then
|
if btn_data(btDOWN) = '1' then
|
if btn_data(btDOWN) = '1' then
|
m_wr_st_next <= st_send_spi_data_sw;
|
m_wr_st_next <= st_send_spi_data_sw;
|
elsif btn_data(btLEFT) = '1' then
|
elsif btn_data(btLEFT) = '1' then
|
m_wr_st_next <= st_send_spi_data_1;
|
m_wr_st_next <= st_send_spi_data_1;
|
elsif btn_data(btCENTER) = '1' then
|
elsif btn_data(btCENTER) = '1' then
|
Line 451... |
Line 458... |
|
|
end case;
|
end case;
|
end process fsm_m_wr_combi_proc;
|
end process fsm_m_wr_combi_proc;
|
|
|
-- slave port fsm state and combinatorial logic
|
-- slave port fsm state and combinatorial logic
|
fsm_s_wr_combi_proc: process ( s_wr_st_reg, spi_di_req_s, spi_wr_ack_s,
|
fsm_s_wr_combi_proc: process ( s_wr_st_reg, spi_di_req_s, spi_wr_ack_s, spi_do_valid_s,
|
spi_di_reg_s, spi_wren_reg_s, spi_ssel_reg) is
|
spi_di_reg_s, spi_wren_reg_s, spi_ssel_reg) is
|
begin
|
begin
|
spi_wren_next_s <= spi_wren_reg_s;
|
spi_wren_next_s <= spi_wren_reg_s;
|
spi_di_next_s <= spi_di_reg_s;
|
spi_di_next_s <= spi_di_reg_s;
|
s_wr_st_next <= s_wr_st_reg;
|
s_wr_st_next <= s_wr_st_reg;
|
Line 471... |
Line 478... |
s_wr_st_next <= st_wait_spi_di_req_2;
|
s_wr_st_next <= st_wait_spi_di_req_2;
|
end if;
|
end if;
|
|
|
when st_wait_spi_di_req_2 =>
|
when st_wait_spi_di_req_2 =>
|
if spi_di_req_s = '1' then
|
if spi_di_req_s = '1' then
|
spi_di_next_s <= X"D2";
|
-- spi_di_next_s <= X"D2"; -- do not write on this cycle (cycle miss)
|
spi_wren_next_s <= '1';
|
-- spi_wren_next_s <= '1';
|
s_wr_st_next <= st_wait_spi_ack_2;
|
s_wr_st_next <= st_wait_spi_do_valid_1;
|
end if;
|
end if;
|
|
|
when st_wait_spi_ack_2 => -- the actual write happens on this state
|
when st_wait_spi_ack_2 => -- the actual write happens on this state
|
if spi_wr_ack_s = '1' then
|
if spi_wr_ack_s = '1' then
|
spi_wren_next_s <= '0'; -- remove write strobe on next clock
|
spi_wren_next_s <= '0'; -- remove write strobe on next clock
|
s_wr_st_next <= st_wait_spi_di_req_3;
|
s_wr_st_next <= st_wait_spi_di_req_3;
|
end if;
|
end if;
|
|
|
|
when st_wait_spi_do_valid_1 =>
|
|
if spi_do_valid_s = '1' then
|
|
s_wr_st_next <= st_wait_spi_di_req_3;
|
|
end if;
|
|
|
when st_wait_spi_di_req_3 =>
|
when st_wait_spi_di_req_3 =>
|
if spi_di_req_s = '1' then
|
if spi_di_req_s = '1' then
|
spi_di_next_s <= X"D3";
|
spi_di_next_s <= X"D3";
|
spi_wren_next_s <= '1';
|
spi_wren_next_s <= '1';
|
s_wr_st_next <= st_wait_spi_ack_3;
|
s_wr_st_next <= st_wait_spi_ack_3;
|
Line 593... |
Line 605... |
-- master signals mapped on dbg
|
-- master signals mapped on dbg
|
dbg(11) <= spi_wren_reg_m;
|
dbg(11) <= spi_wren_reg_m;
|
dbg(10) <= spi_wr_ack_m;
|
dbg(10) <= spi_wr_ack_m;
|
dbg(9) <= spi_di_req_m;
|
dbg(9) <= spi_di_req_m;
|
dbg(8) <= spi_do_valid_m;
|
dbg(8) <= spi_do_valid_m;
|
|
-- dbg(11 downto 8) <= spi_state_s;
|
-- slave signals mapped on dbg
|
-- slave signals mapped on dbg
|
dbg(7) <= spi_wren_reg_s;
|
dbg(7) <= spi_wren_reg_s;
|
dbg(6) <= spi_wr_ack_s;
|
dbg(6) <= spi_wr_ack_s;
|
dbg(5) <= spi_di_req_s;
|
dbg(5) <= spi_di_req_s;
|
dbg(4) <= spi_do_valid_s;
|
dbg(4) <= spi_do_valid_s;
|
|
-- specific ports to test on testbench
|
|
s_do_o <= spi_do_s;
|
|
m_do_o <= spi_do_m;
|
|
m_state_o <= spi_state_m; -- master spi fsm state
|
|
s_state_o <= spi_state_s; -- slave spi fsm state
|
|
|
end behavioral;
|
end behavioral;
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|