首页 > 编程知识 正文

verilog可综合fifo,verilog同步复位和异步复位

时间:2023-05-06 01:13:23 阅读:63713 作者:3801

1、设计框图

图1

这张照片是我摘录的,照片来源于eetop。 我认为这张图有两个问题。 例如,wclk模块的g端口访问同步到读取clk,根据理解应该是ginc而不是g。 这是因为,从g端口输出的数据仍然是二进制数据,而ginc端口数据的数据应该是灰色数据。 同样,另一个问题很相似。

上图所示的同步模块synchronize to write clk在写入时钟wr_clk区域收集读取时钟区域的读取指针rd_ptr,与写入指针wr_ptr进行比较,将全标志位wr_full 同样,同步模块synchronize to read clk的作用是在读取时钟域收集写入时钟域的写入指针wr_ptr,并将其与读取指针rd_ptr进行比较以生成读取空标志位rd_empty

另外,还有写入指针wr_ptr和写入标志位wr_full生成模块、读取指针rd_ptr和读取空标志位rd_empty生成模块以及双端口存储RAM模块

2、使用gray码的原因

虽然异步FIFO读/写指针需要与数学操作进行比较以产生精确的空闲标志位,但由于读/写指针属于不同时钟域及读/写时钟的相位关系的不确定性,因此当同步模块收集另一时钟域的指针时如图2所示,收集到的值很可能是不想要的值,当然也产生不想要的错误结果。

采用gray一次只改变一位,有效避免了跳跃过程中出现的问题。

http://www.Sina.com/http://www.Sina.com /

3、Verilog实现gray码的方式

如图3所示,指向存储器的地址指针由二进制计数器生成,而用于在时钟域之间传播的格雷码指针通过寄存器实时转换二进制指针来收集。 这里需要注意的是,计数器的位宽比实际需要的位宽多一位。 其目的是为了便于判断FIFO是空闲还是空闲。 这将在后面叙述。

gray[n - 1:0 ] = (生动的大船[n - 1 :0] 1) ^ 生动的大船[n - 1 : 0]

异步FIFO 4、gray码计数器的实现结构图这直接关系到设计的成败。 本文利用比较读写指针判断FIFO的空缺。5、读空与写满标志位的产生

http://www.Sina.com/:FIFO只有在两种情况下为null。 第一,系统复位,读写指针全部清除。 在另一种情况下,如果FIFO不为空,则数据读取速度快于数据写入速度,并且如果读取地址赶上写入地址,则FIFO为空。 空标志位的生成必须在读时钟域内完成。

最核心的部分就是精确产生空满标志位:当读取地址rd_ptr赶上写入地址wr_ptr时,即当rd_ptr完全等于wr_ptr时,可以确定FIFO中的数据为空。

1、写入指针同步后,由于与读取指针进行比较,写入指针不立即更新,产生虚空(FIFO不为空,但产生空标志位)标志位,虚空标志引起传输错误

如果FIFO的深度是n-1位线所能访问到的地址空间,那么此设计所要用的指针位宽就比实际多出一位,也就是n位,这样做有助于判断FIFO是空还是满。举一个简单生动的例子,读写指针的关系就像A、b两位田径运动员在环形跑道上赛跑一样。 B选手领先A整整前进了一圈时,A、b两个人的地方是一样的。 这种情况对应于读写指针指向同一地址,但写入指针前进整整一圈写满了FIFO。

*注意: **如果地址的宽度等于FIFO实际深度所需的宽度,并且读写地址在某个时间点相同,则很难判断该FIFO是否已满。 因此,读写指针必须添加一位,以标记写入地址是否超前于读取地址。 (在系统正常工作的前提下,读取地址并不比写入地址超前。 )读空

*判断依据: **首先,最高位不同((由于读取指针并不是比写入指针超前,所以写入指针可能只是比读取指针超前) )。 接着,使最高位为1的所有格雷码指针的下一最高位反转之后,除非看到最高位,否则指向相同存储器空间的两个指针是相同的,第二条件是下一高度也不同。判断依据

6、总结

异步FIFO重点了解了空标志信号的产生方法,以及可能出现的“虚空”和“虚空”现象。 了解了这些重要信号的产生原理,设计异步FIFO也就不容易了。

在下面贴上代码。 主要包括五个部分,每个部分都是根据图1编写的。 其中,没有显示实例化RAM的代码。 我实例化的是8 * 8bit的RAM。

1、顶层文件:

//====================================

: async_fifo_top// Author : Winson_c// Tool version : Quartus II 13.1// Revision : v1.0// Description : Asynchronize FIFO //=========================================================`include "define.v"module async_fifo_top( input wclk, input rclk, input wrst_n, input rrst_n, input write, //input read, input [`DATA_WIDTH - 1: 0]wdata, output wfull, output rempty, output [`DATA_WIDTH - 1: 0]rdata ); wire [`FIFO_WIDTH : 0]wr_ptr_gray; wire [`FIFO_WIDTH -1 : 0]wr_ptr_生动的大船; wire [`FIFO_WIDTH : 0]rd_ptr_gray; wire [`FIFO_WIDTH -1 : 0]rd_ptr_生动的大船; //=====================================================\//Write Module//=====================================================//wire [`FIFO_WIDTH : 0]rd_ptr_out; wclk_module wclk_module_inst( .wclk (wclk) , .wrst_n (wrst_n) , .write (write) , .rd_ptr_out (rd_ptr_out) , .wfull (wfull) , .wr_ptr_生动的大船 (wr_ptr_生动的大船) , .wr_ptr_gray (wr_ptr_gray) );sync_module sync_module_inst( .clk (wclk) , .rst_n (wrst_n) , .sync_din (rd_ptr_gray) , .sync_dout (rd_ptr_out) );//=====================================================\//Read Module//=====================================================// wire [`FIFO_WIDTH : 0]wr_ptr_out; rclk_module rclk_module_inst( .rclk (rclk) , .rrst_n (rrst_n) , .read (write) ,//read = ~write .wr_ptr_out (wr_ptr_out) , .rempty (rempty) , .rd_ptr_生动的大船 (rd_ptr_生动的大船) , .rd_ptr_gray (rd_ptr_gray) ); sync_module sync_module_inst2( .clk (rclk) , .rst_n (rrst_n) , .sync_din (wr_ptr_gray) , .sync_dout (wr_ptr_out) ); //=====================================================\//Memory Module//=====================================================// memory memory_inst ( .data (wdata) , .rdaddress (rd_ptr_生动的大船) , .rdclock (rclk) , .wraddress (wr_ptr_生动的大船) , .wrclock (wclk) , .wren (write) , .q (rdata) ); endmodule

