FIFO

  1. 同步,异步
  2. 读/写指针,空/满检测(标志位),计数
  3. 如何判断FIFO的空/满状态?
    方法一:采用格雷码进行空满条件判断(异步FIFO)
    格雷码判空,直接判断读写地址是否相同即可;
    格雷码判满,需要满足条件:最高位不同,次高位也不同,其余位必须相同;所以,需要将信号最高2位翻转,其余不变;
    原因:格雷码相邻的数据只变化一位,可以减少相邻物理信号线同时变化的情况,减少电路串扰的可能,减少电路中的噪声。
  4. 深度(如何确定深度?),宽度(32-bit)
  5. 异步FIFO的设计目的:多时钟系统中解决不同时钟域数据传输的问题。
  6. 一个异步FIFO的例程

module fifo1(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; //write full
output rempty; //read empty
input [DSIZE-1:0] wdata;
input winc, wclk, wrst_n; //write_increase?,write_clk,write_rst_negetive
input rinc, rclk, rrst_n; //read_increase,read_clk,read_rst_negetive

reg wfull,rempty;
reg [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr, wq1_rptr,rq1_wptr;
reg [ASIZE:0] rbin, wbin;
reg [DSIZE-1:0] mem[0:(1<<ASIZE)-1];
wire [ASIZE-1:0] waddr, raddr;
wire [ASIZE:0] rgraynext, rbinnext,wgraynext,wbinnext;
wire rempty_val,wfull_val;

>//-----------------双口RAM存储器--------------------
assign rdata=mem[raddr];
always@(posedge wclk)
if (winc && !wfull) mem[waddr] <= wdata;

>//-------------同步rptr 指针-------------------------
always @(posedge wclk or negedge wrst_n)
if (!wrst_n) {wq2_rptr,wq1_rptr} <= 0;
else {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};

>//-------------同步wptr指针---------------------------
always @(posedge rclk or negedge rrst_n)
if (!rrst_n) {rq2_wptr,rq1_wptr} <= 0;
else {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};

>//-------------rempty产生与raddr产生-------------------
always @(posedge rclk or negedge rrst_n) // GRAYSTYLE2 pointer
begin
if (!rrst_n) {rbin, rptr} <= 0;
else {rbin, rptr} <= {rbinnext, rgraynext};
end

>// Memory read-address pointer (okay to use binary to address memory)
assign raddr = rbin[ASIZE-1:0];
assign rbinnext = rbin + (rinc & ~rempty);
assign rgraynext = (rbinnext>>1) ^ rbinnext;

>// FIFO empty when the next rptr == synchronized wptr or on reset
assign rempty_val = (rgraynext == rq2_wptr);
always @(posedge rclk or negedge rrst_n)
begin
if (!rrst_n) rempty <= 1'b1;
else rempty <= rempty_val;
end

>//---------------wfull产生与waddr产生------------------------------
always @(posedge wclk or negedge wrst_n) // GRAYSTYLE2 pointer
if (!wrst_n) {wbin, wptr} <= 0;
else {wbin, wptr} <= {wbinnext, wgraynext};

>// Memory write-address pointer (okay to use binary to address memory)
assign waddr = wbin[ASIZE-1:0];
assign wbinnext = wbin + (winc & ~wfull);
assign wgraynext = (wbinnext>>1) ^ wbinnext;
assign wfull_val = (wgraynext=={~wq2_rptr[ASIZE:ASIZE-1], wq2_rptr[ASIZE-2:0]}); //:ASIZE-1]
always @(posedge wclk or negedge wrst_n)
if (!wrst_n) wfull <= 1'b0;
else wfull <= wfull_val;

endmodule

参考:
[1] 异步FIFO:https://www.cnblogs.com/SYoong/p/6110328.html
[2] 同步FIFO实现方法:https://blog.csdn.net/limanjihe/article/details/49910557
[3] 同步FIFO和异步FIFO的Verilog实现: https://blog.csdn.net/liang0000zai/article/details/25830123
[4] 异步FIFO Verilog代码注释分析: https://blog.csdn.net/evolone/article/details/48106143
[5] 同步FIFO结构与实现:https://blog.csdn.net/Hision_fpgaer/article/details/51155980
[6] 异步FIFO设计:https://blog.csdn.net/wyj_2016/article/details/78469272
[7] 异步fifo的设计(FPGA): https://www.cnblogs.com/aslmer/p/6114216.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值