异步fifo读写同步的设计
quartus 异步fifo用法 -回复

quartus 异步fifo用法-回复quartus异步FIFO用法引言:在数字电路设计中,FIFO(First In First Out)是一种常见的数据存储器,它允许数据以先进先出的顺序进出。
在使用Quartus进行FPGA设计时,异步FIFO是一种非常有用的工具,它可以帮助我们处理不同速度的数据流,并实现数据的缓冲和流量控制。
本文将介绍Quartus异步FIFO的基本概念和使用方法,并给出一些实例。
第一部分:Quartus异步FIFO概述1.1 什么是异步FIFO?异步FIFO是一种数据存储器,在其中数据可以以不同速度进入和退出。
与同步FIFO不同,异步FIFO的读写时钟可以是不同的,这使得它可以处理速度不匹配的数据流。
Quartus提供了异步FIFO的库函数和IP核,使得它可以在FPGA设计中方便地使用。
1.2 Quartus异步FIFO的特点Quartus异步FIFO具有以下特点:- 可以使用不同的时钟频率进行读写操作。
- 可以配置不同的缓冲深度来满足特定的设计需求。
- 可以实现流量控制和数据的重排序。
- 可以支持并行读写和读写使能信号。
- 可以适应不同的数据宽度和时钟域要求。
第二部分:Quartus异步FIFO的使用方法2.1 创建异步FIFO在Quartus中创建异步FIFO的方式有两种:使用库函数和使用IP核。
使用库函数创建异步FIFO的步骤如下:- 首先,在Quartus中打开设计工程,并创建一个新的源文件。
- 然后,将异步FIFO的库函数导入到源文件中,以便在设计中调用它。
- 接着,实例化异步FIFO,并通过参数配置其属性,例如宽度,深度,时钟域等。
- 最后,将异步FIFO连接到其他逻辑模块,完成设计。
使用IP核创建异步FIFO的步骤如下:- 首先,在Quartus中打开设计工程,并创建一个新的IP核。
- 然后,在IP核的界面中选择合适的FIFO类型和配置参数。
- 接着,将异步FIFO实例化到设计中,将其连接到其他逻辑模块。
一种读写深度可配置的异步FIFO设计

引 言
随着设计复杂度 的不断 提高 , 现 代 电子信 息设计 中,
单 一 时 钟 驱 动 已无 法 满 足 设 计 与 应 用 的 需 求 。 基 于 多 时 钟 驱 动 的设 计 已经 越 来 越 普 遍 , 在异 步 时钟域 的设计 中,
Байду номын сангаас
模 块 和读 地址 逻 辑 模 块 是 两 个 相 互 独 立 的 时 钟 域模 块 。 F I F O的空/ 满状态 的 判断 是 F I FO 设 计 中 的 一 个 关 键部分 , 主要 通 过对 读 / 写地 址 的 比较 来 实 现 。鉴 于 读 / 写
状态标 志 的产 生 , 同 时 通
F I F O 的存 储 资 源 没 有 使 用 , 造 成 硬件 资 源 的 浪 费 。
针对这一现状, 本 文 提 出 一 种 读 写 深 度 可 配 置 的 FI F O 设 计 。通 过 对 寄 存 器 的配 置 , 来设定产生有效 F I F O
地 址 的控 制 逻 辑 分 别 工 作 在 各 自 的 时 钟 域 下 , 进 行 比 较
时, 通常将二进制码 的地址 转换 为格雷 码 的编码 方式 , 传 输 到 异 步 时 钟 域 再 进 行 比较 , 以使 亚 稳 态 的 产 生 处 于 可 以
跨 时钟 域 数 据 信 号 传 输 是 必 须 考 虑 的 一 个 问题 。控 制 信 号一般使用握手协议来 实现异步传输 , 对 于 异 步 时 钟 域 大
态时就开始读操作 , 防 止 写 满 后 禁 止 写 操 作 再
图 1 通用异步 F l F O原 理 结构 图
进 行 读 取 造 成 数 据 的 丢失 。
敬请登录网站在线投稿
高速异步FIFO的设计与实现

