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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [mp3/] [lib/] [xilinx/] [coregen/] [XilinxCoreLib/] [blkmemdp_v3_0.v] - Blame information for rev 266

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

Line No. Rev Author Line
1 266 lampret
/**************************************************************************
2
 * $Id: blkmemdp_v3_0.v,v 1.1.1.1 2001-11-04 19:00:07 lampret Exp $
3
 **************************************************************************
4
 * Dual Port Block Memory - Verilog Behavioral Model
5
 * ************************************************************************
6
 *
7
 *
8
 * This File is owned and controlled by Xilinx and must be used solely
9
 * for design, simulation, implementation and creation of design files
10
 * limited to Xilinx devices or technologies. Use with non-Xilinx
11
 * devices or technologies is expressly prohibited and immediately
12
 * terminates your license.
13
 *
14
 * Xilinx products are not intended for use in life support
15
 * appliances, devices, or systems. Use in such applications is
16
 * expressly prohibited.
17
 *
18
 *        ****************************
19
 *        ** Copyright Xilinx, Inc. **
20
 *        ** All rights reserved.   **
21
 *        ****************************
22
 *
23
 *
24
 *************************************************************************
25
 * Filename:    BLKMEMDP_V3_0.v
26
 *
27
 * Description: The Verilog behavioral model for the Dual Port Block Memory
28
 *
29
 * ***********************************************************************
30
 */
31
 
32
 
33
`celldefine
34
 
35
 
36
`define c_dp_rom 4
37
`define c_dp_ram 2
38
`define c_write_first 0
39
`define c_read_first  1
40
`define c_no_change   2
41
 
42
module BLKMEMDP_V3_0(DOUTA, DOUTB, ADDRA, CLKA, DINA, ENA, SINITA, WEA, NDA, RFDA, RDYA, ADDRB, CLKB, DINB, ENB, SINITB, WEB,NDB, RFDB, RDYB);
43
 
44
 
45
 
46
  parameter  c_addra_width         =  11 ;
47
  parameter  c_addrb_width         =  9 ;
48
  parameter  c_default_data        = "0"; // indicates string of hex characters used to initialize memory
49
  parameter  c_depth_a             = 2048 ;
50
  parameter  c_depth_b             = 512 ;
51
  parameter  c_enable_rlocs        = 0 ; //  core includes placement constraints
52
  parameter  c_has_default_data    =  1;
53
  parameter  c_has_dina            = 1  ;  // indicate port A has data input pins
54
  parameter  c_has_dinb            = 1  ;  // indicate port B has data input pins
55
  parameter  c_has_douta           = 1 ; // indicates port A has  output
56
  parameter  c_has_doutb           = 1 ; // indicates port B has  output
57
  parameter  c_has_ena             =  1 ; // indicates port A has a ENA pin
58
  parameter  c_has_enb             =  1 ; // indicates port B has a ENB pin
59
  parameter  c_has_limit_data_pitch       = 1 ;
60
  parameter  c_has_nda             = 0 ; //  Port A has a new data pin
61
  parameter  c_has_ndb             = 0 ; //  Port B has a new data pin
62
  parameter  c_has_rdya            = 0 ; //  Port A has result ready pin
63
  parameter  c_has_rdyb            = 0 ; //  Port B has result ready pin
64
  parameter  c_has_rfda            = 0 ; //  Port A has ready for data pin
65
  parameter  c_has_rfdb            = 0 ; //  Port B has ready for data pin
66
  parameter  c_has_sinita          =  1 ; // indicates port A has a SINITA pin
67
  parameter  c_has_sinitb          =  1 ; // indicates port B has a SINITB pin
68
  parameter  c_has_wea             =  1 ; // indicates port A has a WEA pin
69
  parameter  c_has_web             =  1 ; // indicates port B has a WEB pin
70
  parameter  c_limit_data_pitch           = 16 ;
71
  parameter  c_mem_init_file     =  "null.mif";  // controls which .mif file used to initialize memory
72
  parameter  c_pipe_stages_a       =  0 ; // indicates the number of pipe stages needed in port A
73
  parameter  c_pipe_stages_b       =  0 ; // indicates the number of pipe stages needed in port B
74
  parameter  c_reg_inputsa         = 0 ; // indicates we, addr, and din of port A are registered
75
  parameter  c_reg_inputsb         = 0 ; // indicates we, addr, and din of port B are registered
76
  parameter  c_sinita_value        = "0000"; // indicates string of hex used to initialize A output registers
77
  parameter  c_sinitb_value        = "0000"; // indicates string of hex used to initialize B output resisters
78
  parameter  c_width_a             =  8 ;
79
  parameter  c_width_b             = 32 ;
80
  parameter  c_write_modea        = 2; // controls which write modes shall be used
81
  parameter  c_write_modeb        = 2; // controls which write modes shall be used
82
 
83
 
84
 
85
 
86
// IO ports
87
 
88
 
89
 
90
    output [c_width_a-1:0] DOUTA;
91
 
92
    input [c_addra_width-1:0] ADDRA;
93
    input [c_width_a-1:0] DINA;
94
    input ENA, CLKA, WEA, SINITA, NDA;
