FIFO,First In First Out ,是一种先进先出的数据缓存器。

没有外部读写地址线,只能顺序写入数据,顺序的读出数据, 其数据地址由内部读写指针自动加1完成。

不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

FIFO一般用于不同时钟域之间的数据传输,根据工作的时钟域,分为同步FIFO和异步FIFO。

同步FIFO是指读时钟和写时钟为同一个时钟。在时钟沿来临时同时发生读写操作。

异步FIFO是指读写时钟不一致,读写时钟是互相独立的。

同步FIFO

  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2018/05/02 21:34:02
  7. // Design Name:
  8. // Module Name: FIFO_16bits_16
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description: synchronous fifo 16bits * 16
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. `define ADDR_WIDTH //ADDR WIDTH = 4,
  22. `define FIFO_DEPTH //FIFO DEPTH
  23. `define FIFO_WIDTH //FIFO WIDTH 16 BITS
  24.  
  25. module myFIFO(
  26. input wire clk,
  27. input wire rst_n,
  28. input wire wr_en,
  29. input wire rd_en, //wire write/read enable
  30. input wire [`FIFO_WIDTH:] buf_in, // data input to be pushed to buffer
  31. output reg [`FIFO_WIDTH:] buf_out, // port to output the data using pop.
  32. output wire buf_empty,
  33. output wire buf_full, // fifo buffer empty/full indication
  34. output reg [`ADDR_WIDTH:] fifo_cnt // number of data pushed in to buffer,16-> FULL;0-> EMPTY
  35. );
  36.  
  37. reg [`ADDR_WIDTH-:] rd_ptr,wr_ptr; //ADDR PTR .INDEX ,CYCLE 0->15->0->15
  38. reg [`FIFO_WIDTH:] buf_mem[:`FIFO_DEPTH-];
  39. reg rst_nr;
  40. //juge full/empty
  41. assign buf_empty = (fifo_cnt == )?:;
  42. assign buf_full = (fifo_cnt == `FIFO_DEPTH)?:;
  43. //Asynchronous reset,synch release
  44. // always @(posedge clk)begin
  45. // rst_nr <= rst_n;
  46. // end
  47. //FIFO_CNT
  48. always @(posedge clk or negedge rst_n)begin
  49. if(!rst_n)
  50. fifo_cnt <= ;
  51. else if((!buf_full&&wr_en)&&(!buf_empty&&rd_en)) //WRTITE & READ ,HOLD
  52. fifo_cnt <= fifo_cnt;
  53. else if(!buf_full && wr_en) //WRITE-> +1
  54. fifo_cnt <= fifo_cnt + ;
  55. else if(!buf_empty && rd_en) //READ -> -1
  56. fifo_cnt <= fifo_cnt-;
  57. else
  58. fifo_cnt <= fifo_cnt;
  59. end
  60. //READ
  61. always @(posedge clk or negedge rst_n) begin
  62. if(!rst_n)
  63. buf_out <= ;
  64. if(rd_en && !buf_empty)
  65. buf_out <= buf_mem[rd_ptr];
  66. end
  67. //WRITE
  68. always @(posedge clk) begin
  69. if(wr_en && !buf_full)
  70. buf_mem[wr_ptr] <= buf_in;
  71. end
  72. //wr_ptr & rd_ptr ,ADDR PTR
  73. always @(posedge clk or negedge rst_n) begin
  74. if(!rst_n) begin
  75. wr_ptr <= ;
  76. rd_ptr <= ;
  77. end
  78. else begin
  79. if(!buf_full && wr_en)
  80. wr_ptr <= wr_ptr + ;
  81. if(!buf_empty && rd_en)
  82. rd_ptr <= rd_ptr + ;
  83. end
  84. end
  85.  
  86. endmodule

