-- produces FIFO of arbitrary width if >=72 with standard depths 512 library IEEE; use IEEE.STD_LOGIC_1164.all; library UNISIM; use UNISIM.vcomponents.all; entity tsfifo is generic ( width : integer := 672); -- bit width port ( inclk : in std_logic; -- write synchronous to inclk outclk : in std_logic; -- read synchronous to outclk reset_n : in std_logic; -- asyn rest activ low di : in std_logic_vector(width-1 downto 0); -- inclk wren : in std_logic; -- wren full : out std_logic; -- inclk wrerr : out std_logic; -- inclk, When the FIFO is full, any additional write operation generates an error flag. wrcount : out std_logic_vector(11 downto 0); -- inclk, The FIFO data write pointer. The value will wrap around if the maximum write pointer value has been reached do : out std_logic_vector(width-1 downto 0); --outclk rden : in std_logic; empty : out std_logic; -- outclk rderr : out std_logic; -- ouclk, When the FIFO is empty, any additional read operation generates an error flag. rdcount : out std_logic_vector(11 downto 0) -- outclk, The FIFO data read pointer. The value will wrap around if the maximum read pointer value has been reached. ); end tsfifo; architecture behv of tsfifo is component clksync port ( reset_n : in std_logic; fastclk : in std_logic; slowclk : in std_logic; fastin : in std_logic; slowout : out std_logic); end component; signal di_i : std_logic_vector(width-1 downto 0); signal do_i : std_logic_vector(width-1 downto 0); signal restv_in : std_logic_vector(35 downto 0); signal restv_out : std_logic_vector(35 downto 0); signal rst : std_logic; signal rst_syn : std_logic; signal rst_syn_out : std_logic; signal rstcnt : integer range 0 to 4; begin -- behv assert (width >= 72) report "tsfifo works only with width >=72" severity error; di_i <= di; do <= do_i; -- reset FIFO generate for 3 fclkdiv cycles rstsyn : process (inclk) begin -- process rstsyn if inclk'event and inclk = '1' then -- rising clock edge rst_syn <= not reset_n; end if; end process rstsyn; clksync_1 : clksync port map ( reset_n => reset_n, fastclk => inclk, slowclk => outclk, fastin => rst_syn, slowout => rst_syn_out); long_reset_p : process (outclk, reset_n) begin -- process long_reset_p if reset_n = '0' then -- asynchronous reset (active low) rstcnt <= 0; elsif outclk'event and outclk = '1' then -- rising clock edge if rst_syn_out = '1' then rstcnt <= rstcnt + 1; elsif rstcnt = 4 then rstcnt <= 0; elsif rstcnt /= 0 then rstcnt <= rstcnt + 1; end if; end if; end process long_reset_p; rst <= '1' when rstcnt /= 0 else '0'; -- first fifo generates all control signals: FIFO16_inst : FIFO16 generic map ( ALMOST_FULL_OFFSET => X"080", -- Sets almost full threshold ALMOST_EMPTY_OFFSET => X"080", -- Sets the almost empty threshold DATA_WIDTH => 36, -- Sets data width to 4, 9, 18, or 36 FIRST_WORD_FALL_THROUGH => true) -- Sets the FIFO FWFT to TRUE or FALSE port map ( ALMOSTEMPTY => open, -- 1-bit almost empty output flag ALMOSTFULL => open, -- 1-bit almost full output flag DO => do_i(width-1 downto width-32), -- 32-bit data output DOP => do_i(width-33 downto width-36), -- 4-bit parity data output EMPTY => empty, -- 1-bit empty output flag FULL => full, -- 1-bit full output flag RDCOUNT => rdcount, -- 12-bit read count output RDERR => rderr, -- 1-bit read error output WRCOUNT => wrcount, -- 12-bit write count output WRERR => wrerr, -- 1-bit write error DI => di_i(width-1 downto width-32), -- 32-bit data input DIP => di_i(width-33 downto width-36), -- 4-bit parity input RDCLK => outclk, -- 1-bit read clock input RDEN => rden, -- 1-bit read enable input RST => rst, -- 1-bit reset input WRCLK => inclk, -- 1-bit write clock input WREN => wren -- 1-bit write enable input ); norest : if width mod 36 = 0 generate fifo_1toend : for i in 1 to (width/36)-1 generate FIFO16_insta : FIFO16 generic map ( ALMOST_FULL_OFFSET => X"080", -- Sets almost full threshold ALMOST_EMPTY_OFFSET => X"080", -- Sets the almost empty threshold DATA_WIDTH => 36, -- Sets data width to 4, 9, 18, or 36 FIRST_WORD_FALL_THROUGH => true) -- Sets the FIFO FWFT to TRUE or FALSE port map ( ALMOSTEMPTY => open, -- 1-bit almost empty output flag ALMOSTFULL => open, -- 1-bit almost full output flag DO => do_i(width-1 -(i*36) downto width-32-(i*36)), -- 32-bit data output DOP => do_i(width-33-(i*36) downto width-36-(i*36)), -- 4-bit parity data output EMPTY => open, -- 1-bit empty output flag FULL => open, -- 1-bit full output flag RDCOUNT => open, -- 12-bit read count output RDERR => open, -- 1-bit read error output WRCOUNT => open, -- 12-bit write count output WRERR => open, -- 1-bit write error DI => di_i(width-1 -(i*36) downto width-32-(i*36)), -- 32-bit data input DIP => di_i(width-33-(i*36) downto width-36-(i*36)), -- 4-bit parity input RDCLK => outclk, -- 1-bit read clock input RDEN => rden, -- 1-bit read enable input RST => rst, -- 1-bit reset input WRCLK => inclk, -- 1-bit write clock input WREN => wren -- 1-bit write enable input ); end generate fifo_1toend; end generate norest; rest : if width mod 36 /= 0 generate fifo_1tonearend : for i in 1 to (width/36)-1 generate FIFO16_instb : FIFO16 generic map ( ALMOST_FULL_OFFSET => X"080", -- Sets almost full threshold ALMOST_EMPTY_OFFSET => X"080", -- Sets the almost empty threshold DATA_WIDTH => 36, -- Sets data width to 4, 9, 18, or 36 FIRST_WORD_FALL_THROUGH => true) -- Sets the FIFO FWFT to TRUE or FALSE port map ( ALMOSTEMPTY => open, -- 1-bit almost empty output flag ALMOSTFULL => open, -- 1-bit almost full output flag DO => do_i(width-1 -(i*36) downto width-32-(i*36)), -- 32-bit data output DOP => do_i(width-33-(i*36) downto width-36-(i*36)), -- 4-bit parity data output EMPTY => open, -- 1-bit empty output flag FULL => open, -- 1-bit full output flag RDCOUNT => open, -- 12-bit read count output RDERR => open, -- 1-bit read error output WRCOUNT => open, -- 12-bit write count output WRERR => open, -- 1-bit write error DI => di_i(width-1 -(i*36) downto width-32-(i*36)), -- 32-bit data input DIP => di_i(width-33-(i*36) downto width-36-(i*36)), -- 4-bit parity input RDCLK => outclk, -- 1-bit read clock input RDEN => rden, -- 1-bit read enable input RST => rst, -- 1-bit reset input WRCLK => inclk, -- 1-bit write clock input WREN => wren -- 1-bit write enable input ); end generate fifo_1tonearend; restv_in <= di_i(((width mod 36)-1) downto 0) & ((35-(width mod 36)) downto 0 => '0'); do_i(((width mod 36)-1) downto 0) <= restv_out(35 downto (36-(width mod 36))); FIFO16_instc : FIFO16 generic map ( ALMOST_FULL_OFFSET => X"080", -- Sets almost full threshold ALMOST_EMPTY_OFFSET => X"080", -- Sets the almost empty threshold DATA_WIDTH => 36, -- Sets data width to 4, 9, 18, or 36 FIRST_WORD_FALL_THROUGH => true) -- Sets the FIFO FWFT to TRUE or FALSE port map ( ALMOSTEMPTY => open, -- 1-bit almost empty output flag ALMOSTFULL => open, -- 1-bit almost full output flag DO => restv_out(35 downto 4), -- 32-bit data output DOP => restv_out(3 downto 0), -- 4-bit parity data output EMPTY => open, -- 1-bit empty output flag FULL => open, -- 1-bit full output flag RDCOUNT => open, -- 12-bit read count output RDERR => open, -- 1-bit read error output WRCOUNT => open, -- 12-bit write count output WRERR => open, -- 1-bit write error DI => restv_in(35 downto 4), -- 32-bit data input DIP => restv_in(3 downto 0), -- 4-bit parity input RDCLK => outclk, -- 1-bit read clock input RDEN => rden, -- 1-bit read enable input RST => rst, -- 1-bit reset input WRCLK => inclk, -- 1-bit write clock input WREN => wren -- 1-bit write enable input ); end generate rest; end behv;