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 408

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