高速异步FIFO的设计与实现2 异步FIFO的实现读时钟2.1 FIFO设计的难点如何同步异步信号,使触发器不产生亚稳态是设计异步FIFO的难点。
国内外解决此问题的较成熟方法是对写地址膜地址采纳格雷码,本文也挺直采纳格雷码。
异步FIFO设计的另一个难点是如何推断FIFO的空/满状态。
为了保证数据正确的写入或读出。
必需保证异步FIFO在满的状态下.不能举行写操作:在空的状态下不能举行读操作。
通常状况下将存储器组织成一个环形链表。
满/空标记产生的原则是:写满不溢出.读空不多读。
即无论在什么状况.都不应浮现读写地址同时对一个存储器地址操作的状况。
在读写地址相等或相差一个或多个地址的时候,满标记应当有效。
表示此时FIFO 已满,外部电路应停止对FIFO发数据。
在满信号有效时写数据应按照设计的要求,或保持、或抛弃重发。
同理,空标记的产生也是如此。
为了更好的推断满/空标记。
采纳在FIFO本来深度的基础上增强一位的办法,而由该位组成的格雷码并不代表新的地址。
也就是说3位格雷码可表示8位的深度,若再加一位最高位MSB,则这一位加其他三位组成的格雷码并不代表新的地址,也就是说格雷码的0100表示7,而1100仍然表示7,只不过格雷码在经过一个以0位MSB的循环后进入一个以1为MSB的循环,然后又进入一个以0位MSB的循环。
其他的三位码仍然是格雷码。
举例解释:一个深度为8字节的FIFO怎样工作(用法已转换为二进制的指针),N=3,指针宽度为N+I=4。
开头rd_ptr_bin和wr_ptr_bin均为“0000”。
此时FIFO中写入8个字节的数据。
wr_ptr_bin=“1000",rd_ptr_bin=“0000”。
固然,这就是满条件。
现在,假设执行了8次的读操作.使得rd_ptr_bin=“1000”,这就是空条件。
另外的8次写操作将使wr_ptr_bin等于“0000”,但rd_ptr_bin仍然等于“1000”,因此,FIFO为满条件。
FIFO设计

• 4) FULL信号控制进程 • 如何判断FULL信号为‘1’;
• 1、当前没有读/写数据有效信号,FIFO数 据已满 • 2、当前没有读有效信号,有写有效信号, 而且FIFO还差一个就满了。
• 4) FULL信号控制进程
•
Process(clk,reset) begin if reset='1' then full_mid<='1'; elsif rising_edge(clk) then if (rd_enable='0' and (fifo_cnt(8 downto 1) = "11111111") and ((fifo_cnt(0)='1') or (wr_enable='1'))) then full_mid<='1'; else full_mid<='0'; end if; end if; end process;
同步FIFO的操作
1、 同步FIFO的操作 当FIFO不满且wr_en有效时,向FIFO写数据,并 置写使能wr_enable有效; 当FIFO不空且rd_en有效时,从FIFO从读出数据 并置读使能rd_enable有效; 当FIFO满且wr_en有效时,置写使能wr_enable
无效且作废此次写操作; 当FIFO空且rd_en有效时,置读使能rd_enable 无效且作废此次读操作。
异步FIFO的设计
• 异步FIFO的数据读、写受不同时钟的控制; • 异步FIFO的空、满状态不能依靠计数的方 式进行,因为读、写均需要对计数器进行 操作; • 如何判断异步FIFO的空、满情形?如何操 作?
异步FIFO的设计文档

