异步fifo程序

合集下载

异步fifo的uvm验证原理

异步fifo的uvm验证原理

异步fifo的uvm验证原理异步FIFO(First-In-First-Out,先进先出)是一种常用的数据缓冲区结构,常用于解决不同速率的数据传输问题。

UVM (Universal Verification Methodology,通用验证方法学)是一种系统级验证方法学,用于验证硬件设计。

在UVM中,对异步FIFO的验证需要对FIFO的功能和时序进行验证。

以下是异步FIFO的UVM验证原理:1. 创建FIFO模型:首先,需要创建一个FIFO模型,包括FIFO的输入端口和输出端口,以及FIFO的内部数据存储器。

可以使用SystemVerilog语言创建FIFO模型。

2. 编写验证环境:在UVM中,需要编写一个验证环境(testbench),用于生成测试用例,驱动输入数据到FIFO中,并验证FIFO的输出数据是否符合预期。

验证环境包括以下组件:- 驱动(driver):负责将测试向量输入到FIFO中。

- 监视器(monitor):监控FIFO的输出数据,并将其与预期结果进行比较。

- 预测器(predictor):根据输入数据预测FIFO的输出结果。

- 生成器(generator):生成各种测试用例。

3. 设置时序约束:对于异步FIFO的验证,需要设置时序约束,以确保FIFO的输入和输出数据能够按照预期的时序要求进行传输。

时序约束包括FIFO的读写时钟频率和时钟间隔等参数。

4. 进行功能验证:验证FIFO的功能,包括数据的读写操作是否正确,数据的顺序是否符合FIFO原则等。

可以通过在测试用例中使用不同的输入数据和读写操作顺序来验证FIFO的功能。

5. 进行时序验证:验证FIFO的时序,包括输入数据的时序要求是否满足,输出数据的时序是否符合预期。

可以通过在测试用例中使用不同的时序生成输入数据来验证FIFO的时序。

6. 进行性能验证:验证FIFO的性能,包括写入速率和读出速率是否满足要求,以及FIFO的深度是否足够。

quartus 异步fifo用法

quartus 异步fifo用法

quartus 异步fifo用法在Quartus中使用异步FIFO,可以通过IP Core Catalog中的"ALTAsyncFIFO"来实现。

以下是使用异步FIFO的步骤:1. 打开Quartus Prime软件。

点击"File"菜单,选择"New Project"来创建一个新的项目。

2. 在"New Project Wizard"中,选择项目的名称、储存位置和顶层实体的文件。

点击"Next"继续。

3. 在"Add Files"步骤中,添加设计文件,包括顶层实体和其他组件文件。

点击"Next"继续。

4. 在"Family and Device Settings"步骤中,选择您的目标FPGA 器件。

点击"Next"继续。

5. 在"EDA Tool Settings"步骤中,选择Quartus使用的EDA工具。

点击"Next"继续。

6. 在"Summary"步骤中,查看项目设置的摘要。

点击"Finish"完成项目创建。

7. 在Quartus主界面的左侧面板中,点击"IP"选项卡,然后选择"Library"。

在IP Core Library窗口中,搜索"ALTAsyncFIFO"。

8. 在搜索结果中,选择"ALTAsyncFIFO"并点击"OK"来添加该IP到项目中。

9. 在设计文件中实例化ALTAsyncFIFO组件。

可以使用Quartus的"IP Catalog"来生成实例化代码。

10. 配置ALTAsyncFIFO的参数,包括FIFO大小、输出宽度、寄存器位宽等。

quartus 异步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

跨时钟域之异步FIFO

跨时钟域之异步FIFOAsynchronous FIFO Design异步FIFO的读写指针写指针写指针指向当前将要写⼊数据的位置,复位之后,读写指针被置零。

执⾏写操作的时候,向写指针指向的存储区写⼊数据,之后写指针加1,指向接下来要被写⼊数据的位置。

On a FIFO-write operation, the memory location that is pointed to by the write pointer is written, and then the write pointer is incremented to point to the next location to be written.读指针:读指针指向当前要被读取数据的位置,复位时,读写指针被置零,FIFO为空读指针指向⼀个⽆效的数据(FIFO为空,empty信号有效——拉⾼)。

当第⼀个有效数据被写⼊FIFO之后,写指针增加,empty flag信号被拉低,且读指针⼀直指向FIFO第⼀FIFO空标志:当读写指针是相等的时候:分两种情况1.当读写指针执⾏复位操作的时候。