95
    output RFDA, RDYA;
96
 
97
    output [c_width_b-1:0] DOUTB;
98
 
99
    input [c_addrb_width-1:0] ADDRB;
100
    input [c_width_b-1:0] DINB;
101
    input ENB, CLKB, WEB, SINITB, NDB;
102
    output RFDB, RDYB;
103
 
104
 
105
// internal signals
106
 
107
    reg [c_width_a-1:0] douta_mux_out ; // output of multiplexer --
108
    wire [c_width_a-1:0] DOUTA = douta_mux_out;
109
    reg  RFDA, RDYA ;
110
 
111
    reg [c_width_b-1:0] doutb_mux_out ; // output of multiplexer --
112
    wire [c_width_b-1:0] DOUTB = doutb_mux_out;
113
    reg RFDB, RDYB;
114
 
115
 
116
    reg [c_width_a-1:0] douta_out_q; // registered output of douta_out
117
    reg [c_width_a-1:0] doa_out;  // output of Port A RAM
118
    reg [c_width_a-1:0] douta_out; // output of pipeline mux for port A
119
 
120
    reg [c_width_b-1:0] doutb_out_q ; // registered output for doutb_out
121
    reg [c_width_b-1:0] dob_out; // output of Port B RAM
122
    reg [c_width_b-1:0] doutb_out ; // output of pipeline mux for port B
123
 
124
    reg [c_depth_a*c_width_a-1 : 0] mem;
125
    reg [24:0] count ;
126
    reg [1:0] wr_mode_a, wr_mode_b;
127
 
128
    reg [(c_width_a-1) : 0]  pipelinea [0 : c_pipe_stages_a];
129
    reg [(c_width_b-1) : 0]  pipelineb [0 : c_pipe_stages_b];
130
    reg sub_rdy_a[0 : c_pipe_stages_a];
131
    reg sub_rdy_b[0 : c_pipe_stages_b];
132
 
133
    reg [10:0] ci, cj;
134
    reg [10:0] dmi, dmj, dni, dnj, doi, doj, dai, daj, dbi, dbj, dci, dcj, ddi, ddj;
135
    reg [10:0] pmi, pmj, pni, pnj, poi, poj, pai, paj, pbi, pbj, pci, pcj, pdi, pdj;
136
    integer ai, aj, ak, al, am, an, ap ;
137
    integer bi, bj, bk, bl, bm, bn, bp ;
138
    integer i, j, k, l, m, n, p;
139
 
140
    wire [c_addra_width-1:0] addra_i = ADDRA;
141
    reg [c_width_a-1:0] dia_int ;
142
    reg [c_width_a-1:0] dia_q ;
143
    wire [c_width_a-1:0] dia_i ;
144
    wire ena_int  ;
145
    reg ena_q ;
146
    wire clka_int = CLKA  ;
147
    reg wea_int  ;
148
    wire wea_i  ;
149
    reg wea_q ;
150
    wire ssra_int  ;
151
    wire nda_int ;
152
    wire nda_i ;
153
    reg rfda_int ;
154
    reg rdya_int ;
155
    reg nda_q ;
156
    reg new_data_a ;
157
    reg new_data_a_q ;
158
    reg [c_addra_width-1:0] addra_q;
159
    reg [c_addra_width-1:0] addra_int;
160
    reg [c_width_a-1:0] sinita_value ; // initialization value for output registers of Port A
161
 
162
    wire [c_addrb_width-1:0] addrb_i = ADDRB;
163
    reg [c_width_b-1:0] dib_int ;
164
    reg [c_width_b-1:0] dib_q ;
165
    wire [c_width_b-1:0] dib_i ;
166
    wire enb_int ;
167
    reg enb_q ;
168
    wire clkb_int = CLKB  ;
169
    reg web_int  ;
170
    wire web_i ;
171
    reg web_q ;
172
    wire ssrb_int  ;
173
    wire ndb_int ;
174
    wire ndb_i ;
175
    reg rfdb_int ;
176
    reg rdyb_int ;
177
    reg ndb_q ;
178
    reg new_data_b ;
179
    reg new_data_b_q ;
180
    reg [c_addrb_width-1:0] addrb_q ;
181
    reg [c_addrb_width-1:0] addrb_int ;
182
    reg [c_width_b-1:0] sinitb_value ; // initialization value for output registers of Port B
183
 
184
//  variables used to initialize memory contents to default values.
185
 
186
    reg [c_width_a-1:0] bitval ;
187
    reg [c_width_a-1:0] ram_temp [0:c_depth_a-1] ;
188
    reg [c_width_a-1:0] default_data ;
189
 
190
//  variables used to detect address collision on dual port Rams
191
 
192
    reg recovery_a, recovery_b;
193
    reg address_collision;
194
 
195
    wire clka_enable = ena_int && wea_int && enb_int && address_collision;
196
    wire clkb_enable = enb_int && web_int && ena_int && address_collision;
197
    wire collision = clka_enable || clkb_enable;
198
 
199
//   tri0 GSR = glbl.GSR;
200
 
201
    assign dia_i    = (c_has_dina === 1)?DINA:'b0;
