OpenCores
URL https://opencores.org/ocsvn/wb_tk/wb_tk/trunk

Subversion Repositories wb_tk

[/] [wb_tk/] [trunk/] [wb_async_slave.vhd] - Diff between revs 6 and 7

Show entire file | Details | Blame | View Log

Rev 6 Rev 7
Line 1... Line 1...
 
--
 
--  Wishbone bus toolkit.
 
--
 
--  (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 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;
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.