|
FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,没有地址线。
FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端时AD数据采集,另一端时计算机的PCI总线,假设其AD采集的速率为16位 100K SPS,那么每秒的数据量为100K×16bit=1.6Mbps,而PCI总线的速度为33MHz,总线宽度32bit,在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。另外对于不同宽度的数据接口也可以用FIFO,例如单片机位8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。
下面是我写的一个FIFO代码,是深度和宽度都可以改变的,也只是刚刚前仿通过,欢迎大家拍砖。
端口的输入/输出解释:
----------------------------------------------------------------------------------------
---rst为复位信号。
---rd为读允许位,wr为写允许位
---data_in为数据输入,data_out 为数据输出;
---clk_wr,clk_rd 分别是写数据 和 读 数据的时钟。
---wr_reset,rd_reset 分别是 写的指针复位 读的指针复位
---wr_yichu,rd_ok 分别是写满溢出位和“读完毕位”
-----------------------------------------------------------------------
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 19:02:19 03/15/2010
-- Design Name:
-- Module Name: fifo - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity fifo is
generic (bits : integer :=8;
words: integer :=5);
port(rst,clk_rd,clk_wr,rd,wr,rd_reset,wr_reset:in std_logic;
data_in:in std_logic_vector(bits-1 downto 0);
wr_yichu,rd_ok:out std_logic;
data_out:out std_logic_vector(bits-1 downto 0));
end fifo;
architecture Behavioral of fifo is
type fifo_array is array(0 to words-1) of
std_logic_vector(bits-1 downto 0);
signal vector_array:fifo_array;
signal addr_rd:integer range 0 to words;
signal addr_wr:integer range 0 to words;
begin
reset_andwr:process(rst,clk_wr)
begin
if (rst='1') then
for i in vector_array'range loop
vector_array(i)<=(others =>'0');
end loop;
elsif(clk_wr'event and clk_wr='1') then
if(wr='1' and (addr_wr/=words)) then
vector_array(addr_wr)<=data_in;
end if;
end if;
end process;
---------------------------------------------------
read: process(rst,clk_rd)
begin
if(rst='1') then
data_out<=(others=>'Z');
elsif(clk_rd'event and clk_rd='1') then
if(rd='1') then
data_out<=vector_array(addr_rd);
end if;
end if;
end process;
-----------------------------------------
wr_count:process(rst,clk_wr)
begin
if (rst='1') then
addr_wr<=0;
elsif(clk_wr'event and clk_wr='1') then
if(wr_reset='1') then
addr_wr<=0;
elsif (wr='1') then addr_wr<=addr_wr+1;
end if;
end if;
if(addr_wr=words) then wr_yichu<='1';
else wr_yichu<='0';
end if;
end process;
-------------------------------------------------
rd_count:process(rst,clk_rd)
begin
if (rst='1') then
addr_rd<=0;
elsif(clk_rd'event and clk_rd='1') then
if (rd='1') then addr_rd<=addr_rd+1;
end if;
end if;
if(addr_rd=words)then rd_ok<='1';
else rd_ok<='0';
end if;
if(rd_reset='1') then
addr_rd<=0;
end if;
end process;
------------------------------------
end Behavioral;
--------------------------------------------------
wr_count为写到哪里的标志,如果写满,则会停止写。并且wr_yichu置‘1’,然后等待wr_reset;
rd_count为读到哪里的标志 ,如果读不允许,则输出高阻态。读完时,rd_ok置‘1’,等待rd_reset.
------------------------------------------------------------------------------------
结束语:等到下到板子里后肯定会修改的,到时候再说,大家先看看。 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|