202
    assign ena_int  = defval(ENA, c_has_ena, 1);
203
    assign ssra_int = defval( SINITA , c_has_sinita , 0);
204
    assign nda_i  = defval( NDA, c_has_nda, 1);
205
    assign dib_i    = (c_has_dinb === 1)?DINB:'b0;
206
    assign enb_int  = defval(ENB, c_has_enb, 1);
207
    assign ssrb_int = defval( SINITB, c_has_sinitb, 0);
208
    assign ndb_i = defval( NDB, c_has_ndb, 1);
209
 
210
// RAM/ROM functionality
211
 
212
    assign wea_i = (c_has_wea == 1)  ? WEA:1'b0 ;
213
    assign web_i = (c_has_web == 1)  ? WEB:1'b0 ;
214
 
215
 
216
 
217
    function defval;
218
      input i;
219
      input hassig;
220
      input val;
221
            begin
222
                   if(hassig == 1)
223
                           defval = i;
224
                   else
225
                           defval = val;
226
            end
227
    endfunction
228
 
229
    function max;
230
      input a;
231
      input b;
232
        begin
233
                max = (a > b) ? a : b;
234
        end
235
    endfunction
236
 
237
    function a_is_X;
238
      input [c_width_a-1 : 0] i;
239
      integer j ;
240
        begin
241
                a_is_X = 1'b0;
242
                for(j = 0; j < c_width_a; j = j + 1)
243
                begin
