diff --git a/lib/spi/sim/tb_spi_master.wdo b/lib/spi/sim/tb_spi_master.wdo index 208ce36..735a766 100644 --- a/lib/spi/sim/tb_spi_master.wdo +++ b/lib/spi/sim/tb_spi_master.wdo @@ -12,12 +12,14 @@ add wave -noupdate -format Logic /tb_spi_master/mst_shift_en add wave -noupdate -format Literal -radix hexadecimal /tb_spi_master/mst_dout add wave -noupdate -format Logic /tb_spi_master/mst_dout_vld add wave -noupdate -format Logic /tb_spi_master/mst_dout_re -add wave -noupdate -format Logic /tb_spi_master/mosi -add wave -noupdate -format Logic /tb_spi_master/miso add wave -noupdate -format Logic /tb_spi_master/mst_clk +add wave -noupdate -format Logic /tb_spi_master/mosi +add wave -noupdate -format Logic /tb_spi_master/inst_spi_master/spi_clk_write +add wave -noupdate -format Logic /tb_spi_master/miso +add wave -noupdate -format Logic /tb_spi_master/inst_spi_master/spi_clk_read add wave -noupdate -format Logic /tb_spi_master/mso add wave -noupdate -format Literal /tb_spi_master/ctrl -add wave -noupdate -format Literal -expand /tb_spi_master/status +add wave -noupdate -format Literal /tb_spi_master/status add wave -noupdate -format Literal -radix hexadecimal /tb_spi_master/slv_rx_shiftreg add wave -noupdate -format Literal -radix hexadecimal /tb_spi_master/slv_rx_valid_pipe add wave -noupdate -format Literal -radix hexadecimal /tb_spi_master/slv_rx_data @@ -54,8 +56,14 @@ add wave -noupdate -format Literal -radix hexadecimal /tb_spi_master/inst_spi_ma add wave -noupdate -format Literal -radix hexadecimal /tb_spi_master/inst_spi_master/write_fifo_dout add wave -noupdate -format Logic /tb_spi_master/inst_spi_master/write_fifo_full add wave -noupdate -format Logic /tb_spi_master/inst_spi_master/write_fifo_empty +add wave -noupdate -format Logic /tb_spi_master/inst_spi_master/spi_clk_write +add wave -noupdate -format Logic /tb_spi_master/inst_spi_master/spi_clk_read +add wave -noupdate -format Literal /tb_spi_master/inst_spi_master/spi_rst_count +add wave -noupdate -format Logic /tb_spi_master/inst_spi_master/spi_rst +add wave -noupdate -format Logic /tb_spi_master/inst_spi_master/spi_clk_div_en +add wave -noupdate -format Literal /tb_spi_master/inst_spi_master/spi_clk_div_count TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 1} {17474865 ps} 0} +WaveRestoreCursors {{Cursor 1} {38978613 ps} 0} configure wave -namecolwidth 197 configure wave -valuecolwidth 131 configure wave -justifyvalue left diff --git a/lib/spi/src/spi_master.vhd b/lib/spi/src/spi_master.vhd index 6ae66e7..c043642 100644 --- a/lib/spi/src/spi_master.vhd +++ b/lib/spi/src/spi_master.vhd @@ -52,7 +52,8 @@ ARCHITECTURE behavior OF spi_master IS signal spi_clk : std_logic := '0'; signal spi_clk_out : std_logic; signal clk_en : std_logic; - signal spi_clk_data : std_logic; + signal spi_clk_write : std_logic; + signal spi_clk_read : std_logic; signal spi_rst_count : unsigned(5 downto 0); signal spi_rst : std_logic; @@ -81,6 +82,9 @@ ARCHITECTURE behavior OF spi_master IS signal rx_enable : std_logic; signal slv_enable : std_logic; + signal spi_clk_div_en : std_logic; + signal spi_clk_div_count : unsigned(7 downto 0); + -------------------------------------------------------------------------- begin @@ -89,7 +93,8 @@ begin write_fifo_din <= din; cmd_reg <= to_cmd(cat_fifo_dout); mosi <= tx_shift_reg(tx_shift_reg'left) when ctrl_reg.msb_first = '1' else tx_shift_reg(tx_shift_reg'right); - spi_clk_data <= spi_clk xor ctrl_reg.cpha; + spi_clk_write <= spi_clk xor ctrl_reg.cpha; + spi_clk_read <= spi_clk_out; dout_vld <= not read_fifo_empty; status.cmd_fifo_full <= cat_fifo_full; @@ -170,16 +175,14 @@ begin ); -------------------------------------------------------------------------- -proc_spi_clk_gen: +proc_spi_rst_gen: process(clk) begin if rising_edge(clk) then if rst = '1' then spi_rst <= '1'; - spi_clk <= '0'; spi_rst_count <= (others => '1'); else - spi_clk <= not spi_clk; if spi_rst_count /= to_unsigned(0, spi_rst_count'length) then spi_rst_count <= spi_rst_count - 1; else @@ -189,16 +192,46 @@ begin end if; end process; +proc_spi_clk_divider: +process(clk) +begin + if rising_edge(clk) then + spi_clk_div_en <= '0'; + if rst = '1' then + spi_clk_div_count <= (others => '0'); + elsif spi_clk_div_count = ctrl.clk_div then + spi_clk_div_count <= (others => '0'); + spi_clk_div_en <= '1'; + else + spi_clk_div_count <= spi_clk_div_count + 1; + end if; + end if; +end process; + +proc_spi_clk_gen: +process(clk) +begin + if rising_edge(clk) then + if rst = '1' then + spi_clk <= '0'; + elsif spi_clk_div_en = '1' then + spi_clk <= not spi_clk; + end if ; + end if; +end process; + proc_spi_clk_out_gen: process(clk) begin if rising_edge(clk) then if spi_rst = '1' then spi_clk_out <= '0'; - elsif clk_en = '0' then - spi_clk_out <= ctrl_reg.cpol; - else - spi_clk_out <= not spi_clk_out; + elsif spi_clk_div_en = '1' then + if clk_en = '0' then + spi_clk_out <= ctrl_reg.cpol; + else + spi_clk_out <= not spi_clk_out; + end if; end if; end if; end process; @@ -338,9 +371,9 @@ begin end process; PROC_TX_SHIFT_REG: -process(spi_clk_data) +process(spi_clk_write) begin - if rising_edge(spi_clk_data) then + if rising_edge(spi_clk_write) then if data_load_en = '1' then tx_shift_reg <= write_fifo_dout; elsif shift_en = '1' and xfer_count_en = '1' then @@ -355,9 +388,9 @@ end process; -- Receiver PROC_RX_SHIFT_REG: -process(spi_clk_out) +process(spi_clk_read) begin - if rising_edge(spi_clk_out) then + if rising_edge(spi_clk_read) then if shift_en = '1' and xfer_count_en = '1' then if slv_enable = '1' then if (ctrl_reg.msb_first = '1') then diff --git a/lib/spi/src/spi_types.vhd b/lib/spi/src/spi_types.vhd index cbfae48..8b1c902 100644 --- a/lib/spi/src/spi_types.vhd +++ b/lib/spi/src/spi_types.vhd @@ -19,6 +19,7 @@ package spi_types is cpol : std_logic; cpha : std_logic; msb_first : std_logic; + clk_div : unsigned(7 downto 0); end record; type status_t is record diff --git a/lib/spi/src/tb_spi_master.vhd b/lib/spi/src/tb_spi_master.vhd index 06db57c..7a8d8cd 100644 --- a/lib/spi/src/tb_spi_master.vhd +++ b/lib/spi/src/tb_spi_master.vhd @@ -60,12 +60,14 @@ ARCHITECTURE behavior OF tb_spi_master IS signal slv_tx_shiftreg : unsigned(31 downto 0) := (others => '0'); signal slv_rx_valid_pipe : unsigned(31 downto 0) := (others => '0'); signal slv_rx_data : unsigned(31 downto 0) := (others => '0'); + signal slv_rx_data_vld : STD_LOGIC; BEGIN ctrl.cpol <= '0'; ctrl.cpha <= '0'; ctrl.msb_first <= '1'; + ctrl.clk_div <= X"00"; inst_spi_master : entity work.spi_master GENERIC MAP @@ -104,16 +106,26 @@ CLK_GEN: process RX_SLAVE_SIM_SHIFT_REG: process(mst_clk) begin if rising_edge(mst_clk) then + slv_rx_data_vld <= '0'; if mso = '1' then if slv_rx_valid_pipe(slv_rx_valid_pipe'left) = '1' then slv_rx_valid_pipe <= (slv_rx_valid_pipe'left downto 1 => '0') & '1'; + slv_rx_data_vld <= '1'; else slv_rx_valid_pipe <= slv_rx_valid_pipe(slv_rx_valid_pipe'left-1 downto 0) & '1'; end if; slv_rx_shiftreg <= slv_rx_shiftreg(slv_rx_shiftreg'left-1 downto 0) & mosi; - slv_tx_shiftreg <= slv_tx_shiftreg(slv_tx_shiftreg'left-1 downto 0) & mosi; + end if; + end if; + end process; + +TX_SLAVE_SIM_SHIFT_REG: process(mst_clk) + begin + if falling_edge(mst_clk) then + if slv_rx_data_vld = '1' then + slv_tx_shiftreg <= slv_rx_shiftreg; else - slv_tx_shiftreg <= slv_tx_shiftreg(slv_tx_shiftreg'left-1 downto 0) & mosi; + slv_tx_shiftreg <= slv_tx_shiftreg(slv_tx_shiftreg'left-1 downto 0) & '0'; end if; end if; end process; @@ -186,19 +198,6 @@ STIMULUS: process wait until rising_edge(CLK) and mst_din_rdy = '1'; mst_din_vld <= '0'; --------------------------------------------------------- - wait until rising_edge(CLK); - mst_din <= X"C355AAC1"; - mst_din_vld <= '1'; - wait until rising_edge(CLK) and mst_din_rdy = '1'; - mst_din_vld <= '0'; - - wait until rising_edge(CLK); - mst_cmd <= to_cmd(64, 32); - mst_cmd_vld <= '1'; - wait until rising_edge(CLK) and mst_cmd_rdy = '1'; - mst_cmd_vld <= '0'; - -------------------------------------------------------- mst_din <= X"00000000"; for i in 0 to 16 loop @@ -219,6 +218,19 @@ STIMULUS: process wait until rising_edge(CLK) and mso = '0'; end loop; +-------------------------------------------------------- + wait until rising_edge(CLK); + mst_din <= X"C355AAC1"; + mst_din_vld <= '1'; + wait until rising_edge(CLK) and mst_din_rdy = '1'; + mst_din_vld <= '0'; + + wait until rising_edge(CLK); + mst_cmd <= to_cmd(64, 32); + mst_cmd_vld <= '1'; + wait until rising_edge(CLK) and mst_cmd_rdy = '1'; + mst_cmd_vld <= '0'; + -------------------------------------------------------- wait until rising_edge(CLK); mst_din <= X"C355AA00";