异步FIFO的设计版本v1.02011-05-06异步FIFO的设计一.功能描述本设计用16*8 RAM实现一个异步FIFO,具体功能定义如下:1. 异步复位。
2. FIFO不为满时,当写使能有效时,在写时钟的上升沿向FIFO中写入数据。
3. FIFO不为空时,当读使能有效时,在读时钟的上升沿从FIFO中读出数据。
4. 当FIFO写满的时候,产生满信号;当FIFO读空的时候,产生空信号。
5. FIFO一旦空或者满时候,复位FIFO;二.输入输出信号描述信号名输入/输出目标/源功能描述Rclk Input Pin 读时钟频率,10M ,占空比1:1。
Wclk Input Pin 写时钟,频率10M ,占空比1:1。
data_in[7:0] Input Pin 8位的输入数据rd_en Input Pin 读使能,高电平有效,在FIFO非空时,CLK上升沿读入数据;wr_en Input Pin 写使能,高电平有效,在FIFO非满时,CLK上升沿写入数据;Rst Input Pin 异步清零,低电平有效,低电平时读地址,写地址,计数器都清零。
三顶层划分图1 系统框图顶层模块说明:1.RAM :存储器模块,用于存放及输出数据;2.Waddr_Reg : 保存访问RAM的写地址;3.Raddr_Reg : 保存访问RAM的写地址;4.Wbin_addr : 计算RAM下一个写地址;5.Rbin_addr : 计算RAM下一个读地址;6.Gwaddr_reg : 将写地址的二进制编码转换成格雷码,并保存;7.Graddr_reg : 将读地址的二进制编码转换成格雷码,并保存;8.Syn_Rfield : 将写地址同步到读时钟域,并产生空标志;9.Syn_Wfield : 将读地址同步到写时钟域,并产生满标志;10、Reset_Unit : 复位信号产生单元设计思想说明:1、由于实现的异步FIFO,分别用不同的读、写时钟产生读写地址,因此FIFO 的判空和判满是本设计中的一个难点。
最新-一种异步FIFO的设计方法 精品

一种异步FIFO的设计方法摘要使用同步源自不同时钟域的数据是在数字设计中经常使用的方法,设计功能正确的会遇到很多问题,探讨了两种不同的异步的设计思路。
两种思路都能够实现功能正确的。
关键词异步握手同步二进制格雷码本文所研究的,从硬件的观点来看,就是一块数据内存。
它有两个端口,一个用来写数据,就是将数据存入;另一个用来读数据,也就是将数据从当中取出。
与操作相关的有两个指针,写指针指向要写的内存部分,读指针指向要读的内存部分。
控制器通过外部的读写信号控制这两个指针移动,并由此产生空信号或满信号。
对于异步而言,数据是由某一个时钟域的控制信号写入,而由另一个时钟域的控制信号将数据读出。
也就是说,读写指针的变化动作是由不同的时钟产生的。
因此,对空或满的判断是跨时钟域的。
如何根据异步的指针信号对的满状态或空状态进行正确的判断是本文研究的重点。
此外,设计过程中的一些细节问题也将在文中涉及到。
1指针以及满空信号的产生为了更好地说明问题,先探讨一下同步指针移动以及满空信号的产生过程。
对于同步,读写指针都指向一个内存的初始位置,每进行一次读写操作,相应的指针就递增一次,指向下一个内存位置。
当指针移动到了内存的最后一个位置时,它又重新跳回初始位置。
在非满或非空的情况下,这个过程将随着读写控制信号的变化一直进行下去。
如果处于空的状态,下一个读动作将会导致向下溢出,一个无效的数据被读人;同样,对于一个满了的,进行写动作将会导致向上溢出,一个有用的数据被新写入的数据覆盖。
这两种情况都属于误动作,因此需要设置满和空两个信号,对满信号置位表示处于满状态,对满信号复位表示非满,还有空间可以写入数据;对空信号置位表示处于空状态,对空信号复位表示非空,还有有效的数据可以读出。
当读指针和写指针相等也就是指向同一个内存位置的时候,可能处于满或空两种状态。
可以通过不同的方法判断或区分究竟是处于满状态还是空状态,也就是究竟是写指针从后赶上了读指针,还是读指针从后赶上了写指针。
FIFO的使用及设计难点

