⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fifo.vhd

📁 一个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 + -