synthesizeable_vhdl-model-library:patras:fifos

FIFOs library

The FIFOs library consists of the following 2 generic components:

  • ff_N_W: single clocked fifo with N words of W bits each
  • dff_N_W: dual clocked fifo with N words of W bits each

The FIFOs library can be verified with this testbench: test_fifos

fifos.vhd
-- ############################################################################
-- # Project    :    Leonardo CBT-Kernel                                      #
-- #                                                                          #
-- # Filename   :    fifos.vhd                                                #
-- #                                                                          #
-- # Component  :    ff_N_W : single clocked fifo with N words of W bits      #
-- #                                                                          #
-- # Model      :    rtl                                                      #
-- #                                                                          #
-- # Designer   :    S. Theoharis,N. Zervas                                   #
-- # Institute  :    VLSI Design Lab., University of Patras                   #
-- # Date       :    01.05.1999                                               #
-- ############################################################################
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.useful_functions.all;
 
-- ff_N_W Entity Description
entity ff_N_W is
        generic(W: INTEGER := 1; --width of FIFO
                N: INTEGER := 8; --length of FIFO
	        K: INTEGER := 2); --threshold for AEF
	port(
		D: in unsigned(W-1 downto 0);
		Q: out unsigned(W-1 downto 0);
		RES, CLK, RDEN, WREN: in std_ulogic;
		F: buffer std_ulogic :='0';
		E: buffer std_ulogic :='1';
		HF, AEF: out std_ulogic
	);
end ff_N_W;
 
-- ff_N_W Architecture Description
architecture rtl of ff_N_W is
	constant N_2: integer:= N / 2; --N/2
	constant L: integer:=log2(N); --ceiling log2(N)
 
	subtype ramword is unsigned (W-1 downto 0);
	type rammemory is array (N-1 downto 0) of ramword;
	signal ram: rammemory;
 
	signal rcount, wcount: integer range 0 to N-1 :=0;
	signal T, S, R: std_ulogic :='0'; 
 
begin
	Read_Process: process(RES, CLK)
	begin
		if (RES='0') then
			rcount<=0;
			Q<=(OTHERS=>'0');
		elsif (rising_edge(CLK)) then
			if (RDEN='1' and E/='1') then
				Q<=ram(rcount);
				if(rcount=N-1) then
					rcount<=0;
					R<='1';
				else
					rcount<=rcount+1;
					R<='0';
				end if;
				else
					R<='0';
			end if;
		end if;
	end process Read_Process;
 
	Write_Process: process(RES, CLK)
	begin
		if (RES='0') then
			wcount<=0;
			ram<=(OTHERS=>(OTHERS=>'0'));
		elsif (rising_edge(CLK)) then
			if (WREN='1' and F/='1') then
				ram(wcount)<=D;
				if(wcount=N-1) then
					wcount<=0;
					S<='1';
				else
					wcount<=wcount+1;
					S<='0';
				end if;
			else
				S<='0';
			end if;
		end if;
	end process Write_Process;
 
	Toggle_Process:process(RES, S, R)
	begin
		if (RES='0') then
			T<='0';
		elsif (S='1') then
			T<='1';
		elsif (R='1') then
			T<='0';
		end if;
	end process Toggle_Process;
 
	Flag_Process: process(RES, rcount, wcount, T)
		variable rcount_ext, wcount_ext, diff: unsigned(L downto 0);
	begin
		wcount_ext:='0' & Conv_Unsigned(wcount,L);
		rcount_ext:='0' & Conv_Unsigned(rcount,L);
		if T='0' then
			diff:=wcount_ext-rcount_ext;
		else
			diff:=Conv_Unsigned(N,L+1)-rcount_ext+wcount_ext;
		end if;
 
		if (RES='0') then
			E<='1';
			F<='0';
		elsif diff=Conv_Unsigned(0,L+1) then
			E<='1';
			F<='0';
		elsif diff=Conv_Unsigned(N,L+1) then
			E<='0';
			F<='1';
		else
			E<='0';
			F<='0';
		end if;
 
		if (RES='0') then
			HF<='0';
			AEF<='1';
		else
			if (diff>Conv_Unsigned(N_2-1,L+1)) then 
				HF <= '1';
                        else
				HF <= '0';
                        end if; 
			if (diff<Conv_Unsigned(K,L+1) or  diff>Conv_Unsigned(N-K,L+1)) then
				AEF <= '1';
			else
				AEF <= '0';
			end if;
		end if;
	end process Flag_Process;
