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 Generic ( CAT_FIFO_DEPTH : natural := 4; DATA_FIFO_DEPTH : natural := 16 ); 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, CAT_FIFO_DEPTH => CAT_FIFO_DEPTH, DATA_FIFO_DEPTH => DATA_FIFO_DEPTH ) 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.xfer_busy & 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;