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

Subversion Repositories hpdmc

[/] [hpdmc/] [trunk/] [hpdmc_ddr32/] [test/] [tb_hpdmc.v] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 lekernel
/*
2
 * Milkymist VJ SoC
3
 * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, version 3 of the License.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17
 
18
`timescale 1ns / 1ps
19
 
20
//`define ENABLE_VCD
21
`define TEST_SOMETRANSFERS
22
//`define TEST_RANDOMTRANSFERS
23
 
24
module tb_hpdmc();
25
 
26
/* 100MHz system clock */
27
reg clk;
28
initial clk = 1'b0;
29
always #5 clk = ~clk;
30
 
31
/* DQS clock is phased out by 90 degrees, resulting in 2.5ns delay */
32
reg dqs_clk;
33
always @(clk) #2.5 dqs_clk = clk;
34
 
35
wire sdram_cke;
36
wire sdram_cs_n;
37
wire sdram_we_n;
38
wire sdram_cas_n;
39
wire sdram_ras_n;
40
wire [3:0] sdram_dm;
41
wire [12:0] sdram_adr;
42
wire [1:0] sdram_ba;
43
wire [31:0] sdram_dq;
44
wire [3:0] sdram_dqs;
45
 
46
ddr sdram1(
47
        .Addr(sdram_adr),
48
        .Ba(sdram_ba),
49
        .Clk(clk),
50
        .Clk_n(~clk),
51
        .Cke(sdram_cke),
52
        .Cs_n(sdram_cs_n),
53
        .Ras_n(sdram_ras_n),
54
        .Cas_n(sdram_cas_n),
55
        .We_n(sdram_we_n),
56
 
57
        .Dm(sdram_dm[3:2]),
58
        .Dqs(sdram_dqs[3:2]),
59
        .Dq(sdram_dq[31:16])
60
);
61
 
62
ddr sdram0(
63
        .Addr(sdram_adr),
64
        .Ba(sdram_ba),
65
        .Clk(clk),
66
        .Clk_n(~clk),
67
        .Cke(sdram_cke),
68
        .Cs_n(sdram_cs_n),
69
        .Ras_n(sdram_ras_n),
70
        .Cas_n(sdram_cas_n),
71
        .We_n(sdram_we_n),
72
 
73
        .Dm(sdram_dm[1:0]),
74
        .Dqs(sdram_dqs[1:0]),
75
        .Dq(sdram_dq[15:0])
76
);
77
 
78
reg rst;
79
 
80
reg [13:0] csr_a;
81
reg csr_we;
82
reg [31:0] csr_di;
83
wire [31:0] csr_do;
84
 
85
reg [25:0] fml_adr;
86
reg fml_stb;
87
reg fml_we;
88
wire fml_ack;
89
reg [7:0] fml_sel;
90
reg [63:0] fml_di;
91
wire [63:0] fml_do;
92
 