testbench

  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2018/05/02 21:42:06
  7. // Design Name:
  8. // Module Name: tb
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. `define ADDR_WIDTH //ADDR WIDTH = 4,
  22. `define BUF_DEPTH //FIFO DEPTH
  23. `define FIFO_WIDTH //FIFO WIDTH 16 BITS
  24.  
  25. module tb;
  26. reg clk,rst_n;
  27. reg wr_en,rd_en;
  28. reg [:] buf_in; // data input to be pushed to buffer
  29. wire [:] buf_out; // port to output the data using pop.
  30. wire buf_empty,buf_full; // buffer empty and full indication
  31. wire [`ADDR_WIDTH-:] fifo_cnt; // number of data pushed in to buffer
  32.  
  33. myFIFO dut(
  34. .clk(clk),
  35. .rst_n(rst_n),
  36. .buf_in(buf_in),
  37. .buf_out(buf_out),
  38. .wr_en(wr_en),
  39. .rd_en(rd_en),
  40. .buf_empty(buf_empty),
  41. .buf_full(buf_full),
  42. .fifo_cnt(fifo_cnt)
  43. );
  44.  
  45. always # clk = ~clk;
  46.  
  47. reg [:] tempdata = ;
  48. initial begin
  49. clk = ;
  50. rst_n = ;
  51. wr_en = ;
  52. rd_en = ;
  53. buf_in = ;
  54. #;
  55. rst_n = ;
  56.  
  57. push();
  58. fork
  59. push();
  60. pop(tempdata);
  61. join //push and pop together
  62. push();
  63. push();
  64. push();
  65. push();
  66. push();
  67. push();
  68. push();
  69. push();
  70. push();
  71. push();
  72. push();
  73. push();
  74. push();
  75. push();
  76. push();
  77. push();
  78. push();
  79. push();
  80. push();
  81.  
  82. pop(tempdata);
  83. push(tempdata);
  84.  
  85. pop(tempdata);
  86. pop(tempdata);
  87. pop(tempdata);
  88. pop(tempdata);
  89. push();
  90. pop(tempdata);
  91. push(tempdata);
  92. pop(tempdata);
  93. pop(tempdata);
  94. pop(tempdata);
  95. pop(tempdata);
  96. pop(tempdata);
  97. pop(tempdata);
  98. pop(tempdata);
  99. pop(tempdata);
  100. pop(tempdata);
  101. pop(tempdata);
  102. pop(tempdata);
  103. push();
  104. pop(tempdata);
  105. pop(tempdata);
  106. pop(tempdata);
  107. pop(tempdata);
  108. pop(tempdata);
  109. pop(tempdata);
  110. pop(tempdata);
  111. pop(tempdata);
  112. pop(tempdata);
  113. pop(tempdata);
  114. pop(tempdata);
  115. pop(tempdata);
  116. pop(tempdata);
  117. pop(tempdata);
  118. pop(tempdata);
  119.  
  120. #;
  121. rst_n = ;
  122. #;
  123. rst_n = ;
  124. push();
  125. fork
  126. push();
  127. pop(tempdata);
  128. join //push and pop together
  129. push();
  130. push();
  131. push();
  132. pop(tempdata);
  133. pop(tempdata);
  134. pop(tempdata);
  135. end
  136.  
  137. task push (input [:] data);
  138. if(buf_full)
  139. $display("---Cannot push %d: Buffer Full---",data);
  140. else begin
  141. $display("Push:%d",data);
  142. buf_in = data;
  143. wr_en = ;
  144. @(posedge clk);
  145. # wr_en = ;
  146. end
  147. endtask
  148.  
  149. task pop(output[:] data);
  150. if(buf_empty)
  151. $display("---Cannot Pop: Buffer Empty---");
  152. else begin
  153. rd_en = ;
  154. @(posedge clk);
  155. # rd_en = ;
  156. data = buf_out;
  157. $display("------Poped:%d",data);
  158. end
  159. endtask
  160.  
  161. endmodule

在综合是出现错误

[Synth 8-91] ambiguous clock in event control [:61]

是因为该段没有else语句,于是将该段改为

  1. //READ
  2. always @(posedge clk or negedge rst_n) begin
  3. if(!rst_n)
  4. buf_out <= ;
  5. else begin
  6. if(rd_en && !buf_empty)
  7. buf_out <= buf_mem[rd_ptr];
  8. end
  9. end

通过。

//********************************************************************************