FIFO的使用及设计难点根据FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。
同步FIFO是指读时钟和写时钟为同一个时钟。
在时钟沿来临时同时发生读写操作。
异步FIFO是指读写时钟不一致,读写时钟是互相独立的。
FIFO设计的难点在于怎样判断FIFO的空/满状态。
为了保证数据正确的写入或读出,而不发生溢出或读空的状态出现,必须保证FIFO在满的情况下,不能进行写操作。
在空的状态下不能进行读操作。
怎样判断FIFO的满/空就成了FIFO设计的核心问题。
由于同步FIFO 几乎很少用到,这里只描述异步FIFO的空/满标志产生问题。
在用到触发器的设计中,不可避免的会遇到亚稳态的问题(关于亚稳态这里不作介绍,可查看相关资料)。
在涉及到触发器的电路中,亚稳态无法彻底消除,只能想办法将其发生的概率将到最低。
其中的一个方法就是使用格雷码。
格雷码在相邻的两个码元之间只由一位变换(二进制码在很多情况下是很多码元在同时变化)。
这就会避免计数器与时钟同步的时候发生亚稳态现象。
但是格雷码有个缺点就是只能定义2^n的深度,而不能像二进制码那样随意的定义FIFO的深度,因为格雷码必须循环一个2^n,否则就不能保证两个相邻码元之间相差一位的条件,因此也就不是真正的格雷码了。
第二就是使用冗余的触发器,假设一个触发器发生亚稳态的概率为P,那么两个级联的触发器发生亚稳态的概率就为P的平方。
但这会导致延时的增加。
亚稳态的发生会使得FIFO出现错误,读/写时钟采样的地址指针会与真实的值之间不同,这就导致写入或读出的地址错误。
由于考虑延时的作用,空/满标志的产生并不一定出现在FIFO真的空/满时才出现。
可能FIFO还未空/满时就出现了空/满标志。
这并没有什么不好,只要保证FIFO不出现overflow or underflow 就OK了。
格雷码:在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。
高速异步FIFO设计-