2.当读指针赶上写指针的时候,最后⼀笔数据从FIFO读出后FIFO为空FIFO满标志:读写指针相等,当FIFO⾥⾯的写指针写满⼀圈之后⼜转回到和读指针同样的位置。

有个问题,读写指针相等的时候怎么判断FIFO是empty还是full?设计的时候增加⼀位bit去辅助判断FIFO是空还是满。

当写指针超过FIFO的最⼤寻址范围时,写指针将使辅助位zhi⾼,其余位为0.FIFO满的时候:读写指针的低位(n-1位bit)相等,⾼位(第n位bit)不同。

FIFO空的时候,读写指针的低位和⾼位都相等。

(针对⼆进制)但是⼆进制FIFO指针综合电路复杂,⼀般采⽤**格雷码**,⽂章中采⽤⼆进制转换格雷码的⽅法,判断FIFO的空满标志4位⼆进制格雷码,有效地址位为三位。

⼆进制转换为格雷码的算法:rgraynext = (rbinnext>>1) ^ rbinnext;1.顶层模块fifo:例化各个⼦模块//顶层模块实例化各个⼦模块module fifo#(parameter DSIZE = 8, //读写数据位宽均设置为8位parameter ASIZE = 4 // 存储地址位宽设置)(output [DSIZE-1:0] rdata,output wfull,output rempty,input [DSIZE-1:0] wdata,input winc, wclk, wrst_n,input rinc, rclk, rrst_n);wire [ASIZE-1:0] waddr, raddr;wire [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr;// 内部线⽹// synchronize the read pointer into the write-clock domainsync_r2w sync_r2w(.wq2_rptr (wq2_rptr),.rptr (rptr ),.wclk (wclk ),.wrst_n (wrst_n ));// synchronize the write pointer into the read-clock domainsync_w2r sync_w2r(.rq2_wptr(rq2_wptr),.wptr(wptr),.rclk(rclk),.rrst_n(rrst_n));//this is the FIFO memory buffer that is accessed by both the write and read clock domains.//This buffer is most likely an instantiated, synchronous dual-port RAM.//Other memory styles can be adapted to function as the FIFO buffer.fifomem#(DSIZE, ASIZE)fifomem(.rdata(rdata),.wdata(wdata),.waddr(waddr),.raddr(raddr),.wclken(winc),.wfull(wfull),.wclk(wclk));//this module is completely synchronous to the read-clock domain and contains the FIFO read pointer and empty-flag logic.rptr_empty#(ASIZE)rptr_empty(.rempty(rempty),.raddr(raddr),.rptr(rptr),.rq2_wptr(rq2_wptr),.rinc(rinc),.rclk(rclk),.rrst_n(rrst_n));//this module is completely synchronous to the write-clock domain and contains the FIFO write pointer and full-flag logicwptr_full#(ASIZE)wptr_full(.wfull(wfull),.waddr(waddr),.wptr(wptr),.wq2_rptr(wq2_rptr),.winc(winc),.wclk(wclk),.wrst_n(wrst_n));endmodule2.时钟域同步模块sync_r2w:读指针同步到写时钟域wclk// 采⽤两级寄存器同步读指针到写时钟域module sync_r2w#(parameter ADDRSIZE = 4)(output reg [ADDRSIZE:0] wq2_rptr, //读指针同步到写时钟域input [ADDRSIZE:0] rptr, // 格雷码形式的读指针,格雷码的好处后⾯会细说input wclk, wrst_n);reg [ADDRSIZE:0] wq1_rptr;always @(posedge wclk or negedge wrst_n)if (!wrst_n) beginwq1_rptr <= 0;wq2_rptr <= 0;endelse beginwq1_rptr<= rptr;wq2_rptr<=wq1_rptr;endendmodule原理图3.时钟域同步模块sync_w2r:写指针同步到读时钟域rclk//采⽤两级寄存器同步写指针到读时钟域module sync_w2r#(parameter ADDRSIZE = 4)(output reg [ADDRSIZE:0] rq2_wptr, //写指针同步到读时钟域input [ADDRSIZE:0] wptr, //格雷码形式的写指针input rclk, rrst_n);reg [ADDRSIZE:0] rq1_wptr;always @(posedge rclk or negedge rrst_n)if (!rrst_n)beginrq1_wptr <= 0;rq2_wptr <= 0;endelse beginrq1_wptr <= wptr;rq2_wptr <= rq1_wptr;endendmoduleRTL原理图4.存储模块//存储模块module fifomem#(parameter DATASIZE = 8, // Memory data word widthparameter ADDRSIZE = 4 // 深度为8即地址为3位即可,这⾥多定义⼀位的原因是⽤来判断是空还是满,详细在后⽂讲到) // Number of mem address bits(output [DATASIZE-1:0] rdata,input [DATASIZE-1:0] wdata,input [ADDRSIZE-1:0] waddr, raddr,input wclken, wfull, wclk);////////////////////////////////这部分没⽤到,可以单独写⼀个模块来调⽤//////////////`ifdef RAM //可以调⽤⼀个RAM IP核// instantiation of a vendor's dual-port RAMmy_ram mem(.dout(rdata),.din(wdata),.waddr(waddr),.raddr(raddr),.wclken(wclken),.wclken_n(wfull),.clk(wclk));//////////////////////////这部分没⽤到,可以单独写⼀个模块来调⽤//////////////////`else //⽤数组⽣成存储体// RTL Verilog memory modellocalparam DEPTH = 1<<ADDRSIZE; // 左移相当于乘法,2^4 将1左移4位reg [DATASIZE-1:0] mem [0:DEPTH-1]; //⽣成2^4个位宽位8的数组assign rdata = mem[raddr];always @(posedge wclk) //当写使能有效且还未写满的时候将数据写⼊存储实体中,注意这⾥是与wclk同步的if (wclken && !wfull)mem[waddr] <= wdata;`endifendmodule原理图5. rptr_empty模块:产⽣rempty和raddr信号//产⽣empty信号和raddar信号的模块module rptr_empty#(parameter ADDRSIZE = 4)(output reg rempty,output [ADDRSIZE-1:0] raddr, //⼆进制形式的读指针output reg [ADDRSIZE :0] rptr, //格雷码形式的读指针input [ADDRSIZE :0] rq2_wptr, //同步后的写指针同步到读时钟域input rinc, rclk, rrst_n);reg [ADDRSIZE:0] rbin;wire [ADDRSIZE:0] rgraynext, rbinnext;// GRAYSTYLE2 pointer//将⼆进制的读指针与格雷码进制的读指针同步always @(posedge rclk or negedge rrst_n)if (!rrst_n) beginrbin <= 0;rptr <= 0;endelse beginrbin<=rbinnext; //直接作为存储实体的地址rptr<=rgraynext;//输出到 sync_r2w.v模块,被同步到 wrclk 时钟域end// Memory read-address pointer (okay to use binary to address memory)assign raddr = rbin[ADDRSIZE-1:0]; //直接作为存储实体的地址,⽐如连接到RAM存储实体的读地址端。

