OpenCores
URL https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [basal/] [src/] [FIFOs/] [Beyond_Circuits/] [sync_fifo.v] - Blame information for rev 35

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 qaztronic
// -*- mode: Verilog; verilog-auto-lineup-declaration: nil; -*-
2
//-----------------------------------------------------------------------------
3
// Title         : Synchronous FIFO
4
// Project       : Common
5
//-----------------------------------------------------------------------------
6
// File          : sync_fifo.v
7
//-----------------------------------------------------------------------------
8
// Description : Synchronous FIFO using BRAM.
9
//
10
// Implements a variable width/depth synchronous FIFO. The synthesis
11
// tool may choose to implement the memory as a block RAM.
12
//-----------------------------------------------------------------------------
13
// Copyright 1994-2009 Beyond Circuits. All rights reserved.
14
//
15
// Redistribution and use in source and binary forms, with or without modification,
16
// are permitted provided that the following conditions are met:
17
//   1. Redistributions of source code must retain the above copyright notice, 
18
//      this list of conditions and the following disclaimer.
19
//   2. Redistributions in binary form must reproduce the above copyright notice, 
20
//      this list of conditions and the following disclaimer in the documentation 
21
//      and/or other materials provided with the distribution.
22
//
23
// THIS SOFTWARE IS PROVIDED BY THE BEYOND CIRCUITS ``AS IS'' AND ANY EXPRESS OR 
24
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
25
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
26
// SHALL BEYOND CIRCUITS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
28
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
29
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
30
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
31
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
//------------------------------------------------------------------------------
33
 
34
`timescale 1ns/1ns
35
module sync_fifo
36
  #(
37
    parameter depth = 32,
38
    parameter width = 32,
39
    // Need the log of the parameters as parameters also due to an XST bug.
40
    parameter log2_depth = log2(depth),
41
    parameter log2_depthp1 = log2(depth+1)
42
    )
43
  (
44
   input clk,
45
   input reset,
46
   input wr_enable,
47
   input rd_enable,
48
   output reg empty,
49
   output reg full,
50
   output [width-1:0] rd_data,
51
   input [width-1:0] wr_data,
52
   output reg [log2_depthp1-1:0] count
53
   );
54
 
55
  // log2 -- return the log base 2 of value.
56
  function integer log2;
57
    input [31:0] value;
58
    begin
59
      value = value-1;
60
      for (log2=0; value>0; log2=log2+1)
61
        value = value>>1;
62
    end
63
  endfunction
64
 
65
  // increment -- add one to value modulo depth.
66
  function [log2_depth-1:0] increment;
67
    input [log2_depth-1:0] value;
68
    begin
69
      if (value == depth-1)
70
        increment = 0;
71
      else
72
        increment = value+1;
73
    end
74
  endfunction
75
 
76
  // writing -- true when we write to the RAM.
77
  wire writing = wr_enable && (rd_enable || !full);
78
 
79
  // reading -- true when we are reading from the RAM.
80
  wire reading = rd_enable && !empty;
81
 
82
  // rd_ptr -- the read pointer.
83
  reg [log2_depth-1:0] rd_ptr;
84
 
85
  // next_rd_ptr -- the next value for the read pointer.
86
  // We need to name this combinational value because it
87
  // is needed to use the write-before-read style RAM.
88
  reg [log2_depth-1:0] next_rd_ptr;
89
  always @(*)
90
    if (reset)
91
      next_rd_ptr = 0;
92
    else if (reading)
93
      next_rd_ptr = increment(rd_ptr);
94
    else
95
      next_rd_ptr = rd_ptr;
96
 
97
  always @(posedge clk)
98
    rd_ptr <= next_rd_ptr;
99
 
100
  // wr_ptr -- the write pointer
101
  reg [log2_depth-1:0] wr_ptr;
102
 
103
  // next_wr_ptr -- the next value for the write pointer.
104
  reg [log2_depth-1:0] next_wr_ptr;
105
  always @(*)
106
    if (reset)
107
      next_wr_ptr = 0;
108
    else if (writing)
109
      next_wr_ptr = increment(wr_ptr);
110
    else
111
      next_wr_ptr = wr_ptr;
112
 
113
  always @(posedge clk)
114
    wr_ptr <= next_wr_ptr;
115
 
116
  // count -- the number of valid entries in the FIFO.
117
  always @(posedge clk)
118
    if (reset)
119
      count <= 0;
120
    else if (writing && !reading)
121
      count <= count+1;
122
    else if (reading && !writing)
123
      count <= count-1;
124
 
125
  // empty -- true if the FIFO is empty.
126
  // Note that this doesn't depend on count so if the count
127
  // output is unused the logic for computing the count can
128
  // be optimized away.
129
  always @(posedge clk)
130
    if (reset)
131
      empty <= 1;
132
    else if (reading && next_wr_ptr == next_rd_ptr && !full)
133
      empty <= 1;
134
    else
135
      if (writing && !reading)
136
        empty <= 0;
137
 
138
  // full -- true if the FIFO is full.
139
  // Again, this is not dependent on count.
140
  always @(posedge clk)
141
    if (reset)
142
      full <= 0;
143
    else if (writing && next_wr_ptr == next_rd_ptr)
144
      full <= 1;
145
    else if (reading && !writing)
146
      full <= 0;
147
 
148
  // We need to infer a write first style RAM so that when 
149
  // the FIFO is empty the write data can flow through to
150
  // the read side and be available the next clock cycle.
151
  reg [width-1:0] mem [depth-1:0];
152
 
153
  always @(posedge clk)
154
    if (writing)
155
      mem[wr_ptr] <= wr_data;
156
 
157
  assign rd_data = mem[rd_ptr];
158
 
159
endmodule
160
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.