www.pudn.com > noc.rar > fwfrff_32.vhd


-------------------------------------------------------------------------- 
--  Design: FWSRFF  
--  File:   $Id: fwfrff_32.vhd,v 1.1 2003/10/31 11:45:09 aslusarc Exp $ 
-- 
--   
--  A 32bit wide and 16 deep FIFO which has common clocks 
--  for read and write  
-- 
--  Copyright (c) 1998 Nallatech Ltd.  All rights reserved. 
----------------------------------------------------------------------------							 
 
library IEEE; 
use IEEE.std_logic_1164.all; 
use IEEE.std_logic_unsigned.all; 
use IEEE.std_logic_arith.all; 
 
entity FWFRFF_32 is 
	generic( 
		NEEDBACKUPg : integer range 0 to 1 := 0; 
		ATLEASTNEMPTYg : integer range 0 to 15 := 8; 
		ATLEASTNFULLg : integer range 0 to 15 := 8 
	); 
	port( 
		DI	: in std_logic_vector(31 downto 0); 
		DO	: out std_logic_vector(31 downto 0); 
		WEN	: in std_logic; 
		CLK	: in std_logic; 
		REN	: in std_logic; 
		GSR_RST	: in std_logic; 
		SW_RST	: in std_logic; 
		BACKUP	: in std_logic; 
		FULL	: out std_logic; 
		EMPTY	: out std_logic; 
		N_EMPTY : out std_logic; 
		N_FULL  : out std_logic 
	); 
end FWFRFF_32; 
 
architecture FWFRFF_32_arch of FWFRFF_32 is 
 
component FIFOCNT4 
	port( 
		CLK 	: in std_logic; 
		GSR_RST	: in std_logic; 
		SW_RST	: in std_logic; 
		CE 	: in std_logic; 
		DIR 	: in std_logic; 
		Q	: out std_logic_vector(3 downto 0) 
	); 
	 
end component; 
 
component rm16x32d 
  PORT( 
    A: IN std_logic_vector(3 DOWNTO 0); 
    DI: IN std_logic_vector(31 DOWNTO 0); 
    WR_EN: IN std_logic; 
    WR_CLK: IN std_logic; 
    DPRA: IN std_logic_vector(3 DOWNTO 0); 
    SPO: OUT std_logic_vector(31 DOWNTO 0); 
    DPO: OUT std_logic_vector(31 DOWNTO 0)); 
end component; 
 
signal C_RDCNT : std_logic_vector(3 downto 0); 
signal C_WRCNT : std_logic_vector(3 downto 0); 
 
signal FIFO_GAGE : integer range 0 to 16; 
signal RD_DIR : std_logic; 
signal WEN_CHK : std_logic; 
signal REN_CHK : std_logic; 
signal STDLOGICONE : std_logic; 
 
signal FULLi, EMPTYi, N_EMPTYi, N_FULLi		: std_logic; 
 