uart fifo 流程

uart fifo 流程

uart fifo 流程UART FIFO流程一、引言UART(通用异步收发传输器)是一种常用的串行通信协议,用于在嵌入式系统中实现设备之间的数据传输。

其中,FIFO(First In First Out)是一种常见的数据缓冲区,用于解决数据传输过程中的速度不匹配问题。

本文将介绍UART FIFO的工作原理和流程。

二、UART FIFO的概念UART FIFO是一种先进先出的数据缓冲区,用于存储待发送或已接收的数据。

它的主要作用是解决数据传输过程中速度不匹配的问题。

当发送端和接收端的数据传输速度不一致时,FIFO可以暂时存储数据,以平衡两者之间的速度差异。

三、UART FIFO的工作原理1. 发送端工作原理当发送端有数据要发送时,数据首先被写入到FIFO缓冲区中。

如果FIFO缓冲区为空,则数据可以直接写入;如果FIFO缓冲区已满,则发送端需要等待,直到FIFO缓冲区有足够的空间。

发送端通过检查FIFO的状态位来确定是否可以写入数据。

2. 接收端工作原理当接收端准备好接收数据时,它会从FIFO缓冲区中读取数据。

如果FIFO缓冲区为空,则接收端需要等待,直到FIFO缓冲区有数据可读。

接收端通过检查FIFO的状态位来确定是否可以读取数据。

