head 1.2; access; symbols; locks; strict; comment @# @; 1.2 date 2003.11.20.05.07.57; author tantos; state Exp; branches; next 1.1; 1.1 date 2001.04.25.15.05.30; author tantos; state Exp; branches; next ; desc @@ 1.2 log @Large update to new version of wb_tk. Major changes: - Xilinx support added - Altera support is poor: though it's there I haven't tested or even compiled it for quite some time - Behavioral models are added - Async master is completely new: it's much more complicated but actually works - Cores are tested in real HW (x2s300e) - wb_out_reg currently lacks byte-select support - wb_in_reg is added as a trivial input register @ text @-- -- Wishbone bus toolkit. -- -- (c) Copyright Andras Tantos 2001/03/31 -- This code is distributed under the terms and conditions of the GNU General Public Lince. -- -- -- ELEMENTS: -- wb_async_slave: Wishbone bus to async (SRAM-like) bus slave bridge. ------------------------------------------------------------------------------- -- -- wb_async_slave -- ------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.STD_LOGIC_UNSIGNED.all; library wb_tk; use wb_tk.technology.all; entity wb_async_slave is generic ( dat_width: positive := 16; adr_width: positive := 20 ); port ( clk_i: in std_logic; rst_i: in std_logic := '0'; -- interface for wait-state generator state-machine wait_state: in std_logic_vector (3 downto 0); -- interface to wishbone master device adr_i: in std_logic_vector (adr_width-1 downto 0); sel_i: in std_logic_vector ((adr_width/8)-1 downto 0); dat_i: in std_logic_vector (dat_width-1 downto 0); dat_o: out std_logic_vector (dat_width-1 downto 0); dat_oi: in std_logic_vector (dat_width-1 downto 0) := (others => '-'); we_i: in std_logic; stb_i: in std_logic; ack_o: out std_logic := '0'; ack_oi: in std_logic := '-'; -- interface to async slave a_data: inout std_logic_vector (dat_width-1 downto 0) := (others => 'Z'); a_addr: out std_logic_vector (adr_width-1 downto 0) := (others => 'U'); a_rdn: out std_logic := '1'; a_wrn: out std_logic := '1'; a_cen: out std_logic := '1'; -- byte-enable signals a_byen: out std_logic_vector ((dat_width/8)-1 downto 0) ); end wb_async_slave; architecture wb_async_slave of wb_async_slave is -- multiplexed access signals to memory signal i_ack: std_logic; signal sm_ack: std_logic; type states is (sm_idle, sm_wait, sm_deact); signal state: states; signal cnt: std_logic_vector(3 downto 0); begin ack_o <= (stb_i and i_ack) or (not stb_i and ack_oi); dat_o_gen: for i in dat_o'RANGE generate dat_o(i) <= (stb_i and a_data(i)) or (not stb_i and dat_oi(i)); end generate; -- For 0WS operation i_ack is an async signal otherwise it's a sync one. i_ack_gen: process begin wait on sm_ack, stb_i, wait_state, state; if (wait_state = "0000") then case (state) is when sm_deact => i_ack <= '0'; when others => i_ack <= stb_i; end case; else i_ack <= sm_ack; end if; end process; -- SRAM signal-handler process sram_signals: process begin wait on state,we_i,a_data,adr_i,rst_i, stb_i, sel_i, dat_i; if (rst_i = '1') then a_wrn <= '1'; a_rdn <= '1'; a_cen <= '1'; a_addr <= (others => '-'); a_data <= (others => 'Z'); a_byen <= (others => '1'); else case (state) is when sm_deact => a_wrn <= '1'; a_rdn <= '1'; a_cen <= '1'; a_addr <= (others => '-'); a_data <= (others => 'Z'); a_byen <= (others => '1'); when others => a_addr <= adr_i; a_rdn <= not (not we_i and stb_i); a_wrn <= not (we_i and stb_i); a_cen <= not stb_i; a_byen <= not sel_i; if (we_i = '1') then a_data <= dat_i; else a_data <= (others => 'Z'); end if; end case; end if; end process; -- Aysnc access state-machine. async_sm: process -- variable cnt: std_logic_vector(3 downto 0) := "0000"; -- variable state: states := init; begin wait until clk_i'EVENT and clk_i = '1'; if (rst_i = '1') then state <= sm_idle; cnt <= ((0) => '1', others => '0'); sm_ack <= '0'; else case (state) is when sm_idle => -- Check if anyone needs access to the memory. -- it's rdy signal will already be pulled low, so we only have to start the access if (stb_i = '1') then case wait_state is when "0000" => sm_ack <= '1'; state <= sm_deact; when "0001" => sm_ack <= '1'; cnt <= "0001"; state <= sm_wait; when others => sm_ack <= '0'; cnt <= "0001"; state <= sm_wait; end case; end if; when sm_wait => if (cnt = wait_state) then -- wait cycle completed. state <= sm_deact; sm_ack <= '0'; cnt <= "0000"; else if (cnt+"1" = wait_state) then sm_ack <= '1'; else sm_ack <= '0'; end if; cnt <=cnt+"1"; end if; when sm_deact => if (stb_i = '1') then case wait_state is when "0000" => cnt <= "0000"; sm_ack <= '0'; state <= sm_wait; when others => sm_ack <= '0'; cnt <= "0000"; state <= sm_wait; end case; else sm_ack <= '0'; state <= sm_idle; end if; end case; end if; end process; end wb_async_slave; @ 1.1 log @Major reorganization and some new elements added. @ text @d19 1 d26 2 a27 2 width: positive := 16; addr_width: positive := 20 d32 1 a32 1 d37 5 a41 5 adr_i: in std_logic_vector (addr_width-1 downto 0); sel_i: in std_logic_vector ((addr_width/8)-1 downto 0); dat_i: in std_logic_vector (width-1 downto 0); dat_o: out std_logic_vector (width-1 downto 0); dat_oi: in std_logic_vector (width-1 downto 0) := (others => '-'); d46 1 a46 1 d48 2 a49 2 a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z'); a_addr: out std_logic_vector (addr_width-1 downto 0) := (others => 'U'); d54 1 a54 1 a_byen: out std_logic_vector ((width/8)-1 downto 0) d69 1 a69 1 dat_o(i) <= (stb_i and a_data(i)) or (not stb_i and dat_oi(i)); d71 1 a71 1 d73 1 a73 1 i_ack_gen: process is d85 1 a85 1 d87 1 a87 1 sram_signals: process is d96 1 a96 1 a_byen <= (others => '1'); d105 1 a105 1 a_byen <= (others => '1'); d111 3 a113 3 a_byen <= not sel_i; if (we_i = '1') then a_data <= dat_i; d122 1 a122 1 async_sm: process is d158 1 a158 1 if (add_one(cnt) = wait_state) then d163 1 a163 1 cnt <= add_one(cnt); @