exjobb-public/src/fifo_buffer/fifo_buffer.vhd

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;