异步FIFO

参考了很多文章。

直接上代码

  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2018/05/03 13:56:26
  7. // Design Name:
  8. // Module Name: AsyncFIFO
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description: asynchronous fifo
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21.  
  22. module AsyncFIFO
  23. #(
  24. parameter fifo_width = ,
  25. parameter fifo_depth = , // = ((1<<addr_width) -1)
  26. parameter addr_width =
  27. )
  28. (
  29. input wire wclk,
  30. input wire rclk,
  31. input wire wrst_n,
  32. input wire rrst_n,
  33. input wire winc,
  34. input wire rinc,
  35. input wire [fifo_width-:] wdata,
  36. output wire [fifo_width-:] rdata,
  37. output reg wfull,
  38. output reg rempty
  39. //output reg [addr_width:0] fifo_cnt
  40. );
  41.  
  42. reg [addr_width:] wptr,rptr;
  43. reg [addr_width:] rbin,wbin;
  44. reg [addr_width:] wq1_rptr,rq1_wptr,wq2_rptr,rq2_wptr;
  45. reg [fifo_width-:] fifo_mem [:fifo_depth-];
  46. wire [addr_width-:] waddr,raddr;
  47. wire [addr_width:] rgraynext,rbinnext,wgraynext,wbinnext;
  48. wire rempty_val,wfull_val;
  49. //snyc wptr
  50. always @(posedge wclk or negedge wrst_n)
  51. if(!wrst_n) begin
  52. {wq2_rptr,wq1_rptr} <= ;
  53. end
  54. else begin
  55. {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};
  56. end
  57. //snyc rptr
  58. always @(posedge wclk or negedge wrst_n)
  59. if (!wrst_n) begin
  60. {rq2_wptr,rq1_wptr} <= ;
  61. end
  62. else begin
  63. {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};
  64. end
  65. //dualRAM
  66. assign rdata = fifo_mem[raddr];
  67. always@(posedge wclk)
  68. if (winc && !wfull) fifo_mem[waddr] <= wdata;
  69. //------------------------rempty & raddr----------------------------
  70. always @(posedge rclk or negedge rrst_n) // GRAYSTYLE-2 pointer
  71. if (!rrst_n) {rbin, rptr} <= ;
  72. else {rbin, rptr} <= {rbinnext, rgraynext};
  73. // Memory read-address pointer (okay to use binary to address memory)
  74. assign raddr = rbin[addr_width-:];
  75. assign rbinnext = rbin + (rinc & ~rempty);
  76. assign rgraynext = (rbinnext>>) ^ rbinnext;//binary to gray
  77. // FIFO empty when the next rptr == synchronized wptr or on reset
  78. assign rempty_val = (rgraynext == rq2_wptr)?:;
  79. always @(posedge rclk or negedge rrst_n)
  80. if (!rrst_n) rempty <= 'b1;
  81. else rempty <= rempty_val;
  82. //-----------------------wfull & waddr------------------------------
  83. always @(posedge wclk or negedge wrst_n) // GRAYSTYLE2 pointer
  84. if (!wrst_n) {wbin, wptr} <= ;
  85. else {wbin, wptr} <= {wbinnext, wgraynext};
  86. // Memory write-address pointer (okay to use binary to address memory)
  87. assign waddr = wbin[addr_width-:];
  88. assign wbinnext = wbin + (winc & ~wfull);
  89. assign wgraynext = (wbinnext>>) ^ wbinnext;
  90. //------------------------------------------------------------------
  91. // Simplified version of the three necessary full-tests:
  92. // assign wfull_val=((wgnext[ADDRSIZE] !=wq2_rptr[ADDRSIZE] ) &&
  93. // (wgnext[ADDRSIZE-1] !=wq2_rptr[ADDRSIZE-1]) &&
  94. // (wgnext[ADDRSIZE-2:0]==wq2_rptr[ADDRSIZE-2:0]));
  95. //------------------------------------------------------------------
  96. assign wfull_val = (wgraynext=={~wq2_rptr[addr_width:addr_width-], wq2_rptr[addr_width-:]});
  97. always @(posedge wclk or negedge wrst_n)
  98. if (!wrst_n) wfull <= 'b0;
  99. else wfull <= wfull_val;
  100.  
  101. endmodule

