📄 freefifo.vhd
字号:
----------------------------------------------
----------------------------------------------
process (clk, reset)
begin
if reset='1' then
empty_int <= '1';
elsif clk'event and clk='1' then
if empty_int='1' and wr_allow='1' then
empty_int <= '0';
elsif count_int=aempty_count and rd_allow='1' and wr_allow='0' then
empty_int <= '1';
elsif count_int=empty_count then
empty_int <= '1';
else
empty_int <= '0';
end if;
end if;
end process;
----------------------------------------------
----------------------------------------------
process (clk, reset)
begin
if reset='1' then
full_int <= '0';
elsif clk'event and clk='1' then
if full_int='1' and rd_allow='1' then
full_int <= '0';
elsif count_int=afull_count and rd_allow='0' and wr_allow='1' then
full_int <= '1';
elsif count_int=full_count then
full_int <= '1';
else
full_int <= '0';
end if;
end if;
end process;
end arch_fifo_sync;
----------------------------------------------------------------------------
-- This is basically a test model. It shows that the wrcount and rdcount
-- FIFO's are really made up of two seperate FIFO's. But since the *_orig
-- FIFO's are slightly different than the "normal" ones, they are not
-- "pin" compatible. The *_orig FIFO's are included here as reference
-- and "prior art".
----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.free_fifo.all;
use work.ram_lib.all;
entity fifo_wrcount_orig is
generic (data_bits :integer;
addr_bits :integer;
block_type :integer := 0;
fifo_arch :integer := 0); -- 0=Generic architecture, 1=Xilinx, 2=Xilinx w/carry
port (reset :in std_logic;
wr_clk :in std_logic;
wr_en :in std_logic;
wr_data :in std_logic_vector (data_bits-1 downto 0);
rd_clk :in std_logic;
rd_en :in std_logic;
rd_data :out std_logic_vector (data_bits-1 downto 0);
count :out std_logic_vector (addr_bits-1 downto 0);
full :out std_logic;
empty :out std_logic
);
end fifo_wrcount_orig;
architecture arch_fifo_wrcount_orig of fifo_wrcount_orig is
signal i_rd_en :std_logic;
signal i_rd_en2 :std_logic;
signal i_wr_en :std_logic;
signal i_data1 :std_logic_vector (data_bits-1 downto 0);
signal i_data2 :std_logic_vector (data_bits-1 downto 0);
signal i_data3 :std_logic_vector (data_bits-1 downto 0);
signal i_count :std_logic_vector (addr_bits-1 downto 0);
signal i_full1 :std_logic;
signal i_empty1 :std_logic;
signal i_full2 :std_logic;
signal i_empty2 :std_logic;
signal temp_valid :std_logic;
signal count_max :std_logic_vector (addr_bits-1 downto 0);
begin
count_max <= (others=>'1');
-- Misc signals
full <= i_full1;
empty <= i_empty2;
count <= count_max - i_count;
-- The Input FIFO
U1: fifo_sync
generic map (data_bits, addr_bits, block_type)
port map (reset, wr_clk, wr_en, wr_data,
i_rd_en, i_data1, i_count, i_full1, i_empty1);
-- The output FIFO
U2: fifo_async
generic map (data_bits, addr_bits, block_type, fifo_arch)
port map (reset,
wr_clk, i_wr_en, i_data3,
rd_clk, rd_en, rd_data, i_full2, i_empty2);
-- Generate the read enables
i_rd_en <= '1' when i_empty1='0' and i_full2='0' else '0';
process (reset, wr_clk)
begin
if reset='1' then
i_rd_en2 <= '0';
elsif wr_clk'event and wr_clk='1' then
i_rd_en2 <= i_rd_en;
end if;
end process;
-- Latch the data into a temp buffer if the read FIFO is full
process (reset, wr_clk)
begin
if reset='1' then
i_data2 <= (others=>'0');
elsif wr_clk'event and wr_clk='1' then
if i_full2='1' and i_rd_en2='1' then
i_data2 <= i_data1;
end if;
end if;
end process;
-- Track if the temp buffer is being used
process (reset, wr_clk)
begin
if reset='1' then
temp_valid<='0';
elsif wr_clk'event and wr_clk='1' then
if i_full2='1' and i_rd_en2='1' then
temp_valid <= '1';
elsif i_full2='0' then
temp_valid <= '0';
end if;
end if;
end process;
-- Generate the write enable signal
i_wr_en <= '1' when temp_valid='1' else
'1' when i_rd_en2='1' else
'0';
-- Generate the input data to the read fifo
i_data3 <= i_data1 when temp_valid='0' else i_data2;
end arch_fifo_wrcount_orig;
----------------------------------------------------------------------------
-- This is basically a test model. It shows that the wrcount and rdcount
-- FIFO's are really made up of two seperate FIFO's. But since the *_orig
-- FIFO's are slightly different than the "normal" ones, they are not
-- "pin" compatible. The *_orig FIFO's are included here as reference
-- and "prior art".
----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.free_fifo.all;
use work.ram_lib.all;
entity fifo_rdcount_orig is
generic (data_bits :integer;
addr_bits :integer;
block_type :integer := 0;
fifo_arch :integer := 0); -- 0=Generic architecture, 1=Xilinx, 2=Xilinx w/carry
port (reset :in std_logic;
wr_clk :in std_logic;
wr_en :in std_logic;
wr_data :in std_logic_vector (data_bits-1 downto 0);
rd_clk :in std_logic;
rd_en :in std_logic;
rd_data :out std_logic_vector (data_bits-1 downto 0);
count :out std_logic_vector (addr_bits-1 downto 0);
full :out std_logic;
empty :out std_logic
);
end fifo_rdcount_orig;
architecture arch_fifo_rdcount_orig of fifo_rdcount_orig is
signal i_rd_en :std_logic;
signal i_rd_en2 :std_logic;
signal i_wr_en :std_logic;
signal i_data1 :std_logic_vector (data_bits-1 downto 0);
signal i_data2 :std_logic_vector (data_bits-1 downto 0);
signal i_data3 :std_logic_vector (data_bits-1 downto 0);
signal i_count :std_logic_vector (addr_bits-1 downto 0);
signal i_full1 :std_logic;
signal i_empty1 :std_logic;
signal i_full2 :std_logic;
signal i_empty2 :std_logic;
signal temp_valid :std_logic;
begin
-- Misc signals
full <= i_full1;
empty <= i_empty2;
count <= i_count;
-- The Input FIFO
U1: fifo_async
generic map (data_bits, addr_bits, block_type, fifo_arch)
port map (reset,
wr_clk, wr_en, wr_data,
rd_clk, i_rd_en, i_data1, i_full1, i_empty1);
-- The output FIFO
U2: fifo_sync
generic map (data_bits, addr_bits, block_type)
port map(reset, rd_clk, i_wr_en, i_data3,
rd_en, rd_data, i_count, i_full2, i_empty2);
-- Generate the read enables
i_rd_en <= '1' when i_empty1='0' and i_full2='0' else '0';
process (reset, rd_clk)
begin
if reset='1' then
i_rd_en2 <= '0';
elsif rd_clk'event and rd_clk='1' then
i_rd_en2 <= i_rd_en;
end if;
end process;
-- Latch the data into a temp buffer if the read FIFO is full
process (reset, rd_clk)
begin
if reset='1' then
i_data2 <= (others=>'0');
elsif rd_clk'event and rd_clk='1' then
if i_full2='1' and i_rd_en2='1' then
i_data2 <= i_data1;
end if;
end if;
end process;
-- Track if the temp buffer is being used
process (reset, rd_clk)
begin
if reset='1' then
temp_valid<='0';
elsif rd_clk'event and rd_clk='1' then
if i_full2='1' and i_rd_en2='1' then
temp_valid <= '1';
elsif i_full2='0' then
temp_valid <= '0';
end if;
end if;
end process;
-- Generate the write enable signal
i_wr_en <= '1' when temp_valid='1' else
'1' when i_rd_en2='1' else
'0';
-- Generate the input data to the read fifo
i_data3 <= i_data1 when temp_valid='0' else i_data2;
end arch_fifo_rdcount_orig;
----------------------------------------------------------------------------
----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.free_fifo.all;
use work.ram_lib.all;
entity fifo_wrcount is
generic (data_bits :integer;
addr_bits :integer;
block_type :integer := 0;
async_size :integer := 16);
port (reset :in std_logic;
wr_clk :in std_logic;
wr_en :in std_logic;
wr_data :in std_logic_vector (data_bits-1 downto 0);
rd_clk :in std_logic;
rd_en :in std_logic;
rd_data :out std_logic_vector (data_bits-1 downto 0);
count :out std_logic_vector (addr_bits-1 downto 0);
full :out std_logic;
empty :out std_logic
);
end fifo_wrcount;
architecture arch_fifo_wrcount of fifo_wrcount is
signal wrptr_bin :std_logic_vector (addr_bits-1 downto 0);
signal wrptr :std_logic_vector (addr_bits-1 downto 0);
signal wrptr1 :std_logic_vector (addr_bits-1 downto 0);
signal rdptr_bin :std_logic_vector (addr_bits-1 downto 0);
signal rdptr :std_logic_vector (addr_bits-1 downto 0);
signal rdptr_max :std_logic_vector (addr_bits-1 downto 0);
signal rdptr_max_bin :std_logic_vector (addr_bits-1 downto 0);
signal midptr_bin :std_logic_vector (addr_bits-1 downto 0);
signal midptr :std_logic_vector (addr_bits-1 downto 0);
signal midptr1 :std_logic_vector (addr_bits-1 downto 0);
signal wf_count :std_logic_vector (addr_bits-1 downto 0);
signal wf_full_match :std_logic;
signal wf_empty_match :std_logic;
signal wf_aempty_match:std_logic;
signal rf_full_match :std_logic;
signal rf_empty_match :std_logic;
signal wf_full_int :std_logic;
signal wf_empty_int :std_logic;
signal rf_full_int :std_logic;
signal rf_empty_int :std_logic;
signal rd_allow :std_logic;
signal wr_allow :std_logic;
signal mid_allow :std_logic;
begin
empty <= rf_empty_int;
full <= wf_full_int;
count <= wf_count;
---------------------------------------------------------------
-- Generate the read/write allow signals
---------------------------------------------------------------
rd_allow <= '1' when rd_en='1' and rf_empty_int='0' else '0';
wr_allow <= '1' when wr_en='1' and wf_full_int='0' else '0';
mid_allow <= '1' when wf_empty_int='0' and rf_full_int='0' else '0';
---------------------------------------------------------------
-- Instantiate the RAM
---------------------------------------------------------------
fifo_ram: ram_dp
generic map (addr_bits => addr_bits,
data_bits => data_bits,
register_out_flag => 1,
block_type => block_type)
port map (reset,
wr_clk, wr_allow, wrptr, wr_data,
rd_clk, rdptr, rd_data);
---------------------------------------------------------------
-- Generate the write addresses
---------------------------------------------------------------
process (wr_clk, reset)
variable addr :std_logic_vector (wrptr_bin'range);
begin
if reset='1' then
addr := (others=>'0');
wrptr <= bin_to_gray (addr);
addr := addr + 1;
wrptr1 <= bin_to_gray (addr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -