fifo.v
上传用户:jin985143
上传日期:2020-09-30
资源大小:278k
文件大小:4k
源码类别:

Modem编程

开发平台:

VHDL

  1. /* *****************************************************************
  2.  *
  3.  *  This file is part of the
  4.  *
  5.  *   Tone Order and Constellation Encoder Core.
  6.  *  
  7.  *
  8.  * Description:
  9.  *
  10.  *  fifo is a synchronouys FIFO without write through. The read
  11.  *  and write operation happens with the positive edge of the clk
  12.  *  signal. If the FIFO is empty and performing a read/write operation
  13.  *  with at the same clock cycle only the write operation will succeed.
  14.  *  The read operation will not return a valid value.
  15.  *
  16.  *  
  17.  ********************************************************************* 
  18.  *  Copyright (C) 2007 Guenter Dannoritzer
  19.  *
  20.  *   This source is free software; you can redistribute it
  21.  *   and/or modify it under the terms of the 
  22.  *             GNU General Public License
  23.  *   as published by the Free Software Foundation; 
  24.  *   either version 3 of the License,
  25.  *   or (at your option) any later version.
  26.  *
  27.  *   This source is distributed in the hope 
  28.  *   that it will be useful, but WITHOUT ANY WARRANTY;
  29.  *   without even the implied warranty of MERCHANTABILITY
  30.  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the
  31.  *   GNU General Public License for more details.
  32.  *
  33.  *   You should have received a copy of the
  34.  *   GNU General Public License along with this source.
  35.  *   If not, see <http://www.gnu.org/licenses/>.
  36.  *
  37.  * *****************************************************************/
  38. module fifo(
  39.           clk,
  40.           reset,
  41.           empty_o,
  42.           full_o,
  43.           one_available_o,
  44.           two_available_o,
  45.           we_i,
  46.           data_i,
  47.           re_i,
  48.           data_o);
  49. parameter DWIDTH = 8;
  50. parameter AWIDTH = 4;
  51.         
  52. input                 clk;
  53. input                 reset;
  54. output                empty_o;
  55. output                full_o;
  56. output                one_available_o;
  57. output                two_available_o;
  58. input                 we_i;
  59. input   [DWIDTH-1:0]  data_i;
  60. input                 re_i;
  61. output  [DWIDTH-1:0]  data_o;
  62. //
  63. // local reg/wires
  64. // 
  65. reg [AWIDTH-1:0]  read_ptr;
  66. reg [AWIDTH-1:0]  write_ptr;
  67. reg [AWIDTH:0]    fill_ctr;
  68. wire              dp_we_i;
  69. wire              dp_re_i;
  70. //
  71. // instantiate the dual port ram
  72. //
  73. generic_dpram #(.aw(AWIDTH),
  74.                 .dw(DWIDTH)
  75.                )
  76.               dpram ( .rclk(clk),
  77.                       .rrst(reset),
  78.                       .rce(ce),
  79.                       .oe(dp_re_i),
  80.                       .raddr(read_ptr),
  81.                       .do(data_o),
  82.                     
  83.                       .wclk(clk),
  84.                       .wrst(reset),
  85.                       .wce(ce),
  86.                       .we(dp_we_i),
  87.                       .waddr(write_ptr),
  88.                       .di(data_i));
  89. //
  90. // control logic
  91. // 
  92. assign ce = 1'b1;
  93. assign one_available_o = (fill_ctr > 1'b0) ? 1'b1 : 1'b0;
  94. assign two_available_o = (fill_ctr > 1'b1) ? 1'b1 : 1'b0;
  95. assign empty_o = |fill_ctr ? 1'b0 : 1'b1;
  96. assign full_o = fill_ctr[AWIDTH] ? 1'b1 : 1'b0;
  97. // make sure a write only happens to dp_ram when not full
  98. assign dp_we_i = ~full_o ? we_i : 1'b0;
  99. // make sure a read only happens to the dp_ram when not empty
  100. assign dp_re_i = ~empty_o ? re_i : 1'b0;
  101. //
  102. // fill counter
  103. // 
  104. always @(posedge clk or posedge reset) begin
  105.   if(reset) begin
  106.     fill_ctr <= 0;
  107.   end
  108.   else begin
  109.     if(dp_we_i & ~ dp_re_i) begin
  110.       fill_ctr <= fill_ctr + 1;
  111.     end
  112.     else if(dp_re_i & ~ dp_we_i) begin
  113.       fill_ctr <= fill_ctr - 1;
  114.     end
  115.   end
  116. end
  117. // 
  118. // read pointer
  119. // 
  120. always @(posedge clk or posedge reset) begin
  121.   if(reset) begin
  122.     read_ptr <= 0;
  123.   end
  124.   else begin
  125.     if(dp_re_i) begin
  126.       read_ptr <= read_ptr + 1;
  127.     end
  128.   end
  129. end
  130. // 
  131. // write pointer
  132. //
  133. always @(posedge clk or posedge reset) begin
  134.   if(reset) begin
  135.     write_ptr <= 0;
  136.   end
  137.   else begin
  138.     if(dp_we_i) begin
  139.       write_ptr <= write_ptr + 1;
  140.     end
  141.   end
  142. end
  143. endmodule