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

Subversion Repositories sdr_ctrl

[/] [sdr_ctrl/] [trunk/] [verif/] [tb/] [tb_top.sv] - Blame information for rev 68

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

Line No. Rev Author Line
1 8 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////                                                              ////
4
////  This file is part of the SDRAM Controller project           ////
5
////  http://www.opencores.org/cores/sdr_ctrl/                    ////
6
////                                                              ////
7
////  Description                                                 ////
8
////  SDRAM CTRL definitions.                                     ////
9
////                                                              ////
10
////  To Do:                                                      ////
11
////    nothing                                                   ////
12
////                                                              ////
13 43 dinesha
//   Version  :0.1 - Test Bench automation is improvised with     ////
14
//             seperate data,address,burst length fifo.           ////
15
//             Now user can create different write and            ////
16
//             read sequence                                      ////
17
//                                                                ////
18 8 dinesha
////  Author(s):                                                  ////
19
////      - Dinesh Annayya, dinesha@opencores.org                 ////
20
////                                                              ////
21
//////////////////////////////////////////////////////////////////////
22
////                                                              ////
23
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
24
////                                                              ////
25
//// This source file may be used and distributed without         ////
26
//// restriction provided that this copyright statement is not    ////
27
//// removed from the file and that any derivative work contains  ////
28
//// the original copyright notice and the associated disclaimer. ////
29
////                                                              ////
30
//// This source file is free software; you can redistribute it   ////
31
//// and/or modify it under the terms of the GNU Lesser General   ////
32
//// Public License as published by the Free Software Foundation; ////
33
//// either version 2.1 of the License, or (at your option) any   ////
34
//// later version.                                               ////
35
////                                                              ////
36
//// This source is distributed in the hope that it will be       ////
37
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
38
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
39
//// PURPOSE.  See the GNU Lesser General Public License for more ////
40
//// details.                                                     ////
41
////                                                              ////
42
//// You should have received a copy of the GNU Lesser General    ////
43
//// Public License along with this source; if not, download it   ////
44
//// from http://www.opencores.org/lgpl.shtml                     ////
45
////                                                              ////
46
//////////////////////////////////////////////////////////////////////
47
 
48
 
49
`timescale 1ns/1ps
50
 
51 24 dinesha
// This testbench verify with SDRAM TOP
52
 
53 8 dinesha
module tb_top;
54
 
55 30 dinesha
parameter P_SYS  = 10;     //    200MHz
56
parameter P_SDR  = 20;     //    100MHz
57 8 dinesha
 
58
// General
59
reg            RESETN;
60
reg            sdram_clk;
61 30 dinesha
reg            sys_clk;
62 8 dinesha
 
63 30 dinesha
initial sys_clk = 0;
64 8 dinesha
initial sdram_clk = 0;
65
 
66 30 dinesha
always #(P_SYS/2) sys_clk = !sys_clk;
67
always #(P_SDR/2) sdram_clk = !sdram_clk;
68 8 dinesha
 
69
parameter      dw              = 32;  // data width
70
parameter      tw              = 8;   // tag id width
71
parameter      bl              = 5;   // burst_lenght_width
72
 
73
//-------------------------------------------
74 30 dinesha
// WISH BONE Interface
75 8 dinesha
//-------------------------------------------
76 30 dinesha
//--------------------------------------
77
// Wish Bone Interface
78
// -------------------------------------
79
reg             wb_stb_i           ;
80
wire            wb_ack_o           ;
81 68 dinesha
reg  [25:0]     wb_addr_i          ;
82 30 dinesha
reg             wb_we_i            ; // 1 - Write, 0 - Read
83
reg  [dw-1:0]   wb_dat_i           ;
84
reg  [dw/8-1:0] wb_sel_i           ; // Byte enable
85
wire  [dw-1:0]  wb_dat_o           ;
86
reg             wb_cyc_i           ;
87
reg   [2:0]     wb_cti_i           ;
88 8 dinesha
 
89 30 dinesha
 
90
 
91 8 dinesha
//--------------------------------------------
92
// SDRAM I/F
93
//--------------------------------------------
94
 
95
`ifdef SDR_32BIT
96
   wire [31:0]           Dq                 ; // SDRAM Read/Write Data Bus
