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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [boards/] [actel/] [ordb1a3pe1500/] [rtl/] [verilog/] [versatile_mem_ctrl/] [rtl/] [verilog/] [versatile_mem_ctrl_ip.v] - Blame information for rev 411

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 408 julius
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  Versatile memory controller                                 ////
4
////                                                              ////
5
////  Description                                                 ////
6
////  A modular wishbone compatible memory controller with support////
7
////  for various types of memory configurations                  ////
8
////                                                              ////
9
////  To Do:                                                      ////
10
////   - add support for additional SDRAM variants                ////
11
////                                                              ////
12
////  Author(s):                                                  ////
13
////      - Michael Unneback, unneback@opencores.org              ////
14
////        ORSoC AB                                              ////
15
////                                                              ////
16
//////////////////////////////////////////////////////////////////////
17
////                                                              ////
18
//// Copyright (C) 2009 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 411 julius
//////////////////////////////////////////////////////////////////////
43
////                                                              ////
44
////  Versatile counter                                           ////
45
////                                                              ////
46
////  Description                                                 ////
47
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
48
////  counter                                                     ////
49
////                                                              ////
50
////  To Do:                                                      ////
51
////   - add LFSR with more taps                                  ////
52
////                                                              ////
53
////  Author(s):                                                  ////
54
////      - Michael Unneback, unneback@opencores.org              ////
55
////        ORSoC AB                                              ////
56
////                                                              ////
57
//////////////////////////////////////////////////////////////////////
58
////                                                              ////
59
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
60
////                                                              ////
61
//// This source file may be used and distributed without         ////
62
//// restriction provided that this copyright statement is not    ////
63
//// removed from the file and that any derivative work contains  ////
64
//// the original copyright notice and the associated disclaimer. ////
65
////                                                              ////
66
//// This source file is free software; you can redistribute it   ////
67
//// and/or modify it under the terms of the GNU Lesser General   ////
68
//// Public License as published by the Free Software Foundation; ////
69
//// either version 2.1 of the License, or (at your option) any   ////
70
//// later version.                                               ////
71
////                                                              ////
72
//// This source is distributed in the hope that it will be       ////
73
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
74
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
75
//// PURPOSE.  See the GNU Lesser General Public License for more ////
76
//// details.                                                     ////
77
////                                                              ////
78
//// You should have received a copy of the GNU Lesser General    ////
79
//// Public License along with this source; if not, download it   ////
80
//// from http://www.opencores.org/lgpl.shtml                     ////
81
////                                                              ////
82
//////////////////////////////////////////////////////////////////////
83
 
84
module versatile_fifo_async_cmp ( wptr, rptr, fifo_empty, fifo_full, wclk, rclk, rst );
85
 
86
   parameter ADDR_WIDTH = 4;
87
   parameter N = ADDR_WIDTH-1;
88
 
89
   parameter Q1 = 2'b00;
90
   parameter Q2 = 2'b01;
91
   parameter Q3 = 2'b11;
92
   parameter Q4 = 2'b10;
93
 
94
   parameter going_empty = 1'b0;
95
   parameter going_full  = 1'b1;
96
 
97
   input [N:0]  wptr, rptr;
98
   output reg   fifo_empty;
99
   output       fifo_full;
100
   input        wclk, rclk, rst;
101
 
102
`ifndef GENERATE_DIRECTION_AS_LATCH
103
   wire direction;
104
`endif
105
`ifdef GENERATE_DIRECTION_AS_LATCH
106
   reg direction;
107
`endif
108
   reg  direction_set, direction_clr;
109
 
110
   wire async_empty, async_full;
111
   wire fifo_full2;
112
   reg  fifo_empty2;
113
 
114
   // direction_set
115
   always @ (wptr[N:N-1] or rptr[N:N-1])
116
     case ({wptr[N:N-1],rptr[N:N-1]})
117
       {Q1,Q2} : direction_set <= 1'b1;
118
       {Q2,Q3} : direction_set <= 1'b1;
119
       {Q3,Q4} : direction_set <= 1'b1;
120
       {Q4,Q1} : direction_set <= 1'b1;
121
       default : direction_set <= 1'b0;
122
     endcase
123
 
124
   // direction_clear
125
   always @ (wptr[N:N-1] or rptr[N:N-1] or rst)
126
     if (rst)
127
       direction_clr <= 1'b1;
128
     else
129
       case ({wptr[N:N-1],rptr[N:N-1]})
130
         {Q2,Q1} : direction_clr <= 1'b1;
131
         {Q3,Q2} : direction_clr <= 1'b1;
132
         {Q4,Q3} : direction_clr <= 1'b1;
133
         {Q1,Q4} : direction_clr <= 1'b1;
134
         default : direction_clr <= 1'b0;
135
       endcase
136
 
137
`ifndef GENERATE_DIRECTION_AS_LATCH
138
    dff_sr dff_sr_dir( .aclr(direction_clr), .aset(direction_set), .clock(1'b1), .data(1'b1), .q(direction));
139
`endif
140
 
141
`ifdef GENERATE_DIRECTION_AS_LATCH
142
   always @ (posedge direction_set or posedge direction_clr)
143
     if (direction_clr)
144
       direction <= going_empty;
145
     else
146
       direction <= going_full;
147
`endif
148
 
149
   assign async_empty = (wptr == rptr) && (direction==going_empty);
150
   assign async_full  = (wptr == rptr) && (direction==going_full);
151
 
152
    dff_sr dff_sr_empty0( .aclr(rst), .aset(async_full), .clock(wclk), .data(async_full), .q(fifo_full2));
153
    dff_sr dff_sr_empty1( .aclr(rst), .aset(async_full), .clock(wclk), .data(fifo_full2), .q(fifo_full));
154
 
155
/*
156
   always @ (posedge wclk or posedge rst or posedge async_full)
157
     if (rst)
158
       {fifo_full, fifo_full2} <= 2'b00;
159
     else if (async_full)
160
       {fifo_full, fifo_full2} <= 2'b11;
161
     else
162
       {fifo_full, fifo_full2} <= {fifo_full2, async_full};
163
*/
164
   always @ (posedge rclk or posedge async_empty)
165
     if (async_empty)
166
       {fifo_empty, fifo_empty2} <= 2'b11;
167
     else
168
       {fifo_empty,fifo_empty2} <= {fifo_empty2,async_empty};
169
 
170
endmodule // async_comp
171 408 julius
// async FIFO with multiple queues
172
 
173
module async_fifo_mq (
174
    d, fifo_full, write, write_enable, clk1, rst1,
175
    q, fifo_empty, read, read_enable, clk2, rst2
176
);
177
 
178
parameter a_hi_size = 4;
179
parameter a_lo_size = 4;
180
parameter nr_of_queues = 16;
181
parameter data_width = 36;
182
 
183
input [data_width-1:0] d;
184
output [0:nr_of_queues-1] fifo_full;
185
input                     write;
186
input  [0:nr_of_queues-1] write_enable;
187
input clk1;
188
input rst1;
189
 
190
output [data_width-1:0] q;
191
output [0:nr_of_queues-1] fifo_empty;
192
input                     read;
193
input  [0:nr_of_queues-1] read_enable;
194
input clk2;
195
input rst2;
196
 
197
wire [a_lo_size-1:0]  fifo_wadr_bin[0:nr_of_queues-1];
198
wire [a_lo_size-1:0]  fifo_wadr_gray[0:nr_of_queues-1];
199
wire [a_lo_size-1:0]  fifo_radr_bin[0:nr_of_queues-1];
200
wire [a_lo_size-1:0]  fifo_radr_gray[0:nr_of_queues-1];
201
reg [a_lo_size-1:0] wadr;
202
reg [a_lo_size-1:0] radr;
203
reg [data_width-1:0] wdata;
204
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
205
 
206
genvar i;
207
integer j,k,l;
208
 