244
                        if(i[j] === 1'bx)
245
                                a_is_X = 1'b1;
246
                end // loop
247
        end
248
    endfunction
249
 
250
    function b_is_X;
251
      input [c_width_b-1 : 0] i;
252
      integer j ;
253
        begin
254
                b_is_X = 1'b0;
255
                for(j = 0; j < c_width_b; j = j + 1)
256
                begin
257
                        if(i[j] === 1'bx)
258
                                b_is_X = 1'b1;
259
                end // loop
260
        end
261
    endfunction
262
 
263
  function [c_width_a-1:0] hexstr_conv;
264
    input [(c_width_a*8)-1:0] def_data;
265
 
266
    integer index,i,j;
267
    reg [3:0] bin;
268
 
269
    begin
270
      index = 0;
271
      hexstr_conv = 'b0;
272
      for( i=c_width_a-1; i>=0; i=i-1 )
273
      begin
274
        case (def_data[7:0])
275
          8'b00000000 :
276
          begin
277
            bin = 4'b0000;
278
            i = -1;
279
          end
280
          8'b00110000 : bin = 4'b0000;
281
          8'b00110001 : bin = 4'b0001;
282
          8'b00110010 : bin = 4'b0010;
283
          8'b00110011 : bin = 4'b0011;
284
          8'b00110100 : bin = 4'b0100;
285
          8'b00110101 : bin = 4'b0101;
286
          8'b00110110 : bin = 4'b0110;
287
          8'b00110111 : bin = 4'b0111;
288
          8'b00111000 : bin = 4'b1000;
289
          8'b00111001 : bin = 4'b1001;
290
          8'b01000001 : bin = 4'b1010;
291
          8'b01000010 : bin = 4'b1011;
292
          8'b01000011 : bin = 4'b1100;
293
          8'b01000100 : bin = 4'b1101;
294
          8'b01000101 : bin = 4'b1110;
295
          8'b01000110 : bin = 4'b1111;
296
          8'b01100001 : bin = 4'b1010;
297
          8'b01100010 : bin = 4'b1011;
298
          8'b01100011 : bin = 4'b1100;
299
          8'b01100100 : bin = 4'b1101;
300
          8'b01100101 : bin = 4'b1110;
301
          8'b01100110 : bin = 4'b1111;
302
          default :
303
          begin
304
            $display("ERROR : NOT A HEX CHARACTER");
305
            bin = 4'bx;
306
          end
307
        endcase
308
        for( j=0; j<4; j=j+1)
309
        begin
310
          if ((index*4)+j < c_width_a)
311
          begin
312
            hexstr_conv[(index*4)+j] = bin[j];
313
          end
314
        end
315
        index = index + 1;
316
        def_data = def_data >> 8;
317
      end
318
    end
319
  endfunction
320
 
321
  function [c_width_b-1:0] hexstr_conv_b;
322
    input [(c_width_b*8)-1:0] def_data;
323
 
324
    integer index,i,j;
325
    reg [3:0] bin;
326
 
327
    begin
328
      index = 0;
329
      hexstr_conv_b = 'b0;
330
      for( i=c_width_b-1; i>=0; i=i-1 )
331
      begin
332
        case (def_data[7:0])
333
          8'b00000000 :
334
          begin
335
            bin = 4'b0000;
336
            i = -1;
337
          end
338
          8'b00110000 : bin = 4'b0000;
339
          8'b00110001 : bin = 4'b0001;
340
          8'b00110010 : bin = 4'b0010;
341
          8'b00110011 : bin = 4'b0011;
342
          8'b00110100 : bin = 4'b0100;
343
          8'b00110101 : bin = 4'b0101;
344
          8'b00110110 : bin = 4'b0110;
345
          8'b00110111 : bin = 4'b0111;
346
          8'b00111000 : bin = 4'b1000;
347
          8'b00111001 : bin = 4'b1001;
348
          8'b01000001 : bin = 4'b1010;
349
          8'b01000010 : bin = 4'b1011;
350
          8'b01000011 : bin = 4'b1100;
351
          8'b01000100 : bin = 4'b1101;
352
          8'b01000101 : bin = 4'b1110;
353
          8'b01000110 : bin = 4'b1111;
354
          8'b01100001 : bin = 4'b1010;
355
          8'b01100010 : bin = 4'b1011;
356
          8'b01100011 : bin = 4'b1100;
357
          8'b01100100 : bin = 4'b1101;
358
          8'b01100101 : bin = 4'b1110;
359
          8'b01100110 : bin = 4'b1111;
360
          default :
361
          begin
362
            $display("ERROR : NOT A HEX CHARACTER");
363
            bin = 4'bx;
364
          end
365
        endcase
366
        for( j=0; j<4; j=j+1)
367
        begin
368
          if ((index*4)+j < c_width_b)
369
          begin
370
            hexstr_conv_b[(index*4)+j] = bin[j];
371
          end
372
        end
373
        index = index + 1;
374
        def_data = def_data >> 8;
375
      end
376
    end
377
  endfunction
378
 
379
 
380
 
381
 
382
 
383
//  Initialize memory contents to 0 for now . 
384
 
385
    initial begin
386
 
387
        sinita_value = 'b0 ;
388
        sinitb_value = 'b0 ;
389
 
390
             default_data = hexstr_conv(c_default_data);
391
        if (c_has_sinita == 1 )
392
             sinita_value = hexstr_conv(c_sinita_value);
393
        if (c_has_sinitb == 1 )
394
             sinitb_value = hexstr_conv_b(c_sinitb_value);
395
            for(i = 0; i < c_depth_a; i = i + 1)
396
              ram_temp[i] = default_data;
397
       if (c_has_default_data == 0)
398
          $readmemb(c_mem_init_file, ram_temp) ;
399
 
400
        for(i = 0; i < c_depth_a; i = i + 1)
401
           for(j = 0; j < c_width_a; j = j + 1)
402
              begin
403
                 bitval = (1'b1 << j);
404
                 mem[(i*c_width_a) + j] = (ram_temp[i] & bitval) >> j;
405
              end
406
        recovery_a = 0;
407
        recovery_b = 0;
408
        for (k = 0; k <= c_pipe_stages_a; k = k + 1)
409
            pipelinea[k] = sinita_value ;
410
        for (l = 0; l <= c_pipe_stages_b; l = l + 1)
411
            pipelineb[l] = sinitb_value ;
412
        for (m = 0; m <= c_pipe_stages_a; m = m + 1)
413
            sub_rdy_a[m] = 0 ;
414
        for (n = 0; n <= c_pipe_stages_b; n = n + 1)
415
            sub_rdy_b[n] = 0 ;
416
        doa_out = sinita_value ;
417
        dob_out = sinitb_value ;
418
        nda_q = 0;
419
        ndb_q = 0;
420
        new_data_a_q = 0 ;
421
        new_data_b_q = 0 ;
422
        dia_q = 0;
423
        dib_q = 0;
424
        addra_q = 0;
425
        addrb_q = 0;
426
        wea_q   = 0;
427
        web_q   = 0;
428
    end
429
 
430
 
431
    always @(addra_int or addrb_int) begin  //  check address collision
432
        address_collision <= 1'b0;
433
        for (ci = 0; ci < c_width_a; ci = ci + 1) begin // absolute address A
434
            for (cj = 0; cj < c_width_b; cj = cj + 1) begin // absolute address B
435
                if ((addra_int * c_width_a + ci) == (addrb_int * c_width_b + cj)) begin
436
                    address_collision <= 1'b1;
437
                end
438
            end
439
        end
440
    end
441
 
442
    // Data
443
    always @(posedge recovery_a or posedge recovery_b) begin
444
        if (((wr_mode_a == 2'b01) && (wr_mode_b == 2'b01)) ||
445
            ((wr_mode_a != 2'b01) && (wr_mode_b != 2'b01))) begin
446
            if (wea_int == 1 && web_int == 1) begin
447
              if (addra_int < c_depth_a)
448
                for (dmi = 0; dmi < c_width_a; dmi = dmi + 1) begin
449
                    for (dmj = 0; dmj < c_width_b; dmj = dmj + 1) begin
450
                        if ((addra_int * c_width_a + dmi) == (addrb_int * c_width_b + dmj)) begin
451
                            mem[addra_int * c_width_a + dmi] <= 1'bX;
452
                        end
453
                    end
454
                end
455
              else
456
                $display("Warning : Memory out of range");
457
            end
458
        end
459
        recovery_a <= 0;
460
        recovery_b <= 0;
461
    end
462
 
463
    always @(posedge recovery_a or posedge recovery_b) begin
464
        if ((wr_mode_a == 2'b01) && (wr_mode_b != 2'b01)) begin
465
            if (wea_int == 1 && web_int == 1) begin
466
              if (addra_int < c_depth_a)
467
                for (dni = 0; dni < c_width_a; dni = dni + 1) begin
468
                    for (dnj = 0; dnj < c_width_b; dnj = dnj + 1) begin
469
                        if ((addra_int * c_width_a + dni) == (addrb_int * c_width_b + dnj)) begin
470
                            mem[addra_int * c_width_a + dni] <= dia_int[dni];
471
                        end
472
                    end
473
                end
474
              else
475
                $display("Warning : Memory out of range");
476
            end
477
        end
478
    end
479
 
480
    always @(posedge recovery_a or posedge recovery_b) begin
481
        if ((wr_mode_a != 2'b01) && (wr_mode_b == 2'b01)) begin
482
            if (wea_int == 1 && web_int == 1) begin
483
              if (addrb_int < c_depth_b)
484
                for (doi = 0; doi < c_width_a; doi = doi + 1) begin
485
                    for (doj = 0; doj < c_width_b; doj = doj + 1) begin
486
                        if ((addra_int * c_width_a + doi) == (addrb_int * c_width_b + doj)) begin
487
                            mem[addrb_int * c_width_b + doj] <= dib_int[doj];
488
                        end
489
                    end
490
                end
491
              else
492
                $display("Warning : Memory out of range");
493
            end
494
        end
495
    end
496
 
497
    always @(posedge recovery_a or posedge recovery_b) begin
498
        if ((wr_mode_b == 2'b00) || (wr_mode_b == 2'b10)) begin
499
            if ((wea_int == 0) && (web_int == 1) && (ssra_int == 0)) begin
500
              if (addra_int < c_depth_a)
501
                for (dai = 0; dai < c_width_a; dai = dai + 1) begin
502
                    for (daj = 0; daj < c_width_b; daj = daj + 1) begin
503
                        if ((addra_int * c_width_a + dai) == (addrb_int * c_width_b + daj)) begin
504
                            doa_out[dai] <= 1'bX;
505
                        end
506
                    end
507
                end
508
              else
509
                $display("Warning : Memory out of range");
510
            end
511
        end
512
    end
513
 
514
    always @(posedge recovery_a or posedge recovery_b) begin
515
        if ((wr_mode_a == 2'b00) || (wr_mode_a == 2'b10)) begin
516
            if ((wea_int == 1) && (web_int == 0) && (ssrb_int == 0)) begin
517
              if (addrb_int < c_depth_b)
518
                for (dbi = 0; dbi < c_width_a; dbi = dbi + 1) begin
519
                    for (dbj = 0; dbj < c_width_b; dbj = dbj + 1) begin
520
                        if ((addra_int * c_width_a + dbi) == (addrb_int * c_width_b + dbj)) begin
521
                            dob_out[dbj] <= 1'bX;
522
                        end
523
                    end
524
                end
525
              else
526
                $display("Warning : Memory out of range");
527
            end
528
        end
529
    end
530
 
531
    always @(posedge recovery_a or posedge recovery_b) begin
532
        if (((wr_mode_a == 2'b00) && (wr_mode_b == 2'b00)) ||
533
            ((wr_mode_a != 2'b10) && (wr_mode_b == 2'b10)) ||
534
            ((wr_mode_a == 2'b01) && (wr_mode_b == 2'b00))) begin
535
            if ((wea_int == 1) && (web_int == 1) && (ssra_int == 0)) begin
536
              if (addra_int < c_depth_a)
537
                for (dci = 0; dci < c_width_a; dci = dci + 1) begin
538
                    for (dcj = 0; dcj < c_width_b; dcj = dcj + 1) begin
539
                        if ((addra_int * c_width_a + dci) == (addrb_int * c_width_b + dcj)) begin
540
                            doa_out[dci] <= 1'bX;
541
                        end
542
                    end
543
                end
544
              else
545
                $display("Warning : Memory out of range");
546
            end
547
        end
548
    end
549
 
550
    always @(posedge recovery_a or posedge recovery_b) begin
551
        if (((wr_mode_a == 2'b00) && (wr_mode_b == 2'b00)) ||
552
            ((wr_mode_a == 2'b10) && (wr_mode_b != 2'b10)) ||
553
            ((wr_mode_a == 2'b00) && (wr_mode_b == 2'b01))) begin
554
            if ((wea_int == 1) && (web_int == 1) && (ssrb_int == 0)) begin
555
              if (addrb_int < c_depth_b)
556
                for (ddi = 0; ddi < c_width_a; ddi = ddi + 1) begin
557
                    for (ddj = 0; ddj < c_width_b; ddj = ddj + 1) begin
558
                        if ((addra_int * c_width_a + ddi) == (addrb_int * c_width_b + ddj)) begin
559
                            dob_out[ddj] <= 1'bX;
560
                        end
561
                    end
562
                end
563
              else
564
                $display("Warning : Memory out of range");
565
            end
566
        end
567
    end
568
 
569
 //   Parity Section is deleted
570
 
571
    initial begin
572
        case (c_write_modea)
573
            `c_write_first : wr_mode_a <= 2'b00;
574
            `c_read_first  : wr_mode_a <= 2'b01;
575
            `c_no_change   : wr_mode_a <= 2'b10;
576
            default       : begin
577
                                $display("Error : c_write_modea = %s is not WRITE_FIRST, READ_FIRST or NO_CHANGE.", c_write_modea);
578
                                $finish;
579
                            end
580
        endcase
581
    end
582
 
583
    initial begin
584
        case (c_write_modeb)
585
            `c_write_first : wr_mode_b <= 2'b00;
586
            `c_read_first  : wr_mode_b <= 2'b01;
587
            `c_no_change   : wr_mode_b <= 2'b10;
588
            default       : begin
589
                                $display("Error : c_write_modeb = %s is not WRITE_FIRST, READ_FIRST or NO_CHANGE.", c_write_modeb);
590
                                $finish;
591
                            end
592
        endcase
593
    end
594
 
595
// Port A
596
 
597
 
598
// Generate ouput control signals for Port A: RFDA and RDYA
599
 
600
    always @ (rfda_int or rdya_int)
601
    begin
602
       if (c_has_rfda == 1)
603
          RFDA = rfda_int ;
604
       else
605
          RFDA = 1'b0 ;
606
 
607
       if ((c_has_rdya == 1) && (c_has_nda == 1) && (c_has_rfda == 1) )
608
          RDYA  = rdya_int;
609
       else
610
          RDYA  = 1'b0 ;
611
    end
612
 
613
    always @ (ena_int )
614
    begin
615
       if (ena_int == 1'b1)
616
          rfda_int <= 1'b1 ;
617
       else
618
          rfda_int <= 1'b0 ;
619
    end
620
 
621
// Gate nd signal with en     
622
 
623
   assign nda_int = ena_int && nda_i ;
624
 
625
// Register hanshaking signals for port A
626
 
627
    always @ (posedge clka_int)
628
    begin
629
       if (ena_int == 1'b1)
630
          begin
631
              if (ssra_int == 1'b1)
632
                 nda_q <= 1'b0 ;
633
              else
634
                 nda_q <= nda_int ;
635
          end
636
       else
637
          nda_q  <= nda_q ;
638
    end
639
 
640
// Register data/ address / we inputs for port A
641
 
642
    always @ (posedge clka_int)
643
    begin
644
      if (ena_int == 1'b1)
645
         begin
646
          dia_q  <= dia_i ;
647
          addra_q <= addra_i ;
648
          wea_q  <= wea_i ;
649
      end
650
    end
651
 
652
 
653
// Select registered or non-registered write enable for Port A
654
 
655
   always @ ( wea_i or wea_q )
656
   begin
657
      if (c_reg_inputsa == 1)
658
         wea_int = wea_q ;
659
      else
660
         wea_int = wea_i ;
661
   end
662
 
663
// Select registered or non-registered  data/address/nd inputs for Port A
664
 
665
    always @ ( dia_i or dia_q )
666
    begin
667
         if ( c_reg_inputsa == 1)
668
            dia_int = dia_q;
669
         else
670
            dia_int = dia_i;
671
    end
672
 
673
    always @ ( addra_i or addra_q or nda_q or nda_int )
674
    begin
675
         if ( c_reg_inputsa == 1)
676
            begin
677
                addra_int = addra_q ;
678
                new_data_a = nda_q ;
679
            end
680
         else
681
            begin
682
                addra_int = addra_i;
683
                new_data_a = nda_int ;
684
            end
685
    end
686
 
687
// Register the new_data signal for Port A to track the synchronous RAM output
688
 
689
    always @(posedge clka_int)
690
       begin
691
          if (ena_int == 1'b1)
692
             begin
693
                if (ssra_int == 1'b1)
694
                   new_data_a_q <= 1'b0 ;
695
                else
696
                   new_data_a_q <= new_data_a ;
697
             end
698
       end
699
 
700
// Generate data outputs for Port A
701
 
702
    always @(posedge clka_int) begin
703
        if (ena_int == 1'b1) begin
704
            if (ssra_int == 1'b1) begin
705
                for ( ai = 0; ai < c_width_a; ai = ai + 1)
706
                    doa_out[ai] <= sinita_value[ai];
707
            end
708
            else begin
709
                if (wea_int == 1'b1) begin
710
                    if (wr_mode_a == 2'b00) begin
711
                      if (addra_int < c_depth_a)
712
                        for ( aj = 0; aj < c_width_a; aj = aj + 1)
713
                            doa_out[aj] <= dia_int[aj] ;
714
                      else
715
                        $display("Warning : Memory out of range");
716
                    end
717
                    else if (wr_mode_a == 2'b01) begin
718
                      if (addra_int < c_depth_a)
719
                        for ( ak = 0; ak < c_width_a; ak = ak + 1)
720
                            doa_out[ak] <= mem[(addra_int*c_width_a) + ak];
721
                      else
722
                        $display("Warning : Memory out of range");
723
                    end
724
                    else begin
725
                      if (addra_int < c_depth_a)
726
                        doa_out <= doa_out;
727
                      else
728
                        $display("Warning : Memory out of range");
729
                    end
730
                end
731
                else begin
732
                  if (addra_int < c_depth_a)
733
                    for ( al = 0; al < c_width_a; al = al + 1)
734
                        doa_out[al]  <= mem[(addra_int*c_width_a) + al];
735
                  else
736
                    $display("Warning : Memory out of range");
737
                end
738
            end
739
        end
740
    end
741
 
742
    always @(posedge clka_int) begin
743
        if (ena_int == 1'b1 && wea_int == 1'b1) begin
744
          if (addra_int < c_depth_a)
745
            for ( am = 0; am < c_width_a; am = am + 1)
746
                mem[(addra_int*c_width_a) + am] <= dia_int[am];
747
          else
748
            $display("Warning : Memory out of range");
749
        end
750
    end
751
 
752
    //  output pipelines for Port A
753
 
754
   always @(posedge clka_int) begin
755
       if (ena_int == 1'b1)
756
         begin
757
             for (i = c_pipe_stages_a; i > 1; i = i -1 )
758
               begin
759
                  if (ssra_int == 1'b1 && ena_int == 1'b1 )
760
                     begin
761
                      pipelinea[i] <= sinita_value ;
762
                      sub_rdy_a[i]   <= 0 ;
763
                     end
764
                  else
765
                     begin
766
                      pipelinea[i] <= pipelinea[i-1] ;
767
                      sub_rdy_a[i] <= sub_rdy_a[i-1] ;
768
                     end
769
               end
770
             if (ssra_int == 1'b1 && ena_int == 1'b1 )
771
                begin
772
                  pipelinea[1]<= sinita_value ;
773
                  sub_rdy_a[1] <= 0 ;
774
                end
775
             else
776
                begin
777
                 pipelinea[1] <= doa_out ;
778
                 sub_rdy_a[1]  <= new_data_a_q ;
779
             end
780
       end
781
   end
782
 
783
// Select pipeline output if c_pipe_stages_a > 0
784
 
785
   always @( pipelinea[c_pipe_stages_a] or sub_rdy_a[c_pipe_stages_a] or new_data_a_q or doa_out ) begin
786
          if (c_pipe_stages_a == 0 )
787
             begin
788
                douta_out = doa_out ;
789
                rdya_int  = new_data_a_q;
790
             end
791
          else
792
             begin
793
                douta_out = pipelinea[c_pipe_stages_a];
794
                rdya_int  = sub_rdy_a[c_pipe_stages_a];
795
             end
796
   end
797
 
798
 
799
 // Select Port A data outputs based on c_has_douta parameter
800
 
801
  always @( douta_out ) begin
802
         if ( c_has_douta == 1)
803
            douta_mux_out = douta_out ;
804
         else
805
            douta_mux_out = 0 ;
806
  end
807
 
808
 
809
 
810
// Port B
811
 
812
 
813
 
814
// Generate output control signals for Port B: RFDB and RDYB
815
 
816
    always @ (rfdb_int or rdyb_int)
817
    begin
818
       if (c_has_rfdb == 1)
819
          RFDB = rfdb_int ;
820
       else
821
          RFDB = 1'b0 ;
822
 
823
       if ((c_has_rdyb == 1) && (c_has_ndb == 1) && (c_has_rfdb == 1) )
824
          RDYB  = rdyb_int;
825
       else
826
          RDYB  = 1'b0 ;
827
    end
828
 
829
    always @ (enb_int )
830
    begin
831
        if ( enb_int == 1'b1 )
832
           rfdb_int = 1'b1 ;
833
        else
834
          rfdb_int  = 1'b0 ;
835
    end
836
 
837
// Gate nd signal with en
838
 
839
   assign ndb_int = enb_int && ndb_i ;
840
 
841
// Register hanshaking signals for port B
842
 
843
    always @ (posedge clkb_int)
844
    begin
845
       if (enb_int == 1'b1)
846
          begin
847
             if (ssrb_int == 1'b1)
848
                 ndb_q <= 1'b0 ;
849
             else
850
                 ndb_q   <=  ndb_int ;
851
          end
852
       else
853
          ndb_q <=  ndb_q;
854
    end
855
 
856
// Register data / address / we  inputs for port B
857
 
858
    always @ (posedge clkb_int)
859
    begin
860
      if (enb_int == 1'b1)
861
         begin
862
           dib_q  <= dib_i ;
863
           addrb_q <= addrb_i ;
864
           web_q  <= web_i ;
865
         end
866
    end
867
 
868
// Select registered or non-registered write enable for port B
869
 
870
   always @ (web_i or web_q )
871
   begin
872
      if (c_reg_inputsb == 1)
873
         web_int = web_q ;
874
      else
875
         web_int = web_i ;
876
   end
877
 
878
 
879
 
880
// Select registered or non-registered  data/address/nd inputs for Port B
881
 
882
    always @ ( dib_i or dib_q )
883
    begin
884
         if ( c_reg_inputsb == 1)
885
            dib_int = dib_q;
886
         else
887
            dib_int = dib_i;
888
    end
889
 
890
    always @ ( addrb_i or addrb_q or  ndb_q or ndb_int)
891
    begin
892
         if ( c_reg_inputsb == 1)
893
            begin
894
                addrb_int = addrb_q ;
895
                new_data_b = ndb_q ;
896
            end
897
         else
898
            begin
899
                addrb_int = addrb_i;
900
                new_data_b = ndb_int ;
901
            end
902
    end
903
 
904
// Register the new_data signal for Port B to track the synchronous RAM output
905
 
906
    always @(posedge clkb_int)
907
       begin
908
         if (enb_int == 1'b1 )
909
            begin
910
              if (ssrb_int == 1'b1)
911
                 new_data_b_q <= 1'b0 ;
912
              else
913
                 new_data_b_q <= new_data_b ;
914
            end
915
       end
916
 
917
 
918
 
919
 
920
 
921
// Generate data outputs for Port B
922
 
923
    always @(posedge clkb_int) begin
924
        if (enb_int == 1'b1) begin
925
            if (ssrb_int == 1'b1) begin
926
                for (bi = 0; bi < c_width_b; bi = bi + 1)
927
                    dob_out[bi]  <= sinitb_value[bi];
928
            end
929
            else begin
930
                if (web_int == 1'b1) begin
931
                    if (wr_mode_b == 2'b00) begin
932
                      if (addrb_int < c_depth_b)
933
                        for (bj = 0; bj < c_width_b; bj = bj + 1)
934
                            dob_out[bj] <= dib_int[bj];
935
                      else
936
                        $display("Warning : Memory out of range");
937
                    end
938
                    else if (wr_mode_b == 2'b01) begin
939
                      if (addrb_int < c_depth_b)
940
                         for (bk = 0; bk < c_width_b; bk = bk + 1)
941
                             dob_out[bk] <= mem[(addrb_int*c_width_b) + bk];
942
                      else
943
                        $display("Warning : Memory out of range");
944
                    end
945
                    else begin
946
                      if (addrb_int < c_depth_b)
947
                         dob_out  <= dob_out ;
948
                      else
949
                        $display("Warning : Memory out of range");
950
                    end
951
                end
952
                else begin
953
                  if (addrb_int < c_depth_b)
954
                     for (bl = 0; bl < c_width_b; bl = bl + 1)
955
                         dob_out[bl] <= mem[(addrb_int*c_width_b) + bl];
956
                  else
957
                    $display("Warning : Memory out of range");
958
                end
959
            end
960
        end
961
    end
962
 
963
    always @(posedge clkb_int) begin
964
        if (enb_int == 1'b1 && web_int == 1'b1) begin
965
          if (addrb_int < c_depth_b)
966
            for (bm = 0; bm < c_width_b; bm = bm + 1)
967
                 mem[(addrb_int*c_width_b) + bm]  <= dib_int[bm];
968
          else
969
            $display("Warning : Memory out of range");
970
        end
971
    end
972
 
973
  //  output pipelines for Port B
974
 
975
    always @(posedge clkb_int) begin
976
      if (enb_int == 1'b1)
977
         begin
978
              for (j = c_pipe_stages_b; j > 1; j = j -1 )
979
                begin
980
                  if (ssrb_int == 1'b1 && enb_int == 1'b1 )
981
                     begin
982
                       pipelineb[j] <= sinitb_value ;
983
                       sub_rdy_b[j] <= 0 ;
984
                     end
985
                  else
986
                     begin
987
                        pipelineb[j] <= pipelineb[j-1] ;
988
                        sub_rdy_b[j] <= sub_rdy_b[j-1] ;
989
                     end
990
                end
991
              if (ssrb_int == 1'b1 && enb_int == 1'b1)
992
                 begin
993
                    pipelineb[1] <= sinitb_value ;
994
                    sub_rdy_b[1]   <=  0 ;
995
                 end
996
              else
997
                 begin
998
                   pipelineb[1] <= dob_out ;
999
                   sub_rdy_b[1] <= new_data_b_q ;
1000
                 end
1001
         end
1002
   end
1003
 
1004
// Select pipeline for B if c_pipe_stages_b > 0
1005
 
1006
    always @(pipelineb[c_pipe_stages_b] or sub_rdy_b[c_pipe_stages_b] or new_data_b_q or dob_out) begin
1007
           if ( c_pipe_stages_b == 0 )
1008
              begin
1009
               doutb_out = dob_out ;
1010
               rdyb_int = new_data_b_q;
1011
              end
1012
           else
1013
              begin
1014
               rdyb_int   = sub_rdy_b[c_pipe_stages_b];
1015
               doutb_out  = pipelineb[c_pipe_stages_b];
1016
              end
1017
    end
1018
 
1019
 
1020
// Select Port B data outputs based on c_has_doutb parameter
1021
 
1022
   always @(   doutb_out) begin
1023
          if ( c_has_doutb == 1)
1024
             doutb_mux_out = doutb_out ;
1025
          else
1026
             doutb_mux_out = 0 ;
1027
   end
1028
 
1029
 
1030
 
1031
 
1032
 
1033
    specify
1034
        $recovery (posedge CLKB, posedge CLKA &&& collision, 1, recovery_b);
1035
        $recovery (posedge CLKA, posedge CLKB &&& collision, 1, recovery_a);
1036
    endspecify
1037
 
1038
endmodule
1039
 
1040
`endcelldefine

powered by: WebSVN 2.1.0

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