97
   wire [3:0]            sdr_dqm            ; // SDRAM DATA Mask
98 18 dinesha
`elsif SDR_16BIT
99 8 dinesha
   wire [15:0]           Dq                 ; // SDRAM Read/Write Data Bus
100
   wire [1:0]            sdr_dqm            ; // SDRAM DATA Mask
101 18 dinesha
`else
102
   wire [7:0]           Dq                 ; // SDRAM Read/Write Data Bus
103
   wire [0:0]           sdr_dqm            ; // SDRAM DATA Mask
104 8 dinesha
`endif
105
 
106
wire [1:0]            sdr_ba             ; // SDRAM Bank Select
107 68 dinesha
wire [12:0]           sdr_addr           ; // SDRAM ADRESS
108 8 dinesha
wire                  sdr_init_done      ; // SDRAM Init Done
109
 
110
// to fix the sdram interface timing issue
111 30 dinesha
wire #(2.0) sdram_clk_d   = sdram_clk;
112 8 dinesha
 
113
`ifdef SDR_32BIT
114
 
115 30 dinesha
   sdrc_top #(.SDR_DW(32),.SDR_BW(4)) u_dut(
116 18 dinesha
`elsif SDR_16BIT
117 30 dinesha
   sdrc_top #(.SDR_DW(16),.SDR_BW(2)) u_dut(
118 18 dinesha
`else  // 8 BIT SDRAM
119 30 dinesha
   sdrc_top #(.SDR_DW(8),.SDR_BW(1)) u_dut(
