URL
https://opencores.org/ocsvn/simpcon/simpcon/trunk
Subversion Repositories simpcon
[/] [simpcon/] [trunk/] [vhdl/] [sc2avalon.vhd] - Rev 18
Go to most recent revision | Compare with Previous | Blame | View Log
-- -- sc2avalon.vhd -- -- SimpCon to Avalon bridge -- -- Author: Martin Schoeberl martin@jopdesign.com -- -- 2006-08-10 first version -- Library IEEE; use IEEE.std_logic_1164.all; use ieee.numeric_std.all; entity sc2avalon is generic (addr_bits : integer); port ( clk, reset : in std_logic; -- SimpCon interface sc_address : in std_logic_vector(addr_bits-1 downto 0); sc_wr_data : in std_logic_vector(31 downto 0); sc_rd, sc_wr : in std_logic; sc_rd_data : out std_logic_vector(31 downto 0); sc_rdy_cnt : out unsigned(1 downto 0); -- Avalon interface av_address : out std_logic_vector(addr_bits-1+2 downto 0); av_writedata : out std_logic_vector(31 downto 0); av_byteenable : out std_logic_vector(3 downto 0); av_readdata : in std_logic_vector(31 downto 0); av_read : out std_logic; av_write : out std_logic; av_waitrequest : in std_logic ); end sc2avalon; architecture rtl of sc2avalon is type state_type is (idl, rd, rdw, wr, wrw); signal state : state_type; signal next_state : state_type; signal reg_addr : std_logic_vector(addr_bits-1 downto 0); signal reg_wr_data : std_logic_vector(31 downto 0); signal reg_rd_data : std_logic_vector(31 downto 0); signal reg_rd : std_logic; signal reg_wr : std_logic; begin av_byteenable <= "1111"; -- we use only 32 bit transfers av_address(1 downto 0) <= "00"; sc_rd_data <= reg_rd_data; -- -- Register memory address, write data and read data -- process(clk, reset) begin if reset='1' then reg_addr <= (others => '0'); reg_wr_data <= (others => '0'); elsif rising_edge(clk) then if sc_rd='1' or sc_wr='1' then reg_addr <= sc_address; end if; if sc_wr='1' then reg_wr_data <= sc_wr_data; end if; end if; end process; -- -- The address MUX slightly violates the Avalon -- specification. The address changes from the sc_address -- to the registerd address in the second cycle. However, -- as both registers contain the same value there should be -- no real glitch. For synchronous peripherals this is not -- an issue. For asynchronous peripherals (SRAM) the possible -- glitch should be short enough to be not seen on the output -- pins. -- process(sc_rd, sc_wr, sc_address, reg_addr) begin if sc_rd='1' or sc_wr='1' then av_address(addr_bits-1+2 downto 2) <= sc_address; else av_address(addr_bits-1+2 downto 2) <= reg_addr; end if; end process; -- Same game for the write data and write/read control process(sc_wr, sc_wr_data, reg_wr_data) begin if sc_wr='1' then av_writedata <= sc_wr_data; else av_writedata <= reg_wr_data; end if; end process; av_write <= sc_wr or reg_wr; av_read <= sc_rd or reg_rd; -- -- next state logic -- -- At the moment we do not support back to back read -- or write. We don't need it for JOP, right? -- If needed just copy the idl code to rd and wr. -- process(state, sc_rd, sc_wr, av_waitrequest) begin next_state <= state; case state is when idl => if sc_rd='1' then if av_waitrequest='0' then next_state <= rd; else next_state <= rdw; end if; elsif sc_wr='1' then if av_waitrequest='0' then next_state <= wr; else next_state <= wrw; end if; end if; when rdw => if av_waitrequest='0' then next_state <= rd; end if; when rd => next_state <= idl; when wrw => if av_waitrequest='0' then next_state <= wr; end if; when wr => next_state <= idl; end case; end process; -- -- state machine register -- and output register -- process(clk, reset) begin if (reset='1') then state <= idl; reg_rd_data <= (others => '0'); sc_rdy_cnt <= "00"; reg_rd <= '0'; reg_wr <= '0'; elsif rising_edge(clk) then state <= next_state; sc_rdy_cnt <= "00"; reg_rd <= '0'; reg_wr <= '0'; case next_state is when idl => when rdw => sc_rdy_cnt <= "11"; reg_rd <= '1'; when rd => reg_rd_data <= av_readdata; when wrw => sc_rdy_cnt <= "11"; reg_wr <= '1'; when wr => end case; end if; end process; end rtl;
Go to most recent revision | Compare with Previous | Blame | View Log