测试程序

  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2018/05/03 16:53:39
  7. // Design Name:
  8. // Module Name: tb
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21.  
  22. module tb;
  23. // parameter fifo_width = 16;
  24. // parameter fifo_depth = 16;
  25. // parameter addr_width = 4;
  26.  
  27. reg wclk,rclk,wrst_n,rrst_n;
  28. reg winc,rinc;
  29. reg [:] wdata;
  30. wire [:] rdata;
  31. wire rempty,wfull;
  32.  
  33. AsyncFIFO i1(
  34. .wclk(wclk),
  35. .rclk(rclk),
  36. .wrst_n(wrst_n),
  37. .rrst_n(rrst_n),
  38. .winc(winc),
  39. .rinc(rinc),
  40. .wdata(wdata),
  41. .rdata(rdata),
  42. .wfull(wfull),
  43. .rempty(rempty)
  44. );
  45. always # wclk = ~wclk;
  46. always # rclk = ~rclk;
  47.  
  48. reg [:] tempdata;
  49. reg [:] data1;
  50. reg [:] data2;
  51. initial begin
  52. wclk = ;
  53. rclk = ;
  54. wrst_n = ;
  55. rrst_n = ;
  56. winc = ;
  57. rinc = ;
  58. wdata = ;
  59. data1 = ;
  60.  
  61. #
  62. fork
  63. wrst_n = ;
  64. rrst_n = ;
  65. join
  66. #
  67. push();
  68. push();
  69. push();
  70. push();
  71. #
  72. //pop(tempdata);
  73. //push and pop together
  74. while()begin
  75. fork
  76. wr;
  77. rd;
  78. join
  79. end
  80. push();
  81. push();
  82. push();
  83. push();
  84. push();
  85.  
  86. end
  87.  
  88. task wr;begin
  89. while(!wfull)begin
  90. push(data1);
  91. data1 =data1+;
  92. end
  93. end
  94. endtask
  95.  
  96. task rd;begin
  97. while(!rempty)
  98. # pop(tempdata);
  99.  
  100. end
  101. endtask
  102.  
  103. task push (input [:] data);
  104. if(wfull)
  105. $display("---Cannot push %d: Buffer Full---",data);
  106. else begin
  107. $display("Push:%d",data);
  108. wdata = data;
  109. winc = ;
  110. @(posedge wclk);
  111. # winc = ;
  112. end
  113. endtask
  114.  
  115. task pop(output[:] data);
  116. if(rempty)
  117. $display("---Cannot Pop: Buffer Empty---");
  118. else begin
  119. rinc = ;
  120. @(posedge rclk);
  121. # rinc = ;
  122. data = rdata;
  123. $display("------Poped:%d",data);
  124. end
  125. endtask
  126.  
  127. endmodule

测试算是通过,但还是有点问题。相同再弄了。