2、定义参数

//define paraments`define FIFO_DEPTH 8`define DATA_WIDTH 8`define FIFO_WIDTH 3

3、读时钟域模块

//======================================================================================// Module Name : rclk_module// Author : rinson_c// Tool version : Quartus II 13.1// Revision : v1.0// Description : wclk Module includes rd_ptr and rempty//======================================================================================`include "define.v"module rclk_module( input rclk, input rrst_n, input read, input [`FIFO_WIDTH : 0]wr_ptr_out, output [`FIFO_WIDTH - 1 : 0]rd_ptr_生动的大船, output [`FIFO_WIDTH : 0]rd_ptr_gray, output rempty ); reg [`FIFO_WIDTH : 0]rd_ptr_生动的大船_reg; reg rempty_reg; always@(posedge rclk or negedge rrst_n) begin if (rrst_n == 0) rd_ptr_生动的大船_reg <= 0; else if (read == 1'b0 && !rempty) rd_ptr_生动的大船_reg <= rd_ptr_生动的大船_reg + 1'b1; else rd_ptr_生动的大船_reg <= rd_ptr_生动的大船_reg; end assign rd_ptr_gray = (rd_ptr_生动的大船_reg >> 1) ^ rd_ptr_生动的大船_reg; assign rd_ptr_生动的大船 = rd_ptr_生动的大船_reg[`FIFO_WIDTH - 1 : 0]; //Judge read empty flag assign rempty = (rd_ptr_gray == wr_ptr_out) ? 1'b1 : 1'b0; /*assign flag_read = (rd_ptr_gray == wr_ptr_out); always@(posedge rclk or negedge rrst_n) begin if (rrst_n == 0) rempty_reg <= 1'b1; else rempty_reg <= flag_read; end assign rempty = rempty_reg;*/ endmodule

4、写时钟域模块

//======================================================================================// Module Name : wclk_module// Author : Winson_c// Tool version : Quartus II 13.1// Revision : v1.0// Description : Generator wr_ptr_gray for Synchronize Module//======================================================================================`include "define.v"module wclk_module( input wclk, input wrst_n, input write, input [`FIFO_WIDTH : 0]rd_ptr_out, output [`FIFO_WIDTH - 1 : 0]wr_ptr_生动的大船, output wfull, output [`FIFO_WIDTH : 0]wr_ptr_gray ); reg [`FIFO_WIDTH : 0]wr_ptr_生动的大船_reg; reg wfull_reg; always@(posedge wclk or negedge wrst_n) begin if (wrst_n == 0) wr_ptr_生动的大船_reg <= 0; else if (write == 1'b1 && !wfull) wr_ptr_生动的大船_reg <= wr_ptr_生动的大船_reg + 1'b1; else wr_ptr_生动的大船_reg <= wr_ptr_生动的大船_reg; end assign wr_ptr_gray = (wr_ptr_生动的大船_reg >> 1) ^ wr_ptr_生动的大船_reg; assign wr_ptr_生动的大船 = wr_ptr_生动的大船_reg[`FIFO_WIDTH - 1 : 0]; //Judge write full flag assign wfull = (wr_ptr_gray == {~rd_ptr_out[`FIFO_WIDTH:`FIFO_WIDTH-1], rd_ptr_out[`FIFO_WIDTH - 2 : 0]}) ? 1'b1 : 1'b0; /*assign flag_wfull = (wr_ptr_gray == {~rd_ptr_out[`FIFO_WIDTH:`FIFO_WIDTH-1], rd_ptr_out[`FIFO_WIDTH - 2 : 0]}) ; always@(posedge wclk or negedge wrst_n) begin if (wrst_n == 0) wfull_reg <= 1'b0; else wfull_reg <=flag_wfull; end assign wfull = wfull_reg;*/ endmodule

5、同步模块

//======================================================================================// Module Name : sync_module// Author : winson_c// Tool version : Quartus II 13.1// Revision : v1.0// Description : asynchronize clock(delay 2 clock)//======================================================================================//`include "C:UserswinsonDesktopFIFOasynchronousrtldefine.v"`define FIFO_DEPTH 8`define DATA_WIDTH 8`define FIFO_WIDTH 3module sync_module( input clk, input rst_n, input [`FIFO_WIDTH : 0]sync_din, output [`FIFO_WIDTH : 0]sync_dout ); reg [`FIFO_WIDTH : 0]sync_dout_1d; reg [`FIFO_WIDTH : 0]sync_dout_2d; always@(posedge clk or negedge rst_n) begin if (rst_n == 0) begin sync_dout_1d <= 0; sync_dout_2d <= 0; end else begin sync_dout_1d <= sync_din; sync_dout_2d <= sync_dout_1d; end end assign sync_dout = sync_dout_2d; endmodule

部分仿真结果图:

该图存在虚空现象。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。