You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

generic_fifo.v 6.5 KiB

3 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company: BITSILICA PVT LTD
  4. // Design Name:
  5. // Module Name: FIFO
  6. // Project Name:
  7. //////////////////////////////////////////////////////////////////////////////////
  8. /*
  9. Description
  10. ===========
  11. I/Os
  12. ----
  13. rst low active, either sync. or async. master reset (see below how to select)
  14. clr synchronous clear (just like reset but always synchronous), high active
  15. re read enable, synchronous, high active
  16. we read enable, synchronous, high active
  17. din Data Input
  18. dout Data Output
  19. full Indicates the FIFO is full (combinatorial output)
  20. full_r same as above, but registered output (see note below)
  21. empty Indicates the FIFO is empty
  22. empty_r same as above, but registered output (see note below)
  23. full_n Indicates if the FIFO has space for N entries (combinatorial output)
  24. full_n_r same as above, but registered output (see note below)
  25. empty_n Indicates the FIFO has at least N entries (combinatorial output)
  26. empty_n_r same as above, but registered output (see note below)
  27. level indicates the FIFO level:
  28. 2'b00 0-25% full
  29. 2'b01 25-50% full
  30. 2'b10 50-75% full
  31. 2'b11 %75-100% full
  32. combinatorial vs. registered status outputs
  33. -------------------------------------------
  34. Both the combinatorial and registered status outputs have exactly the same
  35. synchronous timing. Meaning they are being asserted immediately at the clock
  36. edge after the last read or write. The combinatorial outputs however, pass
  37. through several levels of logic before they are output. The registered status
  38. outputs are direct outputs of a flip-flop. The reason both are provided, is
  39. that the registered outputs require quite a bit of additional logic inside
  40. the FIFO. If you can meet timing of your device with the combinatorial
  41. outputs, use them ! The FIFO will be smaller. If the status signals are
  42. in the critical pass, use the registered outputs, they have a much smaller
  43. output delay (actually only Tcq).
  44. Parameters
  45. ----------
  46. The FIFO takes 3 parameters:
  47. dw Data bus width
  48. aw Address bus width (Determines the FIFO size by evaluating 2^aw)
  49. n N is a second status threshold constant for full_n and empty_n
  50. */
  51. // Selecting Sync. or Async Reset
  52. // ------------------------------
  53. // Uncomment one of the two lines below. The first line for
  54. // synchronous reset, the second for asynchronous reset
  55. `define SC_FIFO_ASYNC_RESET //Uncomment for Syncr. reset
  56. //`define SC_FIFO_ASYNC_RESET or negedge rst // Uncomment for Async. reset
  57. module fifo#(parameter dw=32,aw=5,n=32)(clk, rst, din, we, dout, re,
  58. full, empty, full_r, empty_r,
  59. full_n, empty_n, full_n_r, empty_n_r,
  60. level,count);
  61. parameter max_size = 1<<aw;
  62. input clk, rst;
  63. input [dw-1:0] din;
  64. input we;
  65. output [dw-1:0] dout;
  66. input re;
  67. output full, full_r;
  68. output empty, empty_r;
  69. output full_n, full_n_r;
  70. output empty_n, empty_n_r;
  71. output [1:0] level;
  72. output [aw:0] count;
  73. ////////////////////////////////////////////////////////////////////
  74. //
  75. // Local Wires
  76. //
  77. wire wen; // Write Enable
  78. wire ren; // Read Enable
  79. reg [aw-1:0] wp;
  80. wire [aw-1:0] wp_pl1;
  81. wire [aw-1:0] wp_pl2;
  82. reg [aw-1:0] rp;
  83. wire [aw-1:0] rp_pl1;
  84. reg full_r;
  85. reg empty_r;
  86. reg gb;
  87. reg gb2;
  88. reg [aw:0] cnt;
  89. wire full_n, empty_n;
  90. reg full_n_r, empty_n_r;
  91. // Write Only when FIFO isn't full & write enable is there
  92. assign wen = (!full && we) ? 1'b1 : 1'b0;
  93. assign ren = (!empty && re) ? 1'b1 : 1'b0;
  94. assign count = cnt;
  95. ////////////////////////////////////////////////////////////////////
  96. // Memory Block
  97. ////////////////////////////////////////////////////////////////////
  98. simple_dual_port_ram #(.WIDTH(dw),.DEPTH(n),.AW(aw))u0(.clk(clk),.wea(wen),.enb(ren),.addra(wp),.addrb(rp),.dia(din),.dob(dout));
  99. ////////////////////////////////////////////////////////////////////
  100. // Misc Logic
  101. always @(posedge clk `SC_FIFO_ASYNC_RESET)
  102. if(!rst) wp <= #1 {aw{1'b0}};
  103. else
  104. if(we) wp <= #1 wp_pl1;
  105. assign wp_pl1 = wp + { {aw-1{1'b0}}, 1'b1};
  106. assign wp_pl2 = wp + { {aw-2{1'b0}}, 2'b10};
  107. always @(posedge clk `SC_FIFO_ASYNC_RESET)
  108. if(!rst) rp <= #1 {aw{1'b0}};
  109. else
  110. if(re) rp <= #1 rp_pl1;
  111. assign rp_pl1 = rp + { {aw-1{1'b0}}, 1'b1};
  112. ////////////////////////////////////////////////////////////////////
  113. // Combinatorial Full & Empty Flags
  114. //
  115. assign empty = ((wp == rp) & !gb);
  116. assign full = ((wp == rp) & gb);
  117. // Guard Bit ...
  118. always @(posedge clk `SC_FIFO_ASYNC_RESET)
  119. if(!rst) gb <= #1 1'b0;
  120. else
  121. if((wp_pl1 == rp) & we) gb <= #1 1'b1;
  122. else
  123. if(re) gb <= #1 1'b0;
  124. ////////////////////////////////////////////////////////////////////
  125. // Registered Full & Empty Flags
  126. //
  127. // Guard Bit ...
  128. always @(posedge clk `SC_FIFO_ASYNC_RESET)
  129. if(!rst) gb2 <= #1 1'b0;
  130. else
  131. if((wp_pl2 == rp) & we) gb2 <= #1 1'b1;
  132. else
  133. if((wp != rp) & re) gb2 <= #1 1'b0;
  134. always @(posedge clk `SC_FIFO_ASYNC_RESET)
  135. if(!rst) full_r <= #1 1'b0;
  136. else
  137. if(we & ((wp_pl1 == rp) & gb2) & !re) full_r <= #1 1'b1;
  138. else
  139. if(re & ((wp_pl1 != rp) | !gb2) & !we) full_r <= #1 1'b0;
  140. always @(posedge clk `SC_FIFO_ASYNC_RESET)
  141. if(!rst) empty_r <= #1 1'b1;
  142. else
  143. if(we & ((wp != rp_pl1) | gb2) & !re) empty_r <= #1 1'b0;
  144. else
  145. if(re & ((wp == rp_pl1) & !gb2) & !we) empty_r <= #1 1'b1;
  146. ////////////////////////////////////////////////////////////////////
  147. // Combinatorial Full_n & Empty_n Flags
  148. assign empty_n = cnt < n;
  149. assign full_n = !(cnt < (max_size-n+1));
  150. assign level = {2{cnt[aw]}} | cnt[aw-1:aw-2];
  151. // N entries status
  152. always @(posedge clk `SC_FIFO_ASYNC_RESET)
  153. if(!rst) cnt <= #1 {aw+1{1'b0}};
  154. else
  155. if( re & !we) cnt <= #1 cnt + { {aw{1'b1}}, 1'b1};
  156. else
  157. if(!re & we) cnt <= #1 cnt + { {aw{1'b0}}, 1'b1};
  158. ////////////////////////////////////////////////////////////////////
  159. // Registered Full_n & Empty_n Flags
  160. always @(posedge clk `SC_FIFO_ASYNC_RESET)
  161. if(!rst) empty_n_r <= #1 1'b1;
  162. else
  163. if(we & (cnt >= (n-1) ) & !re) empty_n_r <= #1 1'b0;
  164. else
  165. if(re & (cnt <= n ) & !we) empty_n_r <= #1 1'b1;
  166. always @(posedge clk `SC_FIFO_ASYNC_RESET)
  167. if(!rst) full_n_r <= #1 1'b0;
  168. else
  169. if(we & (cnt >= (max_size-n) ) & !re) full_n_r <= #1 1'b1;
  170. else
  171. if(re & (cnt <= (max_size-n+1)) & !we) full_n_r <= #1 1'b0;
  172. ////////////////////////////////////////////////////////////////////
  173. // Sanity Check
  174. always @(posedge clk)
  175. if(we & full)
  176. $display("%m WARNING: Writing while fifo is FULL (%t)",$time);
  177. always @(posedge clk)
  178. if(re & empty)
  179. $display("%m WARNING: Reading while fifo is EMPTY (%t)",$time);
  180. endmodule