四、UART FIFO的流程1. 发送端流程(1)检查FIFO状态位,确定是否可以写入数据;(2)如果FIFO缓冲区已满,则等待;(3)将数据写入FIFO缓冲区;(4)检查数据是否成功写入FIFO缓冲区;(5)重复上述步骤,直到所有数据发送完毕。

2. 接收端流程(1)检查FIFO状态位,确定是否有数据可读;(2)如果FIFO缓冲区为空,则等待;(3)从FIFO缓冲区中读取数据;(4)检查数据是否成功读取;(5)重复上述步骤,直到所有数据接收完毕。

五、UART FIFO的优势1. 缓冲作用:FIFO缓冲区可以暂时存储数据,以平衡发送端和接收端之间的速度差异,避免数据丢失或溢出。

quartus 异步fifo用法 -回复

quartus 异步fifo用法 -回复

quartus 异步fifo用法-回复Quartus 异步FIFO 用法说明引言:在现代数字系统设计中,FIFO(先进先出)是一种常见的数据缓冲区,用于解决数据在不同速度的模块之间的数据流问题。

在Quartus 中,异步FIFO 提供了一种灵活和方便的方式来实现数据的缓冲和流控。

本文将逐步介绍Quartus 异步FIFO 的基本用法,帮助读者了解其操作和配置。

第一步:创建FIFO首先,在Quartus 中打开自己的设计项目,选择要创建异步FIFO 的模块。

然后,点击菜单栏中的"Project",选择"New",再选择"FIFO MegaWizard"。

接下来,按照提示选择FIFO 的类型、数据位宽和深度等配置参数。

请注意,深度是指FIFO 可以容纳的数据数量。

点击"Next"继续,然后会出现一个界面,该界面将由Quartus 生成FIFO 的RTL(寄存器传输级)代码。

在这个界面上,您可以选择生成的接口样式以及其他自定义选项。

完成配置后,点击"Finish",Quartus 将自动生成FIFO 的VHDL 或Verilog 代码,并将其添加到项目中。

第二步:添加FIFO 的输入和输出端口一旦FIFO 生成完成并添加到项目中,您需要将其引入到适当的模块中,并为其添加输入和输出端口。

假设我们将FIFO 引入到名为"Top_Module"的模块中,请按照以下步骤进行操作:1. 在"Top_Module"的代码中,将FIFO 的引用添加为一个实例,例如:fifo_inst : entity work.my_fifoport map (clk => internal_clk,reset => reset,wr_data => data_in,wr_en => write_enable,rd_data => data_out,rd_en => read_enable,full => fifo_full,empty => fifo_empty);2. 根据您的设计需要,为FIFO 添加输入和输出信号。

altera fifo异步清零信号的时序

altera fifo异步清零信号的时序

altera fifo异步清零信号的时序一、引言在数字电路设计中,FIFO(First In First Out)是一种常见的数据缓冲器,用于解决不同速度的数据传输之间的数据流失问题。

Altera是一家知名的FPGA芯片制造商,其FIFO模块提供了异步清零信号来实现清空缓冲区的功能。

二、FIFO异步清零信号的定义FIFO异步清零信号是一种特殊的控制信号,用于将FIFO缓冲区中的数据全部清空。

当该信号被激活时,FIFO模块会将缓冲区中的数据全部丢弃,并将指针重置为初始状态。

三、FIFO异步清零信号的工作原理FIFO异步清零信号的工作原理如下:1. 当FIFO异步清零信号被激活时,FIFO模块会检测到该信号的变化。

2. FIFO模块会立即停止写入数据和读取数据的操作,并将指针重置为初始状态。

3. FIFO模块会将缓冲区中的数据全部丢弃,不再进行任何处理。

4. FIFO异步清零信号被取消激活后,FIFO模块会恢复正常的读写操作。

四、FIFO异步清零信号的时序特性FIFO异步清零信号的时序特性如下:1. 异步清零信号可以随时激活,无需与其他信号同步。

2. 异步清零信号的激活时间和激活持续时间可以根据设计要求进行调整。

3. FIFO模块在接收到异步清零信号后会立即响应,无需等待时钟信号。

4. 异步清零信号的取消激活时间可以根据设计要求进行调整。

5. 异步清零信号的取消激活时间应保证足够长,以确保FIFO模块完全恢复正常操作。

五、FIFO异步清零信号的注意事项在使用FIFO异步清零信号时,需要注意以下几点:1. 异步清零信号的激活和取消激活应遵循设计规范,不得出现脉冲信号或持续激活导致异常操作。

