Root/sim/verilog/micron_2048Mb_ddr2/tb.v

1/****************************************************************************************
2*
3* File Name: tb.v
4*
5* Dependencies: ddr2.v, ddr2_parameters.vh
6*
7* Description: Micron SDRAM DDR2 (Double Data Rate 2) test bench
8*
9* Note: -Set simulator resolution to "ps" accuracy
10* -Set Debug = 0 to disable $display messages
11*
12* Disclaimer This software code and all associated documentation, comments or other
13* of Warranty: information (collectively "Software") is provided "AS IS" without
14* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
15* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
16* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
17* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
18* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
19* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
20* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
21* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
22* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
23* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
24* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
25* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
26* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
27* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
28* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
29* DAMAGES. Because some jurisdictions prohibit the exclusion or
30* limitation of liability for consequential or incidental damages, the
31* above limitation may not apply to you.
32*
33* Copyright 2003 Micron Technology, Inc. All rights reserved.
34*
35****************************************************************************************/
36
37// DO NOT CHANGE THE TIMESCALE
38
39`timescale 1ps / 1ps
40
41module tb;
42
43`include "ddr2_parameters.vh"
44
45    // ports
46    reg ck;
47    wire ck_n = ~ck;
48    reg cke;
49    reg cs_n;
50    reg ras_n;
51    reg cas_n;
52    reg we_n;
53    reg [BA_BITS-1:0] ba;
54    reg [ADDR_BITS-1:0] a;
55    wire [DM_BITS-1:0] dm;
56    wire [DQ_BITS-1:0] dq;
57    wire [DQS_BITS-1:0] dqs;
58    wire [DQS_BITS-1:0] dqs_n;
59    wire [DQS_BITS-1:0] rdqs_n;
60    reg odt;
61
62    // mode registers
63    reg [ADDR_BITS-1:0] mode_reg0; //Mode Register
64    reg [ADDR_BITS-1:0] mode_reg1; //Extended Mode Register
65    wire [2:0] cl = mode_reg0[6:4]; //CAS Latency
66    wire bo = mode_reg0[3]; //Burst Order
67    wire [7:0] bl = (1<<mode_reg0[2:0]); //Burst Length
68    wire rdqs_en = mode_reg1[11]; //RDQS Enable
69    wire dqs_n_en = ~mode_reg1[10]; //dqs# Enable
70    wire [2:0] al = mode_reg1[5:3]; //Additive Latency
71    wire [3:0] rl = al + cl; //Read Latency
72    wire [3:0] wl = al + cl-1'b1; //Write Latency
73    
74    // dq transmit
75    reg dq_en;
76    reg [DM_BITS-1:0] dm_out;
77    reg [DQ_BITS-1:0] dq_out;
78    reg dqs_en;
79    reg [DQS_BITS-1:0] dqs_out;
80    assign dm = dq_en ? dm_out : {DM_BITS{1'bz}};
81    assign dq = dq_en ? dq_out : {DQ_BITS{1'bz}};
82    assign dqs = dqs_en ? dqs_out : {DQS_BITS{1'bz}};
83    assign dqs_n = (dqs_en & dqs_n_en) ? ~dqs_out : {DQS_BITS{1'bz}};
84
85    // dq receive
86    reg [DM_BITS-1:0] dm_fifo [2*(AL_MAX+CL_MAX)+BL_MAX:0];
87    reg [DQ_BITS-1:0] dq_fifo [2*(AL_MAX+CL_MAX)+BL_MAX:0];
88    wire [DQ_BITS-1:0] q0, q1, q2, q3;
89    reg [1:0] burst_cntr;
90    assign rdqs_n = {DQS_BITS{1'bz}};
91
92    // timing definition in tCK units
93    real tck;
94    wire [11:0] taa = ceil(CL_TIME/tck);
95    wire [11:0] tanpd = TANPD;
96    wire [11:0] taond = TAOND;
97    wire [11:0] taofd = ceil(TAOFD);
98    wire [11:0] taxpd = TAXPD;
99    wire [11:0] tccd = TCCD;
100    wire [11:0] tcke = TCKE;
101    wire [11:0] tdllk = TDLLK;
102    wire [11:0] tfaw = ceil(TFAW/tck);
103    wire [11:0] tmod = ceil(TMOD/tck);
104    wire [11:0] tmrd = TMRD;
105    wire [11:0] tras = ceil(TRAS_MIN/tck);
106    wire [11:0] trc = TRC;
107    wire [11:0] trcd = ceil(TRCD/tck);
108    wire [11:0] trfc = ceil(TRFC_MIN/tck);
109    wire [11:0] trp = ceil(TRP/tck);
110    wire [11:0] trrd = ceil(TRRD/tck);
111    wire [11:0] trtp = ceil(TRTP/tck);
112    wire [11:0] twr = ceil(TWR/tck);
113    wire [11:0] twtr = ceil(TWTR/tck);
114    wire [11:0] txard = TXARD;
115    wire [11:0] txards = TXARDS;
116    wire [11:0] txp = TXP;
117    wire [11:0] txsnr = ceil(TXSNR/tck);
118    wire [11:0] txsrd = TXSRD;
119
120    initial begin
121        $timeformat (-9, 1, " ns", 1);
122`ifdef period
123        tck <= `period;
124`else
125        tck <= TCK_MIN;
126`endif
127        ck <= 1'b1;
128    end
129
130    // component instantiation
131    ddr2 sdramddr2 (
132        ck,
133        ck_n,
134        cke,
135        cs_n,
136        ras_n,
137        cas_n,
138        we_n,
139        dm,
140        ba,
141        a,
142        dq,
143        dqs,
144        dqs_n,
145        rdqs_n,
146        odt
147    );
148
149    // clock generator
150    always @(posedge ck) begin
151      ck <= #(tck/2) 1'b0;
152      ck <= #(tck) 1'b1;
153    end
154
155    function integer ceil;
156        input number;
157        real number;
158        if (number > $rtoi(number))
159            ceil = $rtoi(number) + 1;
160        else
161            ceil = number;
162    endfunction
163
164    function integer max;
165        input arg1;
166        input arg2;
167        integer arg1;
168        integer arg2;
169        if (arg1 > arg2)
170            max = arg1;
171        else
172            max = arg2;
173    endfunction
174
175    task power_up;
176        begin
177            cke <= 1'b0;
178            odt <= 1'b0;
179            repeat(10) @(negedge ck);
180            cke <= 1'b1;
181            nop (400000/tck+1);
182        end
183    endtask
184
185    task load_mode;
186        input [BA_BITS-1:0] bank;
187        input [ADDR_BITS-1:0] addr;
188        begin
189            case (bank)
190                0: mode_reg0 = addr;
191                1: mode_reg1 = addr;
192            endcase
193            cke <= 1'b1;
194            cs_n <= 1'b0;
195            ras_n <= 1'b0;
196            cas_n <= 1'b0;
197            we_n <= 1'b0;
198            ba <= bank;
199            a <= addr;
200            @(negedge ck);
201        end
202    endtask
203
204    task refresh;
205        begin
206            cke <= 1'b1;
207            cs_n <= 1'b0;
208            ras_n <= 1'b0;
209            cas_n <= 1'b0;
210            we_n <= 1'b1;
211            @(negedge ck);
212        end
213    endtask
214     
215    task precharge;
216        input [BA_BITS-1:0] bank;
217        input ap; //precharge all
218        begin
219            cke <= 1'b1;
220            cs_n <= 1'b0;
221            ras_n <= 1'b0;
222            cas_n <= 1'b1;
223            we_n <= 1'b0;
224            ba <= bank;
225            a <= (ap<<10);
226            @(negedge ck);
227        end
228    endtask
229     
230    task activate;
231        input [BA_BITS-1:0] bank;
232        input [ROW_BITS-1:0] row;
233        begin
234            cke <= 1'b1;
235            cs_n <= 1'b0;
236            ras_n <= 1'b0;
237            cas_n <= 1'b1;
238            we_n <= 1'b1;
239            ba <= bank;
240            a <= row;
241            @(negedge ck);
242        end
243    endtask
244
245    //write task supports burst lengths <= 8
246    task write;
247        input [BA_BITS-1:0] bank;
248        input [COL_BITS-1:0] col;
249        input ap; //Auto Precharge
250        input [8*DM_BITS-1:0] dm;
251        input [8*DQ_BITS-1:0] dq;
252        reg [ADDR_BITS-1:0] atemp [1:0];
253        integer i;
254        begin
255            cke <= 1'b1;
256            cs_n <= 1'b0;
257            ras_n <= 1'b1;
258            cas_n <= 1'b0;
259            we_n <= 1'b0;
260            ba <= bank;
261            atemp[0] = col & 10'h3ff; //addr[ 9: 0] = COL[ 9: 0]
262            atemp[1] = (col>>10)<<11; //addr[ N:11] = COL[ N:10]
263            a <= atemp[0] | atemp[1] | (ap<<10);
264            for (i=0; i<=bl; i=i+1) begin
265
266                dqs_en <= #(wl*tck + i*tck/2) 1'b1;
267                if (i%2 == 0) begin
268                    dqs_out <= #(wl*tck + i*tck/2) {DQS_BITS{1'b0}};
269                end else begin
270                    dqs_out <= #(wl*tck + i*tck/2) {DQS_BITS{1'b1}};
271                end
272
273                dq_en <= #(wl*tck + i*tck/2 + tck/4) 1'b1;
274                dm_out <= #(wl*tck + i*tck/2 + tck/4) dm>>i*DM_BITS;
275                dq_out <= #(wl*tck + i*tck/2 + tck/4) dq>>i*DQ_BITS;
276            end
277            dqs_en <= #(wl*tck + bl*tck/2 + tck/2) 1'b0;
278            dq_en <= #(wl*tck + bl*tck/2 + tck/4) 1'b0;
279            @(negedge ck);
280        end
281    endtask
282
283    // read without data verification
284    task read;
285        input [BA_BITS-1:0] bank;
286        input [COL_BITS-1:0] col;
287        input ap; //Auto Precharge
288        reg [ADDR_BITS-1:0] atemp [1:0];
289        begin
290            cke <= 1'b1;
291            cs_n <= 1'b0;
292            ras_n <= 1'b1;
293            cas_n <= 1'b0;
294            we_n <= 1'b1;
295            ba <= bank;
296            atemp[0] = col & 10'h3ff; //addr[ 9: 0] = COL[ 9: 0]
297            atemp[1] = (col>>10)<<11; //addr[ N:11] = COL[ N:10]
298            a <= atemp[0] | atemp[1] | (ap<<10);
299            @(negedge ck);
300        end
301    endtask
302
303    task nop;
304        input [31:0] count;
305        begin
306            cke <= 1'b1;
307            cs_n <= 1'b0;
308            ras_n <= 1'b1;
309            cas_n <= 1'b1;
310            we_n <= 1'b1;
311            repeat(count) @(negedge ck);
312        end
313    endtask
314
315    task deselect;
316        input [31:0] count;
317        begin
318            cke <= 1'b1;
319            cs_n <= 1'b1;
320            ras_n <= 1'b1;
321            cas_n <= 1'b1;
322            we_n <= 1'b1;
323            repeat(count) @(negedge ck);
324        end
325    endtask
326
327    task power_down;
328        input [31:0] count;
329        begin
330            cke <= 1'b0;
331            cs_n <= 1'b1;
332            ras_n <= 1'b1;
333            cas_n <= 1'b1;
334            we_n <= 1'b1;
335            repeat(count) @(negedge ck);
336        end
337    endtask
338
339    task self_refresh;
340        input [31:0] count;
341        begin
342            cke <= 1'b0;
343            cs_n <= 1'b0;
344            ras_n <= 1'b0;
345            cas_n <= 1'b0;
346            we_n <= 1'b1;
347            cs_n <= #(tck) 1'b1;
348            ras_n <= #(tck) 1'b1;
349            cas_n <= #(tck) 1'b1;
350            we_n <= #(tck) 1'b1;
351            repeat(count) @(negedge ck);
352        end
353    endtask
354
355    // read with data verification
356    task read_verify;
357        input [BA_BITS-1:0] bank;
358        input [COL_BITS-1:0] col;
359        input ap; //Auto Precharge
360        input [8*DM_BITS-1:0] dm; //Expected Data Mask
361        input [8*DQ_BITS-1:0] dq; //Expected Data
362        integer i;
363        begin
364            read (bank, col, ap);
365            for (i=0; i<bl; i=i+1) begin
366                dm_fifo[2*rl + i] = dm >> (i*DM_BITS);
367                dq_fifo[2*rl + i] = dq >> (i*DQ_BITS);
368            end
369        end
370    endtask
371
372    // receiver(s) for data_verify process
373    dqrx dqrx[DQS_BITS-1:0] (dqs, dq, q0, q1, q2, q3);
374
375    // perform data verification as a result of read_verify task call
376    always @(ck) begin:data_verify
377        integer i;
378        integer j;
379        reg [DQ_BITS-1:0] bit_mask;
380        reg [DM_BITS-1:0] dm_temp;
381        reg [DQ_BITS-1:0] dq_temp;
382        
383        for (i = !ck; (i < 2/(2.0 - !ck)); i=i+1) begin
384            if (dm_fifo[i] === {DM_BITS{1'bx}}) begin
385                burst_cntr = 0;
386            end else begin
387
388                dm_temp = dm_fifo[i];
389                for (j=0; j<DQ_BITS; j=j+1) begin
390                    bit_mask[j] = !dm_temp[j/8];
391                end
392
393                case (burst_cntr)
394                    0: dq_temp = q0;
395                    1: dq_temp = q1;
396                    2: dq_temp = q2;
397                    3: dq_temp = q3;
398                endcase
399                //if ( ((dq_temp & bit_mask) === (dq_fifo[i] & bit_mask)))
400                // $display ("%m at time %t: INFO: Successful read data compare. Expected = %h, Actual = %h, Mask = %h, i = %d", $time, dq_fifo[i], dq_temp, bit_mask, burst_cntr);
401                if ((dq_temp & bit_mask) !== (dq_fifo[i] & bit_mask))
402                    $display ("%m at time %t: ERROR: Read data miscompare. Expected = %h, Actual = %h, Mask = %h, i = %d", $time, dq_fifo[i], dq_temp, bit_mask, burst_cntr);
403
404                burst_cntr = burst_cntr + 1;
405            end
406        end
407
408        if (ck) begin
409            if (dm_fifo[2] === {DM_BITS{1'bx}}) begin
410                dqrx[0%DQS_BITS].ptr <= 0; // v2k syntax
411                dqrx[1%DQS_BITS].ptr <= 0; // v2k syntax
412                dqrx[2%DQS_BITS].ptr <= 0; // v2k syntax
413                dqrx[3%DQS_BITS].ptr <= 0; // v2k syntax
414            end
415        end else begin
416            for (i=0; i<=(2*(AL_MAX+CL_MAX)+BL_MAX); i=i+1) begin
417                dm_fifo[i] = dm_fifo[i+2];
418                dq_fifo[i] = dq_fifo[i+2];
419            end
420        end
421    end
422
423    // End-of-test triggered in 'subtest.vh'
424    task test_done;
425        begin
426            $display ("%m at time %t: INFO: Simulation is Complete", $time);
427            $stop(0);
428        end
429    endtask
430
431    // Test included from external file
432    `include "subtest.vh"
433
434endmodule
435
436module dqrx (
437    dqs, dq, q0, q1, q2, q3
438);
439
440    `include "ddr2_parameters.vh"
441
442    input dqs;
443    input [DQ_BITS/DQS_BITS-1:0] dq;
444    output [DQ_BITS/DQS_BITS-1:0] q0;
445    output [DQ_BITS/DQS_BITS-1:0] q1;
446    output [DQ_BITS/DQS_BITS-1:0] q2;
447    output [DQ_BITS/DQS_BITS-1:0] q3;
448
449    reg [DQ_BITS/DQS_BITS-1:0] q [3:0];
450
451    assign q0 = q[0];
452    assign q1 = q[1];
453    assign q2 = q[2];
454    assign q3 = q[3];
455
456    reg [1:0] ptr;
457    reg dqs_q;
458
459    always @(dqs) begin
460        if (dqs ^ dqs_q) begin
461            #(TDQSQ + 1);
462            q[ptr] <= dq;
463            ptr <= (ptr + 1)%4;
464        end
465        dqs_q <= dqs;
466    end
467    
468endmodule
469

Archive Download this file

Branches:
master



interactive