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

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [basal/] [src/] [FIFOs/] [async_fifo.sv] - Blame information for rev 38

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 qaztronic
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// Copyright (C) 2016 Authors and OPENCORES.ORG                 ////
4
////                                                              ////
5
//// This source file may be used and distributed without         ////
6
//// restriction provided that this copyright statement is not    ////
7
//// removed from the file and that any derivative work contains  ////
8
//// the original copyright notice and the associated disclaimer. ////
9
////                                                              ////
10
//// This source file is free software; you can redistribute it   ////
11
//// and/or modify it under the terms of the GNU Lesser General   ////
12
//// Public License as published by the Free Software Foundation; ////
13
//// either version 2.1 of the License, or (at your option) any   ////
14
//// later version.                                               ////
15
////                                                              ////
16
//// This source is distributed in the hope that it will be       ////
17
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
18
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
19
//// PURPOSE.  See the GNU Lesser General Public License for more ////
20
//// details.                                                     ////
21
////                                                              ////
22
//// You should have received a copy of the GNU Lesser General    ////
23
//// Public License along with this source; if not, download it   ////
24
//// from http://www.opencores.org/lgpl.shtml                     ////
25
////                                                              ////
26
//////////////////////////////////////////////////////////////////////
27
 
28
 
29
// --------------------------------------------------------------------
30
//
31
module
32
  cummings_sync_r2w
33
  #(
34
    parameter ADDRSIZE = 4
35
  )
36
  (
37
    output reg [ADDRSIZE:0] wq2_rptr,
38
    input [ADDRSIZE:0]      rptr,
39
    input                   wclk,
40
    input                   wrst_n
41
  );
42
 
43
  reg [ADDRSIZE:0] wq1_rptr;
44
 
45
  always @(posedge wclk or negedge wrst_n)
46
    if (!wrst_n)
47
      {wq2_rptr,wq1_rptr} <= 0;
48
    else
49
      {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};
50
 
51
endmodule
52
 
53
 
54
// --------------------------------------------------------------------
55
//
56
module
57
  cummings_sync_w2r
58
  #(
59
    parameter ADDRSIZE = 4
60
  )
61
  (
62
    output reg  [ADDRSIZE:0]  rq2_wptr,
63
    input       [ADDRSIZE:0]  wptr,
64
    input                     rclk,
65
    input                     rrst_n
66
  );
67
 
68
  reg [ADDRSIZE:0] rq1_wptr;
69
 
70
  always @(posedge rclk or negedge rrst_n)
71
    if(!rrst_n)
72
      {rq2_wptr,rq1_wptr} <= 0;
73
    else
74
      {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};
75
 
76
endmodule
77
 
78
 
79
// --------------------------------------------------------------------
80
//
81
module
82
  cummings_fifomem
83
  #(
84
    parameter DATASIZE = 8,   // Memory data word width
85
    parameter ADDRSIZE = 4    // Number of mem address bits
86
  )
87
  (
88
    output [DATASIZE-1:0] rdata,
89
    input [DATASIZE-1:0]  wdata,
90
    input [ADDRSIZE-1:0]  waddr,
91
    input [ADDRSIZE-1:0]  raddr,
92
    input wclken,
93
    input wfull,
94
    input wclk
95
  );
96
 
97
  // RTL Verilog memory model
98
  localparam DEPTH = 1<
99
  reg [DATASIZE-1:0] mem [0:DEPTH-1];
100
  assign rdata = mem[raddr];
101
 
102
  always @(posedge wclk)
103
    if(wclken && !wfull)
104
      mem[waddr] <= wdata;
105
 
106
endmodule
107
 
108
 
109
// --------------------------------------------------------------------
110
//
111
module
112
  cummings_rptr_empty
113
  #(
114
    parameter ADDRSIZE = 4
115
  )
116
  (
117
    output reg                  rempty,
118
    output      [ADDRSIZE-1:0]  raddr,
119
    output reg  [ADDRSIZE :0]   rptr,
120
    input       [ADDRSIZE :0]   rq2_wptr,
121
    input                       rinc,
122
    input                       rclk,
123
    input                       rrst_n
124
  );
125
 
126
  reg [ADDRSIZE:0] rbin;
127
  wire [ADDRSIZE:0] rgraynext, rbinnext;
128
 
129
  //-------------------
130
  // GRAYSTYLE2 pointer
131
  //-------------------
132
  always @(posedge rclk or negedge rrst_n)
133
    if(!rrst_n)
134
      {rbin, rptr} <= 0;
135
    else
136
      {rbin, rptr} <= {rbinnext, rgraynext};
137
 
138
  // Memory read-address pointer (okay to use binary to address memory)
139
  assign raddr = rbin[ADDRSIZE-1:0];
140
  assign rbinnext = rbin + (rinc & ~rempty);
141
  assign rgraynext = (rbinnext>>1) ^ rbinnext;
142
 
143
  //---------------------------------------------------------------
144
  // FIFO empty when the next rptr == synchronized wptr or on reset
145
  //---------------------------------------------------------------
146
  assign rempty_val = (rgraynext == rq2_wptr);
147
 
148
  always @(posedge rclk or negedge rrst_n)
149
    if(!rrst_n)
150
      rempty <= 1'b1;
151
    else
152
      rempty <= rempty_val;
153
 
154
endmodule
155
 
156
 
157
// --------------------------------------------------------------------
158
//
159
module
160
  cummings_wptr_full
161
  #(
162
    parameter ADDRSIZE = 4
163
  )
