library IEEE; use IEEE.std_logic_1164.all; use IEEE.MATH_REAL.all; use ieee.numeric_std.all; library gan_ganimede; use gan_ganimede.io_types.all; library techmap; use techmap.gencomp.all; entity fifo_buffer is generic ( buffer_size : natural := 64; tech : integer := 0; data_width : natural := 8 ); port ( rst, in_clk, out_clk : in std_logic; ready_in : in std_logic; ready_out : out std_logic; valid_in : in std_logic; valid_out : out std_logic; data_in : in std_logic_vector(data_width - 1 downto 0); data_out : out std_logic_vector(data_width - 1 downto 0); used_slots : out integer range 0 to buffer_size ); end entity fifo_buffer; architecture rtl of fifo_buffer is constant address_bits : natural := integer(ceil(log2(real(buffer_size)))); signal read_pointer : std_logic_vector(address_bits - 1 downto 0); signal write_pointer : std_logic_vector(address_bits - 1 downto 0); signal write_signal : std_logic; signal buffer_full : std_logic; signal buffer_empty : std_logic; signal inverted_in_clock : std_logic; signal customout : std_logic_vector(0 downto 0); -- techmap needs customout and it is does not have a default value for some reason begin -- DECLARATION OF NX_SYNCRAM --entity nx_syncram_be is -- generic ( abits : integer := 6; -- dbits : integer := 8 -- ); -- port ( -- clk : in std_ulogic; -- address : in std_logic_vector (abits -1 downto 0); -- datain : in std_logic_vector (dbits -1 downto 0); -- dataout : out std_logic_vector (dbits -1 downto 0); -- enable : in std_logic_vector (dbits/8-1 downto 0); -- write : in std_logic_vector (dbits/8-1 downto 0) -- ); --end; techmap_ram_inst : entity techmap.syncram_2p generic map(tech => tech, abits => address_bits, dbits => data_width, sepclk => 1 ) port map( rclk => out_clk, renable => '1', raddress => read_pointer, dataout => data_out, wclk => inverted_in_clock, write => write_signal, waddress => write_pointer, datain => data_in, customclk => in_clk, --NOTE: No clue what this does but it has to be set to something customout => customout ); inverted_in_clock <= not in_clk; comb_proc: process(write_pointer, read_pointer, buffer_full, valid_in, rst) variable write_pointer_inc : unsigned(address_bits - 1 downto 0); begin if write_pointer >= read_pointer then used_slots <= to_integer(unsigned(write_pointer) - unsigned(read_pointer)); else used_slots <= buffer_size - to_integer(unsigned(read_pointer)) + to_integer(unsigned(write_pointer)); end if; ready_out <= not buffer_full; write_signal <= (valid_in and not buffer_full) or rst; write_pointer_inc := unsigned(write_pointer) + 1; customout <= "0"; if write_pointer_inc = unsigned(read_pointer) then buffer_full <= '1'; else buffer_full <= '0'; end if; if write_pointer = read_pointer then buffer_empty <= '1'; else buffer_empty <= '0'; end if; end process comb_proc; seq_proc: process(rst, in_clk, out_clk, buffer_full, valid_in, ready_in, buffer_empty, write_pointer, read_pointer) begin if rst = '1' then read_pointer <= (others => '0'); write_pointer <= (others => '0'); else if rising_edge(in_clk) and valid_in = '1' and buffer_full = '0' then write_pointer <= std_logic_vector(unsigned(write_pointer) + 1); end if; if falling_edge(out_clk) then if ready_in = '1' and buffer_empty = '0' then read_pointer <= std_logic_vector(unsigned(read_pointer) + 1); valid_out <= '1'; else valid_out <= '0'; end if; end if; end if; end process seq_proc; end architecture rtl;