课程设计报告高速异步FIFO设计目录技术规范 (3)FIFO的功能描述 (3)FIFO的引脚定义 (3)总体方案设计 (4)电路设计方框图 (4)电路设计连接图 (4)电路模块及其功能简介 (4)电路设计思想 (5)仿真方案及其仿真激励源代码 (8)仿真方案 (8)仿真激励源代码 (8)电路描述代码 (9)功能仿真 (14)分块仿真 (14)双口RAM仿真 (14)读数据控制电路仿真 (15)写数据控制电路仿真 (16)锁存器电路仿真 (16)满空标志电路仿真 (17)总体仿真 (18)综合与布局布线 (18)综合布局布线报告 (19)报告数据分析 (19)时序仿真 (19)实验心得 (20)一、技术规范1、FIFO的功能描述高速异步FIFO(First In First out)深度为256,数据宽度为8位(最大可存储256byte),可实时给出FIFO的满空标志,并可实现数据的平滑输出,其写时钟为带间隔的100MHz,读时钟为5MHz,从而实现了FIFO的异步数据传输。
2、FIFO的应交定义(3)写数据控制器引脚对照表:(4)读数据控制器引脚对照表:二、总体设计方案1、电路设计方框图(如图2.1所示)图2.12、电路设计连接图(如图2.2所示)3、电路模块及其功能简介双口256*8bit的RAM:用于存储FIFO的缓冲数据写数据控制器:用于控制FIFO中数据的写时序操作FIFO 读数据控制器:用于控制FIFO数据中的读时序操作锁存器:用于锁存上一个clock时的读写地址指针FIFO满空标志电路:用于实时标志FIFO的满空状态4、电路设计思想设计高速异步FIFO,首先,考虑如何实现数据的先进先出问题;为了解决这个问题,设计中就必须有一个可用于随机存取的存储器,又要实现异步,即异步读写,所以本设计中存储器选择采用双口RAM;其次,考虑如何实现在不同时钟下,实现读数据和写数据,在设计中,使用独立电路模块,分别控制读写操作;最后,一个要考虑的问题也是本设计中的难点,即对于高速异步FIFO来说,如何高速、实时判断FIFO的满和空。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程论文(设计)题目异步缓冲fifo的设计院系电子与信息工程学院专业电子与通信工程学生姓名卢兴森学号20132281370指导教师刘建成二O一四年元月三日一异步FIFO的介绍 (1)1.1 指针以及满空信号的产生 (1)1.2 二进制指针和格雷码指针的同步 (2)1.3 保守的满空判断 (3)1.4 二进制指针和格雷码指针的比较 (4)二程序及其介绍 (4)三仿真结果图 (13)四总结 (14)一异步FIFO的介绍使用FIFO同步源自不同时钟域的数据是在数字IC设计中经常使用的方法,设计功能正确的FIFO会遇到很多问题,探讨了两种不同的异步FIFO的设计思路。
两种思路都能够实现功能正确的FIFO。
本文所研究的FIFO,从硬件的观点来看,就是一块数据内存。
它有两个端口,一个用来写数据,就是将数据存入FIFO;另一个用来读数据,也就是将数据从FIFO当中取出。
与FIFO操作相关的有两个指针,写指针指向要写的内存部分,读指针指向要读的内存部分。
FIFO控制器通过外部的读写信号控制这两个指针移动,并由此产生FIFO空信号或满信号。
对于异步FIFO而言,数据是由某一个时钟域的控制信号写入FIFO,而由另一个时钟域的控制信号将数据读出FIFO。
也就是说,读写指针的变化动作是由不同的时钟产生的。
因此,对FIFO空或满的判断是跨时钟域的。
如何根据异步的指针信号对FIFO的满状态或空状态进行正确的判断是本文研究的重点。
此外,设计过程中的一些细节问题也将在文中涉及到。
1.1 指针以及满空信号的产生为了更好地说明问题,先探讨一下同步FIFO指针移动以及满空信号的产生过程。
对于同步FIFO,读写指针都指向一个内存的初始位置,每进行一次读写操作,相应的指针就递增一次,指向下一个内存位置。
当指针移动到了内存的最后一个位置时,它又重新跳回初始位置。
在FIFO非满或非空的情况下,这个过程将随着读写控制信号的变化一直进行下去。
如果FIFO处于空的状态,下一个读动作将会导致向下溢出(underflow),一个无效的数据被读人;同样,对于一个满了的FIFO,进行写动作将会导致向上溢出(overflow),一个有用的数据被新写入的数据覆盖。
这两种情况都属于误动作,因此需要设置满和空两个信号,对满信号置位表示FIFO处于满状态,对满信号复位表示FIFO非满,还有空间可以写入数据;对空信号置位表示FIFO处于空状态,对空信号复位表示FIFO非空,还有有效的数据可以读出。
当读指针和写指针相等也就是指向同一个内存位置的时候,FIFO可能处于满或空两种状态。
可以通过不同的方法判断或区分FIFO究竟是处于满状态还是空状态,也就是究竟是写指针从后赶上了读指针,还是读指针从后赶上了写指针。
本文所应用的方法是设置一个额外的状态位,指针由它的地址位以及状态位组成。
地址位随着相应的操作递增,指针由内存的最后位置返回到初始位置的时候状态位取反。
因此,当读写指针的地址位和状态位全部吻合的时候,读写指针经历了相同次数的循环移动,也就是说,FIFO处于空状态;如果读写指针的地址位相同而状态位相反,写指针比读指针多循环一次,标志FIFO处于满状态。
(2)二进制指针可以用于任意大小的FIFO;格雷码指针只能用于大小为2的幂的FIFO。
1.2 二进制指针和格雷码指针的同步二进制指针(如图1)是由一位状态位和若干位二进制编码的地址位组成的(例如由三位地址和一位状态位构成的指针的变化:0000→0001→0010→0011→0100→0101→0110→0111→1000→1001→1010→1011→1100→1101→1110→1111)。
如果在不同的时钟域内直接同步二进制指针,有可能产生问题。
例如,当读指针从0111向1000变化的时侯,指针所有的位都要变化,如果写时钟恰好在读指针的变化时刻采样,写者得到的读指针值有可能是从0000到1111中的任何一个。
所以二进制指针不宜被直接同步,但可以通过一对握手信号同步二进制指针。
图1例如,读指针被读者存人一个寄存器时,读者就发出一个就绪信号。
当写者看到就绪信号时,读取读指针,发出一个收到数据的确认信号。
当读者看到确认信号时,就收回就绪信号,然后用当前的读指针值刷新寄存器。
在收到确认信号前,存放读指针的寄存器内容保持不变,确保了被读取的指针的正确性。
为了能够在不同的时钟域内直接同步指针,可以对指针使用格雷码的编码方式,也就是指针每次移动只变化一位,这样就避免了由于指针多位同时变化而无法直接同步的问题。
图3表示了一个三位地址的内存用于格雷码编码的FIFO。
n位地址的内存需要n+1位的格雷码。
使用最高位(也就是第n-1位)作为状态位,从第n—2到第0位作为地址的第n-2位到第0位;对状态位(也就是第n-1位)和第n-2位进行位异或运算产生地址的第n-2位(也就是地址的最高位)。
通过对图3的观察可以得知,四位格雷码编码的指针和三位二进制加状态位编码的指针具有同样的功能:指针产生的地址循环遍历8个内存地址,每一次遍历后状态位取反。
值得注意的一点,是当指针从0100变化到1100的时候,相应的地址由100变为000,状态位和一位地址同时发生了变化,所以不能同步由另一个时钟域格雷码指针产生的状态位和地址位,此时应该直接由另一个时钟域同步指针来完成,由同步后的指针产生相应的状态位和地址位。
1.3 保守的满空判断对于异步FIFO设计,无论是采用握手还是直接同步的方法来获取对方时钟域的指针,对满空信号的判断总是“保守”的。
(1)满空信号的复位(满信号复位表示FIFO非满,空信号复位表示FIFO非空)和实际FIFO的情况相比有一定的延迟。
例如,空信号是由读者用读指针与同步或握手后得到的写指针进行比较产生的。
由于同步或握手需要一定的时间,在这段时间,写者可能向FIFO写入新的数据,写指针发生了变化,此时FIFO已经非空,但此刻空信号仍然没有复位。
对于写者而言,满信号的复位也会遇到相同的问题。
不过,在通常情况下,FIFO只要确保不会向下溢出或向上溢出,复位的延迟就不会导致向下溢出或向上溢出,是可以接受的。
(2)满空信号的置位(满信号置位表示FIFO满,空信号置位表示FIFO空)和FIFO的实际情况相比没有延迟。
例如,同样考虑FIFO为空的情况,读者使用读指针和同步或握手后的写指针进行比较,由于FIFO为空,写动作不会发生,相应的写指针也保持不变,因此读者获得的就是当时的写指针值。
这样就能马上对空信号置位。
同样地,在FIFO满的情况下,由于读指针不发生变化,写者得到的是当前的读指针值,能够马上判断FIFO为满。
从以上两点的讨论可以得出结论,FIFO满空判断是保守的,写者可能在FIFO 还有一定空间时停止写数据,但不会在FIFO已经满了的情况下继续写数据;读者可能在FIFO还有一些有效的数据时停止读数据,但是不会在FIFO已经空的情况下继续读数据。
保守的满空判断能够满足FIFO的功能要求。
1.4 二进制指针和格雷码指针的比较二进制指针和格雷码指针两者各有优缺点:(1)由于通过握手同步,指针可以有多位同时变化,二进制指针每次移动可以跳跃过任意的长度,这样给FIFO的某些功能的实现带来了方便(例如,硬件直接控制FIFO从缓存的数据流中丢弃一个出错的包);而格雷码指针一般只能做递增或递减的移动。
(2) 与直接同步相比,通过握手同步需要多时钟周期,因此二进制指针的满空判断比格雷码指针的满空判断更“保守”;对于设计一个容量很大且由内存构成的FIFO来说,由于保守判断而损失的空间可以忽略;但对于一个容量较小的FIFO而言,这种“保守”可能是无法接受的。
例如,一个由8个寄存器组成的FIFO,对于格雷码编码的指针,最坏情况下,FIFO被写者判断为满时,里面实际只存有五个数据(使用两级同步器,可能需要三个周期同步,而在这三个周期内都有读动作发生);而对与二进制编码的指针,FIFO被判为满时,FIFO里可能只有三个数据或更少(使用两级同步器,最好的情况下,需要五个周期握手,而在这五个周期里都有读动作发生)。
设计者在两种方法的比较选择上应该考虑到以上的几点。
本文介绍的异步FIFO的设计方法的两种不同尽路都能够实现功能正确的异步FIFO。
对这两种方法设计的FIFO的优缺点所做的简要分析,对FIFO的设计具有指导意义。
二程序及其介绍该fifo缓冲器输入信号为10 khz ,输出信号为20khz,可实现输入结束时输出同时结束;程序分为二部分,顶层文件fifo4080为控制部分,fifo为异步缓冲fifo程序具体如下图2;图2其fifo系统总体设计框图图3如下:图3本程序的使用xilinx ise11.4软件进行设计,仿真使用其自带的testbench;Fifo4080系统顶层框图图4如下:图4Fifo4080程序如下library IEEE;use IEEE.STD_LOGIC_1164.ALL;-- Uncomment the following library declaration if using-- arithmetic functions with Signed or Unsigned values--use IEEE.NUMERIC_STD.ALL;-- Uncomment the following library declaration if instantiating-- any Xilinx primitives in this code.--library UNISIM;--use UNISIM.VComponents.all;entity fifo4080 isgeneric (w:integer:=1024;k:integer:=8);port( rst,wrclk,rdclk,wren: in std_logic;--复位高电平有效,clk上升沿有效,使能端低电平有效din:in std_logic_vector(k-1 downto 0);dout:out std_logic_vector(k-1 downto 0);full,empty:out std_logic);end fifo4080;architecture Behavioral of fifo4080 issignal count:integer range 0 to w-1;signal rden:std_logic:='1';component fifogeneric (w:integer:=1024;k:integer:=8);port( rst,wrclk,rdclk,wren: in std_logic;--复位高电平有效,clk上升沿有效,使能端低电平有效din:in std_logic_vector(k-1 downto 0);dout:out std_logic_vector(k-1 downto 0);full,empty:out std_logic;rden:out std_logic;count:out integer range 0 to w-1);end component;beginu1:fifogeneric map(w=>w,k=>k)port map (rst=>rst,wrclk=>wrclk,rdclk=>rdclk,wren=>wren,din=>din,dout=>dout,full=>full,empty=>empty,rden=>rden,count=>count);process(count)beginif(count>=512) thenrden<='0';elserden<='1';end if;end process;end Behavioral;异步缓冲器fifo文件程序如下entity fifo isgeneric (w:integer:=1024;k:integer:=8);port( rst,wrclk,rdclk,wren: in std_logic;--复位高电平有效,clk上升沿有效,使能端低电平有效din:in std_logic_vector(k-1 downto 0);dout:out std_logic_vector(k-1 downto 0);full,empty:out std_logic;rden:out std_logic;count:out integer range 0 to w-1);end fifo;architecture Behavioral of fifo istype memory is array (0 to w-1) of std_logic_vector (k-1 downto 0);signal ram:memory;signal wradd,rdadd: integer range 0 to w-1; signal infull,inempty:std_logic;signal rdens:std_logic;--signal cnen:std_logic;beginprocess(wrclk) --写数据beginif (wrclk'event and wrclk='1') thenif (wren='0' and infull='0') thenram(wradd) <= din;end if;end if;end process;process(rst,wrclk)--写地址修改beginif (rst='1') thenwradd<=0;elsif (wrclk'event and wrclk='1') then if (wren='0' and infull='0') thenif(wradd=w-1) thenwradd<=0;elsewradd<=wradd+1;end if;end if;end if;end process;process (rst,rdclk)--读地址修改beginif(rst='1') thenrdadd<=w-1;elsif (rdclk'event and rdclk='1') then if (rdens='0' and inempty='0') then if(rdadd=w-1) thenrdadd<=0;else rdadd<=rdadd+1;end if;end if;end if;end process;process (rst,rdclk)--empty 产生beginif(rst='1') theninempty<='1';elsif (rdclk'event and rdclk='1') thenif ((rdadd=wradd-2 or(rdadd=w-1 and wradd=1)or(rdadd=w-2 andwradd=0))and(rdens='0')) theninempty<='1';elseinempty<='0';end if;end if;end process;process (rst,wrclk)--full 产生beginif(rst='1') theninfull<='0';elsif (wrclk'event and wrclk='1') thenif (rdadd=wradd and wren='0') theninfull<='1';elseinfull<='0';end if;end if;end process;process(wrclk) --计数variable counter:integer range 0 to w-1; beginif ((wrclk'event and wrclk='1') and rst='0') then if (wren='0' and infull='0') thencounter:=counter+1;end if;end if;if(counter>=512) thenrdens<='0';end if;if((counter=1024) or (rst='1')) thencounter:=0;rdens<='1';end if;count<=counter;end process;dout<=ram(rdadd);full<=infull;empty<=inempty;rden<=rdens;end Behavioral;在上述程序综合成功后,可在ise中新建testbench程序,在新建程序test 的末端输入下列仿真时序程序即可进行仿真。