begin 
 
	-- NOte that when the direction is set to '0' on these counters, the read enable signal is ignored 
	UWRCNTR : FIFOCNT4 port map( CLK => CLK, GSR_RST => GSR_RST, SW_RST=>SW_RST, CE => WEN_CHK, DIR => STDLOGICONE, Q => C_WRCNT); 
	URDCNTR : FIFOCNT4 port map( CLK => CLK, GSR_RST => GSR_RST, SW_RST=>SW_RST, CE => REN_CHK, DIR => RD_DIR, Q => C_RDCNT); 
	UTHERAM : RM16X32D port map( A => C_WRCNT, DI => DI, WR_EN => WEN, WR_CLK => CLK, DPRA => C_RDCNT , SPO => open, DPO => DO); 
 
	-- This is fixed at '1' all the time 
	STDLOGICONE <= '1'; 
 
	RD_DIR <= not(BACKUP); 
	WEN_CHK <= WEN; 
	REN_CHK <= REN; 
	 
	FULL <= FULLi; 
	EMPTY <= EMPTYi; 
	N_FULL <= N_FULLi; 
	N_EMPTY <= N_EMPTYi; 
	 
	FIFOFLAG : process( CLK, GSR_RST, SW_RST ) 
	begin 
		if GSR_RST='1' then 
			FIFO_GAGE <= 0; 
			N_EMPTYi <= '1'; 
			N_FULLi <= '0'; 
			FULLi <= '0'; 
			EMPTYi <= '1'; 
		elsif SW_RST='1' then 
			FIFO_GAGE <= 0; 
			N_EMPTYi <= '1'; 
			N_FULLi <= '0'; 
			FULLi <= '0'; 
			EMPTYi <= '1'; 
		elsif CLK'event and CLK='1' then 
			if( NEEDBACKUPg=1 ) then 
				if( WEN='1' and BACKUP='1' ) then 
					FIFO_GAGE <= FIFO_GAGE+2; 
				elsif( WEN='0' and BACKUP='1' ) then 
					FIFO_GAGE <= FIFO_GAGE + 1; 
				elsif( REN='1' and WEN='0' ) then 
					FIFO_GAGE <= FIFO_GAGE - 1; 
				elsif ( REN='0' and WEN='1' ) then 
					FIFO_GAGE <= FIFO_GAGE + 1; 
				end if; 
 
				if FIFO_GAGE=16 or FIFO_GAGE=15 or ( FIFO_GAGE=14 and REN='0' ) or ( FIFO_GAGE=13 and REN='0' and WEN='1' ) then 
					FULLi <= '1'; 
				else 
					FULLi <= '0'; 
				end if; 
				-- Do the empty flag 
				if ( FIFO_GAGE=0  and WEN='0' ) or ( FIFO_GAGE=1  and REN='1' and WEN='0' ) then 
					EMPTYi <= '1'; 
				else 
					EMPTYi <= '0'; 
				end if; 
			else 
				if( REN='1' and WEN='0' ) then		-- Take one from the FIFO 
--					if FIFO_GAGE=0 then 
--						FIFO_GAGE <= 16; 
--					else	 
						FIFO_GAGE <= FIFO_GAGE - 1; 
--					end if;	 
				elsif ( REN='0' and WEN='1' ) then	-- Puting one into the FIFO 
--					if FIFO_GAGE=16 then 
--						FIFO_GAGE <= 0; 
--					else	 
						FIFO_GAGE <= FIFO_GAGE + 1; 
--					end if;	 
				end if;					-- Other wise we are doing nothing or doing a read and a Write so no change 
				-- Do the FULL flag 
				if ( FIFO_GAGE=16 and REN='0' ) or ( FIFO_GAGE=15 and REN='0' and WEN='1' ) then 
					FULLi <= '1'; 
				else 
					FULLi <= '0'; 
				end if; 
				-- Do the empty flag 
				if ( FIFO_GAGE=0  and WEN='0' ) or ( FIFO_GAGE=1  and REN='1' and WEN='0' ) then 
					EMPTYi <= '1'; 
				else 
					EMPTYi <= '0'; 
				end if; 
			end if; 
			 
			if NEEDBACKUPg = 1 then 
				if( FIFO_GAGE < 14-ATLEASTNEMPTYg ) then 
					N_EMPTYi <= '1'; 
				else 
					N_EMPTYi <= '0'; 
				end if; 
			else 
				if( FIFO_GAGE < 16-ATLEASTNEMPTYg ) then 
					N_EMPTYi <= '1'; 
				else 
					N_EMPTYi <= '0'; 
				end if; 
			end if; 
			 
			if( FIFO_GAGE > (ATLEASTNFULLg+1) ) then 
				N_FULLi <= '1'; 
			else 
				N_FULLi <= '0'; 
			end if; 
		end if; 
	end process FIFOFLAG; 
	 
	 
end FWFRFF_32_arch;