📄 fifo.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity Fifo is
generic(
data_width: NATURAL :=16;
addr_width: NATURAL :=3;
numwords:NATURAL :=8;
almostfull_threshold:NATURAL :=3;
almostempty_threshold:NATURAL :=8
);
port(
----clock----
clk:in std_logic;
rst:in std_logic; --active high
--write side--
datain:in std_logic_vector(data_width-1 downto 0);
wren:in std_logic;
full:out std_logic;
almostfull:out std_logic; --active high,indicate empty size is less than almostfull_threshold.
almostempty:out std_logic; --acitve high,indicate the data in fifo is less than almostempty_threshold
--read side--
dataout:out std_logic_vector(data_width-1 downto 0);
rden:in std_logic;
empty:out std_logic;
emptysize:buffer std_logic_vector(addr_width-1 downto 0)
);
end entity Fifo;
architecture RTL of Fifo is
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (data_width-1 DOWNTO 0);
COMPONENT altsyncram
GENERIC (
address_aclr_a : STRING;
address_aclr_b : STRING;
address_reg_b : STRING;
indata_aclr_a : STRING;
intended_device_family : STRING;
lpm_type : STRING;
numwords_a : NATURAL;
numwords_b : NATURAL;
operation_mode : STRING;
outdata_aclr_b : STRING;
outdata_reg_b : STRING;
power_up_uninitialized : STRING;
widthad_a : NATURAL;
widthad_b : NATURAL;
width_a : NATURAL;
width_b : NATURAL;
width_byteena_a : NATURAL;
wrcontrol_aclr_a : STRING
);
PORT (
wren_a : IN STD_LOGIC ;
clock0 : IN STD_LOGIC ;
clock1 : IN STD_LOGIC ;
address_a : IN STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (data_width-1 DOWNTO 0);
data_a : IN STD_LOGIC_VECTOR (data_width-1 DOWNTO 0)
);
END COMPONENT;
signal wraddress,rdaddress:std_logic_vector(addr_width-1 downto 0);
signal occupysize:std_logic_vector(addr_width-1 downto 0);
begin
dataout <= sub_wire0(data_width-1 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
address_aclr_a => "NONE",
address_aclr_b => "NONE",
address_reg_b => "CLOCK1",
indata_aclr_a => "NONE",
intended_device_family => "Cyclone",
lpm_type => "altsyncram",
numwords_a => numwords,
numwords_b => numwords,
operation_mode => "DUAL_PORT",
outdata_aclr_b => "NONE",
outdata_reg_b => "UNREGISTERED",
power_up_uninitialized => "FALSE",
widthad_a => addr_width,
widthad_b => addr_width,
width_a => data_width,
width_b => data_width,
width_byteena_a => 1,
wrcontrol_aclr_a => "NONE"
)
PORT MAP (
wren_a => wren,
clock0 => clk,
clock1 => clk,
address_a => wraddress,
address_b => rdaddress,
data_a => datain,
q_b => sub_wire0
);
label_wraddress:
process(clk,rst)
begin
if rst='1' then
wraddress<=conv_std_logic_vector(0,addr_width);
elsif(clk'event and clk='1') then
if wren='1' then
if conv_std_logic_vector(conv_integer(wraddress)+1,addr_width)/=rdaddress then
wraddress<=wraddress+1;
end if;
end if;
end if;
end process;
label_rdaddress:
process(clk,rst)
begin
if rst='1' then
rdaddress<=conv_std_logic_vector(0,addr_width);
elsif(clk'event and clk='1') then
if rden='1' and wraddress/=rdaddress then
rdaddress<=rdaddress+1;
end if;
end if;
end process;
label_full:
process(clk)
begin
if(clk'event and clk='1') then
if wraddress+1=rdaddress then
full<='1';
else
full<='0';
end if;
end if;
end process;
label_empty:
process(clk)
begin
if(clk'event and clk='1') then
if wraddress=rdaddress then
empty<='1';
else
empty<='0';
end if;
end if;
end process;
label_emptysize:
process(clk)
begin
if clk'event and clk='1' then
emptysize<=rdaddress-wraddress-1;
end if;
end process;
label_almostfull:
process(clk)
begin
if clk'event and clk='1' then
if conv_integer(emptysize)<almostfull_threshold then
almostfull<='1';
else
almostfull<='0';
end if;
end if;
end process;
lalbe_occupysize:
process(clk)
begin
if clk'event and clk='1' then
occupysize<=wraddress-rdaddress;
end if;
end process;
label_almostempty:
process(clk)
begin
if clk'event and clk='1' then
if conv_integer(occupysize)<almostempty_threshold then
almostempty<='1';
else
almostempty<='0';
end if;
end if;
end process;
end architecture RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -