📄 freefifo.vhd
字号:
-- Generate Full
---------------------------------------------------------------
process (wr_clk, reset)
begin
if reset='1' then
full <= '1';
elsif wr_clk'event and wr_clk='1' then
if fullg='1' or (almostfullg='1' and wr_allow='1') then
full <= '1';
else
full <= '0';
end if;
end if;
end process;
full_out <= full;
---------------------------------------------------------------
-- Generate the full, empty, almost full, and almost empty
-- combinatorial flags
---------------------------------------------------------------
UNDEFINED0: if fpga_type=0 generate
begin
emptyg <= '1' when wr_addr_gray2=rd_addr_gray2 else '0';
almostemptyg <= '1' when wr_addr_gray2=rd_addr_gray1 else '0';
fullg <= '1' when wr_addr_gray2=rd_addr_gray3 else '0';
almostfullg <= '1' when wr_addr_gray1=rd_addr_gray3 else '0';
end generate UNDEFINED0;
XILINX0: if fpga_type=1 generate
begin
ecomp <= not (wr_addr_gray2 XOR rd_addr_gray2);
aecomp <= not (wr_addr_gray2 XOR rd_addr_gray1);
fcomp <= not (wr_addr_gray2 XOR rd_addr_gray3);
afcomp <= not (wr_addr_gray1 XOR rd_addr_gray3);
EMUXCYi: MUXCY_L port map (DI=>always_one, CI=>always_one, S=>always_one, LO=>ecin);
EMUXCY0: MUXCY_L port map (DI=>always_zero, CI=>ecin, S=>ecomp(0), LO=>emuxcyo(0));
EMUXCYa: for i in 0 to addr_bits-3 generate
begin
EMUXCYb: MUXCY_L port map (DI=>always_zero, CI=>emuxcyo(i), S=>ecomp(i+1), LO=>emuxcyo(i+1));
end generate EMUXCYa;
EMUXCYN: MUXCY_L port map (DI=>always_zero,CI=>emuxcyo(addr_bits-2),S=>ecomp(addr_bits-1),LO=>emptyg);
AEMUXCYi: MUXCY_L port map (DI=>always_one,CI=>always_one, S=>always_one, LO=>aecin);
AEMUXCY0: MUXCY_L port map (DI=>always_zero,CI=>aecin, S=>aecomp(0),LO=>aemuxcyo(0));
AEMUXCYa: for i in 0 to addr_bits-3 generate
begin
AEMUXCYb: MUXCY_L port map (DI=>always_zero,CI=>aemuxcyo(i),S=>aecomp(i+1),LO=>aemuxcyo(i+1));
end generate AEMUXCYa;
AEMUXCYN: MUXCY_L port map (DI=>always_zero,CI=>aemuxcyo(addr_bits-2),S=>aecomp(addr_bits-1),LO=>almostemptyg);
FMUXCYi: MUXCY_L port map (DI=>always_one,CI=>always_one, S=>always_one, LO=>fcin);
FMUXCY0: MUXCY_L port map (DI=>always_zero,CI=>fcin, S=>fcomp(0),LO=>fmuxcyo(0));
FMUXCYa: for i in 0 to addr_bits-3 generate
begin
FMUXCYb: MUXCY_L port map (DI=>always_zero,CI=>fmuxcyo(i),S=>fcomp(i+1),LO=>fmuxcyo(i+1));
end generate FMUXCYa;
FMUXCYn: MUXCY_L port map (DI=>always_zero,CI=>fmuxcyo(addr_bits-2),S=>fcomp(addr_bits-1),LO=>fullg);
AFMUXCYi: MUXCY_L port map (DI=>always_one,CI=>always_one, S=>always_one, LO=>afcin);
AFMUXCY0: MUXCY_L port map (DI=>always_zero,CI=>afcin, S=>afcomp(0),LO=>afmuxcyo(0));
AFMUXCYa: for i in 0 to addr_bits-3 generate
AFMUXCYb: MUXCY_L port map (DI=>always_zero,CI=>afmuxcyo(i),S=>afcomp(i+1),LO=>afmuxcyo(i+1));
end generate AFMUXCYa;
AFMUXCYn: MUXCY_L port map (DI=>always_zero,CI=>afmuxcyo(addr_bits-2),S=>afcomp(addr_bits-1),LO=>almostfullg);
end generate XILINX0;
end arch_fifo_async_xilinx;
----------------------------------------------------------------------------
----------------------------------------------------------------------------
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_async_generic is
generic (data_bits :integer;
addr_bits :integer;
block_type :integer := 0);
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);
full :out std_logic;
empty :out std_logic
);
end fifo_async_generic;
architecture arch_fifo_async_generic of fifo_async_generic is
signal rd_allow :std_logic;
signal wr_allow :std_logic;
signal rd_addr :std_logic_vector (addr_bits-1 downto 0);
signal rd_addr_gray1 :std_logic_vector (addr_bits-1 downto 0);
signal wr_addr :std_logic_vector (addr_bits-1 downto 0);
signal wr_addr_gray1 :std_logic_vector (addr_bits-1 downto 0);
signal wr_addr_gray2 :std_logic_vector (addr_bits-1 downto 0);
signal empty_match :std_logic;
signal full_match :std_logic;
signal empty_int :std_logic;
signal full_int :std_logic;
signal always_one :std_logic;
signal always_zero :std_logic;
begin
always_one <= '1';
always_zero <= '0';
---------------------------------------------------------------
-- Generate the read/write allow signals
---------------------------------------------------------------
rd_allow <= '1' when rd_en='1' and empty_int='0' else '0';
wr_allow <= '1' when wr_en='1' and 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, wr_addr_gray2, wr_data,
rd_clk, rd_addr_gray1, rd_data);
---------------------------------------------------------------
-- Generate the read addresses & pipelined gray-code versions
---------------------------------------------------------------
process (rd_clk, reset)
variable addr :std_logic_vector (rd_addr'range);
begin
if reset='1' then
addr := (others=>'0');
rd_addr_gray1 <= bin_to_gray (addr);
addr := addr + 1;
rd_addr <= addr;
elsif rd_clk'event and rd_clk='1' then
if rd_allow='1' then
rd_addr_gray1 <= bin_to_gray(rd_addr);
rd_addr <= rd_addr + 1;
end if;
end if;
end process;
---------------------------------------------------------------
-- Generate the write addresses & pipelined gray-code versions
---------------------------------------------------------------
process (wr_clk, reset)
variable addr :std_logic_vector (wr_addr'range);
begin
if reset='1' then
addr := (others=>'0');
wr_addr_gray2 <= bin_to_gray (addr);
addr := addr + 1;
wr_addr_gray1 <= bin_to_gray (addr);
addr := addr + 1;
wr_addr <= addr;
elsif wr_clk'event and wr_clk='1' then
if wr_allow='1' then
wr_addr_gray2 <= wr_addr_gray1;
wr_addr_gray1 <= bin_to_gray(wr_addr);
wr_addr <= wr_addr + 1;
end if;
end if;
end process;
---------------------------------------------------------------
-- Generate Empty & Full
---------------------------------------------------------------
empty_match <= '1' when rd_addr_gray1=wr_addr_gray2 else '0';
full_match <= '1' when rd_addr_gray1=wr_addr_gray1 else '0';
process (rd_clk, empty_match)
begin
if empty_match='1' then
empty_int <= '1';
elsif rd_clk'event and rd_clk='1' then
empty_int <= empty_match;
end if;
end process;
process (wr_clk, full_match)
begin
if full_match='1' then
full_int <= '1';
elsif wr_clk'event and wr_clk='1' then
full_int <= full_match;
end if;
end process;
empty <= empty_int;
full <= full_int;
end arch_fifo_async_generic;
----------------------------------------------------------------------------
----------------------------------------------------------------------------
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;
entity fifo_async 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);
full :out std_logic;
empty :out std_logic
);
end fifo_async;
architecture arch_fifo_async of fifo_async is
begin
-- Generic FIFO
UNSPECIFIED0: if fifo_arch=0 generate
begin
U1: fifo_async_generic
generic map (data_bits, addr_bits, block_type)
port map (reset, wr_clk, wr_en, wr_data, rd_clk, rd_en, rd_data, full, empty);
end generate UNSPECIFIED0;
-- Xilinx XAPP175 without carry logic
XILINX0: if fifo_arch=1 generate
begin
U2: fifo_async_xilinx
generic map (data_bits, addr_bits, block_type, 0)
port map (reset, wr_clk, wr_en, wr_data, rd_clk, rd_en, rd_data, full, empty);
end generate XILINX0;
-- Xilinx XAPP175 with carry logic
XILINX1: if fifo_arch=2 generate
begin
U3: fifo_async_xilinx
generic map (data_bits, addr_bits, block_type, 1)
port map (reset, wr_clk, wr_en, wr_data, rd_clk, rd_en, rd_data, full, empty);
end generate XILINX1;
end arch_fifo_async;
----------------------------------------------------------------------------
----------------------------------------------------------------------------
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_sync is
generic (data_bits :integer;
addr_bits :integer;
block_type :integer := 0);
port (reset :in std_logic;
clk :in std_logic;
wr_en :in std_logic;
wr_data :in std_logic_vector (data_bits-1 downto 0);
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_sync;
architecture arch_fifo_sync of fifo_sync is
signal wr_addr :std_logic_vector (addr_bits-1 downto 0);
signal rd_addr :std_logic_vector (addr_bits-1 downto 0);
signal rd_allow :std_logic;
signal wr_allow :std_logic;
signal count_int :std_logic_vector (addr_bits-1 downto 0);
signal empty_int :std_logic;
signal full_int :std_logic;
signal empty_count :std_logic_vector (addr_bits-1 downto 0);
signal aempty_count :std_logic_vector (addr_bits-1 downto 0);
signal full_count :std_logic_vector (addr_bits-1 downto 0);
signal afull_count :std_logic_vector (addr_bits-1 downto 0);
begin
count <= count_int;
full <= full_int;
empty <= empty_int;
-- Some constants
empty_count <= (others=>'0');
aempty_count <= empty_count + 1;
full_count <= (others=>'1');
afull_count <= full_count - 1;
----------------------------------------------
----------------------------------------------
rd_allow <= '1' when rd_en='1' and empty_int='0' else '0';
wr_allow <= '1' when wr_en='1' and full_int='0' else '0';
----------------------------------------------
----------------------------------------------
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,
clk, wr_allow, wr_addr, wr_data,
clk, rd_addr, rd_data);
----------------------------------------------
----------------------------------------------
process (clk, reset)
begin
if reset='1' then
rd_addr <= (others=>'0');
elsif clk'event and clk='1' then
if rd_allow='1' then
rd_addr <= rd_addr + 1;
end if;
end if;
end process;
----------------------------------------------
----------------------------------------------
process (clk, reset)
begin
if reset='1' then
wr_addr <= (others=>'0');
elsif clk'event and clk='1' then
if wr_allow='1' then
wr_addr <= wr_addr + 1;
end if;
end if;
end process;
----------------------------------------------
----------------------------------------------
process (clk, reset)
begin
if reset='1' then
count_int <= (others=>'0');
elsif clk'event and clk='1' then
if wr_allow='0' and rd_allow='1' then
count_int <= count_int-1;
elsif wr_allow='1' and rd_allow='0' then
count_int <= count_int+1;
end if; -- else count<=count
end if;
end process;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -