微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 硬件工程师文库 > FIFO 同步、异步以及Verilog代码实现

FIFO 同步、异步以及Verilog代码实现

时间:02-11 来源:网络整理 点击:

了4部分,每部分分别用高两位的MSB 00 、01、 11、 10决定FIFO是否为going full 或going empty (即将满或空)。如果写指针的高两位MSB小于读指针的高两位MSB则FIFO为"几乎满",若写指针的高两位MSB大于读指针的高两位MSB则FIFO 为"几乎空"。
它是利用将地址空间分成4个象限(也就是四个等大小的区域),然后观察两个指针的相对位置,如果写指针落后读指针一个象限(25%的距离,呵呵), 则证明很可能要写满,反之则很可能要读空,这个时候分别设置两个标志位dirset和dirrst,然后在地址完全相等的情况下,如果dirset有效就 是写满,如果dirrst有效就是读空。
这种方法对深度为2^N字节的FIFO只需N位的指针即可,处理的速度也较第一种方法快。  
这段是说明的原话,算法一,还好理解。算法二,似乎没有说清楚,不太明白。有兴趣的可以查查论文,详细研究下。
总之,第二种写法是推荐的写法。因为异步的多时钟设计应按以下几个原则进行设计:1,尽可能的将多时钟的逻辑电路(非同步器)分割为多个单时钟的模块,这样有利于静态时序分析工具来进行时序验证。2,同步器的实现应使得所有输入来自同一个时钟域,而使用另一个时钟域的异步时钟信号采样数据。3,面向时钟信号的命名方式可以帮助我们确定那些在不同异步时钟域间需要处理的信号。4,当存在多个跨时钟域的控制信号时,我们必须特别注意这些信号,保证这些控制信号到达新的时钟域仍然能够保持正确的顺序。
module fifo2 (rdata, wfull, rempty, wdata,winc, wclk, wrst_n, rinc, rclk, rrst_n);parameter DSIZE = 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] wptr, rptr;wire [ASIZE-1:0] waddr, raddr;async_cmp #(ASIZE) async_cmp(.aempty_n(aempty_n),.afull_n(afull_n),.wptr(wptr), .rptr(rptr),.wrst_n(wrst_n));fifomem2 #(DSIZE, ASIZE) fifomem2(.rdata(rdata),.wdata(wdata),.waddr(wptr),.raddr(rptr),.wclken(winc),.wclk(wclk));rptr_empty2 #(ASIZE) rptr_empty2(.rempty(rempty),.rptr(rptr),.aempty_n(aempty_n),.rinc(rinc),.rclk(rclk),.rrst_n(rrst_n));wptr_full2 #(ASIZE) wptr_full2(.wfull(wfull),.wptr(wptr),.afull_n(afull_n),.winc(winc),.wclk(wclk),.wrst_n(wrst_n));endmodulemodule fifomem2 (rdata, wdata, waddr, raddr, wclken, wclk);parameter DATASIZE = 8; // Memory data word widthparameter ADDRSIZE = 4; // Number of memory address bitsparameter DEPTH = 1<<ADDRSIZE; // DEPTH = 2**ADDRSIZEoutput [DATASIZE-1:0] rdata;input [DATASIZE-1:0] wdata;input [ADDRSIZE-1:0] waddr, raddr;input wclken, wclk;`ifdef VENDORRAM// instanTIaTIon of a vendor's dual-port RAMVENDOR_RAM MEM (.dout(rdata), .din(wdata),.waddr(waddr), .raddr(raddr),.wclken(wclken), .clk(wclk));`elsereg [DATASIZE-1:0] MEM [0:DEPTH-1];assign rdata = MEM[raddr];always @(posedge wclk)if (wclken) MEM[waddr] <= wdata;`endifendmodulemodule async_cmp (aempty_n, afull_n, wptr, rptr, wrst_n);parameter ADDRSIZE = 4;parameter N = ADDRSIZE-1;output aempty_n, afull_n;input [N:0] wptr, rptr;input wrst_n;reg direction;wire high = 1'b1;wire dirset_n = ~( (wptr[N]^rptr[N-1]) & ~(wptr[N-1]^rptr[N]));wire dirclr_n = ~((~(wptr[N]^rptr[N-1]) & (wptr[N-1]^rptr[N])) |~wrst_n);always @(posedge high or negedge dirset_n or negedge dirclr_n)if (!dirclr_n) direction <= 1'b0;else if (!dirset_n) direction <= 1'b1;else direction <= high;//always @(negedge dirset_n or negedge dirclr_n)//if (!dirclr_n) direction <= 1'b0;//else direction <= 1'b1;assign aempty_n = ~((wptr == rptr) && !direction);assign afull_n = ~((wptr == rptr) && direction);endmodulemodule rptr_empty2 (rempty, rptr, aempty_n, rinc, rclk, rrst_n);parameter ADDRSIZE = 4;output rempty;output [ADDRSIZE-1:0] rptr;input aempty_n;input rinc, rclk, rrst_n;reg [ADDRSIZE-1:0] rptr, rbin;reg rempty, rempty2;wire [ADDRSIZE-1:0] rgnext, rbnext;//---------------------------------------------------------------// GRAYSTYLE2 pointer//---------------------------------------------------------------always @(posedge rclk or negedge rrst_n)if (!rrst_n) beginrbin <= 0;rptr <= 0;endelse beginrbin <= rbnext;rptr <= rgnext;end//---------------------------------------------------------------// increment the binary count if not empty//---------------------------------------------------------------assign rbnext = !rempty ? rbin + rinc : rbin;assign rgnext = (rbnext>>1) ^ rbnext; // binary-to-gray conversionalways @(posedge rclk or negedge aempty_n)if (!aempty_n) {rempty,rempty2} <= 2'b11;else {rempty,rempty2} <= {rempty2,~aempty_n};endmodulemodule wptr_full2 (wfull, wptr, afull_n, winc, wclk, wrst_n);parameter ADDRSIZE = 4;output wfull;output [ADDRSIZE-1:0] wptr;input afull_n;input winc, wclk, wrst_n;reg [ADDRSIZE-1:0] wptr, wbin;reg wfull, wfull2;wire [ADDRSIZE-1:0] wgnext, wbnext;//---------------------------------------------------------------// GRAYSTYLE2 pointer//---------------------------------------------------------------always @(posedge wclk or negedge wrst_n)if (!wrst_n) beginwbin <= 0;wptr <= 0;endelse beginwbin <= wbnext;wptr <= wgnext;end//---------------------------------------------------------------// increment the binary count if not full//---------------------------------------------------------------assign wbnext = !wfull ? wbin + winc : wbin;assign wgnext = (wbnext>>1) ^ wbnext; // binary-to-gray conversionalways @(posedge wclk or negedge wrst_n or negedge afull_n)if (!wrst_n ) {wfull,wfull2} <= 2'b00;else if (!afull_n) {wfull,wfull2} <= 2'b11;else {wfull,wfull2} <= {wfull2,~afull_n};endmodule
.............................................................

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top