Verilog笔记.6.FIFO的更多相关文章

  1. Verilog笔记——Verilog数字系统设计(第二版)夏宇闻

    本片记录Verilog学习笔记,主要是和以往用的C语言的不同之处,以例子.代码的形式记录.学习以<Verilog数字系统设计>(第二版)为参考资料,援助作者夏宇闻. 1. C语言和Veri ...

  2. 基于Verilog的带FIFO写入缓冲的串口发送接口封装

    一.模块框图及基本思路 tx_module:串口发送的核心模块,详细介绍请参照前面的“基于Verilog的串口发送实验” fifo2tx_module:当fifo不为空时,读取fifo中的数据并使能发 ...

  3. 基于Verilog的带FIFO输出缓冲的串口接收接口封装

    一.模块框图及基本思路 rx_module:串口接收的核心模块,详细介绍请见“基于Verilog的串口接收实验” rx2fifo_module:rx_module与rx_fifo之间的控制模块,其功能 ...

  4. 基于Verilog的简单FIFO读写实验

    一.模块框图及基本思路 fifo_ip:ISE生成的IP fifo_control:在fifo未满情况下不断写入递增的四位数,每隔1s读出一个数据驱动Led显示 fifo_top:前两个模块的组合 二 ...

  5. Verilog设计异步FIFO

    转自http://ninghechuan.com 异步FIFO有两个异步时钟,一个端口写入数据,一个端口读出数据.通常被用于数据的跨时钟域的传输. 同步FIFO的设计.一个时钟控制一个计数器,计数器增 ...

  6. Verilog笔记.三段式状态机

    之前都是用的一段式状态机,逻辑与输出混在一起,复杂点的就比较吃力了. 所以就开始着手三段式状态机. 组合逻辑与时序逻辑分开,这样就能简单许多了. 但是两者在思考方式上也有着很大的区别. 三段式,分作: ...

  7. Verilog笔记.1.基本语法

    0.前 抽象模型分级: • 系统级(system):用高级语言结构实现设计模块的外部性能的模型.• 算法级(algorithm):用高级语言结构实现设计算法的模型.• RTL级(Register Tr ...

  8. Verilog笔记——YUV2RGB的模块测试

    1 YUV2RGB的模块如下: module yuv2rgb( clk, //时钟输入 rstn, //复位输入,低电平复位 y_in, //变换前Y分量输出 cb_in, //变换前Cb分量输出 c ...

  9. Verilog笔记.5.同步、异步

    在数字电路中经常有同步synchronism.异步asynchronism的概念.异步指输入信号和时钟无关:同步指输入信号和时钟信号有关,实际上就是输入信号和时钟信号进行了与运算或者与非运算.实际开发 ...

随机推荐

  1. vue-cli配置axios,并基于axios进行后台请求函数封装

    文章https://www.cnblogs.com/XHappyness/p/7677153.html已经对axios配置进行了说明,后台请求时可直接this.$axios直接进行.这里的缺点是后端请 ...

  2. PHP面向对象之接口

    接口(interface)技术 什么是接口? 先看抽象类: abstract  class  类名  { 属性1: 属性2: ..... 非抽象方法1: 非抽象方法2: ...... 抽象方法1: 抽 ...

  3. HDU4497——GCD and LCM

    这个题目挺不错的,看到是通化邀请赛的题目,是一个很综合的数论题目. 是这样的,给你三个数的GCD和LCM,现在要你求出这三个数有多少种可能的情况. 对于是否存在这个问题,直接看 LCM%GCD是否为0 ...

  4. Django 2.0 学习(14):Django ORM 数据库操作(上)

    Django ORM 数据库操作(上) ORM介绍 映射关系: 数据库表名 ---------->类名:数据库字段 ---------->类属性:数据库表一行数据 ----------&g ...

  5. 【JavaScript&jQuery】$.ajax()

    $(function(){ $('#send').click(function(){ $.ajax({ type: "GET", url: "test.json" ...

  6. hbase 基本的JavaApi 数据操作及数据过滤(filter)

    本文主要是hbase的表操作.数据操作.数据查询过滤等,如果对JDBC或ADO有了解,容易理解HBASE API. hbase版本是2.0. 1.为了方便先贴helper的部分代码(文末git上有完整 ...

  7. 【BZOJ4311】向量(线段树分治,斜率优化)

    [BZOJ4311]向量(线段树分治,斜率优化) 题面 BZOJ 题解 先考虑对于给定的向量集,如何求解和当前向量的最大内积. 设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2 ...

  8. 【BZOJ3052】【UOJ#58】【WC2013】糖果公园(树上莫队)

    [BZOJ3052][UOJ#58][WC2013]糖果公园(树上莫队) 题面 UOJ 洛谷 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引 ...

  9. Unity3D动态加载外部MovieTexture视频

    网上大家也写了很多Unity3D中播放视频的教程,关于播放外部视频的还是比较少,所以写这篇文章,不足之处,还望读者指正. 在Unity3D中,我们一般使用播放视频的方法:将*.mov,*.mp4等格式 ...

  10. tyvj1305 最大子序和 【单调队列优化dp】

    描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7 当m=2或m=3时,S=5+1=6 输 ...