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

Subversion Repositories spimaster

[/] [spimaster/] [trunk/] [RTL/] [sm_fifoRTL.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sfielding
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// sm_fifoRTL.v                                                 ////
4
////                                                              ////
5
//// This file is part of the spiMaster opencores effort.
6
//// <http://www.opencores.org/cores//>                           ////
7
////                                                              ////
8
//// Module Description:                                          ////
9
////  parameterized dual clock domain fifo. 
10
////  fifo depth is restricted to 2^ADDR_WIDTH
11
////  No protection against over runs and under runs.
12
//// 
13
////                                                              ////
14
//// To Do:                                                       ////
15
//// 
16
////                                                              ////
17
//// Author(s):                                                   ////
18
//// - Steve Fielding, sfielding@base2designs.com                 ////
19
////                                                              ////
20
//////////////////////////////////////////////////////////////////////
21
////                                                              ////
22
//// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG          ////
23
////                                                              ////
24
//// This source file may be used and distributed without         ////
25
//// restriction provided that this copyright statement is not    ////
26
//// removed from the file and that any derivative work contains  ////
27
//// the original copyright notice and the associated disclaimer. ////
28
////                                                              ////
29
//// This source file is free software; you can redistribute it   ////
30
//// and/or modify it under the terms of the GNU Lesser General   ////
31
//// Public License as published by the Free Software Foundation; ////
32
//// either version 2.1 of the License, or (at your option) any   ////
33
//// later version.                                               ////
34
////                                                              ////
35
//// This source is distributed in the hope that it will be       ////
36
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
37
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
38
//// PURPOSE. See the GNU Lesser General Public License for more  ////
39
//// details.                                                     ////
40
////                                                              ////
41
//// You should have received a copy of the GNU Lesser General    ////
42
//// Public License along with this source; if not, download it   ////
43
//// from <http://www.opencores.org/lgpl.shtml>                   ////
44
////                                                              ////
45
//////////////////////////////////////////////////////////////////////
46
//
47
`include "timescale.v"
48
 
49
module sm_fifoRTL(wrClk, rdClk, rstSyncToWrClk, rstSyncToRdClk, dataIn,
50
  dataOut, fifoWEn, fifoREn, fifoFull, fifoEmpty,
51
  forceEmptySyncToWrClk, forceEmptySyncToRdClk, numElementsInFifo);
52
//FIFO_DEPTH = ADDR_WIDTH^2. Min = 2, Max = 66536
53
  parameter FIFO_WIDTH = 8;
54
  parameter FIFO_DEPTH = 64;
55
  parameter ADDR_WIDTH = 6;
56
 
57
// Two clock domains within this module
58
// These ports are within 'wrClk' domain
59
input wrClk;
60
input rstSyncToWrClk;
61
input [FIFO_WIDTH-1:0] dataIn;
62
input fifoWEn;
63
input forceEmptySyncToWrClk;
64
output fifoFull;
65
 
66
// These ports are within 'rdClk' domain
67
input rdClk;
68
input rstSyncToRdClk;
69
output [FIFO_WIDTH-1:0] dataOut;
70
input fifoREn;
71
input forceEmptySyncToRdClk;
72
output fifoEmpty;
73
output [15:0]numElementsInFifo; //note that this implies a max fifo depth of 65536
74
 
75
wire wrClk;
76
wire rdClk;
77
wire rstSyncToWrClk;
78
wire rstSyncToRdClk;
79
wire [FIFO_WIDTH-1:0] dataIn;
80
reg [FIFO_WIDTH-1:0] dataOut;
81
wire fifoWEn;
82
wire fifoREn;
83
reg fifoFull;
84
reg fifoEmpty;
85
wire forceEmpty;
86
reg  [15:0]numElementsInFifo;
87
 
88
 
89
// local registers
90
reg  [ADDR_WIDTH:0]bufferInIndex;
91
reg  [ADDR_WIDTH:0]bufferInIndexSyncToRdClk;
92
reg  [ADDR_WIDTH:0]bufferOutIndex;
93
reg  [ADDR_WIDTH:0]bufferOutIndexSyncToWrClk;
94
reg  [ADDR_WIDTH-1:0]bufferInIndexToMem;
95
reg  [ADDR_WIDTH-1:0]bufferOutIndexToMem;
96
reg  [ADDR_WIDTH:0]bufferCnt;
97
reg  fifoREnDelayed;
98
wire [FIFO_WIDTH-1:0] dataFromMem;
99
 
100
always @(posedge wrClk)
101
begin
102
  bufferOutIndexSyncToWrClk <= bufferOutIndex;
103
  if (rstSyncToWrClk == 1'b1 || forceEmptySyncToWrClk == 1'b1)
104
  begin
105
    fifoFull <= 1'b0;
106
    bufferInIndex <= 0;
107
  end
108
    else
109
    begin
110
      if (fifoWEn == 1'b1) begin
111
        bufferInIndex <= bufferInIndex + 1'b1;
112
      end
113
      if ((bufferOutIndexSyncToWrClk[ADDR_WIDTH-1:0] == bufferInIndex[ADDR_WIDTH-1:0]) &&
114
          (bufferOutIndexSyncToWrClk[ADDR_WIDTH] != bufferInIndex[ADDR_WIDTH]) )
115
        fifoFull <= 1'b1;
116
      else
117
        fifoFull <= 1'b0;
118
    end
119
end
120
 
121
always @(bufferInIndexSyncToRdClk or bufferOutIndex)
122
  bufferCnt <= bufferInIndexSyncToRdClk - bufferOutIndex;
123
 
124
always @(posedge rdClk)
125
begin
126
  numElementsInFifo <= { {16-ADDR_WIDTH-1{1'b0}}, bufferCnt }; //pad bufferCnt with leading zeroes
127
  bufferInIndexSyncToRdClk <= bufferInIndex;
128
  if (rstSyncToRdClk == 1'b1 || forceEmptySyncToRdClk == 1'b1)
129
  begin
130
    fifoEmpty <= 1'b1;
131
    bufferOutIndex <= 0;
132
    fifoREnDelayed <= 1'b0;
133
  end
134
    else
135
    begin
136
      fifoREnDelayed <= fifoREn;
137
      if (fifoREn == 1'b1 && fifoREnDelayed == 1'b0) begin
138
        dataOut <= dataFromMem;
139
        bufferOutIndex <= bufferOutIndex + 1'b1;
140
      end
141
      if (bufferInIndexSyncToRdClk == bufferOutIndex)
142
        fifoEmpty <= 1'b1;
143
      else
144
        fifoEmpty <= 1'b0;
145
    end
146
end
147
 
148
 
149
always @(bufferInIndex or bufferOutIndex) begin
150
  bufferInIndexToMem <= bufferInIndex[ADDR_WIDTH-1:0];
151
  bufferOutIndexToMem <= bufferOutIndex[ADDR_WIDTH-1:0];
152
end
153
 
154
sm_dpMem_dc #(FIFO_WIDTH, FIFO_DEPTH, ADDR_WIDTH)  u_sm_dpMem_dc (
155
  .addrIn(bufferInIndexToMem),
156
  .addrOut(bufferOutIndexToMem),
157
  .wrClk(wrClk),
158
  .rdClk(rdClk),
159
  .dataIn(dataIn),
160
  .writeEn(fifoWEn),
161
  .readEn(fifoREn),
162
  .dataOut(dataFromMem));
163
 
164
endmodule

powered by: WebSVN 2.1.0

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