2. 异步清零信号的激活和取消激活时间应考虑到FIFO模块的响应时间和恢复时间,避免信号过短或过长导致操作不稳定。

3. 在设计中,应考虑到异步清零信号与其他控制信号的相互作用,避免冲突或误操作。

六、总结FIFO异步清零信号是一种重要的控制信号,用于清空FIFO缓冲区中的数据。

基于乒乓操作的异步FIFO设计及VHDL实现

基于乒乓操作的异步FIFO设计及VHDL实现

基于乒乓操作的异步FIFO设计及VHDL实现乒乓操作是一种常用的同步操作,可以实现数据的交换和缓存。

基于乒乓操作的异步FIFO设计,则是在原有的乒乓操作基础上,加入异步读写功能,实现了先进先出的数据存储。

在设计过程中,我们需要考虑以下几个关键点:1.写入数据的操作:当有新的数据要写入到FIFO中时,首先需要判断FIFO是否已满。

如果已满,则需要等待读取操作后再进行写入;如果未满,则直接将数据写入到空闲位置,并更新写指针。

2.读取数据的操作:当有读取操作时,首先需要判断FIFO是否为空。

如果为空,则需要等待写入操作后再进行读取;如果不为空,则从第一个有效数据开始读取,并将读取完的数据位置清空,并更新读指针。

3.FIFO的容量:FIFO的容量应该根据实际需求进行设置。

当FIFO中的数据量达到容量上限时,写操作将被阻塞,直到有读取操作释放空间。

基于以上设计思路,下面是一个简单的基于乒乓操作的异步FIFO的VHDL实现代码:```vhdllibrary ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;entity Async_FIFO isgenericWIDTH : integer := 8; -- 数据位宽DEPTH : integer := 16 -- FIFO深度portclk : in std_logic; -- 时钟reset : in std_logic; -- 复位write : in std_logic; -- 写操作使能信号read : in std_logic; -- 读操作使能信号data_in : in std_logic_vector(WIDTH-1 downto 0); -- 输入数据data_out: out std_logic_vector(WIDTH-1 downto 0); -- 输出数据empty : out std_logic; -- FIFO为空标志位full : out std_logic -- FIFO为满标志位end Async_FIFO;architecture behavioral of Async_FIFO istype fifo_type is array (0 to DEPTH-1) ofstd_logic_vector(WIDTH-1 downto 0); -- FIFO存储类型signal fifo : fifo_type; -- FIFO数组signal write_ptr : integer range 0 to DEPTH-1 := 0; -- 写指针signal read_ptr : integer range 0 to DEPTH-1 := 0; -- 读指针signal count : integer range 0 to DEPTH := 0; -- FIFO计数器beginprocess(clk, reset)beginif reset = '1' then--复位write_ptr <= 0;read_ptr <= 0;count <= 0;elsif rising_edge(clk) then--写操作if write = '1' and count < DEPTH thenfifo(write_ptr) <= data_in;write_ptr <= write_ptr + 1;count <= count + 1;end if;--读操作if read = '1' and count > 0 thendata_out <= fifo(read_ptr);fifo(read_ptr) <= (others => '0');read_ptr <= read_ptr + 1;count <= count - 1;end if;end if;end process;empty <= '1' when count = 0 else '0';full <= '1' when count = DEPTH else '0';end behavioral;```上述代码中,首先定义了一个`fifo_type`类型,它是一个包含`DEPTH`个元素的数组,每个元素的大小为`WIDTH`位。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

高速异步FIFO的设计与实现摘要:本文主要研究了用FPGA芯片实现异步FIFO的一种方法。

通过对FPGA芯片内部EBRSRAM的深入研究.提出了一种利用格雷码对地址进行编码的异步FIFO设计方案。

实践证明.增加了系统可靠性和应用灵活性。

引言现代集成电路芯片中,随着设计规模的不断扩大.一个系统中往往含有数个时钟。

多时钟带来的一个问题就是,如何设计异步时钟之间的接口电路。

异步FIFO(First In First Out)是解决这个问题的一种简便、快捷的解决方案。

使用异步FIFO可以在两个不同时钟系统之间快速而方便地传输实时数据.在网络接口、图像处理等方面,异步FIFO都得到广泛的应用。

