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 8

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 7 unneback
module vl_rom_init ( adr, q, clk);
46
   parameter data_width = 32;
47
   parameter addr_width = 8;
48
   input [(addr_width-1):0]       adr;
49
   output reg [(data_width-1):0] q;
50
   input                         clk;
51
   reg [data_width-1:0] rom [(1<<addr_width)-1:0];
52
   parameter memory_file = "vl_rom.vmem";
53
   initial
54
     begin
55
        $readmemh(memory_file, rom);
56
     end
57
 
58
   always @ (posedge clk)
59
     q <= rom[adr];
60 5 unneback
 
61 7 unneback
endmodule
62
 
63
module vl_rom ( adr, q, clk);
64
 
65 5 unneback
parameter data_width = 32;
66
parameter addr_width = 4;
67
 
68
parameter [0:1>>addr_width-1] data [data_width-1:0] = {
69
    {32'h18000000},
70
    {32'hA8200000},
71
    {32'hA8200000},
72
    {32'hA8200000},
73
    {32'h44003000},
74
    {32'h15000000},
75
    {32'h15000000},
76
    {32'h15000000},
77
    {32'h15000000},
78
    {32'h15000000},
79
    {32'h15000000},
80
    {32'h15000000},
81
    {32'h15000000},
82
    {32'h15000000},
83
    {32'h15000000},
84
    {32'h15000000}};
85
 
86 7 unneback
input [addr_width-1:0] adr;
87 5 unneback
output reg [data_width-1:0] q;
88
input clk;
89
 
90
always @ (posedge clk)
91 7 unneback
    q <= data[adr];
92 5 unneback
 
93
endmodule
94
 
95
// Single port RAM
96
 
97
module vl_ram ( d, adr, we, q, clk);
98
   parameter data_width = 32;
99
   parameter addr_width = 8;
100
   input [(data_width-1):0]      d;
101
   input [(addr_width-1):0]       adr;
102
   input                         we;
103 7 unneback
   output reg [(data_width-1):0] q;
104 5 unneback
   input                         clk;
105
   reg [data_width-1:0] ram [(1<<addr_width)-1:0];
106 7 unneback
   parameter init = 0;
107
   parameter memory_file = "vl_ram.vmem";
108
   generate if (init) begin : init_mem
109
   initial
110
     begin
111
        $readmemh(memory_file, ram);
112
     end
113
   end
114
   endgenerate
115
 
116 5 unneback
   always @ (posedge clk)
117
   begin
118
   if (we)
119
     ram[adr] <= d;
120
   q <= ram[adr];
121
   end
122
 
123
endmodule
124
 
125 7 unneback
module vl_ram_be ( d, adr, be, we, q, clk);
126
   parameter data_width = 32;
127
   parameter addr_width = 8;
128
   input [(data_width-1):0]      d;
129
   input [(addr_width-1):0]       adr;
130
   input [(addr_width/4)-1:0]    be;
131
   input                         we;
132
   output reg [(data_width-1):0] q;
133
   input                         clk;
134
 
135
   reg [data_width-1:0] ram [(1<<addr_width)-1:0];
136
 
137
   parameter init = 0;
138
   parameter memory_file = "vl_ram.vmem";
139
   generate if (init) begin : init_mem
140
   initial
141
     begin
142
        $readmemh(memory_file, ram);
143
     end
144
   end
145
   endgenerate
146
 
147
   genvar i;
148
   generate for (i=0;i<addr_width/4;i=i+1) begin : be_ram
149
      always @ (posedge clk)
150
      if (we & be[i])
151
        ram[adr][(i+1)*8-1:i*8] <= d[(i+1)*8-1:i*8];
152
   end
153
   endgenerate
154
 
155
   always @ (posedge clk)
156
      q <= ram[adr];
157
 
158
endmodule
159
 
160
 
161 5 unneback
// Dual port RAM
162
 
163
// ACTEL FPGA should not use logic to handle rw collision
164
`ifdef ACTEL
165
        `define SYN /*synthesis syn_ramstyle = "no_rw_check"*/
166
`else
167
        `define SYN
168
`endif
169
 
170 7 unneback
module vl_dpram_1r1w ( d_a, adr_a, we_a, clk_a, q_b, adr_b, clk_b );
171 5 unneback
   parameter data_width = 32;
172
   parameter addr_width = 8;
173
   input [(data_width-1):0]      d_a;
174
   input [(addr_width-1):0]       adr_a;
175
   input [(addr_width-1):0]       adr_b;
176
   input                         we_a;
177
   output [(data_width-1):0]      q_b;
178
   input                         clk_a, clk_b;
179
   reg [(addr_width-1):0]         adr_b_reg;
180
   reg [data_width-1:0] ram [(1<<addr_width)-1:0] `SYN;
181 7 unneback
 
182
   parameter init = 0;
183
   parameter memory_file = "vl_ram.vmem";
184
   generate if (init) begin : init_mem
185
   initial
186
     begin
187
        $readmemh(memory_file, ram);
188
     end
189
   end
190
   endgenerate
191
 
192 5 unneback
   always @ (posedge clk_a)
193
   if (we_a)
194
     ram[adr_a] <= d_a;
195
   always @ (posedge clk_b)
196
   adr_b_reg <= adr_b;
197
   assign q_b = ram[adr_b_reg];
198
endmodule
199
 
200 7 unneback
module vl_dpram_2r1w ( d_a, q_a, adr_a, we_a, clk_a, q_b, adr_b, clk_b );
201 5 unneback
   parameter data_width = 32;
202
   parameter addr_width = 8;
203
   input [(data_width-1):0]      d_a;
204
   input [(addr_width-1):0]       adr_a;
205
   input [(addr_width-1):0]       adr_b;
206
   input                         we_a;
207
   output [(data_width-1):0]      q_b;
208
   output reg [(data_width-1):0] q_a;
209
   input                         clk_a, clk_b;
210
   reg [(data_width-1):0]         q_b;
211
   reg [data_width-1:0] ram [(1<<addr_width)-1:0] `SYN;
212 7 unneback
 
213
   parameter init = 0;
214
   parameter memory_file = "vl_ram.vmem";
215
   generate if (init) begin : init_mem
216
   initial
217
     begin
218
        $readmemh(memory_file, ram);
219
     end
220
   end
221
   endgenerate
222
 
223 5 unneback
   always @ (posedge clk_a)
224
     begin
225
        q_a <= ram[adr_a];
226
        if (we_a)
227
             ram[adr_a] <= d_a;
228
     end
229
   always @ (posedge clk_b)
230
          q_b <= ram[adr_b];
231
endmodule
232
 
233 7 unneback
module vl_dpram_2r2w ( d_a, q_a, adr_a, we_a, clk_a, d_b, q_b, adr_b, we_b, clk_b );
234 5 unneback
   parameter data_width = 32;
235
   parameter addr_width = 8;
236
   input [(data_width-1):0]      d_a;
237
   input [(addr_width-1):0]       adr_a;
238
   input [(addr_width-1):0]       adr_b;
239
   input                         we_a;
240
   output [(data_width-1):0]      q_b;
241
   input [(data_width-1):0]       d_b;
242
   output reg [(data_width-1):0] q_a;
243
   input                         we_b;
244
   input                         clk_a, clk_b;
245
   reg [(data_width-1):0]         q_b;
246
   reg [data_width-1:0] ram [(1<<addr_width)-1:0] `SYN;
247 7 unneback
 
248
   parameter init = 0;
249
   parameter memory_file = "vl_ram.vmem";
250
   generate if (init) begin : init_mem
251
   initial
252
     begin
253
        $readmemh(memory_file, ram);
254
     end
255
   end
256
   endgenerate
257
 
258 5 unneback
   always @ (posedge clk_a)
259
     begin
260
        q_a <= ram[adr_a];
261
        if (we_a)
262
             ram[adr_a] <= d_a;
263
     end
264
   always @ (posedge clk_b)
265
     begin
266
        q_b <= ram[adr_b];
267
        if (we_b)
268
          ram[adr_b] <= d_b;
269
     end
270
endmodule
271
 
272
// Content addresable memory, CAM
273
 
274
// FIFO
275
 
276
module vl_fifo_cmp_async ( wptr, rptr, fifo_empty, fifo_full, wclk, rclk, rst );
277
 
278
   parameter ADDR_WIDTH = 4;
279
   parameter N = ADDR_WIDTH-1;
280
 
281
   parameter Q1 = 2'b00;
282
   parameter Q2 = 2'b01;
283
   parameter Q3 = 2'b11;
284
   parameter Q4 = 2'b10;
285
 
286
   parameter going_empty = 1'b0;
287
   parameter going_full  = 1'b1;
288
 
289
   input [N:0]  wptr, rptr;
290
   output reg   fifo_empty;
291
   output       fifo_full;
292
   input        wclk, rclk, rst;
293
 
294
`ifndef GENERATE_DIRECTION_AS_LATCH
295
   wire direction;
296
`endif
297
`ifdef GENERATE_DIRECTION_AS_LATCH
298
   reg direction;
299
`endif
300
   reg  direction_set, direction_clr;
301
 
302
   wire async_empty, async_full;
303
   wire fifo_full2;
304
   reg  fifo_empty2;
305
 
306
   // direction_set
307
   always @ (wptr[N:N-1] or rptr[N:N-1])
308
     case ({wptr[N:N-1],rptr[N:N-1]})
309
       {Q1,Q2} : direction_set <= 1'b1;
310
       {Q2,Q3} : direction_set <= 1'b1;
311
       {Q3,Q4} : direction_set <= 1'b1;
312
       {Q4,Q1} : direction_set <= 1'b1;
313
       default : direction_set <= 1'b0;
314
     endcase
315
 
316
   // direction_clear
317
   always @ (wptr[N:N-1] or rptr[N:N-1] or rst)
318
     if (rst)
319
       direction_clr <= 1'b1;
320
     else
321
       case ({wptr[N:N-1],rptr[N:N-1]})
322
         {Q2,Q1} : direction_clr <= 1'b1;
323
         {Q3,Q2} : direction_clr <= 1'b1;
324
         {Q4,Q3} : direction_clr <= 1'b1;
325
         {Q1,Q4} : direction_clr <= 1'b1;
326
         default : direction_clr <= 1'b0;
327
       endcase
328
 
329
`ifndef GENERATE_DIRECTION_AS_LATCH
330
    dff_sr dff_sr_dir( .aclr(direction_clr), .aset(direction_set), .clock(1'b1), .data(1'b1), .q(direction));
331
`endif
332
 
333
`ifdef GENERATE_DIRECTION_AS_LATCH
334
   always @ (posedge direction_set or posedge direction_clr)
335
     if (direction_clr)
336
       direction <= going_empty;
337
     else
338
       direction <= going_full;
339
`endif
340
 
341
   assign async_empty = (wptr == rptr) && (direction==going_empty);
342
   assign async_full  = (wptr == rptr) && (direction==going_full);
343
 
344
    dff_sr dff_sr_empty0( .aclr(rst), .aset(async_full), .clock(wclk), .data(async_full), .q(fifo_full2));
345
    dff_sr dff_sr_empty1( .aclr(rst), .aset(async_full), .clock(wclk), .data(fifo_full2), .q(fifo_full));
346
 
347
/*
348
   always @ (posedge wclk or posedge rst or posedge async_full)
349
     if (rst)
350
       {fifo_full, fifo_full2} <= 2'b00;
351
     else if (async_full)
352
       {fifo_full, fifo_full2} <= 2'b11;
353
     else
354
       {fifo_full, fifo_full2} <= {fifo_full2, async_full};
355
*/
356
   always @ (posedge rclk or posedge async_empty)
357
     if (async_empty)
358
       {fifo_empty, fifo_empty2} <= 2'b11;
359
     else
360
       {fifo_empty,fifo_empty2} <= {fifo_empty2,async_empty};
361
 
362
endmodule // async_comp
363
 
364
module vl_fifo_1r1w_async (
365
    d, wr, fifo_full, wr_clk, wr_rst,
366
    q, rd, fifo_empty, rd_clk, rd_rst
367
    );
368
 
369
parameter data_width = 18;
370
parameter addr_width = 4;
371
 
372
// write side
373
input  [data_width-1:0] d;
374
input                   wr;
375
output                  fifo_full;
376
input                   wr_clk;
377
input                   wr_rst;
378
// read side
379
output [data_width-1:0] q;
380
input                   rd;
381
output                  fifo_empty;
382
input                   rd_clk;
383
input                   rd_rst;
384
 
385
wire [addr_width:1] wadr, wadr_bin, radr, radr_bin;
386
 
387
vl_fifo_1r1w_async (
388
    d, wr, fifo_full, wr_clk, wr_rst,
389
    q, rd, fifo_empty, rd_clk, rd_rst
390
    );
391
 
392 7 unneback
cnt_gray_ce_bin
393 5 unneback
    # ( .length(addr_width))
394
    fifo_wr_adr( .cke(wr), .q(wadr), .q_bin(wadr_bin), .rst(wr_rst), .clk(wr_clk));
395
 
396 7 unneback
cnt_gray_ce_bin
397 5 unneback
    # (.length(addr_width))
398
    fifo_rd_adr( .cke(wr), .q(radr), .q_bin(radr_bin), .rst(rd_rst), .clk(rd_rst));
399
 
400 7 unneback
vl_dpram_1r1w
401 5 unneback
    # (.data_width(data_width), .addr_width(addr_width))
402
    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));
403
 
404
vl_fifo_cmp_async
405
    # (.addr_width(addr_width))
406
    cmp ( .wptr(wadr), .rptr(radr), .fifo_empty(fifo_empty), .fifo_full(fifo_full), .wclk(wr_clk), .rclk(rd_clk), .rst(wr_rst) );
407
 
408
endmodule
409
 
410 7 unneback
module vl_fifo_2r2w_async (
411 5 unneback
    // a side
412
    a_d, a_wr, a_fifo_full,
413
    a_q, a_rd, a_fifo_empty,
414
    a_clk, a_rst,
415
    // b side
416
    b_d, b_wr, b_fifo_full,
417
    b_q, b_rd, b_fifo_empty,
418
    b_clk, b_rst
419
    );
420
 
421
parameter data_width = 18;
422
parameter addr_width = 4;
423
 
424
// a side
425
input  [data_width-1:0] a_d;
426
input                   a_wr;
427
output                  a_fifo_full;
428
output [data_width-1:0] a_q;
429
input                   a_rd;
430
output                  a_fifo_empty;
431
input                   a_clk;
432
input                   a_rst;
433
 
434
// b side
435
input  [data_width-1:0] b_d;
436
input                   b_wr;
437
output                  b_fifo_full;
438
output [data_width-1:0] b_q;
439
input                   b_rd;
440
output                  b_fifo_empty;
441
input                   b_clk;
442
input                   b_rst;
443
 
444
vl_fifo_1r1w_async # (.data_width(data_width), .addr_width(addr_width))
445
vl_fifo_1r1w_async_a (
446
    .d(a_d), .wr(a_wr), .fifo_full(a_fifo_full), .wr_clk(a_clk), .wr_rst(a_rst),
447
    .q(b_q), .rd(b_rd), .fifo_empty(b_fifo_empty), .rd_clk(b_clk), .rd_rst(b_rst)
448
    );
449
 
450
vl_fifo_1r1w_async # (.data_width(data_width), .addr_width(addr_width))
451
vl_fifo_1r1w_async_b (
452
    .d(b_d), .wr(b_wr), .fifo_full(b_fifo_full), .wr_clk(b_clk), .wr_rst(b_rst),
453
    .q(a_q), .rd(a_rd), .fifo_empty(a_fifo_empty), .rd_clk(a_clk), .rd_rst(a_rst)
454
    );
455
 
456
endmodule
457
 
458 7 unneback
module vl_fifo_2r2w_async_simplex (
459 5 unneback
    // a side
460
    a_d, a_wr, a_fifo_full,
461
    a_q, a_rd, a_fifo_empty,
462
    a_clk, a_rst,
463
    // b side
464
    b_d, b_wr, b_fifo_full,
465
    b_q, b_rd, b_fifo_empty,
466
    b_clk, b_rst
467
    );
468
 
469
parameter data_width = 18;
470
parameter addr_width = 4;
471
 
472
// a side
473
input  [data_width-1:0] a_d;
474
input                   a_wr;
475
output                  a_fifo_full;
476
output [data_width-1:0] a_q;
477
input                   a_rd;
478
output                  a_fifo_empty;
479
input                   a_clk;
480
input                   a_rst;
481
 
482
// b side
483
input  [data_width-1:0] b_d;
484
input                   b_wr;
485
output                  b_fifo_full;
486
output [data_width-1:0] b_q;
487
input                   b_rd;
488
output                  b_fifo_empty;
489
input                   b_clk;
490
input                   b_rst;
491
 
492
// adr_gen
493
wire [addr_width:1] a_wadr, a_wadr_bin, a_radr, a_radr_bin;
494
wire [addr_width:1] b_wadr, b_wadr_bin, b_radr, b_radr_bin;
495
// dpram
496
wire [addr_width:0] a_dpram_adr, b_dpram_adr;
497
 
498 7 unneback
cnt_gray_ce_bin
499 5 unneback
    # ( .length(addr_width))
500
    fifo_a_wr_adr( .cke(a_wr), .q(a_wadr), .q_bin(a_wadr_bin), .rst(a_rst), .clk(a_clk));
501
 
502 7 unneback
cnt_gray_ce_bin
503 5 unneback
    # (.length(addr_width))
504
    fifo_a_rd_adr( .cke(a_rd), .q(a_radr), .q_bin(a_radr_bin), .rst(a_rst), .clk(a_clk));
505
 
506 7 unneback
cnt_gray_ce_bin
507 5 unneback
    # ( .length(addr_width))
508
    fifo_b_wr_adr( .cke(b_wr), .q(b_wadr), .q_bin(b_wadr_bin), .rst(b_rst), .clk(b_clk));
509
 
510 7 unneback
cnt_gray_ce_bin
511 5 unneback
    # (.length(addr_width))
512
    fifo_b_rd_adr( .cke(b_rd), .q(b_radr), .q_bin(b_radr_bin), .rst(b_rst), .clk(b_clk));
513
 
514
// mux read or write adr to DPRAM
515
assign a_dpram_adr = (a_wr) ? {1'b0,a_wadr_bin} : {1'b1,a_radr_bin};
516
assign b_dpram_adr = (b_wr) ? {1'b1,b_wadr_bin} : {1'b0,b_radr_bin};
517
 
518 7 unneback
vl_dp_ram_2r2w
519 5 unneback
    # (.data_width(data_width), .addr_width(addr_width+1))
520
    dpram ( .d_a(a_d), .q_a(a_q), .adr_a(a_dpram_adr), .we_a(a_wr), .clk_a(a_clk),
521
            .d_b(b_d), .q_b(b_q), .adr_b(b_dpram_adr), .we_b(b_wr), .clk_b(b_clk));
522
 
523
vl_fifo_async_cmp
524
    # (.addr_width(addr_width))
525
    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) );
526
 
527 7 unneback
vl_fifo_async_cmp
528 5 unneback
    # (.addr_width(addr_width))
529
    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) );
530
 
531
endmodule

powered by: WebSVN 2.1.0

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