====== FIFOs library ====== The FIFOs library consists of the following 2 generic components: * [[.:fifos#ff_N_W]]: single clocked fifo with N words of W bits each * [[.:fifos#dff_N_W]]: dual clocked fifo with N words of W bits each The FIFOs library can be verified with this testbench: [[.:fifos#testbench|test_fifos]] ===== ff_N_W ===== -- ############################################################################ -- # 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 (diffConv_Unsigned(N-K,L+1)) then AEF <= '1'; else AEF <= '0'; end if; end if; end process Flag_Process; end rtl; ===== dff_N_W ===== -- ############################################################################ -- # 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 (diffConv_Unsigned(N-K,L+1)) then AEF <= '1'; else AEF <= '0'; end if; end if; end process Flag_Process; end rtl; ===== Testbench ===== -- ############################################################################ -- # 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;