异步FIFO是一种先进先出的电路,使用在数据接口部分,用来存储、缓冲在两个异步时钟之间的数据传输。

在异步电路中,由于时钟之间周期和相位完全独立,因而数据的丢失概率不为零。

如何设计一个可靠性高、速度高的异步FIFO电路便成为一个难点。

1 异步FIFO的工作原理及逻辑框图本文根据实际工作的需要.给出了一种利用片内RAM构造FIFO器件的设计,重点强调了设计有效.可靠的握手信号FULL和EMPTY的方法。

并在LATTICE公司的FPGA芯片LFXP2-5E上实现。

LFXP2-5E属于LATIICE 公司XP2系列的一款,他采用优化的FlexiFLASH结构。

内部包含有基于查找表的逻辑、分布式和嵌入式存储器,锁相环(PLL)。

工程预制的源同步I/0以及增强的Sys DSP块。

有166Kbits的EBRSRAM。

利用其内部的EBRSRAM可以实现一定容量的异步FIFO.而无需单独购买FIF0器件。

由图1可以看出:异步FIFO一般由四个模块构成:数据存储单元,写地址产生模块,读地址产生模块,标志位产生模块。

整个系统分为两个完全独立的时钟域—读时钟域和写时钟域:在写时钟域部分由写地址产生逻辑产生写控制信号和写地址:读时钟域部分,由读地址产生逻辑产生读控制信号和读地址;在标志位产生模块部分,由读写地址相互比较产生空/满标志。

异步FIFO的操作过程为:在写时钟的上升沿.当写使能有效时,将数据写入到双口RAM中写地址对应的位置中:在读时钟的上升沿,当读使能有效时。

则按先进先出顺序读出数据。

在FIFO写满或读空的情况下。

分别对满标志FuLL或空标志EMPTY信号置位。

来表示FIFO的两种特殊状态。

图1异步FIFO逻辑框图2 异步FIFO的VHDL实现读时钟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为满条件。

由以上可知。

满标志的产生条件为:写指针赶上读指针.即写满后,又从零地址开始写直到赶上读指针,这时期读写指针的最高位不同,其他位相同,这就是满条件。

空标志的产生条件为:复位或者是读指针赶上写指针.即在写指针循环到第二轮时读指针赶上写指针,这时读写指针的高低位均相同,这就是空条件。

2.2异步F1F0的VHDL语言实现以下为本程序的核心部分程序1格雷码计数器的实现3 仿真验证基于以上的分析结合实际本文构造了一个8192x8的FIFO,用MODELSIM进行仿真。

对该异步FIFO编写测试向量进行仿真,如图2所示。

图2仿真波形图图2中,WClk为写时钟,Writeen_in为写使能,Full_out为满信号,Data_in为数据入,RClk为读时钟,ReadEn_in为读时能,Empty_out为空信号,Data_out为数据出,Clear_in为系统清零信号。

上面部分为写地址产生模块部分的信号波形,从图2中可以看出.在写时钟的上升沿.在写时能为高有效期间擞据开始输入到RAM里面,而在读时钟的上升沿,在读时能有效时,在本仿真时间的195ns处.开始输出数据。

将程序下载到LATTICE公司的FPGA芯片中,经过测试验证,系统的时钟频率可达33MHz。

4 总结本文主要研究了用FPGA芯片实现异步FIFO的一种方法。

详细阐述了空,满标志信号的产生方法。

按照以上思想所设计的异步FIFO已经在实际电路中得到了应用。

实践证明他可以解决大多数异步FIFO电路常见的错误。

同时增加了系统的可靠性和应用灵活性。

FPGA异步FIFO设计中的问题与解决办法21IC中国电子网随着数字电子系统设计规模的扩大,一些实际应用系统中往往含有多个时钟,数据不可避免地要在不同的时钟域之间传递。

如何在异步时钟之间传输数据,是数据传输中一个至关重要的问题,而采用FIFO 正是解决这一问题的有效方法。

异步FIFO是一种在电子系统中得到广泛应用的器件,多数情况下它都是以一个独立芯片的方式在系统中应用。

本文介绍一种充分利用FPGA内部的RAM资源,在FPGA内部实现异步FIFO模块的设计方法。

这种异步FIFO比外部FIFO 芯片更能提高系统的稳定性。