120 8 dinesha
`endif
121
      // System
122
`ifdef SDR_32BIT
123 38 dinesha
          .cfg_sdr_width      (2'b00              ), // 32 BIT SDRAM
124 18 dinesha
`elsif SDR_16BIT
125 38 dinesha
          .cfg_sdr_width      (2'b01              ), // 16 BIT SDRAM
126 18 dinesha
`else
127 38 dinesha
          .cfg_sdr_width      (2'b10              ), // 8 BIT SDRAM
128 8 dinesha
`endif
129 12 dinesha
          .cfg_colbits        (2'b00              ), // 8 Bit Column Address
130 8 dinesha
 
131 30 dinesha
/* WISH BONE */
132
          .wb_rst_i           (!RESETN            ),
133
          .wb_clk_i           (sys_clk            ),
134 8 dinesha
 
135 30 dinesha
          .wb_stb_i           (wb_stb_i           ),
136
          .wb_ack_o           (wb_ack_o           ),
137
          .wb_addr_i          (wb_addr_i          ),
138
          .wb_we_i            (wb_we_i            ),
139
          .wb_dat_i           (wb_dat_i           ),
140
          .wb_sel_i           (wb_sel_i           ),
141
          .wb_dat_o           (wb_dat_o           ),
142
          .wb_cyc_i           (wb_cyc_i           ),
143
          .wb_cti_i           (wb_cti_i           ),
144 8 dinesha
 
145
/* Interface to SDRAMs */
146 30 dinesha
          .sdram_clk          (sdram_clk          ),
147
          .sdram_resetn       (RESETN             ),
148 8 dinesha
          .sdr_cs_n           (sdr_cs_n           ),
149
          .sdr_cke            (sdr_cke            ),
150
          .sdr_ras_n          (sdr_ras_n          ),
151
          .sdr_cas_n          (sdr_cas_n          ),
152
          .sdr_we_n           (sdr_we_n           ),
153
          .sdr_dqm            (sdr_dqm            ),
154
          .sdr_ba             (sdr_ba             ),
155
          .sdr_addr           (sdr_addr           ),
156 37 dinesha
          .sdr_dq             (Dq                 ),
157 8 dinesha
 
158
    /* Parameters */
159
          .sdr_init_done      (sdr_init_done      ),
160 44 dinesha
          .cfg_req_depth      (2'h3               ),            //how many req. buffer should hold
161 8 dinesha
          .cfg_sdr_en         (1'b1               ),
162
          .cfg_sdr_mode_reg   (12'h033            ),
163
          .cfg_sdr_tras_d     (4'h4               ),
164
          .cfg_sdr_trp_d      (4'h2               ),
165
          .cfg_sdr_trcd_d     (4'h2               ),
166 22 dinesha
          .cfg_sdr_cas        (3'h3               ),
167 8 dinesha
          .cfg_sdr_trcar_d    (4'h7               ),
168
          .cfg_sdr_twr_d      (4'h1               ),
169 45 dinesha
          .cfg_sdr_rfsh       (12'h100            ), // reduced from 12'hC35
170 8 dinesha
          .cfg_sdr_rfmax      (3'h6               )
171
 
172
);
173
 
174
 
175
`ifdef SDR_32BIT
176
mt48lc2m32b2 #(.data_bits(32)) u_sdram32 (
177
          .Dq                 (Dq                 ) ,
178 68 dinesha
          .Addr               (sdr_addr[11:0]     ),
179 8 dinesha
          .Ba                 (sdr_ba             ),
180 22 dinesha
          .Clk                (sdram_clk_d        ),
181 8 dinesha
          .Cke                (sdr_cke            ),
182
          .Cs_n               (sdr_cs_n           ),
183
          .Ras_n              (sdr_ras_n          ),
184
          .Cas_n              (sdr_cas_n          ),
185
          .We_n               (sdr_we_n           ),
186
          .Dqm                (sdr_dqm            )
187
     );
188
 
189 18 dinesha
`elsif SDR_16BIT
190 8 dinesha
 
191
   IS42VM16400K u_sdram16 (
192
          .dq                 (Dq                 ),
193 68 dinesha
          .addr               (sdr_addr[11:0]     ),
194 8 dinesha
          .ba                 (sdr_ba             ),
195 22 dinesha
          .clk                (sdram_clk_d        ),
196 8 dinesha
          .cke                (sdr_cke            ),
197
          .csb                (sdr_cs_n           ),
198
          .rasb               (sdr_ras_n          ),
199
          .casb               (sdr_cas_n          ),
200
          .web                (sdr_we_n           ),
201
          .dqm                (sdr_dqm            )
202
    );
203 18 dinesha
`else
204
 
205
 
206
mt48lc8m8a2 #(.data_bits(8)) u_sdram8 (
207
          .Dq                 (Dq                 ) ,
208 68 dinesha
          .Addr               (sdr_addr[11:0]     ),
209 18 dinesha
          .Ba                 (sdr_ba             ),
210 22 dinesha
          .Clk                (sdram_clk_d        ),
211 18 dinesha
          .Cke                (sdr_cke            ),
212
          .Cs_n               (sdr_cs_n           ),
213
          .Ras_n              (sdr_ras_n          ),
214
          .Cas_n              (sdr_cas_n          ),
215
          .We_n               (sdr_we_n           ),
216
          .Dqm                (sdr_dqm            )
217
     );
