119 lines
3.7 KiB
VHDL
119 lines
3.7 KiB
VHDL
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;
|