end rtl;
fifos.vhd
-- ############################################################################
-- # Project    :    Leonardo CBT-Kernel                                      #
-- #                                                                          #
-- # Filename   :    fifos.vhd                                                #
-- #                                                                          #
-- # Component  :    dff_N_W : dual clocked fifo with N words of W bits       #
-- #                                                                          #
-- # Model      :    rtl                                                      #
-- #                                                                          #
-- # Designer   :    S. Theoharis,N. Zervas                                   #
-- # Institute  :    VLSI Design Lab., University of Patras                   #
-- # Date       :    01.05.1999                                               #
-- ############################################################################
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.useful_functions.all;
 
-- dff_N_W Entity Description
entity dff_N_W is
        generic(W: INTEGER := 1; --width of FIFO
                N: INTEGER := 8; --length of FIFO
	        K: INTEGER := 2); --threshold for AEF
	port(
		D: in unsigned(W-1 downto 0);
		Q: out unsigned(W-1 downto 0);
		RES, RDCLK, WRCLK, RDEN, WREN: in std_ulogic;
		F: buffer std_ulogic :='0';
		E: buffer std_ulogic :='1';
		HF, AEF: out std_ulogic
	);
end dff_N_W;
 
-- dff_N_W Architecture Description
architecture rtl of dff_N_W is
	constant N_2: integer:=N / 2; --N/2
	constant L: integer:=log2(N); --ceiling log2(N)
 
	subtype ramword is unsigned (W-1 downto 0);
	type rammemory is array (N-1 downto 0) of ramword;
	signal ram: rammemory;
 
	signal rcount, wcount: integer range 0 to N-1 :=0;
	signal T, S, R: std_ulogic :='0'; 
 
begin
	Read_Process: process(RES, RDCLK)
	begin
		if (RES='0') then
			rcount<=0;
			Q<=(OTHERS=>'0');
		elsif (rising_edge(RDCLK)) then
			if (RDEN='1' and E/='1') then
				Q<=ram(rcount);
				if(rcount=N-1) then
					rcount<=0;
					R<='1';
				else
					rcount<=rcount+1;
					R<='0';
				end if;
			else
				R<='0';
			end if;
		end if;
	end process Read_Process;
 
	Write_Process: process(RES, WRCLK)
	begin
		if (RES='0') then
			wcount<=0;
			ram<=(OTHERS=>(OTHERS=>'0'));
		elsif (rising_edge(WRCLK)) then
			if (WREN='1' and F/='1') then
				ram(wcount)<=D;
				if(wcount=N-1) then
					wcount<=0;
					S<='1';
				else
					wcount<=wcount+1;
					S<='0';
				end if;
			else
				S<='0';
			end if;
		end if;
	end process Write_Process;
 
	Toggle_Process:process(RES, S, R)
	begin
		if (RES='0') then
			T<='0';
		elsif (S='1') then
			T<='1';
		elsif (R='1') then
			T<='0';
		end if;
	end process Toggle_Process;
 
	Flag_Process: process(RES, rcount, wcount, T)
		variable rcount_ext, wcount_ext, diff: unsigned(L downto 0);
	begin
		wcount_ext:='0' & Conv_Unsigned(wcount,L);
		rcount_ext:='0' & Conv_Unsigned(rcount,L);
		if T='0' then
			diff:=wcount_ext-rcount_ext;
		else
			diff:=Conv_Unsigned(N,L+1)-rcount_ext+wcount_ext;
		end if;
 
		if (RES='0') then
			E<='1';
			F<='0';
		elsif diff=Conv_Unsigned(0,L+1) then
			E<='1';
			F<='0';
		elsif diff=Conv_Unsigned(N,L+1) then
			E<='0';
			F<='1';
		else
			E<='0';
			F<='0';
		end if;
 
		if (RES='0') then
			HF<='0';
			AEF<='1';
		else
			if (diff>Conv_Unsigned(N_2-1,L+1)) then 
				HF <= '1';
                        else
				HF <= '0';
                        end if; 
			if (diff<Conv_Unsigned(K,L+1) or  diff>Conv_Unsigned(N-K,L+1)) then
				AEF <= '1';
			else
				AEF <= '0';
			end if;
		end if;
	end process Flag_Process;