218 8 dinesha
`endif
219
 
220
//--------------------
221 43 dinesha
// data/address/burst length FIFO
222 8 dinesha
//--------------------
223 43 dinesha
int dfifo[$]; // data fifo
224
int afifo[$]; // address  fifo
225
int bfifo[$]; // Burst Length fifo
226 8 dinesha
 
227
reg [31:0] read_data;
228
reg [31:0] ErrCnt;
229
int k;
230
reg [31:0] StartAddr;
231
/////////////////////////////////////////////////////////////////////////
232
// Test Case
233
/////////////////////////////////////////////////////////////////////////
234
 
235
initial begin //{
236
  ErrCnt          = 0;
237 30 dinesha
   wb_addr_i      = 0;
238
   wb_dat_i      = 0;
239
   wb_sel_i       = 4'h0;
240
   wb_we_i        = 0;
241
   wb_stb_i       = 0;
242
   wb_cyc_i       = 0;
243 8 dinesha
 
244
  RESETN    = 1'h1;
245
 
246
 #100
247
  // Applying reset
248
  RESETN    = 1'h0;
249
  #10000;
250
  // Releasing reset
251
  RESETN    = 1'h1;
252
  #1000;
253
  wait(u_dut.sdr_init_done == 1);
254
 
255
  #1000;
256 46 dinesha
  $display("-------------------------------------- ");
257
  $display(" Case-1: Single Write/Read Case        ");
258
  $display("-------------------------------------- ");
259
 
260 43 dinesha
  burst_write(32'h4_0000,8'h4);
261 8 dinesha
 #1000;
262 43 dinesha
  burst_read();
263 8 dinesha
 
264 45 dinesha
  // Repeat one more time to analysis the
265
  // SDRAM state change for same col/row address
266 46 dinesha
  $display("-------------------------------------- ");
267
  $display(" Case-2: Repeat same transfer once again ");
268
  $display("----------------------------------------");
269 45 dinesha
  burst_write(32'h4_0000,8'h4);
270 46 dinesha
  burst_read();
271 43 dinesha
  burst_write(32'h0040_0000,8'h5);
272 46 dinesha
  burst_read();
273
  $display("----------------------------------------");
274
  $display(" Case-3 Create a Page Cross Over        ");
275
  $display("----------------------------------------");
276 53 dinesha
  burst_write(32'h0000_0FF0,8'h8);
277
  burst_write(32'h0001_0FF4,8'hF);
278
  burst_write(32'h0002_0FF8,8'hF);
279
  burst_write(32'h0003_0FFC,8'hF);
280
  burst_write(32'h0004_0FE0,8'hF);
281
  burst_write(32'h0005_0FE4,8'hF);
282
  burst_write(32'h0006_0FE8,8'hF);
283
  burst_write(32'h0007_0FEC,8'hF);
284
  burst_write(32'h0008_0FD0,8'hF);
285
  burst_write(32'h0009_0FD4,8'hF);
286
  burst_write(32'h000A_0FD8,8'hF);
287
  burst_write(32'h000B_0FDC,8'hF);
288
  burst_write(32'h000C_0FC0,8'hF);
289
  burst_write(32'h000D_0FC4,8'hF);
290
  burst_write(32'h000E_0FC8,8'hF);
291
  burst_write(32'h000F_0FCC,8'hF);
292
  burst_write(32'h0010_0FB0,8'hF);
293
  burst_write(32'h0011_0FB4,8'hF);
294
  burst_write(32'h0012_0FB8,8'hF);
295
  burst_write(32'h0013_0FBC,8'hF);
296
  burst_write(32'h0014_0FA0,8'hF);
297
  burst_write(32'h0015_0FA4,8'hF);
298
  burst_write(32'h0016_0FA8,8'hF);
299
  burst_write(32'h0017_0FAC,8'hF);
300 43 dinesha
  burst_read();
301 46 dinesha
  burst_read();
302 53 dinesha
  burst_read();
303
  burst_read();
304
  burst_read();
305
  burst_read();
306
  burst_read();
307
  burst_read();
308
  burst_read();
309
  burst_read();
310
  burst_read();
311
  burst_read();
312
  burst_read();
313
  burst_read();
314
  burst_read();
315
  burst_read();
316
  burst_read();
317
  burst_read();
318
  burst_read();
319
  burst_read();
320
  burst_read();
321
  burst_read();
322
  burst_read();
323
  burst_read();
324 8 dinesha
 
325 46 dinesha
  $display("----------------------------------------");
326
  $display(" Case:4 4 Write & 4 Read                ");
327
  $display("----------------------------------------");
328 43 dinesha
  burst_write(32'h4_0000,8'h4);
329
  burst_write(32'h5_0000,8'h5);
330
  burst_write(32'h6_0000,8'h6);
331
  burst_write(32'h7_0000,8'h7);
332
  burst_read();
333
  burst_read();
334
  burst_read();
335
  burst_read();
336
 
337 46 dinesha
  $display("---------------------------------------");
338 53 dinesha
  $display(" Case:5 24 Write & 24 Read With Different Bank and Row ");
339 46 dinesha
  $display("---------------------------------------");
340
  //----------------------------------------
341
  // Address Decodeing:
342
  //  with cfg_col bit configured as: 00
343
  //    <12 Bit Row> <2 Bit Bank> <8 Bit Column> <2'b00>
344
  //
345
  burst_write({12'h000,2'b00,8'h00,2'b00},8'h4);   // Row: 0 Bank : 0
346
  burst_write({12'h000,2'b01,8'h00,2'b00},8'h5);   // Row: 0 Bank : 1
347
  burst_write({12'h000,2'b10,8'h00,2'b00},8'h6);   // Row: 0 Bank : 2
348
  burst_write({12'h000,2'b11,8'h00,2'b00},8'h7);   // Row: 0 Bank : 3
349
  burst_write({12'h001,2'b00,8'h00,2'b00},8'h4);   // Row: 1 Bank : 0
350
  burst_write({12'h001,2'b01,8'h00,2'b00},8'h5);   // Row: 1 Bank : 1
351
  burst_write({12'h001,2'b10,8'h00,2'b00},8'h6);   // Row: 1 Bank : 2
352
  burst_write({12'h001,2'b11,8'h00,2'b00},8'h7);   // Row: 1 Bank : 3
353
  burst_read();
354
  burst_read();
355
  burst_read();
356
  burst_read();
357
  burst_read();
358
  burst_read();
359
  burst_read();
360
  burst_read();
361 43 dinesha
 
362 46 dinesha
  burst_write({12'h002,2'b00,8'h00,2'b00},8'h4);   // Row: 2 Bank : 0
363
  burst_write({12'h002,2'b01,8'h00,2'b00},8'h5);   // Row: 2 Bank : 1
364
  burst_write({12'h002,2'b10,8'h00,2'b00},8'h6);   // Row: 2 Bank : 2
365
  burst_write({12'h002,2'b11,8'h00,2'b00},8'h7);   // Row: 2 Bank : 3
366
  burst_write({12'h003,2'b00,8'h00,2'b00},8'h4);   // Row: 3 Bank : 0
367
  burst_write({12'h003,2'b01,8'h00,2'b00},8'h5);   // Row: 3 Bank : 1
368
  burst_write({12'h003,2'b10,8'h00,2'b00},8'h6);   // Row: 3 Bank : 2
369
  burst_write({12'h003,2'b11,8'h00,2'b00},8'h7);   // Row: 3 Bank : 3
370 43 dinesha
 
371 46 dinesha
  burst_read();
372
  burst_read();
373
  burst_read();
374
  burst_read();
375
  burst_read();
376
  burst_read();
377
  burst_read();
378
  burst_read();
379
 
380 53 dinesha
  burst_write({12'h002,2'b00,8'h00,2'b00},8'h4);   // Row: 2 Bank : 0
381
  burst_write({12'h002,2'b01,8'h01,2'b00},8'h5);   // Row: 2 Bank : 1
382
  burst_write({12'h002,2'b10,8'h02,2'b00},8'h6);   // Row: 2 Bank : 2
383
  burst_write({12'h002,2'b11,8'h03,2'b00},8'h7);   // Row: 2 Bank : 3
384
  burst_write({12'h003,2'b00,8'h04,2'b00},8'h4);   // Row: 3 Bank : 0
385
  burst_write({12'h003,2'b01,8'h05,2'b00},8'h5);   // Row: 3 Bank : 1
386
  burst_write({12'h003,2'b10,8'h06,2'b00},8'h6);   // Row: 3 Bank : 2
387
  burst_write({12'h003,2'b11,8'h07,2'b00},8'h7);   // Row: 3 Bank : 3
388
 
389
  burst_read();
390
  burst_read();
391
  burst_read();
392
  burst_read();
393
  burst_read();
394
  burst_read();
395
  burst_read();
396
  burst_read();
397 46 dinesha
  $display("---------------------------------------------------");
398
  $display(" Case: 6 Random 2 write and 2 read random");
399
  $display("---------------------------------------------------");
400 8 dinesha
  for(k=0; k < 20; k++) begin
401 43 dinesha
     StartAddr = $random & 32'h003FFFFF;
402 53 dinesha
     burst_write(StartAddr,($random & 8'h0f)+1);
403 43 dinesha
 #100;
404
 
405
     StartAddr = $random & 32'h003FFFFF;
406 53 dinesha
     burst_write(StartAddr,($random & 8'h0f)+1);
407 43 dinesha
 #100;
408
     burst_read();
409
 #100;
410
     burst_read();
411
 #100;
412 8 dinesha
  end
413
 
414
  #10000;
415
 
416
        $display("###############################");
417
    if(ErrCnt == 0)
418
        $display("STATUS: SDRAM Write/Read TEST PASSED");
419
    else
420
        $display("ERROR:  SDRAM Write/Read TEST FAILED");
421
        $display("###############################");
422
 
423
    $finish;
424
end
425
 
426
task burst_write;
427
input [31:0] Address;
428 43 dinesha
input [7:0]  bl;
429 8 dinesha
int i;
430
begin
431 43 dinesha
  afifo.push_back(Address);
432
  bfifo.push_back(bl);
433
 
434 30 dinesha
   @ (negedge sys_clk);
435 43 dinesha
   $display("Write Address: %x, Burst Size: %d",Address,bl);
436 8 dinesha
 
437 43 dinesha
   for(i=0; i < bl; i++) begin
438 30 dinesha
      wb_stb_i        = 1;
439
      wb_cyc_i        = 1;
440
      wb_we_i         = 1;
441
      wb_sel_i        = 4'b1111;
442
      wb_addr_i       = Address[31:2]+i;
443 43 dinesha
      wb_dat_i        = $random & 32'hFFFFFFFF;
444
      dfifo.push_back(wb_dat_i);
445 8 dinesha
 
446
      do begin
447 30 dinesha
          @ (posedge sys_clk);
448
      end while(wb_ack_o == 1'b0);
449
          @ (negedge sys_clk);
450 8 dinesha
 
451 30 dinesha
       $display("Status: Burst-No: %d  Write Address: %x  WriteData: %x ",i,wb_addr_i,wb_dat_i);
452 8 dinesha
   end
453 56 dinesha
   wb_stb_i        = 0;
454
   wb_cyc_i        = 0;
455
   wb_we_i         = 'hx;
456
   wb_sel_i        = 'hx;
457
   wb_addr_i       = 'hx;
458
   wb_dat_i        = 'hx;
459 8 dinesha
end
460
endtask
461
 
462
task burst_read;
463 43 dinesha
reg [31:0] Address;
464
reg [7:0]  bl;
465 8 dinesha
 
466
int i,j;
467 43 dinesha
reg [31:0]   exp_data;
468 8 dinesha
begin
469 43 dinesha
 
470
   Address = afifo.pop_front();
471
   bl      = bfifo.pop_front();
472 30 dinesha
   @ (negedge sys_clk);
473 8 dinesha
 
474 43 dinesha
      for(j=0; j < bl; j++) begin
475 30 dinesha
         wb_stb_i        = 1;
476
         wb_cyc_i        = 1;
477
         wb_we_i         = 0;
478
         wb_addr_i       = Address[31:2]+j;
479 8 dinesha
 
480 43 dinesha
         exp_data        = dfifo.pop_front(); // Exptected Read Data
481 30 dinesha
         do begin
482
             @ (posedge sys_clk);
483
         end while(wb_ack_o == 1'b0);
484 43 dinesha
         if(wb_dat_o !== exp_data) begin
485
             $display("READ ERROR: Burst-No: %d Addr: %x Rxp: %x Exd: %x",j,wb_addr_i,wb_dat_o,exp_data);
486 8 dinesha
             ErrCnt = ErrCnt+1;
487
         end else begin
488 30 dinesha
             $display("READ STATUS: Burst-No: %d Addr: %x Rxd: %x",j,wb_addr_i,wb_dat_o);
489 8 dinesha
         end
490
         @ (negedge sdram_clk);
491
      end
492 56 dinesha
   wb_stb_i        = 0;
493
   wb_cyc_i        = 0;
494
   wb_we_i         = 'hx;
495
   wb_addr_i       = 'hx;
496 8 dinesha
end
497
endtask
498
 
499
 
500
endmodule

powered by: WebSVN 2.1.0

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