1 FIFO的基本结构和工作原理FIFO(First In First Out)是一种采用环形存储结构的先进先出存储器。

其使用一个双端口存储器存放数据,数据发送方在一端写入数据,接收方在另一端读出数据,能够协调好两个时钟域的工作,满足高时钟频率的要求。

FIFO在FPGA设计中主要用来缓冲数据和隔离时钟或相位差异。

访问FIFO时不需要地址线,只需要数据线和读写控制信号线,且数据地址由内部读写指针自动加1完成,因此利用FIFO实现数据的缓存具有接口简单、读写方便的优点。

根据FIFO的工作时钟,可将FIFO分为同步FIFO和异步FIFO。

同步FIFO是指读时钟和写时钟为同一个时钟,在时钟沿来临时同时进行读写操作;异步FIFO是指读写时钟不是同一个时钟,而是相互独立的。

实际上,工作在同一时钟的FIFO很少用到,多数都是读写时钟独立的异步FIFO。

本文设计的异步FIFO位宽为8,深度(即FIFO可以存储8位数据的个数)为1 024。

异步FIFO的结构如图1所示。

双端口RAM存储器具有独立的读写端口。

如果用一个单端口RAM存储器实现异步FIFO,还应该包含一个仲裁器来保证同一时刻只能有一种操作(读或写操作)。

本文选择的双端口RAM并不一定是真正的双端口,只要有独立的读写端口即可。

读写控制逻辑由加法计数器构成,实现读写地址的自动加1功能。

空/满标志位的产生逻辑给系统提供空(empty)和满(full)信号。

2 异步FIFO设计中的问题与解决办法2.1 亚稳态问题在含有触发器的电路中往往会出现亚稳态问题。

亚稳态会使异步FIFO的读写地址发生错误,产生误读或者误写。

为此异步FIFO设计中亚稳态问题也是一个比较重要的问题。

亚稳态不可能完全消除,只能使其出现的概率降到最低。

主要有2种方法来降低亚稳态出现的概率:①采用触发器冗余方式。

即采用多个触发器级联的方式,使本来出现概率为P的亚稳态,其出现概率降低到P2,但这种方式会导致延时增加。

②使用格雷码。

格雷码的相临码元之间只有一位发生变化,这就大大地降低了亚稳态出现的概率。

本文采用格雷码方式。

2.2 空/满标志位的判断为保证数据的正确写入和读出,不发生写满和读空操作,怎样判断空/满标志位的产生就成为异步FIFO设计的核心问题。

异步FIFO是环形存储的,当读写地址指针相等时,意味着空标志位或者满标志位的产生。

但是却不能确定是写满还是读空状态。

为解决这一问题,本文将转换为格雷码后的读写地址指针分别经过检测和计数器。

每当读写指针遍历一圈(当读写地址指针指向双端口RAM的最后一个地址)时,写计数i加1,读计数j加1。

这样写满状态和读空状态的判断就需要同时满足两个条件。

下面分别给出写满和读空状态的判断。

①写满状态的判别:当读地址指针等于写地址指针,并且i>j时,产生满标志。

②读空状态的判别:当写地址指针等于读地址指针,并且i=j时,产生空标志。

由于空/满标志位产生的结构图对称,故本文只给出满标志位产生的结构图,如图2所示。

其中,主数i为写地址指针遍历的圈数,计数j为读地址指针遍历的圈数。

从图2中可看出,地址指针转换为格雷码后,经过检测和计数环节,将读写地址和读写指针遍历的圈数分别送入比较器进行比较,从而准确地产生满标志位。

3 FPGA内部软异步FIFO设计本设计中FPGA采用的是Xilinx Spartan3系列中的XC3S400PQ208。

内部有56 Kb的分布式RAM 和288 Kb的RAM,以及4个DCM(数字时钟管理器)单元,为系统提供独立的读写时钟频率。

可以利用这些资源在FPGA内部实现异步FIFO模块。

本文采用VHDL语言对双端口RAM的读写操作进行编程,实现FPGA内部软FIFO的设计。

部分读写双端口RAM和空/满标志位的判断源程序如下:4 系统仿真如果系统的读时钟频率大于写时钟频率,就有可能出现读空的情况;如果系统的写时钟频率大于读时钟频率,就可能出现写满的情况。

在实际系统中,一般都设置写时钟频率大于读时钟频率,故本文只考虑后一种情况。

相关文档
最新文档