164
  (
165
    output reg                  wfull,
166
    output      [ADDRSIZE-1:0]  waddr,
167
    output reg  [ADDRSIZE :0]   wptr,
168
    input       [ADDRSIZE :0]   wq2_rptr,
169
    input                       winc,
170
    input                       wclk,
171
    input                       wrst_n
172
  );
173
 
174
  reg [ADDRSIZE:0] wbin;
175
  wire [ADDRSIZE:0] wgraynext, wbinnext;
176
 
177
  // GRAYSTYLE2 pointer
178
  always @(posedge wclk or negedge wrst_n)
179
    if(!wrst_n)
180
      {wbin, wptr} <= 0;
181
    else
182
      {wbin, wptr} <= {wbinnext, wgraynext};
183
 
184
  // Memory write-address pointer (okay to use binary to address memory)
185
  assign waddr = wbin[ADDRSIZE-1:0];
186
  assign wbinnext = wbin + (winc & ~wfull);
187
  assign wgraynext = (wbinnext>>1) ^ wbinnext;
188
 
189
  //------------------------------------------------------------------
190
  // Simplified version of the three necessary full-tests:
191
  // assign wfull_val=((wgnext[ADDRSIZE] !=wq2_rptr[ADDRSIZE] ) &&
192
  // (wgnext[ADDRSIZE-1] !=wq2_rptr[ADDRSIZE-1]) &&
193
  // (wgnext[ADDRSIZE-2:0]==wq2_rptr[ADDRSIZE-2:0]));
194
  //------------------------------------------------------------------
195
  assign wfull_val = (wgraynext == {~wq2_rptr[ADDRSIZE:ADDRSIZE-1], wq2_rptr[ADDRSIZE-2:0]});
196
 
197
  always @(posedge wclk or negedge wrst_n)
198
    if(!wrst_n)
199
      wfull <= 1'b0;
200
    else
201
      wfull <= wfull_val;
202
 
203
endmodule
204
 
205
 
206
// --------------------------------------------------------------------
207
//
208
module
209
  cummings_fifo1
210
  #(
211
    parameter DSIZE = 8,
212
    parameter ASIZE = 4
213
  )
214
  (
215
    output [DSIZE-1:0]  rdata,
216
    output              wfull,
217
    output              rempty,
218
    input [DSIZE-1:0]   wdata,
219
    input               winc,
220
    input               wclk,
221
    input               wrst_n,
222
    input               rinc,
223
    input               rclk,
224
    input               rrst_n
225
  );
226
 
227
  wire [ASIZE-1:0] waddr, raddr;
228
  wire [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr;
229
 
230
  cummings_sync_r2w sync_r2w (.wq2_rptr(wq2_rptr), .rptr(rptr),
231
  .wclk(wclk), .wrst_n(wrst_n));
232
 
233
  cummings_sync_w2r sync_w2r (.rq2_wptr(rq2_wptr), .wptr(wptr),
234
  .rclk(rclk), .rrst_n(rrst_n));
235
 
236
  cummings_fifomem #(DSIZE, ASIZE) fifomem
237
  (.rdata(rdata), .wdata(wdata),
238
  .waddr(waddr), .raddr(raddr),
239
  .wclken(winc), .wfull(wfull),
240
  .wclk(wclk));
241
 
242
  cummings_rptr_empty #(ASIZE) rptr_empty
243
  (.rempty(rempty),
244
  .raddr(raddr),
245
  .rptr(rptr), .rq2_wptr(rq2_wptr),
246
  .rinc(rinc), .rclk(rclk),
247
  .rrst_n(rrst_n));
248
 
249
  cummings_wptr_full #(ASIZE) wptr_full
250
  (.wfull(wfull), .waddr(waddr),
251
  .wptr(wptr), .wq2_rptr(wq2_rptr),
252
  .winc(winc), .wclk(wclk),
253
  .wrst_n(wrst_n));
254
 
255
endmodule
256
// --------------------------------------------------------------------
257
//
258
 
259
 
260
// --------------------------------------------------------------------
261
//
262
// --------------------------------------------------------------------
263
 
264
 
265
module
266
  async_fifo
267
  #(
268
    W,
269
    D
270
  )
271
  (
272
    output            wr_full,
273
    input  [W-1:0]    wr_data,
274
    input             wr_en,
275
    input             wr_clk,
276
    input             wr_reset,
277
 
278
    output            rd_empty,
279
    output  [W-1:0]   rd_data,
280
    input             rd_en,
281
    input             rd_clk,
282
    input             rd_reset
283
  );
284
 
285
  // --------------------------------------------------------------------
286
  //
287
  cummings_fifo1 #(.DSIZE(W), .ASIZE($clog2(D)))
288
    cummings_fifo1_i
289
    (
290
      .rdata(rd_data),
291
      .wfull(wr_full),
292
      .rempty(rd_empty),
293
      .wdata(wr_data),
294
      .winc(wr_en),
295
      .wclk(wr_clk),
296
      .wrst_n(~wr_reset),
297
      .rinc(rd_en),
298
      .rclk(rd_clk),
299
      .rrst_n(~rd_reset)
300
    );
301
 
302
 
303
// --------------------------------------------------------------------
304
// synthesis translate_off
305
  always_ff @(posedge wr_clk)
306
    if(wr_en & wr_full)
307
      $stop;
308
  always_ff @(posedge rd_clk)
309
    if(rd_en & rd_empty)
310
      $stop;
311
// synthesis translate_on
312
// --------------------------------------------------------------------
313
 
314
 
315
// --------------------------------------------------------------------
316
//
317
endmodule
318
 
319
 

powered by: WebSVN 2.1.0

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