--===========================================================================-- -- Design units : external static ram access control -- -- File name : ramacc.vhd -- -- Purpose : controls read/write access to an external static ram -- -- Note : NON-COMMERCIAL USAGE ONLY -- -- Limitations : -- -- Errors : -- -- Library : -- -- Dependencies : -- -- Author : Juergen Hasch, hasch@t-online.de -- Meisenstr. 23 -- 73066 Uhingen -- Germany -- -- Synthesis : Xilinx Foundation F1.4 ------------------------------------------------------------------------------- -- Revision list -- Version Author Date Changes -- 1.0 JH 16 Mar 98 File created -- 11 Apr 98 incorporated txaddr counter -- 1.1 JH 21 May 98 incorporated epp address counters -- ------------------------------------------------------------------------------- Library ieee; use ieee.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity ramacc is port ( clk: in std_logic; -- mighty master clock rxwrreq: in STD_LOGIC; -- receiver write request txrdreq: in STD_LOGIC; -- transmitter read request rxwrok: out STD_LOGIC; -- receiver write request finished txrdok: buffer STD_LOGIC; -- transmitter read request finished epprdreq: in STD_LOGIC; -- epp read request eppwrreq: in STD_LOGIC; -- epp write request eppok: buffer STD_LOGIC; -- epp write request finished oe: out STD_LOGIC; -- ram output enable (low active) we: out STD_LOGIC; -- ram write enable (low active) ce: buffer STD_LOGIC; -- ram chip enable (low active) enable: out STD_LOGIC; -- data output buffer enable (low active) rxadr: in STD_LOGIC_VECTOR (11 downto 0); -- receiver write address txempty: buffer std_logic; -- tx buffer empty eppdat: in STD_LOGIC_VECTOR (7 downto 0); -- epp write data rxdat: in STD_LOGIC_VECTOR (7 downto 0); -- receiver write data ramadr: out STD_LOGIC_VECTOR (12 downto 0); -- ram address ramout: out STD_LOGIC_VECTOR (7 downto 0); -- ram output data ramin: in STD_LOGIC_VECTOR (7 downto 0); -- ram input data datout: out STD_LOGIC_VECTOR (7 downto 0); -- output data for epp read and tx read epprdaddr: out STD_LOGIC_VECTOR (11 downto 0)); -- receiver write address end ramacc; architecture behavior of ramacc is type StateType is (tx_rd,rx_wr,epp_rd,epp_wr); signal state: StateType; -- what is ramacc doing right now ? signal txadr: std_logic_vector(11 downto 0); signal ewraddr: std_logic_vector(11 downto 0); signal erdaddr: std_logic_vector(11 downto 0); signal ongoing: std_logic; begin --txempty <= '0'; txempty <= '1' when (txadr = ewraddr) else '0'; datout <= ramin; -- route read data through directly epprdaddr <= erdaddr; -- epp read address pointer is needed in hdlcdec -- -- update data pointers -- -- epp write address pointer p01: process(clk,eppok,eppwrreq,ewraddr,state) begin if (clk='1' and clk'event) then if ( eppok='1' and state=epp_wr) then ewraddr <= ewraddr+1; end if; end if; end process; -- epp read address pointer p02: process(clk,eppok,epprdreq,erdaddr) begin if (clk='1' and clk'event) then if ( eppok='1' and state=epp_rd) then erdaddr <= erdaddr+1; end if; end if; end process; p03: process(clk,txrdok,txempty,txadr) begin if (clk'event and clk ='1') then if ( txempty='0' and txrdok='1' and txrdreq='1') then txadr <= txadr+1; end if; end if; end process; -- -- access acknowledge / end of cycle after one clock cycle -- p2: process(clk,txrdreq,rxwrreq,epprdreq,eppwrreq,rxdat,eppdat,rxadr,txadr,erdaddr,ewraddr) begin if (txrdreq='0' and rxwrreq='0' and epprdreq='0' and eppwrreq='0') then ongoing <= '0'; state <= epp_rd; elsif (clk'event and clk='1') then if (ongoing='0') then if ( txrdreq='1' ) then -- highest priority is transmitter read request state <= tx_rd; elsif (rxwrreq='1' ) then state <= rx_wr; elsif (eppwrreq='1') then state <= epp_wr; else -- elsif (epprdreq='1' ) then state <= epp_rd; end if; end if; ongoing <=not(ongoing); end if; end process; process(state,txadr,rxadr,ewraddr,erdaddr,rxdat,eppdat) begin case state is when tx_rd => enable <='1'; ramadr <= ( '1' & txadr); ramout <= (others => '-'); when rx_wr => enable <='0'; ramadr <= ( '0' & rxadr); ramout <= rxdat; when epp_wr => enable <='0'; ramadr <= ( '1' & ewraddr); ramout <= eppdat; when epp_rd => enable <='1'; ramadr <= ( '0' & erdaddr); ramout <= (others => '-'); end case; end process; -- -- set signals for external sram -- p2a: process(clk,txrdreq,rxwrreq,epprdreq,eppwrreq,rxdat,eppdat,rxadr,txadr,erdaddr,ewraddr,ongoing) begin if (ongoing='0') then txrdok <= '0'; rxwrok <= '0'; eppok <= '0'; ce <= '1'; oe <= '1'; we <= '1'; elsif (clk'event and clk='0') then ce <= '0'; case state is when tx_rd => txrdok <= '1'; rxwrok <= '0'; eppok <= '0'; oe <= '0'; we <= '1'; when rx_wr => rxwrok <= '1'; txrdok <= '0'; eppok <= '0'; oe <= '1'; we <= '0'; when epp_wr => eppok <= '1'; txrdok <= '0'; rxwrok <= '0'; oe <= '1'; we <= '0'; when epp_rd => eppok <= '1'; txrdok <= '0'; rxwrok <= '0'; oe <= '0'; we <= '1'; end case; end if; end process; end behavior; --========================= End of ramacc ================================--