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

Subversion Repositories versatile_library

[/] [versatile_library/] [trunk/] [rtl/] [verilog/] [memories.v] - Blame information for rev 5

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

Line No. Rev Author Line
1 5 unneback
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  Versatile library, memories                                 ////
4
////                                                              ////
5
////  Description                                                 ////
6
////  memories                                                    ////
7
////                                                              ////
8
////                                                              ////
9
////  To Do:                                                      ////
10
////   - add more memory types                                    ////
11
////                                                              ////
12
////  Author(s):                                                  ////
13
////      - Michael Unneback, unneback@opencores.org              ////
14
////        ORSoC AB                                              ////
15
////                                                              ////
16
//////////////////////////////////////////////////////////////////////
17
////                                                              ////
18
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
19
////                                                              ////
20
//// This source file may be used and distributed without         ////
21
//// restriction provided that this copyright statement is not    ////
22
//// removed from the file and that any derivative work contains  ////
23
//// the original copyright notice and the associated disclaimer. ////
24
////                                                              ////
25
//// This source file is free software; you can redistribute it   ////
26
//// and/or modify it under the terms of the GNU Lesser General   ////
27
//// Public License as published by the Free Software Foundation; ////
28
//// either version 2.1 of the License, or (at your option) any   ////
29
//// later version.                                               ////
30
////                                                              ////
31
//// This source is distributed in the hope that it will be       ////
32
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
33
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
34
//// PURPOSE.  See the GNU Lesser General Public License for more ////
35
//// details.                                                     ////
36
////                                                              ////
37
//// You should have received a copy of the GNU Lesser General    ////
38
//// Public License along with this source; if not, download it   ////
39
//// from http://www.opencores.org/lgpl.shtml                     ////
40
////                                                              ////
41
//////////////////////////////////////////////////////////////////////
42
 
43
/// ROM
44
 
45
module vl_rom ( a, q, clk);
46
 
47
parameter data_width = 32;
48
parameter addr_width = 4;
49
 