93
hpdmc dut(
94
        .sys_clk(clk),
95
        .sys_clk_n(~clk),
96
        .dqs_clk(dqs_clk),
97
        .dqs_clk_n(~dqs_clk),
98
        .sys_rst(rst),
99
 
100
        .csr_a(csr_a),
101
        .csr_we(csr_we),
102
        .csr_di(csr_di),
103
        .csr_do(csr_do),
104
 
105
        .fml_adr(fml_adr),
106
        .fml_stb(fml_stb),
107
        .fml_we(fml_we),
108
        .fml_ack(fml_ack),
109
        .fml_sel(fml_sel),
110
        .fml_di(fml_di),
111
        .fml_do(fml_do),
112
 
113
        .sdram_cke(sdram_cke),
114
        .sdram_cs_n(sdram_cs_n),
115
        .sdram_we_n(sdram_we_n),
116
        .sdram_cas_n(sdram_cas_n),
117
        .sdram_ras_n(sdram_ras_n),
118
        .sdram_dm(sdram_dm),
119
        .sdram_adr(sdram_adr),
120
        .sdram_ba(sdram_ba),
121
        .sdram_dq(sdram_dq),
122
        .sdram_dqs(sdram_dqs),
123
 
124
        .dqs_psen(),
125
        .dqs_psincdec(),
126
        .dqs_psdone(1'b1)
127
);
128
 
129
task waitclock;
130
begin
131
        @(posedge clk);
132
        #1;
133
end
134
endtask
135
 
136
task waitnclock;
137
input [15:0] n;
138
integer i;
139
begin
140
        for(i=0;i<n;i=i+1)
141
                waitclock;
142
end
143
endtask
144
 
145
task csrwrite;
146
input [31:0] address;
147
input [31:0] data;
148
begin
149
        csr_a = address[16:2];
150
        csr_di = data;
151
        csr_we = 1'b1;
152
        waitclock;
153
        $display("Configuration Write: %x=%x", address, data);
154
        csr_we = 1'b0;
155
end
156
endtask
157
 
158
task csrread;
159
input [31:0] address;
160
begin
161
        csr_a = address[16:2];
162
        waitclock;
163
        $display("Configuration Read : %x=%x", address, csr_do);
164
end
165
endtask
166
 
167
real reads;
168
real read_clocks;
169
 
170
task readburst;
171
input [31:0] address;
172
integer i;
173
begin
174
        $display("READ  [%x]", address);
175
        fml_adr = address;
176
        fml_stb = 1'b1;
177
        fml_we = 1'b0;
178
        i = 0;
179
        while(~fml_ack) begin
180
                i = i+1;
181
                waitclock;
182
        end
183
        $display("%t: Memory Read : %x=%x acked in %d clocks", $time, address, fml_do, i);
184
        fml_stb = 1'b0;
185
        reads = reads + 1;
186
        read_clocks = read_clocks + i;
187
        for(i=0;i<3;i=i+1) begin
188
                waitclock;
189
                $display("%t: (R burst continuing)    %x", $time, fml_do);
190
        end
191
 
192
        waitclock;
193
end
194
endtask
195
 
196
real writes;
197
real write_clocks;
198
 
199
task writeburst;
200
input [31:0] address;
201
integer i;
202
begin
203
        $display("WRITE [%x]", address);
204
        fml_adr = address;
205
        fml_stb = 1'b1;
206
        fml_we = 1'b1;
207
        fml_sel = 8'hff;
208
        fml_di = {$random, $random};
209
        i = 0;
210
        while(~fml_ack) begin
211
                i = i+1;
212
                waitclock;
213
        end
214
        $display("%t: Memory Write : %x=%x acked in %d clocks", $time, address, fml_di, i);
215
        fml_stb = 1'b0;
216
        writes = writes + 1;
217
        write_clocks = write_clocks + i;
218
        for(i=0;i<3;i=i+1) begin
219
                waitclock;
220
                fml_di = {$random, $random};
221
                $display("%t: (W burst continuing)    %x", $time, fml_di);
222
        end
223
 
224
        waitclock;
225
end
226
endtask
227
 
228
integer n, addr;
229
 
230
always begin
231
`ifdef ENABLE_VCD
232
        $dumpfile("hpdmc.vcd");
233
`endif
234
 
235
        /* Reset / Initialize our logic */
236
        rst = 1'b1;
237
 
238
        csr_a = 14'd0;
239
        csr_di = 32'd0;
240
        csr_we = 1'b0;
241
 
242
        fml_adr = 26'd0;
243
        fml_di = 64'd0;
244
        fml_sel = 8'd0;
245
        fml_stb = 1'b0;
246
        fml_we = 1'b0;
247
 
248
        waitclock;
249
 
250
        rst = 1'b0;
251
 
252
        waitclock;
253
 
254
        /* SDRAM initialization sequence. */
255
        /* The controller already comes up in Bypass mode with CKE disabled. */
256
 
257
        /* Wait 200us */
258
        #200000;
259
 
260
        /* Bring CKE high */
261
        csrwrite(32'h00, 32'h07);
262
        /* Precharge All:
263
         * CS=1
264
         * WE=1
265
         * CAS=0
266
         * RAS=1
267
         * A=A10
268
         * BA=Don't Care
269
         */
270
        csrwrite(32'h04, 32'b00_0010000000000_1011);
271
        waitnclock(2);
272
 
273
        /* Load Extended Mode Register:
274
         * CS=1
275
         * WE=1
276
         * CAS=1
277
         * RAS=1
278
         * A=Value
279
         * BA=01
280
         *
281
         * Extended mode register encoding :
282
         * A12-A2 reserved, must be 0
283
         * A1 weak drive strength
284
         * A0 DLL disable
285
         */
286
        csrwrite(32'h04, 32'b01_0000000000000_1111);
287
        waitnclock(2);
288
 
289
        /* Load Mode Register, DLL in Reset:
290
         * CS=1
291
         * WE=1
292
         * CAS=1
293
         * RAS=1
294
         * A=Value
295
         * BA=00
296
         *
297
         * Mode register encoding :
298
         * A12-A7 = 000000 Normal operation w/o DLL reset
299
         *          000010 Normal operation in DLL reset
300
         * A6-A4  = 010    CL2
301
         * A3     = 0      Sequential burst
302
         * A2-A0  = 011    Burst length = 8
303
         */
304
        csrwrite(32'h04, 32'b00__000010_010_0_011__1111);
305
        waitnclock(200);
306
 
307
        /* Precharge All */
308
        csrwrite(32'h04, 32'b00_0010000000000_1011);
309
        waitnclock(2);
310
 
311
        /* Auto Refresh
312
         * CS=1
313
         * WE=0
314
         * CAS=1
315
         * RAS=1
316
         * A=Don't Care
317
         * BA=Don't Care
318
         */
319
        csrwrite(32'h04, 32'b00_0000000000000_1101);
320
        waitnclock(8);
321
 
322
        /* Auto Refresh */
323
        csrwrite(32'h04, 32'b00_0000000000000_1101);
324
        waitnclock(8);
325
 
326
        /* Load Mode Register, DLL enabled */
327
        csrwrite(32'h04, 32'b00__000000_010_0_011__1111);
328
        waitnclock(200);
329
 
330
        /* SDRAM initialization completed */
331
 
332
`ifdef ENABLE_VCD
333
        /* Now, we want to know what the controller will send to the SDRAM chips */
334
        $dumpvars(0, dut);
335
`endif
336
 
337
        /* Bring up the controller ! */
338
        csrwrite(32'h00, 32'h04);
339
 
340
`ifdef TEST_SOMETRANSFERS
341
        /*
342
         * Try some transfers.
343
         */
344
        writeburst(32'h00);
345
        writeburst(32'h20);
346
        //writeburst(32'h40);
347
 
348
        readburst(32'h00);
349
        readburst(32'h20);
350
        /*readburst(32'h40);
351
        writeburst(32'h40);
352
        readburst(32'h40);*/
353
`endif
354
 
355
`ifdef TEST_RANDOMTRANSFERS
356
        writes = 0;
357
        write_clocks = 0;
358
        reads = 0;
359
        read_clocks = 0;
360
        for(n=0;n<500;n=n+1) begin
361
                addr = $random;
362
                if($random > 32'h80000000) begin
363
                        writeburst(addr);
364
                        //writeburst(addr+32'h20);
365
                        //writeburst(addr+32'h40);
366
                end else begin
367
                        readburst(addr);
368
                        //readburst(addr+32'h20);
369
                        //readburst(addr+32'h40);
370
                end
371
        end
372
 
373
        $display("");
374
        $display("=======================================================");
375
        $display(" Tested: %.0f reads, %.0f writes ", reads, writes);
376
        $display("=======================================================");
377
        $display(" Average read latency:    %f cycles", read_clocks/reads);
378
        $display(" Average write latency:   %f cycles", write_clocks/writes);
379
        $display("=======================================================");
380
        $display(" Average read bandwidth:  %f MBit/s @ 100MHz", (4/(4+read_clocks/reads))*64*100);
381
        $display(" Average write bandwidth: %f MBit/s @ 100MHz", (4/(4+write_clocks/writes))*64*100);
382
        $display("=======================================================");
383
 
384
`endif
385
 
386
        $finish;
387
end
388
 
389
endmodule
390
 

powered by: WebSVN 2.1.0

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