diff --git a/lib/spi/src/spi_master_wb.vhd b/lib/spi/src/spi_master_wb.vhd new file mode 100644 index 0000000..decf357 --- /dev/null +++ b/lib/spi/src/spi_master_wb.vhd @@ -0,0 +1,160 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +LIBRARY WORK; +USE WORK.spi_types.all; + +ENTITY spi_master_wb IS + Port + ( + CLK_I : in STD_LOGIC; + RST_I : in STD_LOGIC; + INT_O : out STD_LOGIC; + CYC_I : in STD_LOGIC; + STB_I : in STD_LOGIC; + SEL_I : in unsigned(3 downto 0); + WE_I : in STD_LOGIC; + ACK_O : out STD_LOGIC; + SRDY_O : out STD_LOGIC; + MRDY_I : in STD_LOGIC; + ADDR_I : in unsigned(31 downto 0); + DAT_I : in unsigned(31 downto 0); + DAT_O : out unsigned(31 downto 0); + spi_hold : in std_logic; + spi_ss : out std_logic; + spi_clk : out std_logic; + spi_miso : in std_logic; + spi_mosi : out std_logic + ); +END spi_master_wb; + +ARCHITECTURE rtl OF spi_master_wb IS + + -- Signals for UART connections + signal mst_cmd : cmd_t; + signal mst_cmd_vld : std_logic; + signal mst_cmd_rdy : std_logic; + signal mst_shift_en : std_logic; + signal mst_din_vld : std_logic; + signal mst_din_rdy : std_logic; + + signal mst_ctrl : ctrl_t; + signal mst_status : status_t; + signal mst_din : unsigned(31 downto 0); + signal mst_dout : unsigned(31 downto 0); + signal mst_dout_re : std_logic; + signal mst_dout_vld : std_logic; + +begin + mst_shift_en <= not spi_hold; + + SRDY_O <= CYC_I; + INT_O <= '0'; + +inst_spi_master : entity work.spi_master + GENERIC MAP + ( + word_width => 32 + ) + PORT MAP + ( + rst => RST_I, + clk => CLK_I, + cmd_vld => mst_cmd_vld, + cmd_rdy => mst_cmd_rdy, + cmd => mst_cmd, + din_vld => mst_din_vld, + din_rdy => mst_din_rdy, + din => mst_din, + dout_re => mst_dout_re, + dout_vld => mst_dout_vld, + dout => mst_dout, + shift_en => mst_shift_en, + mosi => spi_mosi, + miso => spi_miso, + sclk => spi_clk, + mso => spi_ss, + ctrl => mst_ctrl, + status => mst_status + + ); + +------------------------------------------------------------------ +registers_write: + process(CLK_I) + begin + if rising_edge(CLK_I) then + mst_cmd_vld <= '0'; + mst_din_vld <= '0'; + if RST_I = '1' then + mst_ctrl.clk_div <= to_unsigned(100, 8); + mst_ctrl.cpol <= '0'; + mst_ctrl.cpha <= '0'; + mst_ctrl.msb_first <= '1'; + elsif (STB_I and CYC_I and WE_I) = '1' then + case ADDR_I(5 downto 2) is + + when "0000" => + mst_cmd_vld <= DAT_I(0); + + when "0001" => + mst_cmd.xfer_size <= DAT_I; + + when "0010" => + mst_cmd.data_size <= DAT_I; + + when "0011" => + mst_din <= DAT_I; + mst_din_vld <= '1'; + + when "0100" => + mst_ctrl.clk_div <= DAT_I(7 downto 0); + mst_ctrl.cpol <= DAT_I(8); + mst_ctrl.cpha <= DAT_I(9); + mst_ctrl.msb_first <= DAT_I(10); + + when others => null; + end case; + end if; + end if; + end process; + +registers_read: + process(CLK_I) + begin + if rising_edge(CLK_I) then + mst_dout_re <= '0'; + ACK_O <= '0'; + if (STB_I and CYC_I) = '1' then + ACK_O <= not WE_I; + DAT_O <= (others => '0'); + case ADDR_I(5 downto 2) is + + when "0000" => + DAT_O(2 downto 0) <= mst_dout_vld & mst_din_rdy & mst_cmd_rdy; + DAT_O(15 downto 8) <= spi_hold & mst_status.rx_valid & mst_status.read_fifo_empty & mst_status.read_fifo_full & mst_status.write_fifo_empty & mst_status.write_fifo_full & mst_status.cmd_fifo_empty & mst_status.cmd_fifo_full; + + when "0001" => + DAT_O <= mst_cmd.xfer_size; + + when "0010" => + DAT_O <= mst_cmd.data_size; + + when "0011" => + DAT_O <= mst_dout; + mst_dout_re <= not WE_I; + + when "0100" => + DAT_O(7 downto 0) <= mst_ctrl.clk_div; + DAT_O(8) <= mst_ctrl.cpol; + DAT_O(9) <= mst_ctrl.cpha; + DAT_O(10) <= mst_ctrl.msb_first; + + when others => null; + end case; + end if; + end if; + end process; + +end rtl;