209
function [a_lo_size-1:0] onehot2bin;
210
input [0:nr_of_queues-1] a;
211
integer i;
212
begin
213
    onehot2bin = {a_lo_size{1'b0}};
214
    for (i=1;i<nr_of_queues;i=i+1) begin
215
        if (a[i])
216
            onehot2bin = i;
217
    end
218
end
219
endfunction
220
 
221
generate
222
    for (i=0;i<nr_of_queues;i=i+1) begin : fifo_adr
223
 
224
        gray_counter wadrcnt (
225
            .cke(write & write_enable[i]),
226
            .q(fifo_wadr_gray[i]),
227
            .q_bin(fifo_wadr_bin[i]),
228
            .rst(rst1),
229
            .clk(clk1));
230
 
231
        gray_counter radrcnt (
232
            .cke(read & read_enable[i]),
233
            .q(fifo_radr_gray[i]),
234
            .q_bin(fifo_radr_bin[i]),
235
            .rst(rst2),
236
            .clk(clk2));
237
 
238
        versatile_fifo_async_cmp
239
            #(.ADDR_WIDTH(a_lo_size))
240
            egresscmp (
241
                .wptr(fifo_wadr_gray[i]),
242
                .rptr(fifo_radr_gray[i]),
243
                .fifo_empty(fifo_empty[i]),
244
                .fifo_full(fifo_full[i]),
245
                .wclk(clk1),
246
                .rclk(clk2),
247
                .rst(rst1));
248
 
249
    end
250
endgenerate
251
 
252
// and-or mux write address
253
always @*
254
begin
255
    wadr = {a_lo_size{1'b0}};
256
    for (j=0;j<nr_of_queues;j=j+1) begin
257
        wadr = (fifo_wadr_bin[j] & {a_lo_size{write_enable[j]}}) | wadr;
258
    end
259
end
260
 
261
// and-or mux read address
262
always @*
263
begin
264
    radr = {a_lo_size{1'b0}};
265
    for (k=0;k<nr_of_queues;k=k+1) begin
266
        radr = (fifo_radr_bin[k] & {a_lo_size{read_enable[k]}}) | radr;
267
    end
268
end
269
 
270
vfifo_dual_port_ram_dc_sw # ( .DATA_WIDTH(data_width), .ADDR_WIDTH(a_hi_size+a_lo_size))
271
    dpram (
272
    .d_a(d),
273
    .adr_a({onehot2bin(write_enable),wadr}),
274
    .we_a(write),
275
    .clk_a(clk1),
276
    .q_b(q),
277
    .adr_b({onehot2bin(read_enable),radr}),
278
    .clk_b(clk2) );
279
 
280
endmodule
281
module vfifo_dual_port_ram_dc_dw
282
  (
283
   d_a,
284
   q_a,
285
   adr_a,
286
   we_a,
287
   clk_a,
288
   q_b,
289
   adr_b,
290
   d_b,
291
   we_b,
292
   clk_b
293
   );
294
   parameter DATA_WIDTH = 32;
295
   parameter ADDR_WIDTH = 8;
296
   input [(DATA_WIDTH-1):0]      d_a;
297
   input [(ADDR_WIDTH-1):0]       adr_a;
298
   input [(ADDR_WIDTH-1):0]       adr_b;
299
   input                         we_a;
300
   output [(DATA_WIDTH-1):0]      q_b;
301
   input [(DATA_WIDTH-1):0]       d_b;
302
   output reg [(DATA_WIDTH-1):0] q_a;
303
   input                         we_b;
304
   input                         clk_a, clk_b;
305
   reg [(DATA_WIDTH-1):0]         q_b;
306 411 julius
   reg [DATA_WIDTH-1:0] ram [(1<<ADDR_WIDTH)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
307 408 julius
   always @ (posedge clk_a)
308
     begin
309
        q_a <= ram[adr_a];
310
        if (we_a)
311
             ram[adr_a] <= d_a;
312
     end
313
   always @ (posedge clk_b)
314
     begin
315
          q_b <= ram[adr_b];
316
        if (we_b)
317
          ram[adr_b] <= d_b;
318
     end
319
endmodule
320
//////////////////////////////////////////////////////////////////////
321
////                                                              ////
322
////  Versatile counter                                           ////
323
////                                                              ////
324
////  Description                                                 ////
325
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
326
////  counter                                                     ////
327
////                                                              ////
328
////  To Do:                                                      ////
329
////   - add LFSR with more taps                                  ////
330
////                                                              ////
331
////  Author(s):                                                  ////
332
////      - Michael Unneback, unneback@opencores.org              ////
333
////        ORSoC AB                                              ////
334
////                                                              ////
335
//////////////////////////////////////////////////////////////////////
336
////                                                              ////
337
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
338
////                                                              ////
339
//// This source file may be used and distributed without         ////
340
//// restriction provided that this copyright statement is not    ////
341
//// removed from the file and that any derivative work contains  ////
342
//// the original copyright notice and the associated disclaimer. ////
343
////                                                              ////
344
//// This source file is free software; you can redistribute it   ////
345
//// and/or modify it under the terms of the GNU Lesser General   ////
346
//// Public License as published by the Free Software Foundation; ////
347
//// either version 2.1 of the License, or (at your option) any   ////
348
//// later version.                                               ////
349
////                                                              ////
350
//// This source is distributed in the hope that it will be       ////
351
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
352
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
353
//// PURPOSE.  See the GNU Lesser General Public License for more ////
354
//// details.                                                     ////
355
////                                                              ////
356
//// You should have received a copy of the GNU Lesser General    ////
357
//// Public License along with this source; if not, download it   ////
358
//// from http://www.opencores.org/lgpl.shtml                     ////
359
////                                                              ////
360
//////////////////////////////////////////////////////////////////////
361
 
362
// LFSR counter
363
module ctrl_counter ( clear, cke, zq, rst, clk);
364
 
365
   parameter length = 5;
366
   input clear;
367
   input cke;
368
   output reg zq;
369
   input rst;
370
   input clk;
371
 
372
   parameter clear_value = 0;
373
   parameter set_value = 0;
374
   parameter wrap_value = 31;
375
 
376
   reg  [length:1] qi;
377
   reg lfsr_fb;
378
   wire [length:1] q_next;
379
   reg [32:1] polynom;
380
   integer i;
381
 
382
   always @ (qi)
383
   begin
384
        case (length)
385
         2: polynom = 32'b11;                               // 0x3
386
         3: polynom = 32'b110;                              // 0x6
387
         4: polynom = 32'b1100;                             // 0xC
388
         5: polynom = 32'b10100;                            // 0x14
389
         6: polynom = 32'b110000;                           // 0x30
390
         7: polynom = 32'b1100000;                          // 0x60
391
         8: polynom = 32'b10111000;                         // 0xb8
392
         9: polynom = 32'b100010000;                        // 0x110
393
        10: polynom = 32'b1001000000;                       // 0x240
394
        11: polynom = 32'b10100000000;                      // 0x500
395
        12: polynom = 32'b100000101001;                     // 0x829
396
        13: polynom = 32'b1000000001100;                    // 0x100C
397
        14: polynom = 32'b10000000010101;                   // 0x2015
398
        15: polynom = 32'b110000000000000;                  // 0x6000
399
        16: polynom = 32'b1101000000001000;                 // 0xD008
400
        17: polynom = 32'b10010000000000000;                // 0x12000
401
        18: polynom = 32'b100000010000000000;               // 0x20400
402
        19: polynom = 32'b1000000000000100011;              // 0x40023
403
        20: polynom = 32'b10000010000000000000;             // 0x82000
404
        21: polynom = 32'b101000000000000000000;            // 0x140000
405
        22: polynom = 32'b1100000000000000000000;           // 0x300000
406
        23: polynom = 32'b10000100000000000000000;          // 0x420000
407
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
408
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
409
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
410
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
411
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
412
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
413
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
414
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
415
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
416
        default: polynom = 32'b0;
417
        endcase
418
        lfsr_fb = qi[length];
419
        for (i=length-1; i>=1; i=i-1) begin
420
            if (polynom[i])
421
                lfsr_fb = lfsr_fb  ~^ qi[i];
422
        end
423
    end
424
   assign q_next =  clear ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
425
 
426
   always @ (posedge clk or posedge rst)
427
     if (rst)
428
       qi <= {length{1'b0}};
429
     else
430
     if (cke)
431
       qi <= q_next;
432
 
433
 
434
 
435
   always @ (posedge clk or posedge rst)
436
     if (rst)
437
       zq <= 1'b1;
438
     else
439
     if (cke)
440
       zq <= q_next == {length{1'b0}};
441
endmodule
442
`include "versatile_mem_ctrl_defines.v"
443
 
444
module fifo
445
  (
446
   // A side
447
   input [35:0]  a_dat_i,
448
   input         a_we_i,
449
   input  [2:0]  a_fifo_sel_i,
450
   output [7:0]  a_fifo_full_o,
451
   input         a_clk,
452
   // B side
453
   output [35:0] b_dat_o,
454
   input         b_re_i,
455
   input [2:0]   b_fifo_sel_i,
456
   output [7:0]  b_fifo_empty_o,
457
   input         b_clk,
458
   // Common
459
   input         rst
460
   );
461
 
462
   wire [4:0]     wadr0, radr0;
463
   wire [4:0]     wadr1, radr1;
464
   wire [4:0]     wadr2, radr2;
465
   wire [4:0]     wadr3, radr3;
466
   wire [4:0]     wadr4, radr4;
467
   wire [4:0]     wadr5, radr5;
468
   wire [4:0]     wadr6, radr6;
469
   wire [4:0]     wadr7, radr7;
470
 
471
`ifdef PORT0
472
   wire [4:0]     wptr0, rptr0;
473
`endif
474
`ifdef PORT1
475
   wire [4:0]     wptr1, rptr1;
476
`endif
477
`ifdef PORT2
478
   wire [4:0]     wptr2, rptr2;
479
`endif
480
`ifdef PORT3
481
   wire [4:0]     wptr3, rptr3;
482
`endif
483
`ifdef PORT4
484
   wire [4:0]     wptr4, rptr4;
485
`endif
486
`ifdef PORT5
487
   wire [4:0]     wptr5, rptr5;
488
`endif
489
`ifdef PORT6
490
   wire [4:0]     wptr6, rptr6;
491
`endif
492
`ifdef PORT7
493
   wire [4:0]     wptr7, rptr7;
494
`endif
495
 
496
   wire [7:0]     dpram_a_a, dpram_a_b;
497
 
498
   // WB#0
499
`ifdef PORT0
500
   fifo_adr_counter wptr0_cnt
501
     (
502
      .q(wptr0),
503
      .q_bin(wadr0),
504
      .cke(a_we_i & (a_fifo_sel_i==3'h0)),
505
      .clk(a_clk),
506
      .rst(rst)
507
      );
508
 
509
   fifo_adr_counter rptr0_cnt
510
     (
511
      .q(rptr0),
512
      .q_bin(radr0),
513
      .cke(b_re_i & (b_fifo_sel_i==3'h0)),
514
      .clk(b_clk),
515
      .rst(rst)
516
      );
517
 
518
  versatile_fifo_async_cmp
519
    #
520
    (
521
     .ADDR_WIDTH(5)
522
     )
523
    cmp0
524
    (
525
      .wptr(wptr0),
526
      .rptr(rptr0),
527
      .fifo_empty(b_fifo_empty_o[0]),
528
      .fifo_full(a_fifo_full_o[0]),
529
      .wclk(a_clk),
530
      .rclk(b_clk),
531
      .rst(rst)
532
      );
533
`else // !`ifdef PORT0
534
   assign wptr0 = 5'h0;
535
   assign wadr0 = 5'h0;
536
   assign rptr0 = 5'h0;
537
   assign radr0 = 5'h0;
538
   assign a_fifo_full_o[0] = 1'b0;
539
   assign b_fifo_empty_o[0] = 1'b1;
540
`endif // !`ifdef PORT0
541
 
542
   // WB#1
543
`ifdef PORT1
544
   fifo_adr_counter wptr1_cnt
545
     (
546
      .q(wptr1),
547
      .q_bin(wadr1),
548
      .cke(a_we_i & (a_fifo_sel_i==3'h1)),
549
      .clk(a_clk),
550
      .rst(rst)
551
      );
552
 
553
   fifo_adr_counter rptr1_cnt
554
     (
555
      .q(rptr1),
556
      .q_bin(radr1),
557
      .cke(b_re_i & (b_fifo_sel_i==3'h1)),
558
      .clk(b_clk),
559
      .rst(rst)
560
      );
561
 
562
  versatile_fifo_async_cmp
563
    #
564
    (
565
     .ADDR_WIDTH(5)
566
     )
567
    cmp1
568
    (
569
      .wptr(wptr1),
570
      .rptr(rptr1),
571
      .fifo_empty(b_fifo_empty_o[1]),
572
      .fifo_full(a_fifo_full_o[1]),
573
      .wclk(a_clk),
574
      .rclk(b_clk),
575
      .rst(rst)
576
      );
577
`else // !`ifdef PORT1
578
   assign wptr1 = 5'h0;
579
   assign wadr1 = 5'h0;
580
   assign rptr1 = 5'h0;
581
   assign radr1 = 5'h0;
582
   assign a_fifo_full_o[1] = 1'b0;
583
   assign b_fifo_empty_o[1] = 1'b1;
584
`endif // !`ifdef PORT1
585
 
586
   // WB#2
587
`ifdef PORT2
588
   fifo_adr_counter wptr2_cnt
589
     (
590
      .q(wptr2),
591
      .q_bin(wadr2),
592
      .cke(a_we_i & (a_fifo_sel_i==3'h2)),
593
      .clk(a_clk),
594
      .rst(rst)
595
      );
596
 
597
   fifo_adr_counter rptr2_cnt
598
     (
599
      .q(rptr2),
600
      .q_bin(radr2),
601
      .cke(b_re_i & (b_fifo_sel_i==3'h2)),
602
      .clk(b_clk),
603
      .rst(rst)
604
      );
605
 
606
  versatile_fifo_async_cmp
607
    #
608
    (
609
     .ADDR_WIDTH(5)
610
     )
611
    cmp2
612
    (
613
      .wptr(wptr2),
614
      .rptr(rptr2),
615
      .fifo_empty(b_fifo_empty_o[2]),
616
      .fifo_full(a_fifo_full_o[2]),
617
      .wclk(a_clk),
618
      .rclk(b_clk),
619
      .rst(rst)
620
      );
621
`else // !`ifdef PORT2
622
   assign wptr2 = 5'h0;
623
   assign wadr2 = 5'h0;
624
   assign rptr2 = 5'h0;
625
   assign radr2 = 5'h0;
626
   assign a_fifo_full_o[2] = 1'b0;
627
   assign b_fifo_empty_o[2] = 1'b1;
628
`endif // !`ifdef PORT2
629
 
630
   // WB#3
631
`ifdef PORT3
632
   fifo_adr_counter wptr3_cnt
633
     (
634
      .q(wptr3),
635
      .q_bin(wadr3),
636
      .cke(a_we_i & (a_fifo_sel_i==3'h3)),
637
      .clk(a_clk),
638
      .rst(rst)
639
      );
640
 
641
   fifo_adr_counter rptr3_cnt
642
     (
643
      .q(rptr3),
644
      .q_bin(radr3),
645
      .cke(b_re_i & (b_fifo_sel_i==3'h3)),
646
      .clk(b_clk),
647
      .rst(rst)
648
      );
649
 
650
  versatile_fifo_async_cmp
651
    #
652
    (
653
     .ADDR_WIDTH(5)
654
     )
655
    cmp3
656
    (
657
      .wptr(wptr3),
658
      .rptr(rptr3),
659
      .fifo_empty(b_fifo_empty_o[3]),
660
      .fifo_full(a_fifo_full_o[3]),
661
      .wclk(a_clk),
662
      .rclk(b_clk),
663
      .rst(rst)
664
      );
665
`else // !`ifdef PORT3
666
   assign wptr3 = 5'h0;
667
   assign wadr3 = 5'h0;
668
   assign rptr3 = 5'h0;
669
   assign radr3 = 5'h0;
670
   assign a_fifo_full_o[3] = 1'b0;
671
   assign b_fifo_empty_o[3] = 1'b1;
672
`endif // !`ifdef PORT3
673
 
674
   // WB#4
675
`ifdef PORT4
676
   fifo_adr_counter wptr4_cnt
677
     (
678
      .q(wptr4),
679
      .q_bin(wadr4),
680
      .cke(a_we_i & (a_fifo_sel_i==3'h4)),
681
      .clk(a_clk),
682
      .rst(rst)
683
      );
684
 
685
   fifo_adr_counter rptr4_cnt
686
     (
687
      .q(rptr4),
688
      .q_bin(radr4),
689
      .cke(b_re_i & (b_fifo_sel_i==3'h4)),
690
      .clk(b_clk),
691
      .rst(rst)
692
      );
693
 
694
  versatile_fifo_async_cmp
695
    #
696
    (
697
     .ADDR_WIDTH(5)
698
     )
699
    cmp4
700
    (
701
      .wptr(wptr4),
702
      .rptr(rptr4),
703
      .fifo_empty(b_fifo_empty_o[4]),
704
      .fifo_full(a_fifo_full_o[4]),
705
      .wclk(a_clk),
706
      .rclk(b_clk),
707
      .rst(rst)
708
      );
709
`else // !`ifdef PORT4
710
   assign wptr4 = 5'h0;
711
   assign wadr4 = 5'h0;
712
   assign rptr4 = 5'h0;
713
   assign radr4 = 5'h0;
714
   assign a_fifo_full_o[4] = 1'b0;
715
   assign b_fifo_empty_o[4] = 1'b1;
716
`endif // !`ifdef PORT4
717
 
718
   // WB#5
719
`ifdef PORT5
720
   fifo_adr_counter wptr5_cnt
721
     (
722
      .q(wptr5),
723
      .q_bin(wadr5),
724
      .cke(a_we_i & (a_fifo_sel_i==3'h5)),
725
      .clk(a_clk),
726
      .rst(rst)
727
      );
728
 
729
   fifo_adr_counter rptr5_cnt
730
     (
731
      .q(rptr5),
732
      .q_bin(radr5),
733
      .cke(b_re_i & (b_fifo_sel_i==3'h5)),
734
      .clk(b_clk),
735
      .rst(rst)
736
      );
737
 
738
  versatile_fifo_async_cmp
739
    #
740
    (
741
     .ADDR_WIDTH(5)
742
     )
743
    cmp5
744
    (
745
      .wptr(wptr5),
746
      .rptr(rptr5),
747
      .fifo_empty(b_fifo_empty_o[5]),
748
      .fifo_full(a_fifo_full_o[5]),
749
      .wclk(a_clk),
750
      .rclk(b_clk),
751
      .rst(rst)
752
      );
753
`else // !`ifdef PORT5
754
   assign wptr5 = 5'h0;
755
   assign wadr5 = 5'h0;
756
   assign rptr5 = 5'h0;
757
   assign radr5 = 5'h0;
758
   assign a_fifo_full_o[5] = 1'b0;
759
   assign b_fifo_empty_o[5] = 1'b1;
760
`endif // !`ifdef PORT5
761
 
762
   // WB#6
763
`ifdef PORT6
764
   fifo_adr_counter wptr6_cnt
765
     (
766
      .q(wptr6),
767
      .q_bin(wadr6),
768
      .cke(a_we_i & (a_fifo_sel_i==3'h6)),
769
      .clk(a_clk),
770
      .rst(rst)
771
      );
772
 
773
   fifo_adr_counter rptr6_cnt
774
     (
775
      .q(rptr6),
776
      .q_bin(radr6),
777
      .cke(b_re_i & (b_fifo_sel_i==3'h6)),
778
      .clk(b_clk),
779
      .rst(rst)
780
      );
781
 
782
  versatile_fifo_async_cmp
783
    #
784
    (
785
     .ADDR_WIDTH(5)
786
     )
787
    cmp6
788
    (
789
      .wptr(wptr6),
790
      .rptr(rptr6),
791
      .fifo_empty(b_fifo_empty_o[6]),
792
      .fifo_full(a_fifo_full_o[6]),
793
      .wclk(a_clk),
794
      .rclk(b_clk),
795
      .rst(rst)
796
      );
797
`else // !`ifdef PORT6
798
   assign wptr6 = 5'h0;
799
   assign wadr6 = 5'h0;
800
   assign rptr6 = 5'h0;
801
   assign radr6 = 5'h0;
802
   assign a_fifo_full_o[6] = 1'b0;
803
   assign b_fifo_empty_o[6] = 1'b1;
804
`endif // !`ifdef PORT6
805
 
806
   // WB#7
807
`ifdef PORT7
808
   fifo_adr_counter wptr7_cnt
809
     (
810
      .q(wptr7),
811
      .q_bin(wadr7),
812
      .cke(a_we_i & (a_fifo_sel_i==3'h7)),
813
      .clk(a_clk),
814
      .rst(rst)
815
      );
816
 
817
   fifo_adr_counter rptr7_cnt
818
     (
819
      .q(rptr7),
820
      .q_bin(radr7),
821
      .cke(b_re_i & (b_fifo_sel_i==3'h7)),
822
      .clk(b_clk),
823
      .rst(rst)
824
      );
825
 
826
  versatile_fifo_async_cmp
827
    #
828
    (
829
     .ADDR_WIDTH(5)
830
     )
831
    cmp7
832
    (
833
      .wptr(wptr7),
834
      .rptr(rptr7),
835
      .fifo_empty(b_fifo_empty_o[7]),
836
      .fifo_full(a_fifo_full_o[7]),
837
      .wclk(a_clk),
838
      .rclk(b_clk),
839
      .rst(rst)
840
      );
841
`else // !`ifdef PORT7
842
   assign wptr7 = 5'h0;
843
   assign wadr7 = 5'h0;
844
   assign rptr7 = 5'h0;
845
   assign radr7 = 5'h0;
846
   assign a_fifo_full_o[7] = 1'b0;
847
   assign b_fifo_empty_o[7] = 1'b1;
848
`endif // !`ifdef PORT7
849
 
850
   assign dpram_a_a = (a_fifo_sel_i==3'd0) ? {a_fifo_sel_i,wadr0} :
851
                      (a_fifo_sel_i==3'd1) ? {a_fifo_sel_i,wadr1} :
852
                      (a_fifo_sel_i==3'd2) ? {a_fifo_sel_i,wadr2} :
853
                      (a_fifo_sel_i==3'd3) ? {a_fifo_sel_i,wadr3} :
854
                      (a_fifo_sel_i==3'd4) ? {a_fifo_sel_i,wadr4} :
855
                      (a_fifo_sel_i==3'd5) ? {a_fifo_sel_i,wadr5} :
856
                      (a_fifo_sel_i==3'd6) ? {a_fifo_sel_i,wadr6} :
857
                                             {a_fifo_sel_i,wadr7} ;
858
 
859
   assign dpram_a_b = (b_fifo_sel_i==3'd0) ? {b_fifo_sel_i,radr0} :
860
                      (b_fifo_sel_i==3'd1) ? {b_fifo_sel_i,radr1} :
861
                      (b_fifo_sel_i==3'd2) ? {b_fifo_sel_i,radr2} :
862
                      (b_fifo_sel_i==3'd3) ? {b_fifo_sel_i,radr3} :
863
                      (b_fifo_sel_i==3'd4) ? {b_fifo_sel_i,radr4} :
864
                      (b_fifo_sel_i==3'd5) ? {b_fifo_sel_i,radr5} :
865
                      (b_fifo_sel_i==3'd6) ? {b_fifo_sel_i,radr6} :
866
                                             {b_fifo_sel_i,radr7} ;
867
 
868
 
869
`ifdef ACTEL
870
   TwoPortRAM_256x36 dpram
871
     (
872
      .WD(a_dat_i),
873
      .RD(b_dat_o),
874
      .WEN(a_we_i),
875
      //.REN(b_re_i),
876
      .REN(1'b1),
877
      .WADDR(dpram_a_a),
878
      .RADDR(dpram_a_b),
879
      .WCLK(a_clk),
880
      .RCLK(b_clk)
881
      );
882
`else
883
   vfifo_dual_port_ram_dc_dw
884
/*     #
885
     (
886
      .ADDR_WIDTH(8),
887
      .DATA_WIDTH(36)
888
      )*/
889
     dpram
890
     (
891
      .d_a(a_dat_i),
892
      .q_a(),
893
      .adr_a(dpram_a_a),
894
      .we_a(a_we_i),
895
      .clk_a(a_clk),
896
      .q_b(b_dat_o),
897
      .adr_b(dpram_a_b),
898
      .d_b(36'h0),
899
      .we_b(1'b0),
900
      .clk_b(b_clk)
901
      );
902
`endif
903
endmodule // sd_fifo
904
`define EOB (!(|cti) | &cti)
905
module fifo_fill (
906
  output reg wbs_flag,
907
  output reg we_req,
908
  input wire ack,
909
  input wire [1:0] bte,
910
  input wire clk,
911
  input wire [2:0] cti,
912
  input wire cyc,
913
  input wire rst,
914
  input wire stb,
915
  input wire we,
916
  input wire we_ack
917
);
918
 
919
 
920
  // state bits
921
  parameter
922
  idle    = 0,
923
  state1  = 1,
924
  state10 = 2,
925
  state11 = 3,
926
  state12 = 4,
927
  state13 = 5,
928
  state14 = 6,
929
  state15 = 7,
930
  state16 = 8,
931
  state2  = 9,
932
  state3  = 10,
933
  state4  = 11,
934
  state5  = 12,
935
  state6  = 13,
936
  state7  = 14,
937
  state8  = 15,
938
  state9  = 16;
939
 
940
  reg [16:0] state;
941
  reg [16:0] nextstate;
942
 
943
  // comb always block
944
  always @* begin
945
    nextstate = 17'b00000000000000000;
946
    wbs_flag = 1'b0; // default
947
    we_req = we & stb; // default
948
    case (1'b1) // synopsys parallel_case full_case
949
      state[idle]   : begin
950
        wbs_flag = 1'b1;
951
        we_req = cyc & stb;
952
        if (cyc & stb & we_ack) begin
953
          nextstate[state1] = 1'b1;
954
        end
955
        else begin
956
          nextstate[idle] = 1'b1; // Added because implied_loopback is true
957
        end
958
      end
959
      state[state1] : begin
960
        if (`EOB & ack) begin
961
          nextstate[idle] = 1'b1;
962
        end
963
        else if (ack) begin
964
          nextstate[state2] = 1'b1;
965
        end
966
        else begin
967
          nextstate[state1] = 1'b1; // Added because implied_loopback is true
968
        end
969
      end
970
      state[state10]: begin
971
        if (`EOB & ack) begin
972
          nextstate[idle] = 1'b1;
973
        end
974
        else if (ack) begin
975
          nextstate[state11] = 1'b1;
976
        end
977
        else begin
978
          nextstate[state10] = 1'b1; // Added because implied_loopback is true
979
        end
980
      end
981
      state[state11]: begin
982
        if (`EOB & ack) begin
983
          nextstate[idle] = 1'b1;
984
        end
985
        else if (ack) begin
986
          nextstate[state12] = 1'b1;
987
        end
988
        else begin
989
          nextstate[state11] = 1'b1; // Added because implied_loopback is true
990
        end
991
      end
992
      state[state12]: begin
993
        if (`EOB & ack) begin
994
          nextstate[idle] = 1'b1;
995
        end
996
        else if (ack) begin
997
          nextstate[state13] = 1'b1;
998
        end
999
        else begin
1000
          nextstate[state12] = 1'b1; // Added because implied_loopback is true
1001
        end
1002
      end
1003
      state[state13]: begin
1004
        if (`EOB & ack) begin
1005
          nextstate[idle] = 1'b1;
1006
        end
1007
        else if (ack) begin
1008
          nextstate[state14] = 1'b1;
1009
        end
1010
        else begin
1011
          nextstate[state13] = 1'b1; // Added because implied_loopback is true
1012
        end
1013
      end
1014
      state[state14]: begin
1015
        if (`EOB & ack) begin
1016
          nextstate[idle] = 1'b1;
1017
        end
1018
        else if (ack) begin
1019
          nextstate[state15] = 1'b1;
1020
        end
1021
        else begin
1022
          nextstate[state14] = 1'b1; // Added because implied_loopback is true
1023
        end
1024
      end
1025
      state[state15]: begin
1026
        if (`EOB & ack) begin
1027
          nextstate[idle] = 1'b1;
1028
        end
1029
        else if (ack) begin
1030
          nextstate[state16] = 1'b1;
1031
        end
1032
        else begin
1033
          nextstate[state15] = 1'b1; // Added because implied_loopback is true
1034
        end
1035
      end
1036
      state[state16]: begin
1037
        if (ack) begin
1038
          nextstate[idle] = 1'b1;
1039
        end
1040
        else begin
1041
          nextstate[state16] = 1'b1; // Added because implied_loopback is true
1042
        end
1043
      end
1044
      state[state2] : begin
1045
        if (`EOB & ack) begin
1046
          nextstate[idle] = 1'b1;
1047
        end
1048
        else if (ack) begin
1049
          nextstate[state3] = 1'b1;
1050
        end
1051
        else begin
1052
          nextstate[state2] = 1'b1; // Added because implied_loopback is true
1053
        end
1054
      end
1055
      state[state3] : begin
1056
        if (`EOB & ack) begin
1057
          nextstate[idle] = 1'b1;
1058
        end
1059
        else if (ack) begin
1060
          nextstate[state4] = 1'b1;
1061
        end
1062
        else begin
1063
          nextstate[state3] = 1'b1; // Added because implied_loopback is true
1064
        end
1065
      end
1066
      state[state4] : begin
1067
        if (`EOB & ack) begin
1068
          nextstate[idle] = 1'b1;
1069
        end
1070
        else if ((bte==2'b01) & ack) begin
1071
          nextstate[idle] = 1'b1;
1072
        end
1073
        else if (ack) begin
1074
          nextstate[state5] = 1'b1;
1075
        end
1076
        else begin
1077
          nextstate[state4] = 1'b1; // Added because implied_loopback is true
1078
        end
1079
      end
1080
      state[state5] : begin
1081
        if (`EOB & ack) begin
1082
          nextstate[idle] = 1'b1;
1083
        end
1084
        else if (ack) begin
1085
          nextstate[state6] = 1'b1;
1086
        end
1087
        else begin
1088
          nextstate[state5] = 1'b1; // Added because implied_loopback is true
1089
        end
1090
      end
1091
      state[state6] : begin
1092
        if (`EOB & ack) begin
1093
          nextstate[idle] = 1'b1;
1094
        end
1095
        else if (ack) begin
1096
          nextstate[state7] = 1'b1;
1097
        end
1098
        else begin
1099
          nextstate[state6] = 1'b1; // Added because implied_loopback is true
1100
        end
1101
      end
1102
      state[state7] : begin
1103
        if (`EOB & ack) begin
1104
          nextstate[idle] = 1'b1;
1105
        end
1106
        else if (ack) begin
1107
          nextstate[state8] = 1'b1;
1108
        end
1109
        else begin
1110
          nextstate[state7] = 1'b1; // Added because implied_loopback is true
1111
        end
1112
      end
1113
      state[state8] : begin
1114
        if (`EOB & ack) begin
1115
          nextstate[idle] = 1'b1;
1116
        end
1117
        else if ((bte==2'b10) & ack) begin
1118
          nextstate[idle] = 1'b1;
1119
        end
1120
        else if (ack) begin
1121
          nextstate[state9] = 1'b1;
1122
        end
1123
        else begin
1124
          nextstate[state8] = 1'b1; // Added because implied_loopback is true
1125
        end
1126
      end
1127
      state[state9] : begin
1128
        if (`EOB & ack) begin
1129
          nextstate[idle] = 1'b1;
1130
        end
1131
        else if (ack) begin
1132
          nextstate[state10] = 1'b1;
1133
        end
1134
        else begin
1135
          nextstate[state9] = 1'b1; // Added because implied_loopback is true
1136
        end
1137
      end
1138
    endcase
1139
  end
1140
 
1141
  // sequential always block
1142
  always @(posedge clk or posedge rst) begin
1143
    if (rst)
1144
      state <= 17'b00000000000000001 << idle;
1145
    else
1146
      state <= nextstate;
1147
  end
1148
 
1149
  // This code allows you to see state names in simulation
1150
  `ifndef SYNTHESIS
1151
  reg [55:0] statename;
1152
  always @* begin
1153
    case (1'b1)
1154
      state[idle]   :
1155
        statename = "idle";
1156
      state[state1] :
1157
        statename = "state1";
1158
      state[state10]:
1159
        statename = "state10";
1160
      state[state11]:
1161
        statename = "state11";
1162
      state[state12]:
1163
        statename = "state12";
1164
      state[state13]:
1165
        statename = "state13";
1166
      state[state14]:
1167
        statename = "state14";
1168
      state[state15]:
1169
        statename = "state15";
1170
      state[state16]:
1171
        statename = "state16";
1172
      state[state2] :
1173
        statename = "state2";
1174
      state[state3] :
1175
        statename = "state3";
1176
      state[state4] :
1177
        statename = "state4";
1178
      state[state5] :
1179
        statename = "state5";
1180
      state[state6] :
1181
        statename = "state6";
1182
      state[state7] :
1183
        statename = "state7";
1184
      state[state8] :
1185
        statename = "state8";
1186
      state[state9] :
1187
        statename = "state9";
1188
      default:
1189
        statename = "XXXXXXX";
1190
    endcase
1191
  end
1192
  `endif
1193
 
1194
 
1195
endmodule
1196
 
1197
module inc_adr
1198
  (
1199
   input  [3:0] adr_i,
1200
   input  [2:0] cti_i,
1201
   input  [1:0] bte_i,
1202
   input  init,
1203
   input  inc,
1204
   output reg [3:0] adr_o,
1205
   output reg done,
1206
   input clk,
1207
   input rst
1208
   );
1209
 
1210
   reg   init_i;
1211
 
1212
   reg [1:0] bte;
1213
   reg [3:0] cnt;
1214
 
1215
   // delay init one clock cycle to be able to read from mem
1216
   always @ (posedge clk or posedge rst)
1217
     if (rst)
1218
       init_i <= 1'b0;
1219
     else
1220
       init_i <= init;
1221
 
1222
   // bte
1223
   always @ (posedge clk or posedge rst)
1224
     if (rst)
1225
       bte <= 2'b00;
1226
     else
1227
       if (init_i)
1228
         bte <= bte_i;
1229
 
1230
   // adr_o
1231
   always @ (posedge clk or posedge rst)
1232
     if (rst)
1233
       adr_o <= 4'd0;
1234
     else
1235
       if (init_i)
1236
         adr_o <= adr_i;
1237
       else
1238
         if (inc)
1239
           case (bte)
1240
             2'b01: adr_o <= {adr_o[3:2], adr_o[1:0] + 2'd1};
1241
             2'b10: adr_o <= {adr_o[3], adr_o[2:0] + 3'd1};
1242
             default: adr_o <= adr_o + 4'd1;
1243
           endcase // case (bte)
1244
 
1245
   // done
1246
   always @ (posedge clk or posedge rst)
1247
     if (rst)
1248
       {done,cnt} <= {1'b0,4'd0};
1249
     else
1250
       if (init_i)
1251
         begin
1252
            done <= ({bte_i,cti_i} == {2'b00,3'b000});
1253
            case (bte_i)
1254
              2'b01: cnt <= 4'd12;
1255
              2'b10: cnt <= 4'd8;
1256
              2'b11: cnt <= 4'd0;
1257
              default: cnt <= adr_i;
1258
            endcase
1259
         end
1260
       else
1261
         if (inc)
1262
           {done,cnt} <= cnt + 4'd1;
1263
 
1264
endmodule // inc_adr
1265
 
1266
 
1267
//////////////////////////////////////////////////////////////////////
1268
////                                                              ////
1269
////  Versatile counter                                           ////
1270
////                                                              ////
1271
////  Description                                                 ////
1272
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1273
////  counter                                                     ////
1274
////                                                              ////
1275
////  To Do:                                                      ////
1276
////   - add LFSR with more taps                                  ////
1277
////                                                              ////
1278
////  Author(s):                                                  ////
1279
////      - Michael Unneback, unneback@opencores.org              ////
1280
////        ORSoC AB                                              ////
1281
////                                                              ////
1282
//////////////////////////////////////////////////////////////////////
1283
////                                                              ////
1284
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1285
////                                                              ////
1286
//// This source file may be used and distributed without         ////
1287
//// restriction provided that this copyright statement is not    ////
1288
//// removed from the file and that any derivative work contains  ////
1289
//// the original copyright notice and the associated disclaimer. ////
1290
////                                                              ////
1291
//// This source file is free software; you can redistribute it   ////
1292
//// and/or modify it under the terms of the GNU Lesser General   ////
1293
//// Public License as published by the Free Software Foundation; ////
1294
//// either version 2.1 of the License, or (at your option) any   ////
1295
//// later version.                                               ////
1296
////                                                              ////
1297
//// This source is distributed in the hope that it will be       ////
1298
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1299
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1300
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1301
//// details.                                                     ////
1302
////                                                              ////
1303
//// You should have received a copy of the GNU Lesser General    ////
1304
//// Public License along with this source; if not, download it   ////
1305
//// from http://www.opencores.org/lgpl.shtml                     ////
1306
////                                                              ////
1307
//////////////////////////////////////////////////////////////////////
1308
 
1309
// LFSR counter
1310
module ref_counter ( zq, rst, clk);
1311
 
1312
   parameter length = 10;
1313
   output reg zq;
1314
   input rst;
1315
   input clk;
1316
 
1317
   parameter clear_value = 0;
1318
   parameter set_value = 0;
1319
   parameter wrap_value = 417;
1320
 
1321
   reg  [length:1] qi;
1322
   reg lfsr_fb;
1323
   wire [length:1] q_next;
1324
   reg [32:1] polynom;
1325
   integer i;
1326
 
1327
   always @ (qi)
1328
   begin
1329
        case (length)
1330
         2: polynom = 32'b11;                               // 0x3
1331
         3: polynom = 32'b110;                              // 0x6
1332
         4: polynom = 32'b1100;                             // 0xC
1333
         5: polynom = 32'b10100;                            // 0x14
1334
         6: polynom = 32'b110000;                           // 0x30
1335
         7: polynom = 32'b1100000;                          // 0x60
1336
         8: polynom = 32'b10111000;                         // 0xb8
1337
         9: polynom = 32'b100010000;                        // 0x110
1338
        10: polynom = 32'b1001000000;                       // 0x240
1339
        11: polynom = 32'b10100000000;                      // 0x500
1340
        12: polynom = 32'b100000101001;                     // 0x829
1341
        13: polynom = 32'b1000000001100;                    // 0x100C
1342
        14: polynom = 32'b10000000010101;                   // 0x2015
1343
        15: polynom = 32'b110000000000000;                  // 0x6000
1344
        16: polynom = 32'b1101000000001000;                 // 0xD008
1345
        17: polynom = 32'b10010000000000000;                // 0x12000
1346
        18: polynom = 32'b100000010000000000;               // 0x20400
1347
        19: polynom = 32'b1000000000000100011;              // 0x40023
1348
        20: polynom = 32'b10000010000000000000;             // 0x82000
1349
        21: polynom = 32'b101000000000000000000;            // 0x140000
1350
        22: polynom = 32'b1100000000000000000000;           // 0x300000
1351
        23: polynom = 32'b10000100000000000000000;          // 0x420000
1352
        24: polynom = 32'b111000010000000000000000;         // 0xE10000
1353
        25: polynom = 32'b1001000000000000000000000;        // 0x1200000
1354
        26: polynom = 32'b10000000000000000000100011;       // 0x2000023
1355
        27: polynom = 32'b100000000000000000000010011;      // 0x4000013
1356
        28: polynom = 32'b1100100000000000000000000000;     // 0xC800000
1357
        29: polynom = 32'b10100000000000000000000000000;    // 0x14000000
1358
        30: polynom = 32'b100000000000000000000000101001;   // 0x20000029
1359
        31: polynom = 32'b1001000000000000000000000000000;  // 0x48000000
1360
        32: polynom = 32'b10000000001000000000000000000011; // 0x80200003
1361
        default: polynom = 32'b0;
1362
        endcase
1363
        lfsr_fb = qi[length];
1364
        for (i=length-1; i>=1; i=i-1) begin
1365
            if (polynom[i])
1366
                lfsr_fb = lfsr_fb  ~^ qi[i];
1367
        end
1368
    end
1369
   assign q_next = (qi == wrap_value) ? {length{1'b0}} :{qi[length-1:1],lfsr_fb};
1370
 
1371
   always @ (posedge clk or posedge rst)
1372
     if (rst)
1373
       qi <= {length{1'b0}};
1374
     else
1375
       qi <= q_next;
1376
 
1377
 
1378
 
1379
   always @ (posedge clk or posedge rst)
1380
     if (rst)
1381
       zq <= 1'b1;
1382
     else
1383
       zq <= q_next == {length{1'b0}};
1384
endmodule
1385
//////////////////////////////////////////////////////////////////////
1386
////                                                              ////
1387
////  Versatile counter                                           ////
1388
////                                                              ////
1389
////  Description                                                 ////
1390
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1391
////  counter                                                     ////
1392
////                                                              ////
1393
////  To Do:                                                      ////
1394
////   - add LFSR with more taps                                  ////
1395
////                                                              ////
1396
////  Author(s):                                                  ////
1397
////      - Michael Unneback, unneback@opencores.org              ////
1398
////        ORSoC AB                                              ////
1399
////                                                              ////
1400
//////////////////////////////////////////////////////////////////////
1401
////                                                              ////
1402
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1403
////                                                              ////
1404
//// This source file may be used and distributed without         ////
1405
//// restriction provided that this copyright statement is not    ////
1406
//// removed from the file and that any derivative work contains  ////
1407
//// the original copyright notice and the associated disclaimer. ////
1408
////                                                              ////
1409
//// This source file is free software; you can redistribute it   ////
1410
//// and/or modify it under the terms of the GNU Lesser General   ////
1411
//// Public License as published by the Free Software Foundation; ////
1412
//// either version 2.1 of the License, or (at your option) any   ////
1413
//// later version.                                               ////
1414
////                                                              ////
1415
//// This source is distributed in the hope that it will be       ////
1416
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1417
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1418
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1419
//// details.                                                     ////
1420
////                                                              ////
1421
//// You should have received a copy of the GNU Lesser General    ////
1422
//// Public License along with this source; if not, download it   ////
1423
//// from http://www.opencores.org/lgpl.shtml                     ////
1424
////                                                              ////
1425
//////////////////////////////////////////////////////////////////////
1426
 
1427
// BINARY counter
1428
module ref_delay_counter ( cke, zq, rst, clk);
1429
 
1430
   parameter length = 6;
1431
   input cke;
1432
   output reg zq;
1433
   input rst;
1434
   input clk;
1435
 
1436
   parameter clear_value = 0;
1437
   parameter set_value = 0;
1438
   parameter wrap_value = 12;
1439
 
1440
   reg  [length:1] qi;
1441
   wire [length:1] q_next;
1442
   assign q_next = qi + {{length-1{1'b0}},1'b1};
1443
 
1444
   always @ (posedge clk or posedge rst)
1445
     if (rst)
1446
       qi <= {length{1'b0}};
1447
     else
1448
     if (cke)
1449
       qi <= q_next;
1450
 
1451
 
1452
 
1453
   always @ (posedge clk or posedge rst)
1454
     if (rst)
1455
       zq <= 1'b1;
1456
     else
1457
     if (cke)
1458
       zq <= q_next == {length{1'b0}};
1459
endmodule
1460
//////////////////////////////////////////////////////////////////////
1461
////                                                              ////
1462
////  Versatile counter                                           ////
1463
////                                                              ////
1464
////  Description                                                 ////
1465
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1466
////  counter                                                     ////
1467
////                                                              ////
1468
////  To Do:                                                      ////
1469
////   - add LFSR with more taps                                  ////
1470
////                                                              ////
1471
////  Author(s):                                                  ////
1472
////      - Michael Unneback, unneback@opencores.org              ////
1473
////        ORSoC AB                                              ////
1474
////                                                              ////
1475
//////////////////////////////////////////////////////////////////////
1476
////                                                              ////
1477
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1478
////                                                              ////
1479
//// This source file may be used and distributed without         ////
1480
//// restriction provided that this copyright statement is not    ////
1481
//// removed from the file and that any derivative work contains  ////
1482
//// the original copyright notice and the associated disclaimer. ////
1483
////                                                              ////
1484
//// This source file is free software; you can redistribute it   ////
1485
//// and/or modify it under the terms of the GNU Lesser General   ////
1486
//// Public License as published by the Free Software Foundation; ////
1487
//// either version 2.1 of the License, or (at your option) any   ////
1488
//// later version.                                               ////
1489
////                                                              ////
1490
//// This source is distributed in the hope that it will be       ////
1491
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1492
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1493
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1494
//// details.                                                     ////
1495
////                                                              ////
1496
//// You should have received a copy of the GNU Lesser General    ////
1497
//// Public License along with this source; if not, download it   ////
1498
//// from http://www.opencores.org/lgpl.shtml                     ////
1499
////                                                              ////
1500
//////////////////////////////////////////////////////////////////////
1501
 
1502
// BINARY counter
1503
module pre_delay_counter ( cke, zq, rst, clk);
1504
 
1505
   parameter length = 2;
1506
   input cke;
1507
   output reg zq;
1508
   input rst;
1509
   input clk;
1510
 
1511
   parameter clear_value = 0;
1512
   parameter set_value = 0;
1513
   parameter wrap_value = 2;
1514
 
1515
   reg  [length:1] qi;
1516
   wire [length:1] q_next;
1517
   assign q_next = qi + {{length-1{1'b0}},1'b1};
1518
 
1519
   always @ (posedge clk or posedge rst)
1520
     if (rst)
1521
       qi <= {length{1'b0}};
1522
     else
1523
     if (cke)
1524
       qi <= q_next;
1525
 
1526
 
1527
 
1528
   always @ (posedge clk or posedge rst)
1529
     if (rst)
1530
       zq <= 1'b1;
1531
     else
1532
     if (cke)
1533
       zq <= q_next == {length{1'b0}};
1534
endmodule
1535
//////////////////////////////////////////////////////////////////////
1536
////                                                              ////
1537
////  Versatile counter                                           ////
1538
////                                                              ////
1539
////  Description                                                 ////
1540
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
1541
////  counter                                                     ////
1542
////                                                              ////
1543
////  To Do:                                                      ////
1544
////   - add LFSR with more taps                                  ////
1545
////                                                              ////
1546
////  Author(s):                                                  ////
1547
////      - Michael Unneback, unneback@opencores.org              ////
1548
////        ORSoC AB                                              ////
1549
////                                                              ////
1550
//////////////////////////////////////////////////////////////////////
1551
////                                                              ////
1552
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
1553
////                                                              ////
1554
//// This source file may be used and distributed without         ////
1555
//// restriction provided that this copyright statement is not    ////
1556
//// removed from the file and that any derivative work contains  ////
1557
//// the original copyright notice and the associated disclaimer. ////
1558
////                                                              ////
1559
//// This source file is free software; you can redistribute it   ////
1560
//// and/or modify it under the terms of the GNU Lesser General   ////
1561
//// Public License as published by the Free Software Foundation; ////
1562
//// either version 2.1 of the License, or (at your option) any   ////
1563
//// later version.                                               ////
1564
////                                                              ////
1565
//// This source is distributed in the hope that it will be       ////
1566
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
1567
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
1568
//// PURPOSE.  See the GNU Lesser General Public License for more ////
1569
//// details.                                                     ////
1570
////                                                              ////
1571
//// You should have received a copy of the GNU Lesser General    ////
1572
//// Public License along with this source; if not, download it   ////
1573
//// from http://www.opencores.org/lgpl.shtml                     ////
1574
////                                                              ////
1575
//////////////////////////////////////////////////////////////////////
1576
 
1577
// BINARY counter
1578
module burst_length_counter ( cke, zq, rst, clk);
1579
 
1580
   parameter length = 2;
1581
   input cke;
1582
   output reg zq;
1583
   input rst;
1584
   input clk;
1585
 
1586
   parameter clear_value = 0;
1587
   parameter set_value = 0;
1588
   parameter wrap_value = 3;
1589
 
1590
   reg  [length:1] qi;
1591
   wire [length:1] q_next;
1592
   assign q_next = (qi == wrap_value) ? {length{1'b0}} :qi + {{length-1{1'b0}},1'b1};
1593
 
1594
   always @ (posedge clk or posedge rst)
1595
     if (rst)
1596
       qi <= {length{1'b0}};
1597
     else
1598
     if (cke)
1599
       qi <= q_next;
1600
 
1601
 
1602
 
1603
   always @ (posedge clk or posedge rst)
1604
     if (rst)
1605
       zq <= 1'b1;
1606
     else
1607
     if (cke)
1608
       zq <= q_next == {length{1'b0}};
1609
endmodule
1610
 `timescale 1ns/1ns
1611
module ddr_16 (
1612
  output reg [14:0] a,
1613
  output reg adr_init,
1614
  output reg bl_en,
1615
  output reg [2:0] cmd,
1616
  output reg cs_n,
1617
  output reg [12:0] cur_row,
1618
  output reg fifo_re,
1619
  output reg read,
1620
  output reg ref_ack,
1621
  output reg ref_delay,
1622
  output reg state_idle,
1623
  output reg write,
1624
  input wire bl_ack,
1625
  input wire [3:0] burst_adr,
1626
  input wire clk,
1627
  input wire fifo_empty,
1628
  input wire fifo_re_d,
1629
  input wire [2:0] fifo_sel,
1630
  input wire ref_delay_ack,
1631
  input wire ref_req,
1632
  input wire rst,
1633
  input wire [35:0] tx_fifo_dat_o
1634
);
1635
  parameter
1636
  IDLE        = 0,
1637
  ACT_ROW     = 1,
1638
  AREF        = 2,
1639
  AREF_0      = 3,
1640
  AREF_1      = 4,
1641
  AWAIT_CMD   = 5,
1642
  LEMR2       = 6,
1643
  LEMR3       = 7,
1644
  LEMR_0      = 8,
1645
  LEMR_1      = 9,
1646
  LEMR_2      = 10,
1647
  LMR_0       = 11,
1648
  LMR_1       = 12,
1649
  NOP0        = 13,
1650
  NOP1        = 14,
1651
  NOP10       = 15,
1652
  NOP11       = 16,
1653
  NOP12       = 17,
1654
  NOP14       = 18,
1655
  NOP15       = 19,
1656
  NOP2        = 20,
1657
  NOP20       = 21,
1658
  NOP21       = 22,
1659
  NOP22       = 23,
1660
  NOP3        = 24,
1661
  NOP30       = 25,
1662
  NOP31       = 26,
1663
  NOP32       = 27,
1664
  NOP4        = 28,
1665
  NOP5        = 29,
1666
  NOP6        = 30,
1667
  NOP7        = 31,
1668
  NOP8        = 32,
1669
  NOP9        = 33,
1670
  NOP_tRFC    = 34,
1671
  NOP_tWR     = 35,
1672
  PRECHARGE   = 36,
1673
  PRE_0       = 37,
1674
  PRE_1       = 38,
1675
  READ_ADDR   = 39,
1676
  READ_BURST  = 40,
1677
  WRITE_ADDR  = 41,
1678
  WRITE_BURST = 42;
1679
  reg [42:0] state;
1680
  reg [42:0] nextstate;
1681
  always @* begin
1682
    nextstate = 43'b0000000000000000000000000000000000000000000;
1683
    adr_init = 1'b0;
1684
    bl_en = 1'b0;
1685
    fifo_re = 1'b0;
1686
    read = 1'b0;
1687
    ref_ack = 1'b0;
1688
    ref_delay = 1'b0;
1689
    state_idle = 1'b0;
1690
    write = 1'b0;
1691
    case (1'b1)
1692
      state[IDLE]       : begin
1693
        begin
1694
          nextstate[NOP0] = 1'b1;
1695
        end
1696
      end
1697
      state[ACT_ROW]    : begin
1698
        if (tx_fifo_dat_o[5]) begin
1699
          nextstate[NOP14] = 1'b1;
1700
        end
1701
        else begin
1702
          nextstate[NOP15] = 1'b1;
1703
        end
1704
      end
1705
      state[AREF]       : begin
1706
        ref_ack = 1'b1;
1707
        ref_delay = 1'b1;
1708
        begin
1709
          nextstate[NOP_tRFC] = 1'b1;
1710
        end
1711
      end
1712
      state[AREF_0]     : begin
1713
        ref_ack = 1'b1;
1714
        begin
1715
          nextstate[NOP7] = 1'b1;
1716
        end
1717
      end
1718
      state[AREF_1]     : begin
1719
        ref_ack = 1'b1;
1720
        begin
1721
          nextstate[NOP8] = 1'b1;
1722
        end
1723
      end
1724
      state[AWAIT_CMD]  : begin
1725
        adr_init = !fifo_empty;
1726
        state_idle = 1'b1;
1727
        if (ref_req) begin
1728
          nextstate[AREF] = 1'b1;
1729
        end
1730
        else if (!fifo_empty) begin
1731
          nextstate[NOP12] = 1'b1;
1732
        end
1733
        else begin
1734
          nextstate[AWAIT_CMD] = 1'b1;
1735
        end
1736
      end
1737
      state[LEMR2]      : begin
1738
        ref_ack = 1'b1;
1739
        begin
1740
          nextstate[NOP2] = 1'b1;
1741
        end
1742
      end
1743
      state[LEMR3]      : begin
1744
        ref_ack = 1'b1;
1745
        begin
1746
          nextstate[NOP3] = 1'b1;
1747
        end
1748
      end
1749
      state[LEMR_0]     : begin
1750
        ref_ack = 1'b1;
1751
        begin
1752
          nextstate[NOP4] = 1'b1;
1753
        end
1754
      end
1755
      state[LEMR_1]     : begin
1756
        ref_ack = 1'b1;
1757
        begin
1758
          nextstate[NOP10] = 1'b1;
1759
        end
1760
      end
1761
      state[LEMR_2]     : begin
1762
        ref_ack = 1'b1;
1763
        begin
1764
          nextstate[NOP11] = 1'b1;
1765
        end
1766
      end
1767
      state[LMR_0]      : begin
1768
        ref_ack = 1'b1;
1769
        begin
1770
          nextstate[NOP5] = 1'b1;
1771
        end
1772
      end
1773
      state[LMR_1]      : begin
1774
        ref_ack = 1'b1;
1775
        begin
1776
          nextstate[NOP9] = 1'b1;
1777
        end
1778
      end
1779
      state[NOP0]       : begin
1780
        begin
1781
          nextstate[PRE_0] = 1'b1;
1782
        end
1783
      end
1784
      state[NOP1]       : begin
1785
        if (ref_req) begin
1786
          nextstate[LEMR2] = 1'b1;
1787
        end
1788
        else begin
1789
          nextstate[NOP1] = 1'b1;
1790
        end
1791
      end
1792
      state[NOP10]      : begin
1793
        if (ref_req) begin
1794
          nextstate[LEMR_2] = 1'b1;
1795
        end
1796
        else begin
1797
          nextstate[NOP10] = 1'b1;
1798
        end
1799
      end
1800
      state[NOP11]      : begin
1801
        if (ref_req) begin
1802
          nextstate[AWAIT_CMD] = 1'b1;
1803
        end
1804
        else begin
1805
          nextstate[NOP11] = 1'b1;
1806
        end
1807
      end
1808
      state[NOP12]      : begin
1809
        begin
1810
          nextstate[ACT_ROW] = 1'b1;
1811
        end
1812
      end
1813
      state[NOP14]      : begin
1814
        begin
1815
          nextstate[WRITE_ADDR] = 1'b1;
1816
        end
1817
      end
1818
      state[NOP15]      : begin
1819
        begin
1820
          nextstate[READ_ADDR] = 1'b1;
1821
        end
1822
      end
1823
      state[NOP2]       : begin
1824
        if (ref_req) begin
1825
          nextstate[LEMR3] = 1'b1;
1826
        end
1827
        else begin
1828
          nextstate[NOP2] = 1'b1;
1829
        end
1830
      end
1831
      state[NOP20]      : begin
1832
        begin
1833
          nextstate[NOP21] = 1'b1;
1834
        end
1835
      end
1836
      state[NOP21]      : begin
1837
        adr_init = 1'b1;
1838
        fifo_re = 1'b1;
1839
        begin
1840
          nextstate[NOP22] = 1'b1;
1841
        end
1842
      end
1843
      state[NOP22]      : begin
1844
        begin
1845
          nextstate[NOP_tWR] = 1'b1;
1846
        end
1847
      end
1848
      state[NOP3]       : begin
1849
        if (ref_req) begin
1850
          nextstate[LEMR_0] = 1'b1;
1851
        end
1852
        else begin
1853
          nextstate[NOP3] = 1'b1;
1854
        end
1855
      end
1856
      state[NOP30]      : begin
1857
        begin
1858
          nextstate[NOP31] = 1'b1;
1859
        end
1860
      end
1861
      state[NOP31]      : begin
1862
        adr_init = 1'b1;
1863
        fifo_re = 1'b1;
1864
        begin
1865
          nextstate[NOP32] = 1'b1;
1866
        end
1867
      end
1868
      state[NOP32]      : begin
1869
        begin
1870
          nextstate[NOP_tWR] = 1'b1;
1871
        end
1872
      end
1873
      state[NOP4]       : begin
1874
        if (ref_req) begin
1875
          nextstate[LMR_0] = 1'b1;
1876
        end
1877
        else begin
1878
          nextstate[NOP4] = 1'b1;
1879
        end
1880
      end
1881
      state[NOP5]       : begin
1882
        if (ref_req) begin
1883
          nextstate[PRE_1] = 1'b1;
1884
        end
1885
        else begin
1886
          nextstate[NOP5] = 1'b1;
1887
        end
1888
      end
1889
      state[NOP6]       : begin
1890
        if (ref_req) begin
1891
          nextstate[AREF_0] = 1'b1;
1892
        end
1893
        else begin
1894
          nextstate[NOP6] = 1'b1;
1895
        end
1896
      end
1897
      state[NOP7]       : begin
1898
        if (ref_req) begin
1899
          nextstate[AREF_1] = 1'b1;
1900
        end
1901
        else begin
1902
          nextstate[NOP7] = 1'b1;
1903
        end
1904
      end
1905
      state[NOP8]       : begin
1906
        if (ref_req) begin
1907
          nextstate[LMR_1] = 1'b1;
1908
        end
1909
        else begin
1910
          nextstate[NOP8] = 1'b1;
1911
        end
1912
      end
1913
      state[NOP9]       : begin
1914
        if (ref_req) begin
1915
          nextstate[LEMR_1] = 1'b1;
1916
        end
1917
        else begin
1918
          nextstate[NOP9] = 1'b1;
1919
        end
1920
      end
1921
      state[NOP_tRFC]   : begin
1922
        ref_delay = !ref_delay_ack;
1923
        if (ref_delay_ack) begin
1924
          nextstate[AWAIT_CMD] = 1'b1;
1925
        end
1926
        else begin
1927
          nextstate[NOP_tRFC] = 1'b1;
1928
        end
1929
      end
1930
      state[NOP_tWR]    : begin
1931
        begin
1932
          nextstate[PRECHARGE] = 1'b1;
1933
        end
1934
      end
1935
      state[PRECHARGE]  : begin
1936
        begin
1937
          nextstate[AWAIT_CMD] = 1'b1;
1938
        end
1939
      end
1940
      state[PRE_0]      : begin
1941
        ref_ack = 1'b1;
1942
        begin
1943
          nextstate[NOP1] = 1'b1;
1944
        end
1945
      end
1946
      state[PRE_1]      : begin
1947
        ref_ack = 1'b1;
1948
        begin
1949
          nextstate[NOP6] = 1'b1;
1950
        end
1951
      end
1952
      state[READ_ADDR]  : begin
1953
        bl_en = 1'b1;
1954
        read = 1'b1;
1955
        begin
1956
          nextstate[READ_BURST] = 1'b1;
1957
        end
1958
      end
1959
      state[READ_BURST] : begin
1960
        bl_en = !bl_ack;
1961
        read = !bl_ack;
1962
        if (bl_ack) begin
1963
          nextstate[NOP30] = 1'b1;
1964
        end
1965
        else begin
1966
          nextstate[READ_BURST] = 1'b1;
1967
        end
1968
      end
1969
      state[WRITE_ADDR] : begin
1970
        bl_en = 1'b1;
1971
        write = 1'b1;
1972
        begin
1973
          nextstate[WRITE_BURST] = 1'b1;
1974
        end
1975
      end
1976
      state[WRITE_BURST]: begin
1977
        bl_en = !bl_ack;
1978
        fifo_re = 1'b1;
1979
        write = 1'b1;
1980
        if (bl_ack) begin
1981
          nextstate[NOP20] = 1'b1;
1982
        end
1983
        else begin
1984
          nextstate[WRITE_BURST] = 1'b1;
1985
        end
1986
      end
1987
    endcase
1988
  end
1989
  always @(posedge clk or posedge rst) begin
1990
    if (rst)
1991
      state <= 43'b0000000000000000000000000000000000000000001 << IDLE;
1992
    else
1993
      state <= nextstate;
1994
  end
1995
  always @(posedge clk or posedge rst) begin
1996
    if (rst) begin
1997
      a[14:0] <= 15'd0;
1998
      cmd[2:0] <= 3'b111;
1999
      cs_n <= 1'b1;
2000
      cur_row[12:0] <= cur_row;
2001
    end
2002
    else begin
2003
      a[14:0] <= 15'd0;
2004
      cmd[2:0] <= 3'b111;
2005
      cs_n <= 1'b0;
2006
      cur_row[12:0] <= cur_row;
2007
      case (1'b1)
2008
        nextstate[IDLE]       : begin
2009
          cs_n <= 1'b1;
2010
        end
2011
        nextstate[ACT_ROW]    : begin
2012
          a[14:0] <= {tx_fifo_dat_o[28:27],tx_fifo_dat_o[26:14]};
2013
          cmd[2:0] <= 3'b011;
2014
          cur_row[12:0] <= tx_fifo_dat_o[26:14];
2015
        end
2016
        nextstate[AREF]       : begin
2017
          a[14:0] <= a;
2018
          cmd[2:0] <= 3'b001;
2019
        end
2020
        nextstate[AREF_0]     : begin
2021
          a[14:0] <= a;
2022
          cmd[2:0] <= 3'b001;
2023
        end
2024
        nextstate[AREF_1]     : begin
2025
          a[14:0] <= a;
2026
          cmd[2:0] <= 3'b001;
2027
        end
2028
        nextstate[AWAIT_CMD]  : begin
2029
          a[14:0] <= a;
2030
          cs_n <= 1'b1;
2031
        end
2032
        nextstate[LEMR2]      : begin
2033
          a[14:0] <= {2'b10,5'b00000,1'b0,7'b0000000};
2034
          cmd[2:0] <= 3'b000;
2035
        end
2036
        nextstate[LEMR3]      : begin
2037
          a[14:0] <= {2'b11,13'b0000000000000};
2038
          cmd[2:0] <= 3'b000;
2039
        end
2040
        nextstate[LEMR_0]     : begin
2041
          a[14:0] <= {2'b01,1'b0,1'b0,1'b0,3'b000,1'b0,3'b000,1'b0,1'b0,1'b0};
2042
          cmd[2:0] <= 3'b000;
2043
        end
2044
        nextstate[LEMR_1]     : begin
2045
          a[14:0] <= {2'b01,1'b0,1'b0,1'b0,3'b111,1'b0,3'b000,1'b0,1'b0,1'b0};
2046
          cmd[2:0] <= 3'b000;
2047
        end
2048
        nextstate[LEMR_2]     : begin
2049
          a[14:0] <= {2'b01,1'b0,1'b0,1'b0,3'b000,1'b0,3'b000,1'b0,1'b0,1'b0};
2050
          cmd[2:0] <= 3'b000;
2051
        end
2052
        nextstate[LMR_0]      : begin
2053
          a[14:0] <= {2'b00,1'b0,3'b001,1'b1,1'b0,3'b100,1'b0,3'b011};
2054
          cmd[2:0] <= 3'b000;
2055
        end
2056
        nextstate[LMR_1]      : begin
2057
          a[14:0] <= {2'b00,1'b0,3'b001,1'b0,1'b0,3'b100,1'b0,3'b011};
2058
          cmd[2:0] <= 3'b000;
2059
        end
2060
        nextstate[NOP0]       : begin
2061
          a[14:0] <= a;
2062
        end
2063
        nextstate[NOP1]       : begin
2064
          a[14:0] <= a;
2065
        end
2066
        nextstate[NOP10]      : begin
2067
          a[14:0] <= a;
2068
        end
2069
        nextstate[NOP11]      : begin
2070
          a[14:0] <= a;
2071
        end
2072
        nextstate[NOP14]      : begin
2073
          a[14:0] <= a;
2074
        end
2075
        nextstate[NOP15]      : begin
2076
          a[14:0] <= a;
2077
        end
2078
        nextstate[NOP2]       : begin
2079
          a[14:0] <= a;
2080
        end
2081
        nextstate[NOP20]      : begin
2082
          a[14:0] <= a;
2083
        end
2084
        nextstate[NOP21]      : begin
2085
          a[14:0] <= a;
2086
        end
2087
        nextstate[NOP22]      : begin
2088
          a[14:0] <= a;
2089
        end
2090
        nextstate[NOP3]       : begin
2091
          a[14:0] <= a;
2092
        end
2093
        nextstate[NOP30]      : begin
2094
          a[14:0] <= a;
2095
        end
2096
        nextstate[NOP31]      : begin
2097
          a[14:0] <= a;
2098
        end
2099
        nextstate[NOP32]      : begin
2100
          a[14:0] <= a;
2101
        end
2102
        nextstate[NOP4]       : begin
2103
          a[14:0] <= a;
2104
        end
2105
        nextstate[NOP5]       : begin
2106
          a[14:0] <= a;
2107
        end
2108
        nextstate[NOP6]       : begin
2109
          a[14:0] <= a;
2110
        end
2111
        nextstate[NOP7]       : begin
2112
          a[14:0] <= a;
2113
        end
2114
        nextstate[NOP8]       : begin
2115
          a[14:0] <= a;
2116
        end
2117
        nextstate[NOP9]       : begin
2118
          a[14:0] <= a;
2119
        end
2120
        nextstate[NOP_tRFC]   : begin
2121
          a[14:0] <= a;
2122
        end
2123
        nextstate[NOP_tWR]    : begin
2124
          a[14:0] <= a;
2125
        end
2126
        nextstate[PRECHARGE]  : begin
2127
          a[14:0] <= {2'b00,13'b0010000000000};
2128
          cmd[2:0] <= 3'b010;
2129
        end
2130
        nextstate[PRE_0]      : begin
2131
          a[14:0] <= {2'b00,13'b0010000000000};
2132
          cmd[2:0] <= 3'b010;
2133
        end
2134
        nextstate[PRE_1]      : begin
2135
          a[14:0] <= {2'b00,13'b0010000000000};
2136
          cmd[2:0] <= 3'b010;
2137
        end
2138
        nextstate[READ_ADDR]  : begin
2139
          a[14:0] <= {tx_fifo_dat_o[28:27],{4'b0000,tx_fifo_dat_o[13:10],burst_adr,1'b0}};
2140
          cmd[2:0] <= 3'b101;
2141
        end
2142
        nextstate[READ_BURST] : begin
2143
          a[14:0] <= a;
2144
        end
2145
        nextstate[WRITE_ADDR] : begin
2146
          a[14:0] <= {tx_fifo_dat_o[28:27],{4'b0000,tx_fifo_dat_o[13:10],burst_adr,1'b0}};
2147
          cmd[2:0] <= 3'b100;
2148
        end
2149
        nextstate[WRITE_BURST]: begin
2150
          a[14:0] <= a;
2151
        end
2152
      endcase
2153
    end
2154
  end
2155
  reg [87:0] statename;
2156
  always @* begin
2157
    case (1'b1)
2158
      state[IDLE]       :
2159
        statename = "IDLE";
2160
      state[ACT_ROW]    :
2161
        statename = "ACT_ROW";
2162
      state[AREF]       :
2163
        statename = "AREF";
2164
      state[AREF_0]     :
2165
        statename = "AREF_0";
2166
      state[AREF_1]     :
2167
        statename = "AREF_1";
2168
      state[AWAIT_CMD]  :
2169
        statename = "AWAIT_CMD";
2170
      state[LEMR2]      :
2171
        statename = "LEMR2";
2172
      state[LEMR3]      :
2173
        statename = "LEMR3";
2174
      state[LEMR_0]     :
2175
        statename = "LEMR_0";
2176
      state[LEMR_1]     :
2177
        statename = "LEMR_1";
2178
      state[LEMR_2]     :
2179
        statename = "LEMR_2";
2180
      state[LMR_0]      :
2181
        statename = "LMR_0";
2182
      state[LMR_1]      :
2183
        statename = "LMR_1";
2184
      state[NOP0]       :
2185
        statename = "NOP0";
2186
      state[NOP1]       :
2187
        statename = "NOP1";
2188
      state[NOP10]      :
2189
        statename = "NOP10";
2190
      state[NOP11]      :
2191
        statename = "NOP11";
2192
      state[NOP12]      :
2193
        statename = "NOP12";
2194
      state[NOP14]      :
2195
        statename = "NOP14";
2196
      state[NOP15]      :
2197
        statename = "NOP15";
2198
      state[NOP2]       :
2199
        statename = "NOP2";
2200
      state[NOP20]      :
2201
        statename = "NOP20";
2202
      state[NOP21]      :
2203
        statename = "NOP21";
2204
      state[NOP22]      :
2205
        statename = "NOP22";
2206
      state[NOP3]       :
2207
        statename = "NOP3";
2208
      state[NOP30]      :
2209
        statename = "NOP30";
2210
      state[NOP31]      :
2211
        statename = "NOP31";
2212
      state[NOP32]      :
2213
        statename = "NOP32";
2214
      state[NOP4]       :
2215
        statename = "NOP4";
2216
      state[NOP5]       :
2217
        statename = "NOP5";
2218
      state[NOP6]       :
2219
        statename = "NOP6";
2220
      state[NOP7]       :
2221
        statename = "NOP7";
2222
      state[NOP8]       :
2223
        statename = "NOP8";
2224
      state[NOP9]       :
2225
        statename = "NOP9";
2226
      state[NOP_tRFC]   :
2227
        statename = "NOP_tRFC";
2228
      state[NOP_tWR]    :
2229
        statename = "NOP_tWR";
2230
      state[PRECHARGE]  :
2231
        statename = "PRECHARGE";
2232
      state[PRE_0]      :
2233
        statename = "PRE_0";
2234
      state[PRE_1]      :
2235
        statename = "PRE_1";
2236
      state[READ_ADDR]  :
2237
        statename = "READ_ADDR";
2238
      state[READ_BURST] :
2239
        statename = "READ_BURST";
2240
      state[WRITE_ADDR] :
2241
        statename = "WRITE_ADDR";
2242
      state[WRITE_BURST]:
2243
        statename = "WRITE_BURST";
2244
      default    :
2245
        statename = "XXXXXXXXXXX";
2246
    endcase
2247
  end
2248
endmodule
2249
module fsm_wb (
2250
               stall_i, stall_o,
2251
               we_i, cti_i, bte_i, stb_i, cyc_i, ack_o,
2252
               egress_fifo_we, egress_fifo_full,
2253
               ingress_fifo_re, ingress_fifo_empty,
2254
               state_idle,
2255
               sdram_burst_reading,
2256
               debug_state,
2257
               wb_clk, wb_rst
2258
               );
2259
 
2260
   input stall_i;
2261
   output stall_o;
2262
 
2263
   input [2:0] cti_i;
2264
   input [1:0] bte_i;
2265
   input       we_i, stb_i, cyc_i;
2266
   output      ack_o;
2267
   output      egress_fifo_we, ingress_fifo_re;
2268
   input       egress_fifo_full, ingress_fifo_empty;
2269
   input       sdram_burst_reading;
2270
   output      state_idle;
2271
   input       wb_clk, wb_rst;
2272
   output [1:0] debug_state;
2273
 
2274
 
2275
 
2276
   reg         ingress_fifo_read_reg;
2277
 
2278
   // bte
2279
   parameter linear       = 2'b00;
2280
   parameter wrap4        = 2'b01;
2281
   parameter wrap8        = 2'b10;
2282
   parameter wrap16       = 2'b11;
2283
   // cti
2284
   parameter classic      = 3'b000;
2285
   parameter endofburst   = 3'b111;
2286
 
2287
   parameter idle = 2'b00;
2288
   parameter rd   = 2'b01;
2289
   parameter wr   = 2'b10;
2290
   parameter fe   = 2'b11;
2291
   reg [1:0]   state;
2292
 
2293
   assign debug_state = state;
2294
 
2295
 
2296
   reg         sdram_burst_reading_1, sdram_burst_reading_2;
2297
   wire        sdram_burst_reading_wb_clk;
2298
 
2299
 
2300
   always @ (posedge wb_clk or posedge wb_rst)
2301
     if (wb_rst)
2302
       state <= idle;
2303
     else
2304
       case (state)
2305
         idle:
2306
           if (we_i & stb_i & cyc_i & !egress_fifo_full & !stall_i)
2307
             state <= wr;
2308
           else if (!we_i & stb_i & cyc_i & !egress_fifo_full & !stall_i)
2309
             state <= rd;
2310
         wr:
2311
           if ((cti_i==classic | cti_i==endofburst | bte_i==linear) &
2312
               stb_i & cyc_i & !egress_fifo_full & !stall_i)
2313
             state <= idle;
2314
         rd:
2315
           if ((cti_i==classic | cti_i==endofburst | bte_i==linear) &
2316
               stb_i & cyc_i & ack_o)
2317
             state <= fe;
2318
         fe:
2319
           if (ingress_fifo_empty & !sdram_burst_reading_wb_clk)
2320
             state <= idle;
2321
         default: ;
2322
       endcase
2323
 
2324
   assign state_idle = (state==idle);
2325
 
2326
   assign stall_o = (stall_i) ? 1'b1 :
2327
                    (state==idle & stb_i & cyc_i & !egress_fifo_full) ? 1'b1 :
2328
                    (state==wr   & stb_i & cyc_i & !egress_fifo_full) ? 1'b1 :
2329
                    (state==rd   & stb_i & cyc_i & !ingress_fifo_empty) ? 1'b1 :
2330
                    (state==fe   & !ingress_fifo_empty) ? 1'b1 :
2331
                    1'b0;
2332
 
2333
   assign egress_fifo_we = (state==idle & stb_i & cyc_i & !egress_fifo_full & !stall_i) ? 1'b1 :
2334
                           (state==wr   & stb_i & cyc_i & !egress_fifo_full & !stall_i) ? 1'b1 :
2335
                           1'b0;
2336
 
2337
   assign ingress_fifo_re = (state==rd & stb_i & cyc_i & !ingress_fifo_empty & !stall_i) ? 1'b1 :
2338
                            (state==fe & !ingress_fifo_empty & !stall_i) ? 1'b1:
2339
                            1'b0;
2340
 
2341
   always @ (posedge wb_clk or posedge wb_rst)
2342
     if (wb_rst)
2343
       ingress_fifo_read_reg <= 1'b0;
2344
     else
2345
       ingress_fifo_read_reg <= ingress_fifo_re;
2346
 
2347
   /*assign ack_o = (ingress_fifo_read_reg & stb_i) ? 1'b1 :
2348
                  (state==fe) ? 1'b0 :
2349
                  (state==wr & stb_i & cyc_i & !egress_fifo_full & !stall_i) ? 1'b1 :
2350
                  1'b0;*/
2351
 
2352
   assign ack_o = !(state==fe) & ((ingress_fifo_read_reg & stb_i) | (state==wr & stb_i & cyc_i & !egress_fifo_full & !stall_i));
2353
 
2354
 
2355
   // Sample the SDRAM burst reading signal in WB domain
2356
   always @(posedge wb_clk)
2357
     sdram_burst_reading_1 <= sdram_burst_reading;
2358
 
2359
   always @(posedge wb_clk)
2360
     sdram_burst_reading_2 <= sdram_burst_reading_1;
2361
 
2362
   assign sdram_burst_reading_wb_clk = sdram_burst_reading_2;
2363
 
2364
endmodule`timescale 1ns/1ns
2365
module delay (d, q, clk, rst);
2366
 
2367
   parameter width = 4;
2368
   parameter depth = 3;
2369
 
2370
   input  [width-1:0] d;
2371
   output [width-1:0] q;
2372
   input              clk;
2373
   input              rst;
2374
 
2375
   reg [width-1:0] dffs [1:depth];
2376
 
2377
   integer i;
2378
 
2379
   always @ (posedge clk or posedge rst)
2380
     if (rst)
2381
       for ( i=1; i <= depth; i=i+1)
2382
         dffs[i] <= {width{1'b0}};
2383
     else
2384
       begin
2385
          dffs[1] <= d;
2386
          for ( i=2; i <= depth; i=i+1 )
2387
            dffs[i] <= dffs[i-1];
2388
       end
2389
 
2390
   assign q = dffs[depth];
2391
 
2392
endmodule //delay
2393
 
2394
 
2395
`include "versatile_mem_ctrl_defines.v"
2396
 
2397
module ddr_ff_in
2398
  (
2399
   input  C0,   // clock
2400
   input  C1,   // clock
2401
   input  D,    // data input
2402
   input  CE,   // clock enable
2403
   output Q0,   // data output
2404
   output Q1,   // data output
2405
   input  R,    // reset
2406
   input  S     // set
2407
   );
2408
 
2409
`ifdef XILINX
2410
   IDDR2 #(
2411
     .DDR_ALIGNMENT("NONE"),
2412
     .INIT_Q0(1'b0),
2413
     .INIT_Q1(1'b0),
2414
     .SRTYPE("SYNC"))
2415
   IDDR2_inst (
2416
     .Q0(Q0),
2417
     .Q1(Q1),
2418
     .C0(C0),
2419
     .C1(C1),
2420
     .CE(CE),
2421
     .D(D),
2422
     .R(R),
2423
     .S(S)
2424
   );
2425
`endif   // XILINX
2426
 
2427
`ifdef ALTERA
2428
   altddio_in #(
2429
     .WIDTH(1),
2430
     .POWER_UP_HIGH("OFF"),
2431
     .INTENDED_DEVICE_FAMILY("Stratix III"))
2432
   altddio_in_inst (
2433
     .aset(),
2434
     .datain(D),
2435
     .inclocken(CE),
2436
     .inclock(C0),
2437
     .aclr(R),
2438
     .dataout_h(Q0),
2439
     .dataout_l(Q1)
2440
   );
2441
`endif   // ALTERA
2442
 
2443
`ifdef GENERIC_PRIMITIVES
2444
   reg Q0_i, Q1_i;
2445
   always @ (posedge R or posedge C0)
2446
     if (R)
2447
       Q0_i <= 1'b0;
2448
     else
2449
       Q0_i <= D;
2450
 
2451
   assign Q0 = Q0_i;
2452
 
2453
   always @ (posedge R or posedge C1)
2454
     if (R)
2455
       Q1_i <= 1'b0;
2456
     else
2457
       Q1_i <= D;
2458
 
2459
   assign Q1 = Q1_i;
2460
`endif   // GENERIC_PRIMITIVES
2461
 
2462
endmodule   // ddr_ff_in
2463
 
2464
 
2465
module ddr_ff_out
2466
  (
2467
   input  C0,   // clock
2468
   input  C1,   // clock
2469
   input  D0,   // data input
2470
   input  D1,   // data input
2471
   input  CE,   // clock enable
2472
   output Q,    // data output
2473
   input  R,    // reset
2474
   input  S     // set
2475
   );
2476
 
2477
`ifdef XILINX
2478
   ODDR2 #(
2479
     .DDR_ALIGNMENT("NONE"),
2480
     .INIT(1'b0),
2481
     .SRTYPE("SYNC"))
2482
   ODDR2_inst (
2483
     .Q(Q),
2484
     .C0(C0),
2485
     .C1(C1),
2486
     .CE(CE),
2487
     .D0(D0),
2488
     .D1(D1),
2489
     .R(R),
2490
     .S(S)
2491
   );
2492
`endif   // XILINX
2493
 
2494
`ifdef ALTERA
2495
   altddio_out #(
2496
     .WIDTH(1),
2497
     .POWER_UP_HIGH("OFF"),
2498
     .INTENDED_DEVICE_FAMILY("Stratix III"),
2499
     .OE_REG("UNUSED"))
2500
   altddio_out_inst (
2501
     .aset(),
2502
     .datain_h(D0),
2503
     .datain_l(D1),
2504
     .outclocken(CE),
2505
     .outclock(C0),
2506
     .aclr(R),
2507
     .dataout(Q)
2508
   );
2509
`endif   // ALTERA
2510
 
2511
`ifdef GENERIC_PRIMITIVES
2512
   reg Q0, Q1;
2513
   always @ (posedge R or posedge C0)
2514
     if (R)
2515
       Q0 <= 1'b0;
2516
     else
2517
       Q0 <= D0;
2518
 
2519
   always @ (posedge R or posedge C1)
2520
     if (R)
2521
       Q1 <= 1'b0;
2522
     else
2523
       Q1 <= D1;
2524
 
2525
   assign Q = C0 ? Q0 : Q1;
2526
`endif   // GENERIC_PRIMITIVES
2527
 
2528
endmodule   // ddr_ff_out
2529
 
2530
`include "versatile_mem_ctrl_defines.v"
2531
 
2532
module dcm_pll
2533
  (
2534
   input  rst,          // reset
2535
   input  clk_in,       // clock in
2536
   input  clkfb_in,     // feedback clock in
2537
   output clk0_out,     // clock out
2538
   output clk90_out,    // clock out, 90 degree phase shift
2539
   output clk180_out,   // clock out, 180 degree phase shift
2540
   output clk270_out,   // clock out, 270 degree phase shift
2541
   output clkfb_out     // feedback clock out
2542
   );
2543
 
2544
`ifdef XILINX
2545
   wire clk_in_ibufg;
2546
   wire clk0_bufg, clk90_bufg, clk180_bufg, clk270_bufg;
2547
   // DCM with internal feedback
2548
   DCM #(
2549
      .CLKDV_DIVIDE(2.0),
2550
      .CLKFX_DIVIDE(1),
2551
      .CLKFX_MULTIPLY(4),
2552
      .CLKIN_DIVIDE_BY_2("FALSE"),
2553
      .CLKIN_PERIOD(8.0),
2554
      .CLKOUT_PHASE_SHIFT("NONE"),
2555
      .CLK_FEEDBACK("1X"),
2556
      .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
2557
      .DLL_FREQUENCY_MODE("LOW"),
2558
      .DUTY_CYCLE_CORRECTION("TRUE"),
2559
      .PHASE_SHIFT(0),
2560
      .STARTUP_WAIT("FALSE"))
2561
   DCM_internal (
2562
      .CLK0(clk0_bufg),
2563
      .CLK180(clk180_bufg),
2564
      .CLK270(clk270_bufg),
2565
      .CLK2X(),
2566
      .CLK2X180(),
2567
      .CLK90(clk90_bufg),
2568
      .CLKDV(),
2569
      .CLKFX(),
2570
      .CLKFX180(),
2571
      .LOCKED(),
2572
      .PSDONE(),
2573
      .STATUS(),
2574
      .CLKFB(clk0_out),
2575
      .CLKIN(clk_in_ibufg),
2576
      .DSSEN(),
2577
      .PSCLK(),
2578
      .PSEN(),
2579
      .PSINCDEC(),
2580
      .RST(rst)
2581
   );
2582
   // DCM with external feedback
2583
   DCM #(
2584
      .CLKDV_DIVIDE(2.0),
2585
      .CLKFX_DIVIDE(1),
2586
      .CLKFX_MULTIPLY(4),
2587
      .CLKIN_DIVIDE_BY_2("FALSE"),
2588
      .CLKIN_PERIOD(8.0),
2589
      .CLKOUT_PHASE_SHIFT("NONE"),
2590
      .CLK_FEEDBACK("1X"),
2591
      .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
2592
      .DLL_FREQUENCY_MODE("LOW"),
2593
      .DUTY_CYCLE_CORRECTION("TRUE"),
2594
      .PHASE_SHIFT(0),
2595
      .STARTUP_WAIT("FALSE"))
2596
   DCM_external (
2597
      .CLK0(clkfb_bufg),
2598
      .CLK180(),
2599
      .CLK270(),
2600
      .CLK2X(),
2601
      .CLK2X180(),
2602
      .CLK90(),
2603
      .CLKDV(),
2604
      .CLKFX(),
2605
      .CLKFX180(),
2606
      .LOCKED(),
2607
      .PSDONE(),
2608
      .STATUS(),
2609
      .CLKFB(clkfb_ibufg),
2610
      .CLKIN(clk_in_ibufg),
2611
      .DSSEN(),
2612
      .PSCLK(),
2613
      .PSEN(),
2614
      .PSINCDEC(),
2615
      .RST(rst)
2616
   );
2617
 
2618
   // Input buffer on DCM clock source
2619
   IBUFG IBUFG_clk (
2620
     .I(clk_in),
2621
     .O(clk_in_ibufg));
2622
 
2623
   // Global buffers on DCM generated clocks
2624
   BUFG BUFG_0 (
2625
     .I(clk0_bufg),
2626
     .O(clk0_out));
2627
   BUFG BUFG_90 (
2628
     .I(clk90_bufg),
2629
     .O(clk90_out));
2630
   BUFG BUFG_180 (
2631
     .I(clk180_bufg),
2632
     .O(clk180_out));
2633
   BUFG BUFG_270 (
2634
     .I(clk270_bufg),
2635
     .O(clk270_out));
2636
 
2637
   // External feedback to DCM
2638
   IBUFG IBUFG_clkfb (
2639
     .I(clkfb_in),
2640
     .O(clkfb_ibufg));
2641
   OBUF OBUF_clkfb (
2642
     .I(clkfb_bufg),
2643
     .O(clkfb_out));
2644
`endif   // XILINX
2645
 
2646
 
2647
`ifdef ALTERA
2648
   wire [9:0] sub_wire0;
2649
   wire [0:0] sub_wire8 = 1'h0;
2650
   wire [3:3] sub_wire4 = sub_wire0[3:3];
2651
   wire [2:2] sub_wire3 = sub_wire0[2:2];
2652
   wire [1:1] sub_wire2 = sub_wire0[1:1];
2653
   wire [0:0] sub_wire1 = sub_wire0[0:0];
2654
   wire       sub_wire6 = clk_in;
2655
   wire [1:0] sub_wire7 = {sub_wire8, sub_wire6};
2656
 
2657
   assign clk0_out   = sub_wire1;
2658
   assign clk90_out  = sub_wire2;
2659
   assign clk180_out = sub_wire3;
2660
   assign clk270_out = sub_wire4;
2661
 
2662
   // PLL with external feedback
2663
   altpll #(
2664
     .bandwidth_type("AUTO"),
2665
     .clk0_divide_by(1),
2666
     .clk0_duty_cycle(50),
2667
     .clk0_multiply_by(1),
2668
     .clk0_phase_shift("0"),
2669
     .clk1_divide_by(1),
2670
     .clk1_duty_cycle(50),
2671
     .clk1_multiply_by(1),
2672
     .clk1_phase_shift("1250"),
2673
     .clk2_divide_by(1),
2674
     .clk2_duty_cycle(50),
2675
     .clk2_multiply_by(1),
2676
     .clk2_phase_shift("2500"),
2677
     .clk3_divide_by(1),
2678
     .clk3_duty_cycle(50),
2679
     .clk3_multiply_by(1),
2680
     .clk3_phase_shift("3750"),
2681
     .compensate_clock("CLK0"),
2682
     .inclk0_input_frequency(5000),
2683
     .intended_device_family("Stratix III"),
2684
     .lpm_hint("UNUSED"),
2685
     .lpm_type("altpll"),
2686
     .operation_mode("NORMAL"),
2687
//   .operation_mode("SOURCE_SYNCHRONOUS"),
2688
     .pll_type("AUTO"),
2689
     .port_activeclock("PORT_UNUSED"),
2690
     .port_areset("PORT_USED"),
2691
     .port_clkbad0("PORT_UNUSED"),
2692
     .port_clkbad1("PORT_UNUSED"),
2693
     .port_clkloss("PORT_UNUSED"),
2694
     .port_clkswitch("PORT_UNUSED"),
2695
     .port_configupdate("PORT_UNUSED"),
2696
     .port_fbin("PORT_USED"),
2697
     .port_fbout("PORT_USED"),
2698
     .port_inclk0("PORT_USED"),
2699
     .port_inclk1("PORT_UNUSED"),
2700
     .port_locked("PORT_UNUSED"),
2701
     .port_pfdena("PORT_UNUSED"),
2702
     .port_phasecounterselect("PORT_UNUSED"),
2703
     .port_phasedone("PORT_UNUSED"),
2704
     .port_phasestep("PORT_UNUSED"),
2705
     .port_phaseupdown("PORT_UNUSED"),
2706
     .port_pllena("PORT_UNUSED"),
2707
     .port_scanaclr("PORT_UNUSED"),
2708
     .port_scanclk("PORT_UNUSED"),
2709
     .port_scanclkena("PORT_UNUSED"),
2710
     .port_scandata("PORT_UNUSED"),
2711
     .port_scandataout("PORT_UNUSED"),
2712
     .port_scandone("PORT_UNUSED"),
2713
     .port_scanread("PORT_UNUSED"),
2714
     .port_scanwrite("PORT_UNUSED"),
2715
     .port_clk0("PORT_USED"),
2716
     .port_clk1("PORT_USED"),
2717
     .port_clk2("PORT_USED"),
2718
     .port_clk3("PORT_USED"),
2719
     .port_clk4("PORT_UNUSED"),
2720
     .port_clk5("PORT_UNUSED"),
2721
     .port_clk6("PORT_UNUSED"),
2722
     .port_clk7("PORT_UNUSED"),
2723
     .port_clk8("PORT_UNUSED"),
2724
     .port_clk9("PORT_UNUSED"),
2725
     .port_clkena0("PORT_UNUSED"),
2726
     .port_clkena1("PORT_UNUSED"),
2727
     .port_clkena2("PORT_UNUSED"),
2728
     .port_clkena3("PORT_UNUSED"),
2729
     .port_clkena4("PORT_UNUSED"),
2730
     .port_clkena5("PORT_UNUSED"),
2731
     .using_fbmimicbidir_port("OFF"),
2732
     .width_clock(10))
2733
   altpll_internal (
2734
     .fbin (),//(clkfb_in),
2735
     .inclk (sub_wire7),
2736
     .areset (rst),
2737
     .clk (sub_wire0),
2738
     .fbout (),//(clkfb_out),
2739
     .activeclock (),
2740
     .clkbad (),
2741
     .clkena ({6{1'b1}}),
2742
     .clkloss (),
2743
     .clkswitch (1'b0),
2744
     .configupdate (1'b0),
2745
     .enable0 (),
2746
     .enable1 (),
2747
     .extclk (),
2748
     .extclkena ({4{1'b1}}),
2749
     .fbmimicbidir (),
2750
     .locked (),
2751
     .pfdena (1'b1),
2752
     .phasecounterselect ({4{1'b1}}),
2753
     .phasedone (),
2754
     .phasestep (1'b1),
2755
     .phaseupdown (1'b1),
2756
     .pllena (1'b1),
2757
     .scanaclr (1'b0),
2758
     .scanclk (1'b0),
2759
     .scanclkena (1'b1),
2760
     .scandata (1'b0),
2761
     .scandataout (),
2762
     .scandone (),
2763
     .scanread (1'b0),
2764
     .scanwrite (1'b0),
2765
     .sclkout0 (),
2766
     .sclkout1 (),
2767
     .vcooverrange (),
2768
     .vcounderrange ()
2769
   );
2770
`endif   // ALTERA
2771
 
2772
//`ifdef GENERIC_PRIMITIVES
2773
//`endif   // GENERIC_PRIMITIVES
2774
 
2775
 
2776
endmodule   // dcm_pll
2777
 
2778
 
2779
//////////////////////////////////////////////////////////////////////
2780
////                                                              ////
2781
////  Versatile counter                                           ////
2782
////                                                              ////
2783
////  Description                                                 ////
2784
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
2785
////  counter                                                     ////
2786
////                                                              ////
2787
////  To Do:                                                      ////
2788
////   - add LFSR with more taps                                  ////
2789
////                                                              ////
2790
////  Author(s):                                                  ////
2791
////      - Michael Unneback, unneback@opencores.org              ////
2792
////        ORSoC AB                                              ////
2793
////                                                              ////
2794
//////////////////////////////////////////////////////////////////////
2795
////                                                              ////
2796
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
2797
////                                                              ////
2798
//// This source file may be used and distributed without         ////
2799
//// restriction provided that this copyright statement is not    ////
2800
//// removed from the file and that any derivative work contains  ////
2801
//// the original copyright notice and the associated disclaimer. ////
2802
////                                                              ////
2803
//// This source file is free software; you can redistribute it   ////
2804
//// and/or modify it under the terms of the GNU Lesser General   ////
2805
//// Public License as published by the Free Software Foundation; ////
2806
//// either version 2.1 of the License, or (at your option) any   ////
2807
//// later version.                                               ////
2808
////                                                              ////
2809
//// This source is distributed in the hope that it will be       ////
2810
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
2811
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
2812
//// PURPOSE.  See the GNU Lesser General Public License for more ////
2813
//// details.                                                     ////
2814
////                                                              ////
2815
//// You should have received a copy of the GNU Lesser General    ////
2816
//// Public License along with this source; if not, download it   ////
2817
//// from http://www.opencores.org/lgpl.shtml                     ////
2818
////                                                              ////
2819
//////////////////////////////////////////////////////////////////////
2820
 
2821
module dff_sr ( aclr, aset, clock, data, q);
2822
 
2823
    input         aclr;
2824
    input         aset;
2825
    input         clock;
2826
    input         data;
2827
    output reg    q;
2828
 
2829
   always @ (posedge clock or posedge aclr or posedge aset)
2830
     if (aclr)
2831
       q <= 1'b0;
2832
     else if (aset)
2833
       q <= 1'b1;
2834
     else
2835
       q <= data;
2836
 
2837
endmodule
2838
module versatile_mem_ctrl_ddr (
2839
  // DDR2 SDRAM side
2840
  ck_o, ck_n_o,
2841
  dq_io, dqs_io, dqs_n_io,
2842
  dm_rdqs_io,
2843
  //rdqs_n_i, odt_o, 
2844
  // Memory controller side
2845
  tx_dat_i, rx_dat_o,
2846
  dq_en, dqm_en,
2847
  rst, clk_0, clk_90, clk_180, clk_270
2848
  );
2849
 
2850
  output        ck_o;
2851
  output        ck_n_o;
2852
  inout  [15:0] dq_io;
2853
  inout   [1:0] dqs_io;
2854
  inout   [1:0] dqs_n_io;
2855
  inout   [1:0] dm_rdqs_io;
2856
  //input   [1:0] rdqs_n_i;
2857
  //output        odt_o;
2858
  input  [35:0] tx_dat_i;
2859
  output [31:0] rx_dat_o;
2860
  input         dq_en;
2861
  input         dqm_en;
2862
  input         rst;
2863
  input         clk_0;
2864
  input         clk_90;
2865
  input         clk_180;
2866
  input         clk_270;
2867
 
2868
  reg    [31:0] dq_rx_reg;
2869
  wire   [31:0] dq_rx;
2870
  wire    [1:0] dqs_o, dqs_n_o, dqm_o;
2871
  wire   [15:0] dq_o;
2872
  wire    [1:0] dqs_delayed, dqs_n_delayed;
2873
 
2874
  wire   [15:0] dq_iobuf;
2875
  wire    [1:0] dqs_iobuf, dqs_n_iobuf;
2876
 
2877
  genvar        i;
2878
 
2879
///////////////////////////////////////////////////////////////////////////////
2880
// Common for both Xilinx and Altera
2881
///////////////////////////////////////////////////////////////////////////////
2882
 
2883
  // Generate clock with equal delay as data
2884
  ddr_ff_out ddr_ff_out_ck (
2885
    .Q(ck_o),
2886
    .C0(clk_0),
2887
    .C1(clk_180),
2888
    .CE(1'b1),
2889
    .D0(1'b1),
2890
    .D1(1'b0),
2891
    .R(1'b0),
2892
    .S(1'b0));
2893
 
2894
  ddr_ff_out ddr_ff_out_ck_n (
2895
    .Q(ck_n_o),
2896
    .C0(clk_0),
2897
    .C1(clk_180),
2898
    .CE(1'b1),
2899
    .D0(1'b0),
2900
    .D1(1'b1),
2901
    .R(wb_rst),
2902
    .S(1'b0));
2903
 
2904
  // Generate strobe with equal delay as data
2905
  generate
2906
    for (i=0; i<2; i=i+1) begin:dqs_oddr
2907
      ddr_ff_out ddr_ff_out_dqs (
2908
        .Q(dqs_o[i]),
2909
        .C0(clk_0),
2910
        .C1(clk_180),
2911
        .CE(1'b1),
2912
        .D0(1'b1),
2913
        .D1(1'b0),
2914
        .R(1'b0),
2915
        .S(1'b0));
2916
    end
2917
  endgenerate
2918
 
2919
  generate
2920
    for (i=0; i<2; i=i+1) begin:dqs_n_oddr
2921
      ddr_ff_out ddr_ff_out_dqs_n (
2922
        .Q(dqs_n_o[i]),
2923
        .C0(clk_0),
2924
        .C1(clk_180),
2925
        .CE(1'b1),
2926
        .D0(1'b0),
2927
        .D1(1'b1),
2928
        .R(wb_rst),
2929
        .S(1'b0));
2930
    end
2931
  endgenerate
2932
 
2933
 
2934
 
2935
///////////////////////////////////////////////////////////////////////////////
2936
// Xilinx
2937
///////////////////////////////////////////////////////////////////////////////
2938
 
2939
`ifdef XILINX
2940
 
2941
  reg  [15:0] dq_tx_reg;
2942
  wire [15:0] dq_tx;
2943
  reg   [3:0] dqm_tx_reg;
2944
  wire  [3:0] dqm_tx;
2945
 
2946
  // IO BUFFER
2947
  // DDR data to/from DDR2 SDRAM
2948
  generate
2949
    for (i=0; i<16; i=i+1) begin:iobuf_dq
2950
      IOBUF u_iobuf_dq (
2951
        .I(dq_o[i]),
2952
        .T(!dq_en),
2953
        .IO(dq_io[i]),
2954
        .O(dq_iobuf[i]));
2955
    end
2956
  endgenerate
2957
 
2958
  // DQS strobe to/from DDR2 SDRAM
2959
  generate
2960
    for (i=0; i<2; i=i+1) begin:iobuf_dqs
2961
      IOBUF u_iobuf_dqs (
2962
        .I(dqs_o[i]),
2963
        .T(!dq_en),
2964
        .IO(dqs_io[i]),
2965
        .O(dqs_iobuf[i]));
2966
    end
2967
  endgenerate
2968
 
2969
  // DQS strobe to/from DDR2 SDRAM
2970
  generate
2971
    for (i=0; i<2; i=i+1) begin:iobuf_dqs_n
2972
      IOBUF u_iobuf_dqs_n (
2973
        .I(dqs_n_o[i]),
2974
        .T(!dq_en),
2975
        .IO(dqs_n_io[i]),
2976
        .O(dqs_n_iobuf[i]));
2977
    end
2978
  endgenerate
2979
 
2980
 
2981
  // Data from Tx FIFO
2982
  always @ (posedge clk_270 or posedge wb_rst)
2983
    if (wb_rst)
2984
      dq_tx_reg[15:0] <= 16'h0;
2985
    else
2986
      if (dqm_en)
2987
        dq_tx_reg[15:0] <= tx_dat_i[19:4];
2988
      else
2989
        dq_tx_reg[15:0] <= tx_dat_i[19:4];
2990
 
2991
  assign dq_tx[15:0] = tx_dat_i[35:20];
2992
 
2993
  // Output Data DDR flip-flops
2994
  generate
2995
    for (i=0; i<16; i=i+1) begin:data_out_oddr
2996
      ddr_ff_out ddr_ff_out_inst_0 (
2997
        .Q(dq_o[i]),
2998
        .C0(clk_270),
2999
        .C1(clk_90),
3000
        .CE(dq_en),
3001
        .D0(dq_tx[i]),
3002
        .D1(dq_tx_reg[i]),
3003
        .R(wb_rst),
3004
        .S(1'b0));
3005
    end
3006
  endgenerate
3007
 
3008
  // Data mask from Tx FIFO
3009
  always @ (posedge clk_270 or posedge wb_rst)
3010
    if (wb_rst)
3011
      dqm_tx_reg[1:0] <= 2'b00;
3012
    else
3013
      if (dqm_en)
3014
        dqm_tx_reg[1:0] <= 2'b00;
3015
      else
3016
        dqm_tx_reg[1:0] <= tx_dat_i[1:0];
3017
 
3018
  always @ (posedge clk_180 or posedge wb_rst)
3019
    if (wb_rst)
3020
      dqm_tx_reg[3:2] <= 2'b00;
3021
    else
3022
      if (dqm_en)
3023
        dqm_tx_reg[3:2] <= 2'b00;
3024
      else
3025
        dqm_tx_reg[3:2] <= tx_dat_i[3:2];
3026
 
3027
  assign dqm_tx[1:0] = (dqm_en) ? 2'b00 : tx_dat_i[3:2];
3028
 
3029
  // Mask output DDR flip-flops
3030
  generate
3031
    for (i=0; i<2; i=i+1) begin:data_mask_oddr
3032
      ddr_ff_out ddr_ff_out_inst_1 (
3033
        .Q(dqm_o[i]),
3034
        .C0(clk_270),
3035
        .C1(clk_90),
3036
        .CE(dq_en),
3037
        .D0(!dqm_tx[i]),
3038
        .D1(!dqm_tx_reg[i]),
3039
        .R(wb_rst),
3040
        .S(1'b0));
3041
    end
3042
  endgenerate
3043
 
3044
  // Data mask to DDR2 SDRAM
3045
  generate
3046
    for (i=0; i<2; i=i+1) begin:iobuf_dqm
3047
      IOBUF u_iobuf_dqm (
3048
        .I(dqm_o[i]),
3049
        .T(!dq_en),
3050
        .IO(dm_rdqs_io[i]),
3051
        .O());
3052
    end
3053
  endgenerate
3054
 
3055
 
3056
`ifdef INT_CLOCKED_DATA_CAPTURE
3057
  // Data in
3058
  // DDR flip-flops
3059
  generate
3060
    for (i=0; i<16; i=i+1) begin:iddr2gen
3061
      ddr_ff_in ddr_ff_in_inst_0 (
3062
        .Q0(dq_rx[i]),
3063
        .Q1(dq_rx[i+16]),
3064
        .C0(clk_270),
3065
        .C1(clk_90),
3066
        .CE(1'b1),
3067
        .D(dq_io[i]),
3068
        .R(wb_rst),
3069
        .S(1'b0));
3070
    end
3071
  endgenerate
3072
 
3073
  // Data to Rx FIFO
3074
  always @ (posedge clk_0 or posedge wb_rst)
3075
    if (wb_rst)
3076
      dq_rx_reg[31:16] <= 16'h0;
3077
    else
3078
      dq_rx_reg[31:16] <= dq_rx[31:16];
3079
 
3080
  always @ (posedge clk_180 or posedge wb_rst)
3081
    if (wb_rst)
3082
      dq_rx_reg[15:0] <= 16'h0;
3083
    else
3084
      dq_rx_reg[15:0] <= dq_rx[15:0];
3085
 
3086
  assign rx_dat_o = dq_rx_reg;
3087
`endif   // INT_CLOCKED_DATA_CAPTURE
3088
 
3089
 
3090
`ifdef DEL_DQS_DATA_CAPTURE_1
3091
 
3092
  wire  [1:0] dqs_iodelay, dqs_n_iodelay;
3093
 
3094
  // Delay DQS
3095
  assign # 2 dqs_iodelay   = dqs_iobuf;
3096
  assign # 2 dqs_n_iodelay = dqs_n_iobuf;
3097
 
3098
  // IDDR FF
3099
  generate
3100
    for (i=0; i<16; i=i+1) begin:iddr_dq
3101
      ddr_ff_in ddr_ff_in_inst_0 (
3102
        .Q0(dq_rx[i]),
3103
        .Q1(dq_rx[i+16]),
3104
        .C0(dqs_iodelay[0]),
3105
        .C1(dqs_n_iodelay[0]),
3106
        .CE(1'b1),
3107
        .D(dq_iobuf[i]),
3108
        .R(wb_rst),
3109
        .S(1'b0));
3110
    end
3111
  endgenerate
3112
 
3113
  // Data to Rx FIFO
3114
  always @ (posedge clk_0 or posedge wb_rst)
3115
    if (wb_rst)
3116
      dq_rx_reg[31:16] <= 16'h0;
3117
    else
3118
      dq_rx_reg[31:16] <= dq_rx[31:16];
3119
 
3120
  always @ (posedge clk_0 or posedge wb_rst)
3121
    if (wb_rst)
3122
      dq_rx_reg[15:0] <= 16'h0;
3123
    else
3124
      dq_rx_reg[15:0] <= dq_rx[15:0];
3125
 
3126
  assign rx_dat_o = dq_rx_reg;
3127
 
3128
`endif   // DEL_DQS_DATA_CAPTURE_1
3129
 
3130
 
3131
`ifdef DEL_DQS_DATA_CAPTURE_2
3132
 
3133
  wire [15:0] dq_iodelay;
3134
  wire  [1:0] dqs_iodelay, dqs_n_iodelay;
3135
  wire [15:0] dq_iddr_fall, dq_iddr_rise;
3136
  reg  [15:0] dq_fall_1, dq_rise_1;
3137
  reg  [15:0] dq_fall_2, dq_rise_2;
3138
  reg  [15:0] dq_fall_3, dq_rise_3;
3139
 
3140
 
3141
  // Delay data
3142
  // IODELAY is available in the Xilinx Virtex FPGAs
3143
  /*IODELAY # (
3144
    .DELAY_SRC(),
3145
    .IDELAY_TYPE(),
3146
    .HIGH_PERFORMANCE_MODE(),
3147
    .IDELAY_VALUE(),
3148
    .ODELAY_VALUE())
3149
   u_idelay_dq (
3150
      .DATAOUT(),
3151
      .C(),
3152
      .CE(),
3153
      .DATAIN(),
3154
      .IDATAIN(),
3155
      .INC(),
3156
      .ODATAIN(),
3157
      .RST(),
3158
      .T());*/
3159
  // IODELAY is NOT available in the Xilinx Spartan FPGAs, 
3160
  // equivalent delay can be implemented using a chain of LUT
3161
  /*lut_delay lut_delay_dq (
3162
    .clk_i(),
3163
    .d_i(dq_iobuf),
3164
    .d_o(dq_iodelay));*/
3165
 
3166
  // IDDR FF
3167
  generate
3168
    for (i=0; i<16; i=i+1) begin:iddr_dq
3169
      ddr_ff_in ddr_ff_in_inst_0 (
3170
        .Q0(dq_iddr_fall[i]),
3171
        .Q1(dq_iddr_rise[i]),
3172
        .C0(dqs_iodelay[0]),
3173
        .C1(dqs_n_iodelay[0]),
3174
        .CE(1'b1),
3175
        .D(dq_iobuf[i]),
3176
        .R(wb_rst),
3177
        .S(1'b0));
3178
    end
3179
  endgenerate
3180
 
3181
  // Rise & fall clocked FF
3182
  always @ (posedge clk_0 or posedge wb_rst)
3183
    if (wb_rst) begin
3184
      dq_fall_1 <= 16'h0;
3185
      dq_rise_1 <= 16'h0;
3186
    end else begin
3187
      dq_fall_1 <= dq_iddr_fall;
3188
      dq_rise_1 <= dq_iddr_rise;
3189
    end
3190
 
3191
  always @ (posedge clk_180 or posedge wb_rst)
3192
    if (wb_rst) begin
3193
      dq_fall_2 <= 16'h0;
3194
      dq_rise_2 <= 16'h0;
3195
    end else begin
3196
      dq_fall_2 <= dq_iddr_fall;
3197
      dq_rise_2 <= dq_iddr_rise;
3198
    end
3199
 
3200
  // Fall sync FF
3201
  always @ (posedge clk_0 or posedge wb_rst)
3202
    if (wb_rst) begin
3203
      dq_fall_3 <= 16'h0;
3204
      dq_rise_3 <= 16'h0;
3205
    end else begin
3206
      dq_fall_3 <= dq_fall_2;
3207
      dq_rise_3 <= dq_rise_2;
3208
    end
3209
 
3210
  // Mux
3211
  assign rx_dat_o[31:16] = dq_fall_1;
3212
  assign rx_dat_o[15:0]  = dq_rise_1;
3213
 
3214
  // DDR DQS to IODUFDS
3215
  // Delay DQS
3216
  // IODELAY is NOT available in the Xilinx Spartan FPGAs, 
3217
  // equivalent delay can be implemented using a chain of LUTs
3218
/*
3219
  generate
3220
    for (i=0; i<2; i=i+1) begin:lut_delay_dqs
3221
      lut_delay lut_delay_dqs (
3222
        .d_i(dqs_iobuf[i]),
3223
        .d_o(dqs_iodelay[i]));
3224
    end
3225
  endgenerate
3226
  generate
3227
    for (i=0; i<2; i=i+1) begin:lut_delay_dqs_n
3228
      lut_delay lut_delay_dqs_n (
3229
        .d_i(dqs_n_iobuf[i]),
3230
        .d_o(dqs_n_iodelay[i]));
3231
    end
3232
  endgenerate
3233
*/
3234
 
3235
  assign # 2 dqs_iodelay   = dqs_iobuf;
3236
  assign # 2 dqs_n_iodelay = dqs_n_iobuf;
3237
 
3238
 
3239
  // BUFIO (?)
3240
`endif   // DEL_DQS_DATA_CAPTURE_2
3241
 
3242
`endif   // XILINX
3243
 
3244
 
3245
///////////////////////////////////////////////////////////////////////////////
3246
// Altera
3247
///////////////////////////////////////////////////////////////////////////////
3248
 
3249
`ifdef ALTERA
3250
 
3251
  wire  [3:0] dqm_tx;
3252
 
3253
  // Data out
3254
  // DDR flip-flops
3255
  generate
3256
    for (i=0; i<16; i=i+1) begin:data_out_oddr
3257
      ddr_ff_out ddr_ff_out_inst_0 (
3258
        .Q(dq_o[i]),
3259
        .C0(clk_270),
3260
        .C1(clk_90),
3261
        .CE(dq_en),
3262
        .D0(tx_dat_i[i+16+4]),
3263
        .D1(tx_dat_i[i+4]),
3264
        .R(wb_rst),
3265
        .S(1'b0));
3266
    end
3267
  endgenerate
3268
 
3269
  // Assign outport
3270
  assign dq_io = dq_en ? dq_o : {16{1'bz}};
3271
 
3272
  // Data mask
3273
  // Data mask from Tx FIFO
3274
  assign dqm_tx = dqm_en ? {4{1'b0}} : tx_dat_i[3:0];
3275
 
3276
  // DDR flip-flops
3277
  generate
3278
    for (i=0; i<2; i=i+1) begin:data_mask_oddr
3279
      ddr_ff_out ddr_ff_out_inst_1 (
3280
        .Q(dqm_o[i]),
3281
        .C0(clk_270),
3282
        .C1(clk_90),
3283
        .CE(dq_en),
3284
        .D0(!dqm_tx[i+2]),
3285
        .D1(!dqm_tx[i]),
3286
        .R(wb_rst),
3287
        .S(1'b0));
3288
    end
3289
  endgenerate
3290
 
3291
  // Assign outport
3292
  assign dm_rdqs_io = dq_en ? dqm_o : 2'bzz;
3293
 
3294
 
3295
  // Data in
3296
`ifdef INT_CLOCKED_DATA_CAPTURE
3297
  // DDR flip-flops
3298
  generate
3299
    for (i=0; i<16; i=i+1) begin:iddr2gen
3300
      ddr_ff_in ddr_ff_in_inst_0 (
3301
        .Q0(dq_rx[i]),
3302
        .Q1(dq_rx[i+16]),
3303
        .C0(clk_270),
3304
        .C1(clk_90),
3305
        .CE(1'b1),
3306
        .D(dq_io[i]),
3307
        .R(wb_rst),
3308
        .S(1'b0));
3309
    end
3310
  endgenerate
3311
 
3312
  // Data to Rx FIFO
3313
  always @ (posedge clk_180 or posedge wb_rst)
3314
    if (wb_rst)
3315
      dq_rx_reg <= 32'h0;
3316
    else
3317
      dq_rx_reg <= dq_rx;
3318
 
3319
  assign rx_dat_o = dq_rx_reg;
3320
`endif   // INT_CLOCKED_DATA_CAPTURE
3321
 
3322
`ifdef DEL_DQS_DATA_CAPTURE_1
3323
   // Delay DQS
3324
   // DDR FF
3325
`endif   // DEL_DQS_DATA_CAPTURE_1
3326
 
3327
`ifdef DEL_DQS_DATA_CAPTURE_2
3328
   // DDR data to IOBUFFER
3329
   // Delay data (?)
3330
   // DDR FF
3331
   // Rise & fall clocked FF
3332
   // Fall sync FF
3333
   // Mux
3334
   // DDR DQS to IODUFDS
3335
   // Delay DQS
3336
   // BUFIO (?)
3337
`endif   // DEL_DQS_DATA_CAPTURE_2
3338
 
3339
`endif   // ALTERA
3340
 
3341
 
3342
endmodule   // versatile_mem_ctrl_ddr
3343
 
3344
 
3345
`timescale 1ns/1ns
3346
 
3347
 
3348
//
3349
// Specify either type of memory
3350
// or
3351
// BA_SIZE, ROW_SIZE, COL_SIZE and SDRAM_DATA_WIDTH
3352
//
3353
// either in this file or as command line option; +define+MT48LC16M16
3354
//
3355
 
3356
// number of adr lines to use
3357
// 2^2 = 4 32 bit word burst
3358
//`define BURST_SIZE 2
3359
 
3360
 
3361
// DDR2 SDRAM
3362
// MT47H32M16 – 8 Meg x 16 x 4 banks
3363
`define MT47H32M16
3364
`ifdef MT47H32M16
3365
// using 1 of MT47H32M16
3366
// SDRAM data width is 16
3367
`define BURST_SIZE 4
3368
`define SDRAM_DATA_WIDTH 16
3369
`define COL_SIZE 10
3370
`define ROW_SIZE 13
3371
`define BA_SIZE 2
3372
 
3373
`define SDRAM16
3374
`define BA tx_fifo_dat_o[28:27]
3375
`define ROW tx_fifo_dat_o[26:14]
3376
`define COL {4'b0000,tx_fifo_dat_o[13:10],burst_adr,1'b0}
3377
`define WORD_SIZE 1
3378
`define WB_ADR_HI 24
3379
`define WB_ADR_LO 2
3380
 
3381
// Mode Register (MR) Definition
3382
// [16]    (BA2)   1'b0
3383
// [15:14] (BA1-0) Mode Register Definition (MR): 2'b00 - Mode Register (MR)
3384
// [13]    (A13)   1'b0
3385
// [12]    (A12)   PD Mode (PD): 1'b0 - Fast exit (normal), 1'b1 - Slow exit (low power)
3386
// [11:9]  (A11-9) Write Recovery (WR): 3'b000 - reserved, 3b'001 - 2, ... , 3b'111 - 8
3387
// [8]     (A8)    DLL Reset (DLL): 1'b0 - No, 1'b1 - Yes
3388
// [7]     (A7)    Mode (TM): 1'b0 - Normal, 1'b1 - Test
3389
// [6:4]   (A5-4)  CAS Latency (CL): 3'b011 - 3, ... , 3'b111 - 7
3390
// [3]     (A3)    Burst Type (BT): 1'b0 - Sequential, 1'b1 - Interleaved
3391
// [2:0]   (A2-0)  Burst Length (BL): 3'b010 - 4, 3'b011 - 8
3392
`define MR  2'b00
3393
`define PD  1'b0
3394
`define WR  3'b001
3395
`define DLL 1'b0
3396
`define DLL_RST 1'b1
3397
`define TM  1'b0
3398
`define CL  3'b100
3399
`define BT  1'b0
3400
`define BL  3'b011
3401
 
3402
// Extended Mode Register (EMR) Definition
3403
// [16]    (BA2)    1'b0
3404
// [15:14] (BA1-0)  Mode Register Set (MRS): 2'b01 - Extended Mode Register (EMR)
3405
// [13]    (A13)    1'b0
3406
// [12]    (A12)    Outputs (OUT): 1'b0 - Enabled, 1'b1 - Disabled
3407
// [11]    (A11)    RDQS Enable (RDQS): 1'b0 - Enabled, 1'b1 - Disabled
3408
// [10]    (A10)    DQS# Enable (DQS): 1'b0 - Enabled, 1'b1 - Disabled
3409
// [9:7]   (A9-7)   OCD Opearation (OCD): 3'b000 - OCD exit, 3b'111 - Enable OCD defaults
3410
// [6,2]   (A6, A2) RTT Nominal (RTT6,2): 2'b00 - Disabled, 2'b01 - 75 ohm, 
3411
//                                        2'b10 - 150 ohm, 2'b11 - 50 ohm,
3412
// [5:3]   (A5-3)   Posted CAS# Additive Latenct (AL): 3'b000 - 0, ... , 3'b110 - 6
3413
// [1]     (A1)     Output Drive Strength (ODS): 1'b0 - Full, 1'b1 - Reduced
3414
// [0]     (A0)     DLL Enable (DLL_EN): 1'b0 - Enable (normal), 1'b1 - Disable (test/debug)
3415
`define MRS    2'b01
3416
`define OUT    1'b0
3417
`define RDQS   1'b0
3418
`define DQS    1'b0
3419
`define OCD    3'b000
3420
`define OCD_DEFAULT 3'b111
3421
`define RTT6   1'b0
3422
`define RTT2   1'b0
3423
`define AL     3'b000
3424
`define ODS    1'b0
3425
`define DLL_EN 1'b0
3426
 
3427
// Extended Mode Register 2 (EMR2) Definition
3428
// [16]    (BA2)    1'b0
3429
// [15:14] (BA1-0)  Mode Register Set (MRS2): 2'b10 - Extended Mode Register 2 (EMR2)
3430
// [13:8]  (A13-8)  6'b000000
3431
// [7]     (A7)     SRT Enable (SRT): 1'b0 - 1x refresh rate (0 - 85 C), 
3432
//                                    1'b1 - 2x refresh rate (> 85 C)
3433
// [6:0]   (A6-0)   7'b0000000
3434
`define MRS2 2'b10
3435
`define SRT  1'b0
3436
 
3437
// Extended Mode Register 3 (EMR3) Definition
3438
// [16]    (BA2)    1'b0
3439
// [15:14] (BA1-0)  Mode Register Set (MRS): 2'b11 - Extended Mode Register 2 (EMR2)
3440
// [13:0]  (A13-0)  14'b00000000000000
3441
`define MRS3 2'b11
3442
 
3443
// Addr to SDRAM {ba[1:0],a[12:0]}
3444
`define A_LMR     {`MR,`PD,`WR,`DLL,`TM,`CL,`BT,`BL}
3445
`define A_LMR_DLL_RST {`MR,`PD,`WR,`DLL_RST,`TM,`CL,`BT,`BL}
3446
`define A_LEMR    {`MRS,`OUT,`RDQS,`DQS,`OCD,`RTT6,`AL,`RTT2,`ODS,`DLL_EN}
3447
`define A_LEMR_OCD_DEFAULT {`MRS,`OUT,`RDQS,`DQS,`OCD_DEFAULT,`RTT6,`AL,`RTT2,`ODS,`DLL}
3448
`define A_LEMR2   {`MRS2,5'b00000,`SRT,7'b0000000}
3449
`define A_LEMR3   {`MRS3,13'b0000000000000}
3450
`define A_PRE     {2'b00,13'b0010000000000}
3451
`define A_ACT     {`BA,`ROW}
3452
`define A_READ    {`BA,`COL}
3453
`define A_WRITE   {`BA,`COL}
3454
`define A_DEFAULT {2'b00,13'b0000000000000}
3455
 
3456
// Command
3457
`define CMD {ras, cas, we}
3458
`define CMD_NOP   3'b111
3459
`define CMD_AREF  3'b001
3460
`define CMD_LMR   3'b000
3461
`define CMD_LEMR  3'b000
3462
`define CMD_LEMR2 3'b000
3463
`define CMD_LEMR3 3'b000
3464
`define CMD_PRE   3'b010
3465
`define CMD_ACT   3'b011
3466
`define CMD_READ  3'b101
3467
`define CMD_WRITE 3'b100
3468
`define CMD_BT    3'b110
3469
 
3470
`endif //  `ifdef MT47H32M16
3471
 
3472
//
3473
// Specify either type of memory
3474
// or
3475
// BA_SIZE, ROW_SIZE, COL_SIZE and SDRAM_DATA_WIDTH
3476
//
3477
// either in this file or as command line option; +define+MT48LC16M16
3478
//
3479
 
3480
// Most of these defines have an effect on things in fsm_sdr_16.v
3481
 
3482
//`define MT48LC32M16   // 64MB part
3483 411 julius
`define MT48LC16M16   // 32MB part
3484
//`define MT48LC4M16    //  8MB part
3485 408 julius
 
3486
// Define this to allow indication that a burst read is still going
3487
// to the wishbone state machine, so it doesn't start emptying the
3488
// ingress fifo after a aborted burst before the burst read is
3489
// actually finished.
3490
`define SDRAM_WB_SAME_CLOCKS
3491
 
3492
// If intending to burst write, and the wishbone clock is about 1/4 the speed
3493
// of the SDRAM clock, then the data may come late, and this triggers a bug
3494
// during write. To avoid this we can just wait a little longer for data when
3495
// burst reading (there's no almost_empty signal from the FIFO)
3496
`define SLOW_WB_CLOCK
3497
 
3498
 
3499
`ifdef MT48LC32M16
3500 411 julius
// using 1 of MT48LC32M16
3501 408 julius
// SDRAM data width is 16
3502
 
3503
`define SDRAM_DATA_WIDTH 16
3504
`define COL_SIZE 10
3505
`define ROW_SIZE 13
3506
`define BA_SIZE 2
3507
 
3508
`endif //  `ifdef MT48LC16M16
3509
 
3510
`ifdef MT48LC16M16
3511
// using 1 of MT48LC16M16
3512
// SDRAM data width is 16
3513
 
3514
`define SDRAM_DATA_WIDTH 16
3515
`define COL_SIZE 9
3516
`define ROW_SIZE 13
3517
`define BA_SIZE 2
3518
 
3519
`endif //  `ifdef MT48LC16M16
3520
 
3521
`ifdef MT48LC4M16
3522
// using 1 of MT48LC4M16
3523
// SDRAM data width is 16
3524
 
3525
`define SDRAM_DATA_WIDTH 16
3526
`define COL_SIZE 8
3527
`define ROW_SIZE 12
3528
`define BA_SIZE 2
3529
 
3530
`endif //  `ifdef MT48LC4M16
3531
 
3532
// LMR
3533
// [12:10] reserved
3534
// [9]     WB, write burst; 0 - programmed burst length, 1 - single location
3535
// [8:7]   OP Mode, 2'b00
3536
// [6:4]   CAS Latency; 3'b010 - 2, 3'b011 - 3
3537
// [3]     BT, Burst Type; 1'b0 - sequential, 1'b1 - interleaved
3538
// [2:0]   Burst length; 3'b000 - 1, 3'b001 - 2, 3'b010 - 4, 3'b011 - 8, 3'b111 - full page
3539
`define INIT_WB 1'b0
3540
`define INIT_CL 3'b010
3541
`define INIT_BT 1'b0
3542
`define INIT_BL 3'b001
3543
`timescale 1ns/1ns
3544
module encode (
3545
    fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3,
3546
    fifo_sel, fifo_sel_domain
3547
);
3548
 
3549
input  [0:15] fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3;
3550
output [0:15] fifo_sel;
3551
output [1:0]  fifo_sel_domain;
3552
 
3553
function [0:15] encode;
3554
input [0:15] a;
3555
input [0:15] b;
3556
input [0:15] c;
3557
input [0:15] d;
3558
integer i;
3559
begin
3560
    if (!(&d))
3561
        casex (d)
3562
        16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
3563
        16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
3564
        16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
3565
        16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
3566
        16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
3567
        16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
3568
        16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
3569
        16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
3570
        16'b111111110xxxxxxx: encode = 16'b0000000010000000;
3571
        16'b1111111110xxxxxx: encode = 16'b0000000001000000;
3572
        16'b11111111110xxxxx: encode = 16'b0000000000100000;
3573
        16'b111111111110xxxx: encode = 16'b0000000000010000;
3574
        16'b1111111111110xxx: encode = 16'b0000000000001000;
3575
        16'b11111111111110xx: encode = 16'b0000000000000100;
3576
        16'b111111111111110x: encode = 16'b0000000000000010;
3577
        16'b1111111111111110: encode = 16'b0000000000000001;
3578
        default:              encode = 16'b0000000000000000;
3579
        endcase
3580
    else if (!(&c))
3581
        casex (c)
3582
        16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
3583
        16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
3584
        16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
3585
        16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
3586
        16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
3587
        16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
3588
        16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
3589
        16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
3590
        16'b111111110xxxxxxx: encode = 16'b0000000010000000;
3591
        16'b1111111110xxxxxx: encode = 16'b0000000001000000;
3592
        16'b11111111110xxxxx: encode = 16'b0000000000100000;
3593
        16'b111111111110xxxx: encode = 16'b0000000000010000;
3594
        16'b1111111111110xxx: encode = 16'b0000000000001000;
3595
        16'b11111111111110xx: encode = 16'b0000000000000100;
3596
        16'b111111111111110x: encode = 16'b0000000000000010;
3597
        16'b1111111111111110: encode = 16'b0000000000000001;
3598
        default:              encode = 16'b0000000000000000;
3599
        endcase
3600
    else if (!(&b))
3601
        casex (b)
3602
        16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
3603
        16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
3604
        16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
3605
        16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
3606
        16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
3607
        16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
3608
        16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
3609
        16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
3610
        16'b111111110xxxxxxx: encode = 16'b0000000010000000;
3611
        16'b1111111110xxxxxx: encode = 16'b0000000001000000;
3612
        16'b11111111110xxxxx: encode = 16'b0000000000100000;
3613
        16'b111111111110xxxx: encode = 16'b0000000000010000;
3614
        16'b1111111111110xxx: encode = 16'b0000000000001000;
3615
        16'b11111111111110xx: encode = 16'b0000000000000100;
3616
        16'b111111111111110x: encode = 16'b0000000000000010;
3617
        16'b1111111111111110: encode = 16'b0000000000000001;
3618
        default:              encode = 16'b0000000000000000;
3619
        endcase
3620
    else
3621
        casex (a)
3622
        16'b0xxxxxxxxxxxxxxx: encode = 16'b1000000000000000;
3623
        16'b10xxxxxxxxxxxxxx: encode = 16'b0100000000000000;
3624
        16'b110xxxxxxxxxxxxx: encode = 16'b0010000000000000;
3625
        16'b1110xxxxxxxxxxxx: encode = 16'b0001000000000000;
3626
        16'b11110xxxxxxxxxxx: encode = 16'b0000100000000000;
3627
        16'b111110xxxxxxxxxx: encode = 16'b0000010000000000;
3628
        16'b1111110xxxxxxxxx: encode = 16'b0000001000000000;
3629
        16'b11111110xxxxxxxx: encode = 16'b0000000100000000;
3630
        16'b111111110xxxxxxx: encode = 16'b0000000010000000;
3631
        16'b1111111110xxxxxx: encode = 16'b0000000001000000;
3632
        16'b11111111110xxxxx: encode = 16'b0000000000100000;
3633
        16'b111111111110xxxx: encode = 16'b0000000000010000;
3634
        16'b1111111111110xxx: encode = 16'b0000000000001000;
3635
        16'b11111111111110xx: encode = 16'b0000000000000100;
3636
        16'b111111111111110x: encode = 16'b0000000000000010;
3637
        16'b1111111111111110: encode = 16'b0000000000000001;
3638
        default:              encode = 16'b0000000000000000;
3639
        endcase
3640
end
3641
endfunction
3642
 
3643
assign fifo_sel = encode( fifo_empty_0, fifo_empty_1, fifo_empty_2, fifo_empty_3);
3644
assign fifo_sel_domain = (!(&fifo_empty_3)) ? 2'b11 :
3645
                         (!(&fifo_empty_2)) ? 2'b10 :
3646
                         (!(&fifo_empty_1)) ? 2'b01 :
3647
                         2'b00;
3648
 
3649
endmodule
3650
 
3651
`timescale 1ns/1ns
3652
module decode (
3653
    fifo_sel, fifo_sel_domain,
3654
    fifo_we_0, fifo_we_1, fifo_we_2, fifo_we_3
3655
);
3656
 
3657
input  [0:15] fifo_sel;
3658
input  [1:0]  fifo_sel_domain;
3659
output [0:15] fifo_we_0, fifo_we_1, fifo_we_2, fifo_we_3;
3660
 
3661
assign fifo_we_0 = (fifo_sel_domain == 2'b00) ? fifo_sel : {16{1'b0}};
3662
assign fifo_we_1 = (fifo_sel_domain == 2'b01) ? fifo_sel : {16{1'b0}};
3663
assign fifo_we_2 = (fifo_sel_domain == 2'b10) ? fifo_sel : {16{1'b0}};
3664
assign fifo_we_3 = (fifo_sel_domain == 2'b11) ? fifo_sel : {16{1'b0}};
3665
 
3666
endmodule
3667
//////////////////////////////////////////////////////////////////////
3668
////                                                              ////
3669
////  Versatile counter                                           ////
3670
////                                                              ////
3671
////  Description                                                 ////
3672
////  Versatile counter, a reconfigurable binary, gray or LFSR    ////
3673
////  counter                                                     ////
3674
////                                                              ////
3675
////  To Do:                                                      ////
3676
////   - add LFSR with more taps                                  ////
3677
////                                                              ////
3678
////  Author(s):                                                  ////
3679
////      - Michael Unneback, unneback@opencores.org              ////
3680
////        ORSoC AB                                              ////
3681
////                                                              ////
3682
//////////////////////////////////////////////////////////////////////
3683
////                                                              ////
3684
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
3685
////                                                              ////
3686
//// This source file may be used and distributed without         ////
3687
//// restriction provided that this copyright statement is not    ////
3688
//// removed from the file and that any derivative work contains  ////
3689
//// the original copyright notice and the associated disclaimer. ////
3690
////                                                              ////
3691
//// This source file is free software; you can redistribute it   ////
3692
//// and/or modify it under the terms of the GNU Lesser General   ////
3693
//// Public License as published by the Free Software Foundation; ////
3694
//// either version 2.1 of the License, or (at your option) any   ////
3695
//// later version.                                               ////
3696
////                                                              ////
3697
//// This source is distributed in the hope that it will be       ////
3698
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
3699
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
3700
//// PURPOSE.  See the GNU Lesser General Public License for more ////
3701
//// details.                                                     ////
3702
////                                                              ////
3703
//// You should have received a copy of the GNU Lesser General    ////
3704
//// Public License along with this source; if not, download it   ////
3705
//// from http://www.opencores.org/lgpl.shtml                     ////
3706
////                                                              ////
3707
//////////////////////////////////////////////////////////////////////
3708
 
3709
// GRAY counter
3710
module gray_counter ( cke, q, q_bin, rst, clk);
3711
 
3712
   parameter length = 4;
3713
   input cke;
3714
   output reg [length:1] q;
3715
   output [length:1] q_bin;
3716
   input rst;
3717
   input clk;
3718
 
3719
   parameter clear_value = 0;
3720
 
3721
   reg  [length:1] qi;
3722
   wire [length:1] q_next;
3723
   assign q_next = qi + {{length-1{1'b0}},1'b1};
3724
 
3725
   always @ (posedge clk or posedge rst)
3726
     if (rst)
3727
       qi <= {length{1'b0}};
3728
     else
3729
     if (cke)
3730
       qi <= q_next;
3731
 
3732
   always @ (posedge clk or posedge rst)
3733
     if (rst)
3734
       q <= {length{1'b0}};
3735
     else
3736
       if (cke)
3737
         q <= (q_next>>1) ^ q_next;
3738
 
3739
   assign q_bin = qi;
3740
 
3741
endmodule
3742
// async FIFO with multiple queues, multiple data
3743
`define ORIGINAL_EGRESS_FIFO
3744
`ifdef ORIGINAL_EGRESS_FIFO
3745
module egress_fifo (
3746
    d, fifo_full, write, write_enable, clk1, rst1,
3747
    q, fifo_empty, read_adr, read_data, read_enable, clk2, rst2
3748
);
3749
 
3750
parameter a_hi_size = 4;
3751
parameter a_lo_size = 4;
3752
parameter nr_of_queues = 16;
3753
parameter data_width = 36;
3754
 
3755
input [data_width*nr_of_queues-1:0] d;
3756
output [0:nr_of_queues-1] fifo_full;
3757
input                     write;
3758
input  [0:nr_of_queues-1] write_enable;
3759
input clk1;
3760
input rst1;
3761
 
3762
output reg [data_width-1:0] q;
3763
output [0:nr_of_queues-1] fifo_empty;
3764
input                     read_adr, read_data;
3765
input  [0:nr_of_queues-1] read_enable;
3766
input clk2;
3767
input rst2;
3768
 
3769
wire [data_width-1:0] fifo_q;
3770
 
3771
wire [a_lo_size-1:0]  fifo_wadr_bin[0:nr_of_queues-1];
3772
wire [a_lo_size-1:0]  fifo_wadr_gray[0:nr_of_queues-1];
3773
wire [a_lo_size-1:0]  fifo_radr_bin[0:nr_of_queues-1];
3774
wire [a_lo_size-1:0]  fifo_radr_gray[0:nr_of_queues-1];
3775
reg [a_lo_size-1:0] wadr;
3776
reg [a_lo_size-1:0] radr;
3777
reg [data_width-1:0] wdata;
3778
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
3779
 
3780
reg read_adr_reg;
3781
reg [0:nr_of_queues-1] read_enable_reg;
3782
 
3783
genvar i;
3784
integer j,k,l;
3785
 
3786
function [a_lo_size-1:0] onehot2bin;
3787
input [0:nr_of_queues-1] a;
3788
integer i;
3789
begin
3790
    onehot2bin = {a_lo_size{1'b0}};
3791
    for (i=1;i<nr_of_queues;i=i+1) begin
3792
        if (a[i])
3793
            onehot2bin = i;
3794
    end
3795
end
3796
endfunction
3797
 
3798
// a pipeline stage for address read gives higher clock frequency but adds one 
3799
// clock latency for adr read
3800
always @ (posedge clk2 or posedge rst2)
3801
if (rst2)
3802
    read_adr_reg <= 1'b0;
3803
else
3804
    read_adr_reg <= read_adr;
3805
 
3806
always @ (posedge clk2 or posedge rst2)
3807
if (rst2)
3808
    read_enable_reg <= {nr_of_queues{1'b0}};
3809
else
3810
    if (read_adr)
3811
        read_enable_reg <= read_enable;
3812
 
3813
 
3814
generate
3815
    for (i=0;i<nr_of_queues;i=i+1) begin : fifo_adr
3816
 
3817
        gray_counter wadrcnt (
3818
            .cke(write & write_enable[i]),
3819
            .q(fifo_wadr_gray[i]),
3820
            .q_bin(fifo_wadr_bin[i]),
3821
            .rst(rst1),
3822
            .clk(clk1));
3823
 
3824
        gray_counter radrcnt (
3825
            .cke((read_adr_reg | read_data) & read_enable_reg[i]),
3826
            .q(fifo_radr_gray[i]),
3827
            .q_bin(fifo_radr_bin[i]),
3828
            .rst(rst2),
3829
            .clk(clk2));
3830
 
3831
        versatile_fifo_async_cmp
3832
            #(.ADDR_WIDTH(a_lo_size))
3833
            egresscmp (
3834
                .wptr(fifo_wadr_gray[i]),
3835
                .rptr(fifo_radr_gray[i]),
3836
                .fifo_empty(fifo_empty[i]),
3837
                .fifo_full(fifo_full[i]),
3838
                .wclk(clk1),
3839
                .rclk(clk2),
3840
                .rst(rst1));
3841
 
3842
    end
3843
endgenerate
3844
 
3845
// and-or mux write address
3846
always @*
3847
begin
3848
    wadr = {a_lo_size{1'b0}};
3849
    for (j=0;j<nr_of_queues;j=j+1) begin
3850
        wadr = (fifo_wadr_bin[j] & {a_lo_size{write_enable[j]}}) | wadr;
3851
    end
3852
end
3853
 
3854
// and-or mux read address
3855
always @*
3856
begin
3857
    radr = {a_lo_size{1'b0}};
3858
    for (k=0;k<nr_of_queues;k=k+1) begin
3859
        radr = (fifo_radr_bin[k] & {a_lo_size{read_enable_reg[k]}}) | radr;
3860
    end
3861
end
3862
 
3863
// and-or mux write data
3864
generate
3865
    for (i=0;i<nr_of_queues;i=i+1) begin : vector2array
3866
        assign wdataa[i] = d[(nr_of_queues-i)*data_width-1:(nr_of_queues-1-i)*data_width];
3867
    end
3868
endgenerate
3869
 
3870
always @*
3871
begin
3872
    wdata = {data_width{1'b0}};
3873
    for (l=0;l<nr_of_queues;l=l+1) begin
3874
        wdata = (wdataa[l] & {data_width{write_enable[l]}}) | wdata;
3875
    end
3876
end
3877
 
3878
 
3879
 
3880
vfifo_dual_port_ram_dc_sw
3881
  # (
3882
      .DATA_WIDTH(data_width),
3883
      .ADDR_WIDTH(a_hi_size+a_lo_size)
3884
      )
3885
    dpram (
3886
    .d_a(wdata),
3887
    .adr_a({onehot2bin(write_enable),wadr}),
3888
    .we_a(write),
3889
    .clk_a(clk1),
3890
    .q_b(fifo_q),
3891
    .adr_b({onehot2bin(read_enable_reg),radr}),
3892
    .clk_b(clk2) );
3893
 
3894
   // Added registering of FIFO output to break a timing path
3895
   always@(posedge clk2)
3896
     q <= fifo_q;
3897
 
3898
 
3899
endmodule
3900
`else // !`ifdef ORIGINAL_EGRESS_FIFO
3901
module egress_fifo (
3902
    d, fifo_full, write, write_enable, clk1, rst1,
3903
    q, fifo_empty, read_adr, read_data, read_enable, clk2, rst2
3904
);
3905
 
3906
parameter a_hi_size = 2;
3907
parameter a_lo_size = 4;
3908
parameter nr_of_queues = 16;
3909
parameter data_width = 36;
3910
 
3911
input [data_width*nr_of_queues-1:0] d;
3912
output [0:nr_of_queues-1] fifo_full;
3913
input                     write;
3914
input  [0:nr_of_queues-1] write_enable;
3915
input clk1;
3916
input rst1;
3917
 
3918
output reg [data_width-1:0] q;
3919
output [0:nr_of_queues-1] fifo_empty;
3920
input                     read_adr, read_data;
3921
input  [0:nr_of_queues-1] read_enable;
3922
input clk2;
3923
input rst2;
3924
 
3925
wire [data_width-1:0] fifo_q;
3926
 
3927
wire [a_lo_size-1:0]  fifo_wadr_bin[0:nr_of_queues-1];
3928
wire [a_lo_size-1:0]  fifo_wadr_gray[0:nr_of_queues-1];
3929
wire [a_lo_size-1:0]  fifo_radr_bin[0:nr_of_queues-1];
3930
wire [a_lo_size-1:0]  fifo_radr_gray[0:nr_of_queues-1];
3931
wire [a_lo_size-1:0] wadr;
3932
wire [a_lo_size-1:0] radr;
3933
wire [data_width-1:0] wdata;
3934
wire [data_width-1:0] wdataa[0:nr_of_queues-1];
3935
 
3936
reg read_adr_reg;
3937
reg [0:nr_of_queues-1] read_enable_reg;
3938
 
3939
genvar i;
3940
integer j,k,l;
3941
 
3942
// a pipeline stage for address read gives higher clock frequency but adds one 
3943
// clock latency for adr read
3944
always @ (posedge clk2 or posedge rst2)
3945
if (rst2)
3946
    read_adr_reg <= 1'b0;
3947
else
3948
    read_adr_reg <= read_adr;
3949
 
3950
always @ (posedge clk2 or posedge rst2)
3951
if (rst2)
3952
    read_enable_reg <= {nr_of_queues{1'b0}};
3953
else
3954
    if (read_adr)
3955
        read_enable_reg <= read_enable;
3956
 
3957
   // 0        
3958
   gray_counter wadrcnt0
3959
     (
3960
      .cke(write & write_enable[0]),
3961
      .q(fifo_wadr_gray[0]),
3962
      .q_bin(fifo_wadr_bin[0]),
3963
      .rst(rst1),
3964
      .clk(clk1)
3965
      );
3966
 
3967
   gray_counter radrcnt0
3968
     (
3969
      .cke((read_adr_reg | read_data) & read_enable_reg[0]),
3970
      .q(fifo_radr_gray[0]),
3971
      .q_bin(fifo_radr_bin[0]),
3972
      .rst(rst2),
3973
      .clk(clk2)
3974
      );
3975
 
3976
   versatile_fifo_async_cmp
3977
     #(
3978
      .ADDR_WIDTH(a_lo_size)
3979
      )
3980
   egresscmp0
3981
     (
3982
       .wptr(fifo_wadr_gray[0]),
3983
       .rptr(fifo_radr_gray[0]),
3984
       .fifo_empty(fifo_empty[0]),
3985
       .fifo_full(fifo_full[0]),
3986
       .wclk(clk1),
3987
       .rclk(clk2),
3988
       .rst(rst1)
3989
       );
3990
 
3991
   // 1
3992
      gray_counter wadrcnt1
3993
     (
3994
      .cke(write & write_enable[1]),
3995
      .q(fifo_wadr_gray[1]),
3996
      .q_bin(fifo_wadr_bin[1]),
3997
      .rst(rst1),
3998
      .clk(clk1)
3999
      );
4000
 
4001
   gray_counter radrcnt1
4002
     (
4003
      .cke((read_adr_reg | read_data) & read_enable_reg[1]),
4004
      .q(fifo_radr_gray[1]),
4005
      .q_bin(fifo_radr_bin[1]),
4006
      .rst(rst2),
4007
      .clk(clk2)
4008
      );
4009
 
4010
   versatile_fifo_async_cmp
4011
     #(
4012
      .ADDR_WIDTH(a_lo_size)
4013
      )
4014
   egresscmp1
4015
     (
4016
       .wptr(fifo_wadr_gray[1]),
4017
       .rptr(fifo_radr_gray[1]),
4018
       .fifo_empty(fifo_empty[1]),
4019
       .fifo_full(fifo_full[1]),
4020
       .wclk(clk1),
4021
       .rclk(clk2),
4022
       .rst(rst1)
4023
       );
4024
 
4025
   // 2
4026
      gray_counter wadrcnt2
4027
     (
4028
      .cke(write & write_enable[2]),
4029
      .q(fifo_wadr_gray[2]),
4030
      .q_bin(fifo_wadr_bin[2]),
4031
      .rst(rst1),
4032
      .clk(clk1)
4033
      );
4034
 
4035
   gray_counter radrcnt2
4036
     (
4037
      .cke((read_adr_reg | read_data) & read_enable_reg[2]),
4038
      .q(fifo_radr_gray[2]),
4039
      .q_bin(fifo_radr_bin[2]),
4040
      .rst(rst2),
4041
      .clk(clk2)
4042
      );
4043
 
4044
   versatile_fifo_async_cmp
4045
     #(
4046
      .ADDR_WIDTH(a_lo_size)
4047
      )
4048
   egresscmp2
4049
     (
4050
       .wptr(fifo_wadr_gray[2]),
4051
       .rptr(fifo_radr_gray[2]),
4052
       .fifo_empty(fifo_empty[2]),
4053
       .fifo_full(fifo_full[2]),
4054
       .wclk(clk1),
4055
       .rclk(clk2),
4056
       .rst(rst1)
4057
       );
4058
 
4059
 
4060
   assign wadr = (fifo_wadr_bin[0] & {a_lo_size{write_enable[0]}}) |
4061
                 (fifo_wadr_bin[1] & {a_lo_size{write_enable[1]}}) |
4062
                 (fifo_wadr_bin[2] & {a_lo_size{write_enable[2]}});
4063
 
4064
   assign radr = (fifo_radr_bin[0] & {a_lo_size{read_enable_reg[0]}}) |
4065
                 (fifo_radr_bin[1] & {a_lo_size{read_enable_reg[1]}}) |
4066
                 (fifo_radr_bin[2] & {a_lo_size{read_enable_reg[2]}});
4067
 
4068
 
4069
   assign wdataa[0] = d[108-1:72];
4070
   assign wdataa[1] = d[72-1:36];
4071
   assign wdataa[2] = d[36-1:0];
4072
 
4073
   assign wdata = ( d[108-1:72] & {data_width{write_enable[0]}}) |
4074
                  ( d[72-1:36]  & {data_width{write_enable[1]}}) |
4075
                  ( d[36-1:0]   & {data_width{write_enable[2]}});
4076
 
4077
   wire [1:0] wadr_top;
4078
   assign wadr_top = write_enable[1] ? 2'b01 :
4079
                     write_enable[2] ? 2'b10 :
4080
                     2'b00;
4081
   wire [1:0] radr_top;
4082
   assign radr_top = read_enable_reg[1] ? 2'b01 :
4083
                     read_enable_reg[2] ? 2'b10 :
4084
                     2'b00;
4085
 
4086
vfifo_dual_port_ram_dc_sw
4087
  # (
4088
      .DATA_WIDTH(data_width),
4089
      .ADDR_WIDTH(2+a_lo_size)
4090
      )
4091
    dpram (
4092
    .d_a(wdata),
4093
    .adr_a({wadr_top,wadr}),
4094
    .we_a(write),
4095
    .clk_a(clk1),
4096
    .q_b(fifo_q),
4097
    .adr_b({radr_top,radr}),
4098
    .clk_b(clk2) );
4099
 
4100
   // Added registering of FIFO output to break a timing path
4101
   always@(posedge clk2)
4102
     q <= fifo_q;
4103
 
4104
 
4105
endmodule
4106
`endif // !`ifdef ORIGINAL_EGRESS_FIFO
4107 411 julius
// true dual port RAM, sync
4108
 
4109
`ifdef ACTEL
4110
        `define SYN
4111
`endif
4112 408 julius
module vfifo_dual_port_ram_dc_sw
4113
  (
4114
   d_a,
4115
   adr_a,
4116
   we_a,
4117
   clk_a,
4118
   q_b,
4119
   adr_b,
4120
   clk_b
4121
   );
4122
   parameter DATA_WIDTH = 32;
4123
   parameter ADDR_WIDTH = 8;
4124
   input [(DATA_WIDTH-1):0]      d_a;
4125
   input [(ADDR_WIDTH-1):0]       adr_a;
4126
   input [(ADDR_WIDTH-1):0]       adr_b;
4127
   input                         we_a;
4128
   output [(DATA_WIDTH-1):0]      q_b;
4129
   input                         clk_a, clk_b;
4130
   reg [(ADDR_WIDTH-1):0]         adr_b_reg;
4131 411 julius
   reg [DATA_WIDTH-1:0] ram [(1<<ADDR_WIDTH)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
4132 408 julius
   always @ (posedge clk_a)
4133
   if (we_a)
4134
     ram[adr_a] <= d_a;
4135
   always @ (posedge clk_b)
4136
   adr_b_reg <= adr_b;
4137
   assign q_b = ram[adr_b_reg];
4138
endmodule
4139
`timescale 1ns/1ns
4140
`include "sdr_16_defines.v"
4141
module fsm_sdr_16 (
4142
                   adr_i, we_i, bte_i, cti_i, sel_i,
4143
                   fifo_empty, fifo_rd_adr, fifo_rd_data, count0,
4144
                   refresh_req, cmd_aref, cmd_read, state_idle,
4145
                   ba, a, cmd, dqm, dq_oe,
4146
                   sdram_burst_reading,
4147
                   debug_state, debug_fifo_we_record,
4148
                   sdram_clk, sdram_fifo_wr, sdram_rst
4149
                   );
4150
 
4151
   /* Now these are defined
4152
    parameter ba_size = 2;
4153
    parameter row_size = 13;
4154
    parameter col_size = 9;
4155
    */
4156
 
4157
   input [`BA_SIZE+`ROW_SIZE+`COL_SIZE-1:0] adr_i;
4158
   input                                 we_i;
4159
   input [1:0]                            bte_i;
4160
   input [2:0]                            cti_i;
4161
   input [3:0]                            sel_i;
4162
 
4163
   input                                 fifo_empty;
4164
   output                                fifo_rd_adr, fifo_rd_data;
4165
   output reg                            count0;
4166
 
4167
   input                                 refresh_req;
4168
   output reg                            cmd_aref; // used for rerfresh ack
4169
   output reg                            cmd_read; // used for ingress fifo control
4170
   output                                state_idle; // state=idle
4171
 
4172
   output reg [1:0]                       ba /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
4173
   output reg [12:0]                      a /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
4174
   output reg [2:0]                       cmd /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
4175
   output reg [1:0]                       dqm /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
4176
   output reg                            dq_oe;
4177
 
4178
   output                                sdram_burst_reading;
4179
   input                                 sdram_clk, sdram_fifo_wr, sdram_rst;
4180
 
4181
   output [2:0]                   debug_state;
4182
   output [3:0]                   debug_fifo_we_record;
4183
 
4184
   wire [`BA_SIZE-1:0]                    bank;
4185
   wire [`ROW_SIZE-1:0]                   row;
4186
   wire [`COL_SIZE-1:0]                   col;
4187
   wire [12:0]                            col_reg_a10_fix;
4188
   reg [0:31]                             shreg;
4189
   wire                                  stall; // active if write burst need data
4190
 
4191
   reg [0:15]                             fifo_sel_reg_int;
4192
   reg [1:0]                              fifo_sel_domain_reg_int;
4193
 
4194
   // adr_reg {ba,row,col,we}
4195
   reg [1:0]                              ba_reg;
4196
   reg [`ROW_SIZE-1:0]                    row_reg;
4197
   reg [`COL_SIZE-1:0]                    col_reg;
4198
   reg                                   we_reg;
4199
   reg [1:0]                              bte_reg;
4200
   reg [2:0]                              cti_reg;
4201
 
4202
   // to keep track of open rows per bank
4203
   reg [`ROW_SIZE-1:0]                    open_row[0:3];
4204
   reg [0:3]                              open_ba;
4205
   wire                                  current_bank_closed, current_row_open;
4206
   reg                                   current_bank_closed_reg, current_row_open_reg;
4207
 
4208
   parameter [2:0] classic=3'b000,
4209
                constant=3'b001,
4210
                increment=3'b010,
4211
                endburst=3'b111;
4212
 
4213
   parameter [1:0] linear = 2'b00,
4214
                beat4  = 2'b01,
4215
                beat8  = 2'b10,
4216
                beat16 = 2'b11;
4217
 
4218
   parameter [2:0] cmd_nop = 3'b111,
4219
                cmd_act = 3'b011,
4220
                cmd_rd  = 3'b101,
4221
                cmd_wr  = 3'b100,
4222
                cmd_pch = 3'b010,
4223
                cmd_rfr = 3'b001,
4224
                cmd_lmr = 3'b000;
4225
 
4226
   // ctrl FSM
4227
 
4228
/*    define instead of param, as synplify is doing weird things
4229
 parameter [2:0] init = 3'b000,
4230
                idle = 3'b001,
4231
                rfr  = 3'b010,
4232
                adr  = 3'b011,
4233
                pch  = 3'b100,
4234
                act  = 3'b101,
4235
                w4d  = 3'b110,
4236
                rw   = 3'b111;
4237
 */
4238
`define FSM_INIT 3'b000
4239
`define FSM_IDLE 3'b001
4240
`define FSM_RFR  3'b010
4241
`define FSM_ADR  3'b011
4242
`define FSM_PCH  3'b100
4243
`define FSM_ACT  3'b101
4244
`define FSM_W4D  3'b110
4245
`define FSM_RW   3'b111
4246
 
4247
   reg [2:0]                              state, next;
4248
 
4249
   assign debug_state = state;
4250
 
4251
   function [12:0] a10_fix;
4252
      input [`COL_SIZE-1:0]               a;
4253
      integer                            i;
4254
      begin
4255
         for (i=0;i<13;i=i+1) begin
4256
            if (i<10)
4257
              if (i<`COL_SIZE)
4258
                a10_fix[i] = a[i];
4259
              else
4260
                a10_fix[i] = 1'b0;
4261
            else if (i==10)
4262
              a10_fix[i] = 1'b0;
4263
            else
4264
              if (i<`COL_SIZE)
4265
                a10_fix[i] = a[i-1];
4266
              else
4267
                a10_fix[i] = 1'b0;
4268
         end
4269
      end
4270
   endfunction
4271
 
4272
 
4273
   assign {bank,row,col} = adr_i;
4274
 
4275
   always @ (posedge sdram_clk or posedge sdram_rst)
4276
     if (sdram_rst)
4277
       state <= `FSM_INIT;
4278
     else
4279
       state <= next;
4280
 
4281
   always @*
4282
     begin
4283
        next = 3'bx;
4284
        case (state)
4285
          `FSM_INIT:
4286
            if (shreg[31])
4287
              next = `FSM_IDLE;
4288
            else
4289
              next = `FSM_INIT;
4290
          `FSM_IDLE:
4291
            if (refresh_req)
4292
              next = `FSM_RFR;
4293
            else if (!shreg[0] & !fifo_empty)
4294
              next = `FSM_ADR;
4295
            else
4296
              next = `FSM_IDLE;
4297
          `FSM_RFR:
4298
            if (shreg[5])
4299
              next = `FSM_IDLE;
4300
            else
4301
              next = `FSM_RFR;
4302
          `FSM_ADR:
4303
            if (shreg[5])
4304
              begin
4305
                 if (current_bank_closed_reg)
4306
                   next = `FSM_ACT;
4307
                 else if (current_row_open_reg)
4308
                   next = (we_reg) ?  `FSM_W4D : `FSM_RW;
4309
                 else
4310
                   next = `FSM_PCH;
4311
              end
4312
            else
4313
              next = `FSM_ADR;
4314
          `FSM_PCH:
4315
            if (shreg[1])
4316
              next = `FSM_ACT;
4317
            else
4318
              next = `FSM_PCH;
4319
          `FSM_ACT:
4320
            if (shreg[2])
4321
              begin
4322
`ifdef SLOW_WB_CLOCK
4323
                 // Automatiacally go to wait for data if burst writing
4324
                 if ((|bte_reg) & we_reg & cti_reg==increment)
4325
                   next = `FSM_W4D;
4326
                 else if ((!fifo_empty | !we_reg))
4327
                   next = `FSM_RW;
4328
`else
4329
                 if ((!fifo_empty | !we_reg))
4330
                   next = `FSM_RW;
4331
`endif
4332
                 else if (fifo_empty)
4333
                   next = `FSM_W4D;
4334
              end
4335
            else
4336
              next = `FSM_ACT;
4337
`ifdef SLOW_WB_CLOCK
4338
          // Add some wait here if bursting and the wishbone clock is slow
4339
          `FSM_W4D:
4340
            if (!fifo_empty & ((cti_reg!=increment)|(cti_reg==increment /*& bte_reg==beat4*/  & shreg[14])))
4341
              next = `FSM_RW;
4342
`else
4343
          `FSM_W4D:
4344
            if (!fifo_empty)
4345
              next = `FSM_RW;
4346
`endif
4347
            else
4348
              next = `FSM_W4D;
4349
          `FSM_RW:
4350
            if ((bte_reg==linear | !(cti_reg==increment)) & shreg[1])
4351
              next = `FSM_IDLE;
4352
            else if (bte_reg==beat4 & shreg[7])
4353
              next = `FSM_IDLE;
4354
`ifdef BEAT8
4355
            else if (bte_reg==beat8 & shreg[15])
4356
              next = `FSM_IDLE;
4357
`endif
4358
`ifdef BEAT16
4359
            else if (bte_reg==beat16 & shreg[31])
4360
              next = `FSM_IDLE;
4361
`endif
4362
            else
4363
              next = `FSM_RW;
4364
        endcase
4365
     end // always @ *
4366
 
4367
 
4368
   // active if write burst need data
4369
   assign stall = state==`FSM_RW & next==`FSM_RW & fifo_empty & count0 & we_reg;
4370
 
4371
   // counter
4372
   always @ (posedge sdram_clk or posedge sdram_rst)
4373
     begin
4374
        if (sdram_rst) begin
4375
           shreg   <= {1'b1,{31{1'b0}}};
4376
           count0  <= 1'b0;
4377
        end else
4378
          if (state!=next) begin
4379
             shreg   <= {1'b1,{31{1'b0}}};
4380
             count0  <= 1'b0;
4381
          end else
4382
            if (~stall) begin
4383
               shreg   <= shreg >> 1;
4384
               count0  <= ~count0;
4385
            end
4386
     end
4387
 
4388
   // ba, a, cmd
4389
   // col_reg_a10 has bit [10] set to zero to disable auto precharge
4390
   assign col_reg_a10_fix = a10_fix(col_reg);
4391
 
4392
   // outputs dependent on state vector
4393
   always @ (posedge sdram_clk or posedge sdram_rst)
4394
     begin
4395
        if (sdram_rst) begin
4396
           {ba,a,cmd} <= {2'b00,13'd0,cmd_nop};
4397
           dqm <= 2'b11;
4398
           cmd_aref <= 1'b0;
4399
           cmd_read <= 1'b0;
4400
           dq_oe <= 1'b0;
4401
           {open_ba,open_row[0],open_row[1],open_row[2],open_row[3]} <=
4402
                                                  {4'b0000,{`ROW_SIZE*4{1'b0}}};
4403
           {ba_reg,row_reg,col_reg,we_reg,cti_reg,bte_reg} <=
4404
                     {2'b00, {`ROW_SIZE{1'b0}}, {`COL_SIZE{1'b0}}, 1'b0,3'b000, 2'b00 };
4405
        end else begin
4406
           {ba,a,cmd} <= {2'b00,13'd0,cmd_nop};
4407
           dqm <= 2'b11;
4408
           cmd_aref <= 1'b0;
4409
           cmd_read <= 1'b0;
4410
           dq_oe <= 1'b0;
4411
           case (state)
4412
             `FSM_INIT:
4413
               if (shreg[3]) begin
4414
                  {ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch};
4415
                  open_ba[ba_reg] <= 1'b0;
4416
               end else if (shreg[7] | shreg[19])
4417
                 {ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1};
4418
               else if (shreg[31])
4419
                 {ba,a,cmd} <=
4420
                  {2'b00,3'b000,`INIT_WB,2'b00,`INIT_CL,`INIT_BT,`INIT_BL, cmd_lmr};
4421
             `FSM_RFR:
4422
               if (shreg[0]) begin
4423
                  {ba,a,cmd} <= {2'b00, 13'b0010000000000, cmd_pch};
4424
                  open_ba <= 4'b0000;
4425
               end else if (shreg[2])
4426
                 {ba,a,cmd,cmd_aref} <= {2'b00, 13'd0, cmd_rfr,1'b1};
4427
             `FSM_ADR:
4428
               if (shreg[4])
4429
                 {ba_reg,row_reg,col_reg,we_reg,cti_reg,bte_reg} <=
4430
                                                {bank,row,col,we_i,cti_i,bte_i};
4431
             `FSM_PCH:
4432
               if (shreg[0]) begin
4433
                  {ba,a,cmd} <= {ba_reg,13'd0,cmd_pch};
4434
                  //open_ba <= 4'b0000;
4435
                  open_ba[ba_reg] <= 1'b0;
4436
               end
4437
             `FSM_ACT:
4438
               if (shreg[0]) begin
4439
                  {ba,a,cmd} <= {ba_reg,(13'd0 | row_reg),cmd_act};
4440
                  {open_ba[ba_reg],open_row[ba_reg]} <= {1'b1,row_reg};
4441
               end
4442
             `FSM_RW:
4443
               begin
4444
                  if (we_reg & !count0)
4445
                    cmd <= cmd_wr;
4446
                  else if (!count0)
4447
                    {cmd,cmd_read} <= {cmd_rd,1'b1};
4448
                  else
4449
                    cmd <= cmd_nop;
4450
                  if (we_reg)
4451
                    begin
4452
                       dqm <= count0 ? ~sel_i[1:0] : ~sel_i[3:2];
4453
                    end
4454
                  else
4455
                    dqm <= 2'b00;
4456
                  //if (we_reg)
4457
                  dq_oe <= we_reg;//1'b1;
4458
                  if (!stall)
4459
                    begin
4460
                       if (cti_reg==increment)
4461
                         case (bte_reg)
4462
                           linear: {ba,a} <= {ba_reg,col_reg_a10_fix};
4463
                           beat4:  {ba,a,col_reg[2:0]} <=
4464
                                  {ba_reg,col_reg_a10_fix, col_reg[2:0] + 3'd1};
4465
          `ifdef BEAT8
4466
                           beat8:  {ba,a,col_reg[3:0]} <=
4467
                                  {ba_reg,col_reg_a10_fix, col_reg[3:0] + 4'd1};
4468
          `endif
4469
          `ifdef BEAT16
4470
                           beat16: {ba,a,col_reg[4:0]} <=
4471
                                  {ba_reg,col_reg_a10_fix, col_reg[4:0] + 5'd1};
4472
          `endif
4473
                         endcase // case (bte_reg)
4474
                       else
4475
                         {ba,a} <= {ba_reg,col_reg_a10_fix};
4476
 
4477
                    end // if (!stall)
4478
               end
4479
                           endcase
4480
        end
4481
     end
4482
 
4483
   reg fifo_read_data_en;
4484
   always @(posedge sdram_clk)
4485
     if (sdram_rst)
4486
       fifo_read_data_en <= 1;
4487
     else if (next==`FSM_RW)
4488
       fifo_read_data_en <= ~fifo_read_data_en;
4489
     else
4490
       fifo_read_data_en <= 1;
4491
 
4492
   reg [3:0] beat4_data_read_limiter; // Use this to record how many times we've pulsed fifo_rd_data
4493
   // Only 3 bits, becuase we're looking at when fifo_read_data_en goes low - should only happen 3
4494
   // times for a 4-beat burst
4495
   always @(posedge sdram_clk)
4496
     if (sdram_rst)
4497
       beat4_data_read_limiter <= 0;
4498
     else if(state==`FSM_ADR)
4499
       beat4_data_read_limiter <= 0;
4500
     else if (!fifo_read_data_en)
4501
       beat4_data_read_limiter <= {beat4_data_read_limiter[2:0],1'b1};
4502
 
4503
 
4504
 
4505
   // rd_adr goes high when next adr is fetched from sync RAM and during write burst
4506
   assign fifo_rd_adr  = state==`FSM_ADR & shreg[1];
4507
 
4508
   assign fifo_rd_data = (((state!=`FSM_RW & next==`FSM_RW)|(state==`FSM_RW & (cti_reg==increment && bte_reg==beat4 & fifo_read_data_en & !(&beat4_data_read_limiter)))) & we_reg & !fifo_empty);
4509
 
4510
   /*
4511
   assign fifo_rd_data = ((state==`FSM_RW & next==`FSM_RW) &
4512
                          we_reg & !count0 & !fifo_empty);
4513
*/
4514
   assign state_idle = (state==`FSM_IDLE);
4515
 
4516
   // bank and row open ?
4517
   assign current_bank_closed = !(open_ba[bank]);
4518
   assign current_row_open = open_row[bank]==row;
4519
 
4520
   always @ (posedge sdram_clk or posedge sdram_rst)
4521
     if (sdram_rst)
4522
       {current_bank_closed_reg, current_row_open_reg} <= {1'b1, 1'b0};
4523
     else
4524
       //if (state==adr & counter[1:0]==2'b10)
4525
       {current_bank_closed_reg, current_row_open_reg} <=
4526
                                        {current_bank_closed, current_row_open};
4527
 
4528
   // Record the number of write enables going to INGRESS fifo (ie. that we 
4529
   // generate when we're reading) - this makes sure we keep track of when a
4530
   // burst read is in progress, and we can signal the wishbone bus to wait
4531
   // for this data to be put into the FIFO before it'll empty it when it's
4532
   // had a terminated burst transfer.
4533
   reg [3:0] fifo_we_record;
4534
   assign debug_fifo_we_record = fifo_we_record;
4535
   always @(posedge sdram_clk)
4536
     if (sdram_rst)
4537
       fifo_we_record <= 0;
4538
     else if (next==`FSM_RW & ((state==`FSM_ADR)|(state==`FSM_ACT)) &
4539
              cti_reg==increment & (bte_reg==beat4) & !we_reg)
4540
       fifo_we_record <= 4'b0001;
4541
     else if (sdram_fifo_wr)
4542
       fifo_we_record <= {fifo_we_record[2:0],1'b0};
4543
`ifdef SDRAM_WB_SAME_CLOCKS
4544
   assign sdram_burst_reading = |fifo_we_record;
4545
`else
4546
   assign sdram_burst_reading = 0;
4547
`endif
4548
 
4549
 
4550
endmodule
4551
`timescale 1ns/1ns
4552
module versatile_mem_ctrl_wb
4553
  (
4554
   // wishbone side
4555
   wb_adr_i_v, wb_dat_i_v, wb_dat_o_v,
4556
   wb_stb_i, wb_cyc_i, wb_ack_o,
4557
   wb_clk, wb_rst,
4558
    // SDRAM controller interface
4559
   sdram_dat_o, sdram_fifo_empty, sdram_fifo_rd_adr, sdram_fifo_rd_data, sdram_fifo_re,
4560
   sdram_dat_i, sdram_fifo_wr, sdram_fifo_we, sdram_burst_reading,
4561
   debug_wb_fsm_state, debug_ingress_fifo_empty, debug_egress_fifo_empty,
4562
   sdram_clk, sdram_rst
4563
 
4564
);
4565
 
4566
parameter nr_of_wb_ports = 3;
4567
 
4568
input  [36*nr_of_wb_ports-1:0]  wb_adr_i_v;
4569
input  [36*nr_of_wb_ports-1:0]  wb_dat_i_v;
4570
input  [0:nr_of_wb_ports-1]     wb_stb_i;
4571
input  [0:nr_of_wb_ports-1]     wb_cyc_i;
4572
output [32*nr_of_wb_ports-1:0]  wb_dat_o_v;
4573
output [0:nr_of_wb_ports-1]     wb_ack_o;
4574
input                           wb_clk;
4575
input                           wb_rst;
4576
 
4577
output [35:0]               sdram_dat_o;
4578
output [0:nr_of_wb_ports-1] sdram_fifo_empty;
4579
input                       sdram_fifo_rd_adr, sdram_fifo_rd_data;
4580
input  [0:nr_of_wb_ports-1] sdram_fifo_re;
4581
input  [31:0]               sdram_dat_i;
4582
input                       sdram_fifo_wr;
4583
input  [0:nr_of_wb_ports-1] sdram_fifo_we;
4584
input                       sdram_burst_reading;
4585
input                       sdram_clk;
4586
input                       sdram_rst;
4587
 
4588
   output [(2*nr_of_wb_ports)-1:0] debug_wb_fsm_state;
4589
   output [nr_of_wb_ports-1:0]   debug_ingress_fifo_empty;
4590
   output [nr_of_wb_ports-1:0]   debug_egress_fifo_empty;
4591
 
4592
 
4593
 
4594
parameter linear       = 2'b00;
4595
parameter wrap4        = 2'b01;
4596
parameter wrap8        = 2'b10;
4597
parameter wrap16       = 2'b11;
4598
parameter classic      = 3'b000;
4599
parameter endofburst   = 3'b111;
4600
 
4601
`define CTI_I 2:0
4602
`define BTE_I 4:3
4603
`define WE_I  5
4604
 
4605
parameter idle = 2'b00;
4606
parameter rd   = 2'b01;
4607
parameter wr   = 2'b10;
4608
parameter fe   = 2'b11;
4609
 
4610
reg [1:0] wb_state[0:nr_of_wb_ports-1];
4611
 
4612
wire [35:0] wb_adr_i[0:nr_of_wb_ports-1];
4613
wire [35:0] wb_dat_i[0:nr_of_wb_ports-1];
4614
wire [36*nr_of_wb_ports-1:0] egress_fifo_di;
4615
wire [31:0] wb_dat_o;
4616
 
4617
wire [0:nr_of_wb_ports] stall;
4618
wire [0:nr_of_wb_ports-1] state_idle;
4619
wire [0:nr_of_wb_ports-1] egress_fifo_we,  egress_fifo_full;
4620
wire [0:nr_of_wb_ports-1] ingress_fifo_re, ingress_fifo_empty;
4621
 
4622
   wire [1:0]              debug_each_wb_fsm_state [0:nr_of_wb_ports-1];
4623
 
4624
 
4625
genvar i;
4626
 
4627
assign stall[0] = 1'b0;
4628
 
4629
`define INDEX (nr_of_wb_ports-i)*36-1:(nr_of_wb_ports-1-i)*36
4630
generate
4631
    for (i=0;i<nr_of_wb_ports;i=i+1) begin : vector2array
4632
        assign wb_adr_i[i] = wb_adr_i_v[`INDEX];
4633
        assign wb_dat_i[i] = wb_dat_i_v[`INDEX];
4634
        assign egress_fifo_di[`INDEX] = (state_idle[i]) ?
4635
                                        wb_adr_i[i] : wb_dat_i[i];
4636
 
4637
    end
4638
endgenerate
4639
 
4640
   // Debug output assignments
4641
   generate
4642
      for (i=0;i<nr_of_wb_ports;i=i+1) begin : vector2debugarray
4643
         assign debug_wb_fsm_state[(nr_of_wb_ports-i)*2-1:(nr_of_wb_ports-1-i)*2] = debug_each_wb_fsm_state[i];
4644
      end
4645
   endgenerate
4646
   assign debug_ingress_fifo_empty = ingress_fifo_empty;
4647
   assign debug_egress_fifo_empty = egress_fifo_we;
4648
 
4649
 
4650
generate
4651
    for (i=0;i<nr_of_wb_ports;i=i+1) begin : fsm
4652
        fsm_wb fsm_wb_i
4653
          (
4654
           .stall_i(stall[i]),
4655
           .stall_o(stall[i+1]),
4656
           .we_i (wb_adr_i[i][`WE_I]),
4657
           .cti_i(wb_adr_i[i][`CTI_I]),
4658
           .bte_i(wb_adr_i[i][`BTE_I]),
4659
           .stb_i(wb_stb_i[i]),
4660
           .cyc_i(wb_cyc_i[i]),
4661
           .ack_o(wb_ack_o[i]),
4662
           .egress_fifo_we(egress_fifo_we[i]),
4663
           .egress_fifo_full(egress_fifo_full[i]),
4664
            .ingress_fifo_re(ingress_fifo_re[i]),
4665
           .ingress_fifo_empty(ingress_fifo_empty[i]),
4666
           .state_idle(state_idle[i]),
4667
           .sdram_burst_reading(sdram_burst_reading),
4668
           .debug_state(debug_each_wb_fsm_state[i]),
4669
           .wb_clk(wb_clk),
4670
           .wb_rst(wb_rst)
4671
           );
4672
    end
4673
endgenerate
4674
 
4675
egress_fifo # (
4676
               .a_hi_size(4),.a_lo_size(4),.nr_of_queues(nr_of_wb_ports),
4677
               .data_width(36))
4678
   egress_FIFO(
4679
               .d(egress_fifo_di),
4680
               .fifo_full(egress_fifo_full),
4681
               .write(|(egress_fifo_we)),
4682
               .write_enable(egress_fifo_we),
4683
               .q(sdram_dat_o),
4684
               .fifo_empty(sdram_fifo_empty),
4685
               .read_adr(sdram_fifo_rd_adr),
4686
               .read_data(sdram_fifo_rd_data),
4687
               .read_enable(sdram_fifo_re),
4688
               .clk1(wb_clk),
4689
               .rst1(wb_rst),
4690
               .clk2(sdram_clk),
4691
               .rst2(sdram_rst)
4692
               );
4693
 
4694
   async_fifo_mq # (
4695
                    .a_hi_size(4),.a_lo_size(4),.nr_of_queues(nr_of_wb_ports),
4696
                    .data_width(32))
4697
   ingress_FIFO(
4698
                .d(sdram_dat_i), .fifo_full(), .write(sdram_fifo_wr),
4699
                .write_enable(sdram_fifo_we), .q(wb_dat_o),
4700
                .fifo_empty(ingress_fifo_empty), .read(|(ingress_fifo_re)),
4701
                .read_enable(ingress_fifo_re), .clk1(sdram_clk),
4702
                .rst1(sdram_rst), .clk2(wb_clk), .rst2(wb_rst)
4703
                );
4704
 
4705
assign wb_dat_o_v = {nr_of_wb_ports{wb_dat_o}};
4706
 
4707
endmodule`timescale 1ns/1ns
4708
`ifdef DDR_16
4709
 `include "ddr_16_defines.v"
4710
`endif
4711
`ifdef SDR_16
4712
 `include "sdr_16_defines.v"
4713
`endif
4714
module versatile_mem_ctrl_top
4715
  (
4716
   // wishbone side
4717
   wb_adr_i_0, wb_dat_i_0, wb_dat_o_0,
4718
   wb_stb_i_0, wb_cyc_i_0, wb_ack_o_0,
4719
   wb_adr_i_1, wb_dat_i_1, wb_dat_o_1,
4720
   wb_stb_i_1, wb_cyc_i_1, wb_ack_o_1,
4721
   wb_adr_i_2, wb_dat_i_2, wb_dat_o_2,
4722
   wb_stb_i_2, wb_cyc_i_2, wb_ack_o_2,
4723
   wb_adr_i_3, wb_dat_i_3, wb_dat_o_3,
4724
   wb_stb_i_3, wb_cyc_i_3, wb_ack_o_3,
4725
   wb_clk, wb_rst,
4726
 
4727
`ifdef SDR_16
4728
   ba_pad_o, a_pad_o, cs_n_pad_o, ras_pad_o, cas_pad_o, we_pad_o, dq_o, dqm_pad_o, dq_i, dq_oe, cke_pad_o,
4729
`endif
4730
 
4731
`ifdef DDR_16
4732
   ck_pad_o, ck_n_pad_o, cke_pad_o, ck_fb_pad_o, ck_fb_pad_i,
4733
   cs_n_pad_o, ras_pad_o, cas_pad_o,  we_pad_o,
4734
   dm_rdqs_pad_io,  ba_pad_o, addr_pad_o, dq_pad_io, dqs_pad_io, dqs_oe, dqs_n_pad_io, rdqs_n_pad_i, odt_pad_o,
4735
`endif
4736
   // SDRAM signals
4737
   sdram_clk, sdram_rst
4738
   );
4739
 
4740
   // number of wb clock domains
4741
   parameter nr_of_wb_clk_domains = 1;
4742
   // number of wb ports in each wb clock domain
4743
   parameter nr_of_wb_ports_clk0  = 3;
4744
   parameter nr_of_wb_ports_clk1  = 0;
4745
   parameter nr_of_wb_ports_clk2  = 0;
4746
   parameter nr_of_wb_ports_clk3  = 0;
4747
 
4748
   input  [36*nr_of_wb_ports_clk0-1:0] wb_adr_i_0;
4749
   input [36*nr_of_wb_ports_clk0-1:0]  wb_dat_i_0;
4750
   output [32*nr_of_wb_ports_clk0-1:0] wb_dat_o_0;
4751
   input [0:nr_of_wb_ports_clk0-1]     wb_stb_i_0, wb_cyc_i_0;
4752
   output [0:nr_of_wb_ports_clk0-1]    wb_ack_o_0;
4753
 
4754
 
4755
   input [36*nr_of_wb_ports_clk1-1:0]  wb_adr_i_1;
4756
   input [36*nr_of_wb_ports_clk1-1:0]  wb_dat_i_1;
4757
   output [32*nr_of_wb_ports_clk1-1:0] wb_dat_o_1;
4758
   input [0:nr_of_wb_ports_clk1-1]     wb_stb_i_1, wb_cyc_i_1;
4759
   output [0:nr_of_wb_ports_clk1-1]    wb_ack_o_1;
4760
 
4761
   input [36*nr_of_wb_ports_clk2-1:0]  wb_adr_i_2;
4762
   input [36*nr_of_wb_ports_clk2-1:0]  wb_dat_i_2;
4763
   output [32*nr_of_wb_ports_clk2-1:0] wb_dat_o_2;
4764
   input [0:nr_of_wb_ports_clk2-1]     wb_stb_i_2, wb_cyc_i_2;
4765
   output [0:nr_of_wb_ports_clk2-1]    wb_ack_o_2;
4766
 
4767
   input [36*nr_of_wb_ports_clk3-1:0]  wb_adr_i_3;
4768
   input [36*nr_of_wb_ports_clk3-1:0]  wb_dat_i_3;
4769
   output [32*nr_of_wb_ports_clk3-1:0] wb_dat_o_3;
4770
   input [0:nr_of_wb_ports_clk3-1]     wb_stb_i_3, wb_cyc_i_3;
4771
   output [0:nr_of_wb_ports_clk3-1]    wb_ack_o_3;
4772
 
4773
   input [0:nr_of_wb_clk_domains-1]    wb_clk;
4774
   input [0:nr_of_wb_clk_domains-1]    wb_rst;
4775
 
4776
`ifdef SDR_16
4777
   output [1:0]                 ba_pad_o;
4778
   output [12:0]                        a_pad_o;
4779
   output                              cs_n_pad_o;
4780
   output                              ras_pad_o;
4781
   output                              cas_pad_o;
4782
   output                              we_pad_o;
4783
   output reg [(`SDRAM_DATA_WIDTH)-1:0] dq_o /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
4784
   output [1:0]                 dqm_pad_o;
4785
   input [(`SDRAM_DATA_WIDTH)-1:0]     dq_i ;
4786
   output                              dq_oe;
4787
   output                              cke_pad_o;
4788
`endif
4789
`ifdef DDR_16
4790
   output                              ck_pad_o;
4791
   output                              ck_n_pad_o;
4792
   output                              cke_pad_o;
4793
   output                              ck_fb_pad_o;
4794
   input                               ck_fb_pad_i;
4795
   output                              cs_n_pad_o;
4796
   output                              ras_pad_o;
4797
   output                              cas_pad_o;
4798
   output                              we_pad_o;
4799
   inout [1:0]                          dm_rdqs_pad_io;
4800
   output [1:0]                 ba_pad_o;
4801
   output [12:0]                        addr_pad_o;
4802
   inout [15:0]                 dq_pad_io;
4803
   inout [1:0]                          dqs_pad_io;
4804
   output                              dqs_oe;
4805
   inout [1:0]                          dqs_n_pad_io;
4806
   input [1:0]                          rdqs_n_pad_i;
4807
   output                              odt_pad_o;
4808
`endif
4809
   input                               sdram_clk, sdram_rst;
4810
 
4811
   wire [0:15]                          fifo_empty[0:3];
4812
   wire                                current_fifo_empty;
4813
   wire [0:15]                          fifo_re[0:3];
4814
   wire [35:0]                          fifo_dat_o[0:3];
4815
   wire [31:0]                          fifo_dat_i;
4816
   wire [0:15]                          fifo_we[0:3];
4817
   wire                                fifo_rd_adr, fifo_rd_data, fifo_wr, idle, count0;
4818
 
4819
   wire [0:15]                          fifo_sel_i, fifo_sel_dly;
4820
   reg [0:15]                           fifo_sel_reg;
4821
   wire [1:0]                           fifo_sel_domain_i, fifo_sel_domain_dly;
4822
   reg [1:0]                            fifo_sel_domain_reg;
4823
 
4824
   reg                                 refresh_req;
4825
 
4826
   wire [35:0]                          tx_fifo_dat_o;
4827
 
4828
   wire                                burst_reading;
4829
   reg                                 sdram_fifo_wr_r;
4830
 
4831
 
4832
   generate
4833
      if (nr_of_wb_clk_domains > 0) begin
4834
         versatile_mem_ctrl_wb
4835
           # (.nr_of_wb_ports(nr_of_wb_ports_clk0))
4836
         wb0
4837
           (
4838
            // wishbone side
4839
            .wb_adr_i_v(wb_adr_i_0),
4840
            .wb_dat_i_v(wb_dat_i_0),
4841
            .wb_dat_o_v(wb_dat_o_0),
4842
            .wb_stb_i(wb_stb_i_0),
4843
            .wb_cyc_i(wb_cyc_i_0),
4844
            .wb_ack_o(wb_ack_o_0),
4845
            .wb_clk(wb_clk[0]),
4846
            .wb_rst(wb_rst[0]),
4847
            // SDRAM controller interface
4848
            .sdram_dat_o(fifo_dat_o[0]),
4849
            .sdram_fifo_empty(fifo_empty[0][0:nr_of_wb_ports_clk0-1]),
4850
            .sdram_fifo_rd_adr(fifo_rd_adr),
4851
            .sdram_fifo_rd_data(fifo_rd_data),
4852
            .sdram_fifo_re(fifo_re[0][0:nr_of_wb_ports_clk0-1]),
4853
            .sdram_dat_i(fifo_dat_i),
4854
            .sdram_fifo_wr(fifo_wr),
4855
            .sdram_fifo_we(fifo_we[0][0:nr_of_wb_ports_clk0-1]),
4856
            .sdram_burst_reading(burst_reading),
4857
            .debug_wb_fsm_state(),
4858
            .debug_ingress_fifo_empty(),
4859
            .debug_egress_fifo_empty(),
4860
            .sdram_clk(sdram_clk),
4861
            .sdram_rst(sdram_rst) );
4862
      end
4863
      if (nr_of_wb_ports_clk0 < 16) begin
4864
         assign fifo_empty[0][nr_of_wb_ports_clk0:15] = {(16-nr_of_wb_ports_clk0){1'b1}};
4865
      end
4866
   endgenerate
4867
 
4868
   generate
4869
      if (nr_of_wb_clk_domains > 1) begin
4870
         versatile_mem_ctrl_wb
4871
           # (.nr_of_wb_ports(nr_of_wb_ports_clk1))
4872
         wb1
4873
           (
4874
            // wishbone side
4875
            .wb_adr_i_v(wb_adr_i_1),
4876
            .wb_dat_i_v(wb_dat_i_1),
4877
            .wb_dat_o_v(wb_dat_o_1),
4878
            .wb_stb_i(wb_stb_i_1),
4879
            .wb_cyc_i(wb_cyc_i_1),
4880
            .wb_ack_o(wb_ack_o_1),
4881
            .wb_clk(wb_clk[1]),
4882
            .wb_rst(wb_rst[1]),
4883
            // SDRAM controller interface
4884
            .sdram_dat_o(fifo_dat_o[1]),
4885
            .sdram_fifo_empty(fifo_empty[1][0:nr_of_wb_ports_clk1-1]),
4886
            .sdram_fifo_rd_adr(fifo_rd_adr),
4887
            .sdram_fifo_rd_data(fifo_rd_data),
4888
            .sdram_fifo_re(fifo_re[1][0:nr_of_wb_ports_clk1-1]),
4889
            .sdram_dat_i(fifo_dat_i),
4890
            .sdram_fifo_wr(fifo_wr),
4891
            .sdram_fifo_we(fifo_we[1][0:nr_of_wb_ports_clk1-1]),
4892
            .sdram_burst_reading(burst_reading),
4893
            .sdram_clk(sdram_clk),
4894
            .sdram_rst(sdram_rst) );
4895
         if (nr_of_wb_ports_clk1 < 16) begin
4896
            assign fifo_empty[1][nr_of_wb_ports_clk1:15] = {(16-nr_of_wb_ports_clk1){1'b1}};
4897
         end
4898
      end else begin
4899
         assign fifo_empty[1] = {16{1'b1}};
4900
         assign fifo_dat_o[1] = {36{1'b0}};
4901
      end
4902
   endgenerate
4903
 
4904
   generate
4905
      if (nr_of_wb_clk_domains > 2) begin
4906
         versatile_mem_ctrl_wb
4907
           # (.nr_of_wb_ports(nr_of_wb_ports_clk1))
4908
         wb2
4909
           (
4910
            // wishbone side
4911
            .wb_adr_i_v(wb_adr_i_2),
4912
            .wb_dat_i_v(wb_dat_i_2),
4913
            .wb_dat_o_v(wb_dat_o_2),
4914
            .wb_stb_i(wb_stb_i_2),
4915
            .wb_cyc_i(wb_cyc_i_2),
4916
            .wb_ack_o(wb_ack_o_2),
4917
            .wb_clk(wb_clk[2]),
4918
            .wb_rst(wb_rst[2]),
4919
            // SDRAM controller interface
4920
            .sdram_dat_o(fifo_dat_o[2]),
4921
            .sdram_fifo_empty(fifo_empty[2][0:nr_of_wb_ports_clk2-1]),
4922
            .sdram_fifo_rd_adr(fifo_rd_adr),
4923
            .sdram_fifo_rd_data(fifo_rd_data),
4924
            .sdram_fifo_re(fifo_re[2][0:nr_of_wb_ports_clk2-1]),
4925
            .sdram_dat_i(fifo_dat_i),
4926
            .sdram_fifo_wr(fifo_wr),
4927
            .sdram_fifo_we(fifo_we[2][0:nr_of_wb_ports_clk2-1]),
4928
            .sdram_burst_reading(burst_reading),
4929
            .sdram_clk(sdram_clk),
4930
            .sdram_rst(sdram_rst) );
4931
         if (nr_of_wb_ports_clk2 < 16) begin
4932
            assign fifo_empty[2][nr_of_wb_ports_clk2:15] = {(16-nr_of_wb_ports_clk2){1'b1}};
4933
         end
4934
      end else begin
4935
         assign fifo_empty[2] = {16{1'b1}};
4936
         assign fifo_dat_o[2] = {36{1'b0}};
4937
      end
4938
   endgenerate
4939
 
4940
   generate
4941
      if (nr_of_wb_clk_domains > 3) begin
4942
         versatile_mem_ctrl_wb
4943
           # (.nr_of_wb_ports(nr_of_wb_ports_clk3))
4944
         wb3
4945
           (
4946
            // wishbone side
4947
            .wb_adr_i_v(wb_adr_i_3),
4948
            .wb_dat_i_v(wb_dat_i_3),
4949
            .wb_dat_o_v(wb_dat_o_3),
4950
            .wb_stb_i(wb_stb_i_3),
4951
            .wb_cyc_i(wb_cyc_i_3),
4952
            .wb_ack_o(wb_ack_o_3),
4953
            .wb_clk(wb_clk[3]),
4954
            .wb_rst(wb_rst[3]),
4955
            // SDRAM controller interface
4956
            .sdram_dat_o(fifo_dat_o[3]),
4957
            .sdram_fifo_empty(fifo_empty[3][0:nr_of_wb_ports_clk3-1]),
4958
            .sdram_fifo_rd_adr(fifo_rd_adr),
4959
            .sdram_fifo_rd_data(fifo_rd_data),
4960
            .sdram_fifo_re(fifo_re[3][0:nr_of_wb_ports_clk3-1]),
4961
            .sdram_dat_i(fifo_dat_i),
4962
            .sdram_fifo_wr(fifo_wr),
4963
            .sdram_fifo_we(fifo_we[3][0:nr_of_wb_ports_clk3-1]),
4964
            .sdram_burst_reading(burst_reading),
4965
            .sdram_clk(sdram_clk),
4966
            .sdram_rst(sdram_rst) );
4967
         if (nr_of_wb_ports_clk3 < 16) begin
4968
            assign fifo_empty[3][nr_of_wb_ports_clk3:15] = {(16-nr_of_wb_ports_clk3){1'b1}};
4969
         end
4970
      end else begin
4971
         assign fifo_empty[3] = {16{1'b1}};
4972
         assign fifo_dat_o[3] = {36{1'b0}};
4973
      end
4974
   endgenerate
4975
 
4976
   encode encode0
4977
     (
4978
      .fifo_empty_0(fifo_empty[0]), .fifo_empty_1(fifo_empty[1]),
4979
      .fifo_empty_2(fifo_empty[2]), .fifo_empty_3(fifo_empty[3]),
4980
      .fifo_sel(fifo_sel_i), .fifo_sel_domain(fifo_sel_domain_i)
4981
      );
4982
 
4983
   always @ (posedge sdram_clk or posedge sdram_rst)
4984
     begin
4985
        if (sdram_rst)
4986
          {fifo_sel_reg,fifo_sel_domain_reg} <= {16'h0,2'b00};
4987
        else
4988
          if (idle)
4989
            {fifo_sel_reg,fifo_sel_domain_reg}<={fifo_sel_i,fifo_sel_domain_i};
4990
     end
4991
 
4992
   decode decode0
4993
     (
4994
      .fifo_sel(fifo_sel_reg), .fifo_sel_domain(fifo_sel_domain_reg),
4995
      .fifo_we_0(fifo_re[0]), .fifo_we_1(fifo_re[1]), .fifo_we_2(fifo_re[2]),
4996
      .fifo_we_3(fifo_re[3])
4997
      );
4998
 
4999
   // fifo_re[0-3] is a one-hot read enable structure
5000
   // fifo_empty should go active when chosen fifo queue is empty
5001
   assign current_fifo_empty = (idle) ?
5002
                               (!(|fifo_sel_i)) :
5003
                               (|(fifo_empty[0] & fifo_re[0])) |
5004
                               (|(fifo_empty[1] & fifo_re[1])) |
5005
                               (|(fifo_empty[2] & fifo_re[2])) |
5006
                               (|(fifo_empty[3] & fifo_re[3]));
5007
 
5008
   decode decode1
5009
     (
5010
      .fifo_sel(fifo_sel_dly), .fifo_sel_domain(fifo_sel_domain_dly),
5011
      .fifo_we_0(fifo_we[0]), .fifo_we_1(fifo_we[1]), .fifo_we_2(fifo_we[2]),
5012
      .fifo_we_3(fifo_we[3])
5013
      );
5014
 
5015
`ifdef SDR_16
5016
 
5017
   wire ref_cnt_zero;
5018
   reg [(`SDRAM_DATA_WIDTH)-1:0] dq_i_reg /*synthesis syn_useioff=1 syn_allow_retiming=0 */;
5019
   reg [(`SDRAM_DATA_WIDTH)-1:0] dq_i_tmp_reg;
5020
   reg [17:0] dq_o_tmp_reg;
5021
   wire       cmd_aref, cmd_read;
5022
 
5023
   // refresch counter
5024
   //ref_counter ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk));
5025
   ref_counter
5026
`ifdef MT48LC32M16
5027
     #(.length(9), .wrap_value(67))
5028
`endif
5029
   ref_counter0( .zq(ref_cnt_zero), .rst(sdram_rst), .clk(sdram_clk));
5030
 
5031
   always @ (posedge sdram_clk or posedge sdram_rst)
5032
     if (sdram_rst)
5033
       refresh_req <= 1'b0;
5034
     else
5035
       if (ref_cnt_zero)
5036
         refresh_req <= 1'b1;
5037
       else if (cmd_aref)
5038
         refresh_req <= 1'b0;
5039
 
5040
   reg        current_fifo_empty_r;
5041
   always @(posedge sdram_clk)
5042
     current_fifo_empty_r <= current_fifo_empty;
5043
 
5044
   always @(posedge sdram_clk)
5045
     sdram_fifo_wr_r <= fifo_wr;
5046
 
5047
 
5048
 
5049
   // SDR SDRAM 16 FSM
5050
   fsm_sdr_16 fsm_sdr_16_0
5051
     (
5052
      .adr_i({fifo_dat_o[0][`BA_SIZE+`ROW_SIZE+`COL_SIZE+6-2:6],1'b0}),
5053
      .we_i(fifo_dat_o[0][5]),
5054
      .bte_i(fifo_dat_o[0][4:3]),
5055
      .cti_i(fifo_dat_o[0][2:0]),
5056
      .sel_i({fifo_dat_o[0][3:2],dq_o_tmp_reg[1:0]}),
5057
      .fifo_empty(current_fifo_empty_r),
5058
      .fifo_rd_adr(fifo_rd_adr),
5059
      .fifo_rd_data(fifo_rd_data),
5060
      .state_idle(idle),
5061
      .count0(count0),
5062
      .refresh_req(refresh_req),
5063
      .cmd_aref(cmd_aref),
5064
      .cmd_read(cmd_read),
5065
      .ba(ba_pad_o), .a(a_pad_o),
5066
      .cmd({ras_pad_o, cas_pad_o, we_pad_o}),
5067
      .dq_oe(dq_oe),
5068
      .dqm(dqm_pad_o),
5069
      .sdram_fifo_wr(sdram_fifo_wr_r),
5070
      .sdram_burst_reading(burst_reading),
5071
      .debug_state(),
5072
      .debug_fifo_we_record(),
5073
      .sdram_clk(sdram_clk),
5074
      .sdram_rst(sdram_rst)
5075
      );
5076
 
5077
   assign cs_pad_o = 1'b0;
5078
   assign cke_pad_o = 1'b1;
5079
 
5080
   genvar     i;
5081
   generate
5082
      for (i=0; i < 16; i=i+1) begin : dly
5083
 
5084
         defparam delay0.depth=`INIT_CL+2;
5085
         defparam delay0.width=1;
5086
         delay delay0 (
5087
                       .d(fifo_sel_reg[i]),
5088
                       .q(fifo_sel_dly[i]),
5089
                       .clk(sdram_clk),
5090
                       .rst(sdram_rst)
5091
                       );
5092
      end
5093
 
5094
      defparam delay1.depth=`INIT_CL+2;
5095
      defparam delay1.width=2;
5096
      delay delay1 (
5097
                    .d(fifo_sel_domain_reg),
5098
                    .q(fifo_sel_domain_dly),
5099
                    .clk(sdram_clk),
5100
                    .rst(sdram_rst)
5101
                    );
5102
 
5103
      defparam delay2.depth=`INIT_CL+2;
5104
      defparam delay2.width=1;
5105
      delay delay2 (
5106
                    .d(cmd_read),
5107
                    .q(fifo_wr),
5108
                    .clk(sdram_clk),
5109
                    .rst(sdram_rst)
5110
                    );
5111
 
5112
   endgenerate
5113
 
5114
   // output registers
5115
   assign cs_n_pad_o = 1'b0;
5116
   assign cke_pad_o  = 1'b1;
5117
 
5118
   always @ (posedge sdram_clk)
5119
     dq_i_reg <= dq_i;
5120
 
5121
   always @(posedge sdram_clk)
5122
     dq_i_tmp_reg <= dq_i_reg;
5123
 
5124
   assign fifo_dat_i = {dq_i_tmp_reg, dq_i_reg};
5125
 
5126
   always @ (posedge sdram_clk or posedge sdram_rst)
5127
     if (sdram_rst)
5128
       dq_o_tmp_reg <= 18'h0;
5129
     else
5130
       dq_o_tmp_reg <= {fifo_dat_o[0][19:4],fifo_dat_o[0][1:0]};
5131
 
5132
   // output dq_o mux and dffs
5133
   always @ (posedge sdram_clk or posedge sdram_rst)
5134
     if (sdram_rst)
5135
       dq_o <= 16'h0000;
5136
     else
5137
       if (~count0)
5138
         dq_o <= fifo_dat_o[0][35:20];
5139
       else
5140
         dq_o <= dq_o_tmp_reg[17:2];
5141
 
5142
   /*
5143
    // data mask signals should be not(sel_i) for write and 2'b00 for read
5144
    always @ (posedge sdram_clk or posedge sdram_rst)
5145
    if (sdram_rst)
5146
    dqm_pad_o <= 2'b00;
5147
    else
5148
    if (~count0)
5149
    dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2];
5150
    else
5151
    dqm_pad_o <= ~dq_o_tmp_reg[1:0];
5152
    */
5153
   /*
5154
    always @ (posedge sdram_clk or posedge sdram_rst)
5155
    if (sdram_rst) begin
5156
    {dq_o, dqm_pad_o} <= {16'h0000,2'b00};
5157
 
5158
    end else
5159
    if (~count0) begin
5160
    dq_o <= fifo_dat_o[fifo_sel_domain_reg][35:20];
5161
    dq_o_tmp_reg[17:2] <= fifo_dat_o[fifo_sel_domain_reg][19:4];
5162
    if (cmd_read)
5163
    dqm_pad_o <= 2'b00;
5164
    else
5165
    dqm_pad_o <= ~fifo_dat_o[fifo_sel_domain_reg][3:2];
5166
    if (cmd_read)
5167
    dq_o_tmp_reg[1:0] <= 2'b00;
5168
    else
5169
    dq_o_tmp_reg[1:0] <= ~fifo_dat_o[fifo_sel_domain_reg][1:0];
5170
       end else
5171
    {dq_o,dqm_pad_o} <= dq_o_tmp_reg;
5172
    */
5173
 
5174
 
5175
`endif //  `ifdef SDR_16
5176
 
5177
 
5178
`ifdef DDR_16
5179
   wire        read, write;
5180
   wire        sdram_clk_90, sdram_clk_180, sdram_clk_270;
5181
   wire        ck_fb;
5182
   reg         cke, ras, cas, we, cs_n;
5183
   wire        cke_d, ras_d, cas_d, we_d, cs_n_d;
5184
   wire        ras_o, cas_o, we_o, cs_n_o;
5185
   wire [1:0]  ba_o;
5186
   wire [12:0] addr_o;
5187
   reg  [1:0]  ba;
5188
   wire [1:0]  ba_d;
5189
   reg [12:0]  addr;
5190
   wire [12:0] addr_d;
5191
   wire        dq_en, dqm_en;
5192
   reg [15:0]  dq_tx_reg;
5193
   wire [15:0] dq_tx;
5194
   reg [31:0]  dq_rx_reg;
5195
   wire [31:0] dq_rx;
5196
   wire [15:0] dq_o;
5197
   reg [3:0]   dqm_tx_reg;
5198
   wire [3:0]  dqm_tx;
5199
   wire [1:0]  dqm_o, dqs_o, dqs_n_o;
5200
   wire        ref_delay, ref_delay_ack;
5201
   wire        bl_en, bl_ack;
5202
   wire        tx_fifo_re, tx_fifo_re_i;
5203
   //wire        adr_init_delay;
5204
   //reg         adr_init_delay_i;
5205
   reg [3:0]   burst_cnt;
5206
   wire [3:0]  burst_next_cnt, burst_length;
5207
   //wire        burst_mask;
5208
   reg         burst_mask;
5209
   wire [12:0] cur_row;
5210
   wire  [3:0] burst_adr;
5211
   //wire  [2:0] tx_fifo_b_sel_i_cur;
5212
   wire  [2:0] rx_fifo_a_sel_i;
5213
   //wire  [7:0] tx_fifo_empty;
5214
   wire        rx_fifo_we;
5215
 
5216
   wire ref_cnt_zero;
5217
   wire cmd_aref;
5218
 
5219
   // refresh counter
5220
   ref_counter ref_counter0(
5221
     .zq(ref_cnt_zero),
5222
     .rst(sdram_rst),
5223
     .clk(sdram_clk));
5224
   always @ (posedge sdram_clk or posedge sdram_rst)
5225
   if (sdram_rst)
5226
     refresh_req <= 1'b0;
5227
   else
5228
     if (ref_cnt_zero)
5229
       refresh_req <= 1'b1;
5230
     else if (cmd_aref)
5231
       refresh_req <= 1'b0;
5232
 
5233
   // DDR SDRAM 16 FSM
5234
   ddr_16 ddr_16_0
5235
     (
5236
      .adr_init(adr_init),
5237
      .fifo_re(tx_fifo_re_i),
5238
      .fifo_re_d(tx_fifo_re),
5239
      .tx_fifo_dat_o(fifo_dat_o[fifo_sel_domain_reg]),
5240
      .burst_adr(burst_adr),
5241
      .fifo_empty(current_fifo_empty),
5242
      .fifo_sel(),
5243
      .read(read),
5244
      .write(write),
5245
      .ref_req(refresh_req),
5246
      .ref_ack(cmd_aref),
5247
      .ref_delay(ref_delay),
5248
      .state_idle(idle),
5249
      .ref_delay_ack(ref_delay_ack),
5250
      .bl_en(bl_en),
5251
      .bl_ack(bl_ack),
5252
      .a({ba_o,addr_o}),
5253
      .cmd({ras_o,cas_o,we_o}),
5254
      .cs_n(cs_n_o),
5255
      .cur_row(cur_row),
5256
      .clk(sdram_clk_0),
5257
      .rst(sdram_rst)
5258
      );
5259
 
5260
   inc_adr inc_adr0
5261
     (
5262
      .adr_i(fifo_dat_o[fifo_sel_domain_reg][9:6]),
5263
      .bte_i(fifo_dat_o[fifo_sel_domain_reg][4:3]),
5264
      .cti_i(fifo_dat_o[fifo_sel_domain_reg][2:0]),
5265
      .init(adr_init),
5266
      .inc(),
5267
      .adr_o(burst_adr),
5268
      .done(done),
5269
      .clk(sdram_clk_0),
5270
      .rst(sdram_rst)
5271
      );
5272
 
5273
   // Delay, refresh to activate/refresh
5274
   ref_delay_counter ref_delay_counter0
5275
     (
5276
      .cke(ref_delay),
5277
      .zq(ref_delay_ack),
5278
      .clk(sdram_clk_0),
5279
      .rst(sdram_rst)
5280
      );
5281
 
5282
   // Burst length, DDR2 SDRAM
5283
   burst_length_counter burst_length_counter0
5284
     (
5285
      .cke(bl_en),
5286
      .zq(bl_ack),
5287
      .clk(sdram_clk_0),
5288
      .rst(sdram_rst)
5289
      );
5290
 
5291
   // Wishbone burst length
5292
   assign burst_length = (adr_init && fifo_dat_o[fifo_sel_domain_reg][2:0] == 3'b000) ? 4'd1 :   // classic cycle
5293
                         (adr_init && fifo_dat_o[fifo_sel_domain_reg][2:0] == 3'b010) ? 4'd4 :   // incremental burst cycle
5294
                         burst_length;
5295
 
5296
   // Burst mask
5297
   // Burst length counter
5298
   assign burst_next_cnt = (burst_cnt == 3) ? 4'd0 : burst_cnt + 4'd1;
5299
   always @ (posedge sdram_clk_0 or posedge sdram_rst)
5300
     if (sdram_rst)
5301
       burst_cnt <= 4'h0;
5302
     else
5303
       if (bl_en)
5304
         burst_cnt <= burst_next_cnt;
5305
   // Burst Mask
5306
   //assign burst_mask = (burst_cnt >= burst_length) ? 1'b1 : 1'b0;
5307
 
5308
   // Burst Mask
5309
   always @ (posedge sdram_clk_0 or posedge sdram_rst)
5310
     if (sdram_rst)
5311
       burst_mask <= 1'b0;
5312
     else
5313
       burst_mask <= (burst_cnt >= burst_length) ? 1'b1 : 1'b0;
5314
 
5315
   // Delay address and control to compensate for delay in Tx FIOFs
5316
   defparam delay0.depth=3;
5317
   defparam delay0.width=20;
5318
   delay delay0 (
5319
      .d({cs_n_o,1'b1,ras_o,cas_o,we_o,ba_o,addr_o}),
5320
      .q({cs_n_d,cke_d,ras_d,cas_d,we_d,ba_d,addr_d}),
5321
      .clk(sdram_clk_180),
5322
      .rst(sdram_rst));
5323
 
5324
   // Assing outputs
5325
   // Non-DDR outputs
5326
   assign cs_n_pad_o  = cs_n_d;
5327
   assign cke_pad_o   = cke_d;
5328
   assign ras_pad_o   = ras_d;
5329
   assign cas_pad_o   = cas_d;
5330
   assign we_pad_o    = we_d;
5331
   assign ba_pad_o    = ba_d;
5332
   assign addr_pad_o  = addr_d;
5333
   assign ck_fb_pad_o = ck_fb;
5334
   assign dqs_oe      = dq_en;
5335
 
5336
   // Read latency, delay the control signals to fit latency of the DDR2 SDRAM
5337
   defparam delay1.depth=`CL+`AL+4;
5338
   defparam delay1.width=1;
5339
   delay delay1
5340
     (
5341
      .d(read && !burst_mask),
5342
      .q(fifo_wr),
5343
      .clk(sdram_clk_0),
5344
      .rst(sdram_rst)
5345
      );
5346
 
5347
   // write latency, delay the control signals to fit latency of the DDR2 SDRAM
5348
   defparam delay2.depth=`CL+`AL+1;
5349
   defparam delay2.width=1;
5350
   delay delay2
5351
     (
5352
      .d(write),
5353
      .q(dq_en),
5354
      .clk(sdram_clk_270),
5355
      .rst(sdram_rst)
5356
      );
5357
 
5358
   // write latency, delay the control signals to fit latency of the DDR2 SDRAM
5359
   defparam delay21.depth=`CL+`AL;
5360
   defparam delay21.width=1;
5361
   delay delay21
5362
     (
5363
      .d(burst_mask),
5364
      .q(dqm_en),
5365
      .clk(sdram_clk_270),
5366
      .rst(sdram_rst)
5367
      );
5368
 
5369
/*   // if CL>3 delay read from Tx FIFO
5370
   defparam delay3.depth=`CL+`AL-3;
5371
   defparam delay3.width=1;
5372
   delay delay3
5373
     (
5374
                 .d(tx_fifo_re_i && !burst_mask),
5375
                 .q(tx_fifo_re),
5376
                 .clk(sdram_clk_0),
5377
                 .rst(sdram_rst)
5378
                 );
5379
*/
5380
 
5381
   // if CL=3, no delay
5382
   assign tx_fifo_re = tx_fifo_re_i && !burst_mask;
5383
   assign fifo_rd_adr = tx_fifo_re;
5384
 
5385
   //
5386
   genvar i;
5387
   generate
5388
     for (i=0; i < 16; i=i+1) begin : dly
5389
 
5390
       defparam delay4.depth=`CL+2;
5391
       defparam delay4.width=1;
5392
       delay delay4 (
5393
         .d(fifo_sel_reg[i]),
5394
         .q(fifo_sel_dly[i]),
5395
         .clk(sdram_clk),
5396
         .rst(sdram_rst)
5397
       );
5398
     end
5399
 
5400
     defparam delay5.depth=`CL+2;
5401
     defparam delay5.width=2;
5402
     delay delay5 (
5403
       .d(fifo_sel_domain_reg),
5404
       .q(fifo_sel_domain_dly),
5405
       .clk(sdram_clk),
5406
       .rst(sdram_rst)
5407
     );
5408
endgenerate
5409
 
5410
 
5411
   // Increment address
5412
   defparam delay6.depth=`CL+`AL-1;
5413
   defparam delay6.width=1;
5414
   delay delay6
5415
     (
5416
      .d({write|read}),
5417
      .q({adr_inc}),
5418
      .clk(sdram_clk_0),
5419
      .rst(sdram_rst)
5420
      );
5421
 
5422
   // DCM/PLL with internal and external feedback
5423
   // Remove skew from internal and external clock
5424
   // Parameters are set in dcm_pll.v
5425
   dcm_pll dcm_pll_0
5426
     (
5427
      .rst(sdram_rst),
5428
      .clk_in(sdram_clk),
5429
      .clkfb_in(ck_fb_pad_i),
5430
      .clk0_out(sdram_clk_0),
5431
      .clk90_out(sdram_clk_90),
5432
      .clk180_out(sdram_clk_180),
5433
      .clk270_out(sdram_clk_270),
5434
      .clkfb_out(ck_fb)
5435
      );
5436
 
5437
   // DDR2 IF
5438
   versatile_mem_ctrl_ddr versatile_mem_ctrl_ddr_0
5439
     (
5440
      // DDR2 SDRAM ports
5441
      .ck_o(ck_pad_o),
5442
      .ck_n_o(ck_n_pad_o),
5443
      .dq_io(dq_pad_io),
5444
      .dqs_io(dqs_pad_io),
5445
      .dqs_n_io(dqs_n_pad_io),
5446
      .dm_rdqs_io(dm_rdqs_pad_io),
5447
      // Memory controller side
5448
      .tx_dat_i(fifo_dat_o[fifo_sel_domain_reg]),
5449
      .rx_dat_o(fifo_dat_i),
5450
      .dq_en(dq_en),
5451
      .dqm_en(dqm_en),
5452
      .rst(sdram_rst),
5453
      .clk_0(sdram_clk_0),
5454
      .clk_90(sdram_clk_90),
5455
      .clk_180(sdram_clk_180),
5456
      .clk_270(sdram_clk_270));
5457
 
5458
`endif //  `ifdef DDR_16
5459
 
5460
endmodule // wb_sdram_ctrl_top

powered by: WebSVN 2.1.0

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