50
parameter [0:1>>addr_width-1] data [data_width-1:0] = {
51
    {32'h18000000},
52
    {32'hA8200000},
53
    {32'hA8200000},
54
    {32'hA8200000},
55
    {32'h44003000},
56
    {32'h15000000},
57
    {32'h15000000},
58
    {32'h15000000},
59
    {32'h15000000},
60
    {32'h15000000},
61
    {32'h15000000},
62
    {32'h15000000},
63
    {32'h15000000},
64
    {32'h15000000},
65
    {32'h15000000},
66
    {32'h15000000}};
67
 
68
input [addr_width-1:0] a;
69
output reg [data_width-1:0] q;
70
input clk;
71
 
72
always @ (posedge clk)
73
    q <= data[a];
74
 
75
endmodule
76
 
77
// Single port RAM
78
 
79
module vl_ram ( d, adr, we, q, clk);
80
   parameter data_width = 32;
81
   parameter addr_width = 8;
82
   input [(data_width-1):0]      d;
83
   input [(addr_width-1):0]       adr;
84
   input                         we;
85
   output reg [(data_width-1):0]          q;
86
   input                         clk;
87
   reg [data_width-1:0] ram [(1<<addr_width)-1:0];
88
   always @ (posedge clk)
89
   begin
90
   if (we)
91
     ram[adr] <= d;
92
   q <= ram[adr];
93
   end
94
 
95
endmodule
96
 
97
// Dual port RAM
98
 
99
// ACTEL FPGA should not use logic to handle rw collision
100
`ifdef ACTEL
101
        `define SYN /*synthesis syn_ramstyle = "no_rw_check"*/
102
`else
103
        `define SYN
104
`endif
105
 
106
module vl_dual_port_ram_1r1w ( d_a, adr_a, we_a, clk_a, q_b, adr_b, clk_b );
107
   parameter data_width = 32;
108
   parameter addr_width = 8;
109
   input [(data_width-1):0]      d_a;
110
   input [(addr_width-1):0]       adr_a;
111
   input [(addr_width-1):0]       adr_b;
112
   input                         we_a;
113
   output [(data_width-1):0]      q_b;
114
   input                         clk_a, clk_b;
115
   reg [(addr_width-1):0]         adr_b_reg;
116
   reg [data_width-1:0] ram [(1<<addr_width)-1:0] `SYN;
117
   always @ (posedge clk_a)
118
   if (we_a)
119
     ram[adr_a] <= d_a;
120
   always @ (posedge clk_b)
121
   adr_b_reg <= adr_b;
122
   assign q_b = ram[adr_b_reg];
123
endmodule
124
 
125
module vl_dual_port_ram_2r1w ( d_a, q_a, adr_a, we_a, clk_a, q_b, adr_b, clk_b );
126
   parameter data_width = 32;
127
   parameter addr_width = 8;
128
   input [(data_width-1):0]      d_a;
129
   input [(addr_width-1):0]       adr_a;
130
   input [(addr_width-1):0]       adr_b;
131
   input                         we_a;
132
   output [(data_width-1):0]      q_b;
133
   output reg [(data_width-1):0] q_a;
134
   input                         clk_a, clk_b;
135
   reg [(data_width-1):0]         q_b;
136
   reg [data_width-1:0] ram [(1<<addr_width)-1:0] `SYN;
137
   always @ (posedge clk_a)
138
     begin
139
        q_a <= ram[adr_a];
140
        if (we_a)
141
             ram[adr_a] <= d_a;
142
     end
143
   always @ (posedge clk_b)
144
          q_b <= ram[adr_b];
145
endmodule
146
 
147
module vl_dual_port_ram_2r2w ( d_a, q_a, adr_a, we_a, clk_a, q_b, adr_b, d_b, we_b, clk_b );
148
   parameter data_width = 32;
149
   parameter addr_width = 8;
150
   input [(data_width-1):0]      d_a;
151
   input [(addr_width-1):0]       adr_a;
152
   input [(addr_width-1):0]       adr_b;
153
   input                         we_a;
154
   output [(data_width-1):0]      q_b;
155
   input [(data_width-1):0]       d_b;
156
   output reg [(data_width-1):0] q_a;
157
   input                         we_b;
158
   input                         clk_a, clk_b;
159
   reg [(data_width-1):0]         q_b;
160
   reg [data_width-1:0] ram [(1<<addr_width)-1:0] `SYN;
161
   always @ (posedge clk_a)
162
     begin
163
        q_a <= ram[adr_a];
164
        if (we_a)
165
             ram[adr_a] <= d_a;
166
     end
167
   always @ (posedge clk_b)
168
     begin
169
        q_b <= ram[adr_b];
170
        if (we_b)
171
          ram[adr_b] <= d_b;
172
     end
173
endmodule
174
 
175
// Content addresable memory, CAM
176
 
177
// FIFO
178
 
179
module vl_fifo_cmp_async ( wptr, rptr, fifo_empty, fifo_full, wclk, rclk, rst );
180
 
181
   parameter ADDR_WIDTH = 4;
182
   parameter N = ADDR_WIDTH-1;
183
 
184
   parameter Q1 = 2'b00;
185
   parameter Q2 = 2'b01;
186
   parameter Q3 = 2'b11;
187
   parameter Q4 = 2'b10;
188
 
189
   parameter going_empty = 1'b0;
190
   parameter going_full  = 1'b1;
191
 
192
   input [N:0]  wptr, rptr;
193
   output reg   fifo_empty;
194
   output       fifo_full;
195
   input        wclk, rclk, rst;
196
 
197
`ifndef GENERATE_DIRECTION_AS_LATCH
198
   wire direction;
199
`endif
200
`ifdef GENERATE_DIRECTION_AS_LATCH
201
   reg direction;
202
`endif
203
   reg  direction_set, direction_clr;
204
 
205
   wire async_empty, async_full;
206
   wire fifo_full2;
207
   reg  fifo_empty2;
208
 
209
   // direction_set
210
   always @ (wptr[N:N-1] or rptr[N:N-1])
211
     case ({wptr[N:N-1],rptr[N:N-1]})
212
       {Q1,Q2} : direction_set <= 1'b1;
213
       {Q2,Q3} : direction_set <= 1'b1;
214
       {Q3,Q4} : direction_set <= 1'b1;
215
       {Q4,Q1} : direction_set <= 1'b1;
216
       default : direction_set <= 1'b0;
217
     endcase
218
 
219
   // direction_clear
220
   always @ (wptr[N:N-1] or rptr[N:N-1] or rst)
221
     if (rst)
222
       direction_clr <= 1'b1;
223
     else
224
       case ({wptr[N:N-1],rptr[N:N-1]})
225
         {Q2,Q1} : direction_clr <= 1'b1;
226
         {Q3,Q2} : direction_clr <= 1'b1;
227
         {Q4,Q3} : direction_clr <= 1'b1;
228
         {Q1,Q4} : direction_clr <= 1'b1;
229
         default : direction_clr <= 1'b0;
230
       endcase
231
 
232
`ifndef GENERATE_DIRECTION_AS_LATCH
233
    dff_sr dff_sr_dir( .aclr(direction_clr), .aset(direction_set), .clock(1'b1), .data(1'b1), .q(direction));
234
`endif
235
 
236
`ifdef GENERATE_DIRECTION_AS_LATCH
237
   always @ (posedge direction_set or posedge direction_clr)
238
     if (direction_clr)
239
       direction <= going_empty;
240
     else
241
       direction <= going_full;
242
`endif
243
 
244
   assign async_empty = (wptr == rptr) && (direction==going_empty);
245
   assign async_full  = (wptr == rptr) && (direction==going_full);
246
 
247
    dff_sr dff_sr_empty0( .aclr(rst), .aset(async_full), .clock(wclk), .data(async_full), .q(fifo_full2));
248
    dff_sr dff_sr_empty1( .aclr(rst), .aset(async_full), .clock(wclk), .data(fifo_full2), .q(fifo_full));
249
 
250
/*
251
   always @ (posedge wclk or posedge rst or posedge async_full)
252
     if (rst)
253
       {fifo_full, fifo_full2} <= 2'b00;
254
     else if (async_full)
255
       {fifo_full, fifo_full2} <= 2'b11;
256
     else
257
       {fifo_full, fifo_full2} <= {fifo_full2, async_full};
258
*/
259
   always @ (posedge rclk or posedge async_empty)
260
     if (async_empty)
261
       {fifo_empty, fifo_empty2} <= 2'b11;
262
     else
263
       {fifo_empty,fifo_empty2} <= {fifo_empty2,async_empty};
264
 
265
endmodule // async_comp
266
 
267
module vl_fifo_1r1w_async (
268
    d, wr, fifo_full, wr_clk, wr_rst,
269
    q, rd, fifo_empty, rd_clk, rd_rst
270
    );
271
 
272
parameter data_width = 18;
273
parameter addr_width = 4;
274
 
275
// write side
276
input  [data_width-1:0] d;
277
input                   wr;
278
output                  fifo_full;
279
input                   wr_clk;
280
input                   wr_rst;
281
// read side
282
output [data_width-1:0] q;
283
input                   rd;
284
output                  fifo_empty;
285
input                   rd_clk;
286
input                   rd_rst;
287
 
288
wire [addr_width:1] wadr, wadr_bin, radr, radr_bin;
289
 
290
vl_fifo_1r1w_async (
291
    d, wr, fifo_full, wr_clk, wr_rst,
292
    q, rd, fifo_empty, rd_clk, rd_rst
293
    );
294
 
295
adr_gen
296
    # ( .length(addr_width))
297
    fifo_wr_adr( .cke(wr), .q(wadr), .q_bin(wadr_bin), .rst(wr_rst), .clk(wr_clk));
298
 
299
adr_gen
300
    # (.length(addr_width))
301
    fifo_rd_adr( .cke(wr), .q(radr), .q_bin(radr_bin), .rst(rd_rst), .clk(rd_rst));
302
 
303
vl_dual_port_ram_1r1w
304
    # (.data_width(data_width), .addr_width(addr_width))
305
    dpram ( .d_a(d), .adr_a(wadr_bin), .we_a(wr), .clk_a(wr_clk), .q_b(q), .adr_b(radr_bin), .clk_b(rd_clk));
306
 
307
vl_fifo_cmp_async
308
    # (.addr_width(addr_width))
309
    cmp ( .wptr(wadr), .rptr(radr), .fifo_empty(fifo_empty), .fifo_full(fifo_full), .wclk(wr_clk), .rclk(rd_clk), .rst(wr_rst) );
310
 
311
endmodule
312
 
313
module vl_fifo_2r2w (
314
    // a side
315
    a_d, a_wr, a_fifo_full,
316
    a_q, a_rd, a_fifo_empty,
317
    a_clk, a_rst,
318
    // b side
319
    b_d, b_wr, b_fifo_full,
320
    b_q, b_rd, b_fifo_empty,
321
    b_clk, b_rst
322
    );
323
 
324
parameter data_width = 18;
325
parameter addr_width = 4;
326
 
327
// a side
328
input  [data_width-1:0] a_d;
329
input                   a_wr;
330
output                  a_fifo_full;
331
output [data_width-1:0] a_q;
332
input                   a_rd;
333
output                  a_fifo_empty;
334
input                   a_clk;
335
input                   a_rst;
336
 
337
// b side
338
input  [data_width-1:0] b_d;
339
input                   b_wr;
340
output                  b_fifo_full;
341
output [data_width-1:0] b_q;
342
input                   b_rd;
343
output                  b_fifo_empty;
344
input                   b_clk;
345
input                   b_rst;
346
 
347
vl_fifo_1r1w_async # (.data_width(data_width), .addr_width(addr_width))
348
vl_fifo_1r1w_async_a (
349
    .d(a_d), .wr(a_wr), .fifo_full(a_fifo_full), .wr_clk(a_clk), .wr_rst(a_rst),
350
    .q(b_q), .rd(b_rd), .fifo_empty(b_fifo_empty), .rd_clk(b_clk), .rd_rst(b_rst)
351
    );
352
 
353
vl_fifo_1r1w_async # (.data_width(data_width), .addr_width(addr_width))
354
vl_fifo_1r1w_async_b (
355
    .d(b_d), .wr(b_wr), .fifo_full(b_fifo_full), .wr_clk(b_clk), .wr_rst(b_rst),
356
    .q(a_q), .rd(a_rd), .fifo_empty(a_fifo_empty), .rd_clk(a_clk), .rd_rst(a_rst)
357
    );
358
 
359
endmodule
360
 
361
module vl_fifo_2r2w_simplex (
362
    // a side
363
    a_d, a_wr, a_fifo_full,
364
    a_q, a_rd, a_fifo_empty,
365
    a_clk, a_rst,
366
    // b side
367
    b_d, b_wr, b_fifo_full,
368
    b_q, b_rd, b_fifo_empty,
369
    b_clk, b_rst
370
    );
371
 
372
parameter data_width = 18;
373
parameter addr_width = 4;
374
 
375
// a side
376
input  [data_width-1:0] a_d;
377
input                   a_wr;
378
output                  a_fifo_full;
379
output [data_width-1:0] a_q;
380
input                   a_rd;
381
output                  a_fifo_empty;
382
input                   a_clk;
383
input                   a_rst;
384
 
385
// b side
386
input  [data_width-1:0] b_d;
387
input                   b_wr;
388
output                  b_fifo_full;
389
output [data_width-1:0] b_q;
390
input                   b_rd;
391
output                  b_fifo_empty;
392
input                   b_clk;
393
input                   b_rst;
394
 
395
// adr_gen
396
wire [addr_width:1] a_wadr, a_wadr_bin, a_radr, a_radr_bin;
397
wire [addr_width:1] b_wadr, b_wadr_bin, b_radr, b_radr_bin;
398
// dpram
399
wire [addr_width:0] a_dpram_adr, b_dpram_adr;
400
 
401
adr_gen
402
    # ( .length(addr_width))
403
    fifo_a_wr_adr( .cke(a_wr), .q(a_wadr), .q_bin(a_wadr_bin), .rst(a_rst), .clk(a_clk));
404
 
405
adr_gen
406
    # (.length(addr_width))
407
    fifo_a_rd_adr( .cke(a_rd), .q(a_radr), .q_bin(a_radr_bin), .rst(a_rst), .clk(a_clk));
408
 
409
adr_gen
410
    # ( .length(addr_width))
411
    fifo_b_wr_adr( .cke(b_wr), .q(b_wadr), .q_bin(b_wadr_bin), .rst(b_rst), .clk(b_clk));
412
 
413
adr_gen
414
    # (.length(addr_width))
415
    fifo_b_rd_adr( .cke(b_rd), .q(b_radr), .q_bin(b_radr_bin), .rst(b_rst), .clk(b_clk));
416
 
417
// mux read or write adr to DPRAM
418
assign a_dpram_adr = (a_wr) ? {1'b0,a_wadr_bin} : {1'b1,a_radr_bin};
419
assign b_dpram_adr = (b_wr) ? {1'b1,b_wadr_bin} : {1'b0,b_radr_bin};
420
 
421
vfifo_dual_port_ram_dc_dw
422
    # (.data_width(data_width), .addr_width(addr_width+1))
423
    dpram ( .d_a(a_d), .q_a(a_q), .adr_a(a_dpram_adr), .we_a(a_wr), .clk_a(a_clk),
424
            .d_b(b_d), .q_b(b_q), .adr_b(b_dpram_adr), .we_b(b_wr), .clk_b(b_clk));
425
 
426
vl_fifo_async_cmp
427
    # (.addr_width(addr_width))
428
    cmp1 ( .wptr(a_wadr), .rptr(b_radr), .fifo_empty(b_fifo_empty), .fifo_full(a_fifo_full), .wclk(a_clk), .rclk(b_clk), .rst(a_rst) );
429
 
430
versatile_fifo_async_cmp
431
    # (.addr_width(addr_width))
432
    cmp2 ( .wptr(b_wadr), .rptr(a_radr), .fifo_empty(a_fifo_empty), .fifo_full(b_fifo_full), .wclk(b_clk), .rclk(a_clk), .rst(b_rst) );
433
 
434
endmodule

powered by: WebSVN 2.1.0

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