end rtl;
test_fifos.vhd
-- ############################################################################
-- # Project    :    Leonardo CBT-Kernel                                      #
-- #                                                                          #
-- # Filename   :    test_fifos.vhd                                           #
-- #                                                                          #
-- # Component  :    test_fifos : Test Bench for various FIFOs                #
-- #                                                                          #
-- # Model      :    rtl                                                      #
-- #                                                                          #
-- # Designer   :    S. Theoharis,N. Zervas                                   #
-- # Institute  :    VLSI Design Lab., University of Patras                   #
-- # Date       :    01.05.1999                                               #
-- ############################################################################
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
 
entity test_fifos IS
END test_fifos;
 
ARCHITECTURE rtl OF test_fifos IS
 
COMPONENT ff_N_W is
        generic(W: INTEGER := 1; --width of FIFO
                N: INTEGER := 8; --length of FIFO
	        K: INTEGER := 2); --threshold for AEF
	port(
		D: in unsigned(W-1 downto 0);
		Q: out unsigned(W-1 downto 0);
		RES, CLK, RDEN, WREN: in std_ulogic;
		F: buffer std_ulogic :='0';
		E: buffer std_ulogic :='1';
		HF, AEF: out std_ulogic
	);
end COMPONENT;
 
COMPONENT dff_N_W is
        generic(W: INTEGER := 1; --width of FIFO
                N: INTEGER := 8; --length of FIFO
	        K: INTEGER := 2); --threshold for AEF
	port(
		D: in unsigned(W-1 downto 0);
		Q: out unsigned(W-1 downto 0);
		RES, RDCLK, WRCLK, RDEN, WREN: in std_ulogic;
		F: buffer std_ulogic :='0';
		E: buffer std_ulogic :='1';
		HF, AEF: out std_ulogic
	);
end COMPONENT;
 
 FOR ALL : ff_N_W USE ENTITY WORK.ff_N_W(rtl);
 FOR ALL : dff_N_W USE ENTITY WORK.dff_N_W(rtl);
 
 CONSTANT N : integer := 16;
 CONSTANT W : integer := 8;
 CONSTANT K : integer := 12;
 SIGNAL DIN1,DIN2,DOUT1,DOUT2 : unsigned(W-1 downto 0);
 SIGNAL RESET,CLK,RDEN,WREN,F1,E1,HF1,AEF1,F2,E2,HF2,AEF2 : std_ulogic := '0';
 
 BEGIN
 
Single_Fifo : ff_N_W
        GENERIC MAP (
                     W=>W,
                     N=>N,
                     K=>K
                    )
	PORT MAP (
		  D=>DIN1,
		  Q=>DOUT1,
		  RES=>RESET,
		  CLK=>CLK,
		  RDEN=>RDEN,
		  WREN=>WREN,
		  F=>F1,
		  E=>E1,
		  HF=>HF1,
		  AEF=>AEF1
		 );
 
Dual_Fifo : dff_N_W
        GENERIC MAP (
                     W=>W,
                     N=>N,
                     K=>K
                    )
	PORT MAP (
		  D=>DIN2,
		  Q=>DOUT2,
		  RES=>RESET,
		  RDCLK=>CLK,
		  WRCLK=>CLK,
		  RDEN=>RDEN,
		  WREN=>WREN,
		  F=>F2,
		  E=>E2,
		  HF=>HF2,
		  AEF=>AEF2
		 );
 
CLK <= not CLK AFTER 50 ns;
RESET <= '0', '1' AFTER 120 ns;
 
RDEN <= '0', '1' AFTER 1500 ns;
WREN <= '1', '0' AFTER 1500 ns;
 
PROCESS(RESET,CLK)
BEGIN
IF (RESET='0') THEN
	DIN1 <= (OTHERS=>'0');
	DIN2 <= (OTHERS=>'1');
ELSIF (rising_edge(CLK)) THEN
	DIN1 <= DIN1 + "1";
	DIN2 <= DIN2 - "1";
END IF;
END PROCESS;
 
END rtl;