在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 3914|回复: 9

求救:如何实现可综合的SDRAM控制器的测试平台

[复制链接]
发表于 2006-4-2 23:08:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
不可综合的测试平台代码:
`timescale 1ps / 1ps
module sdr_sdram_tb();

// defines for the testbench
`define         BL              8               // burst length
`define         CL              3               // cas latency
`define         RCD             2               // RCD
`define         LOOP_LENGTH     1024            // memory test loop length

`include        "params.v"

reg                             clk;                    // Generated System Clock
reg                             clk2;                   // staggered system clock for sdram models
reg                             reset_n;                // Reset
reg     [2:0]                   cmd;
reg     [`ASIZE-1:0]            addr;
reg                             ref_ack;
reg     [`DSIZE-1:0]            datain;
reg     [`DSIZE/8-1:0]          dm;

wire                            cmdack;
wire    [`DSIZE-1:0]            dataout;
wire    [11:0]                  sa;
wire    [1:0]                   ba;
wire    [1:0]                   cs_n;
wire                            cke;
wire                            ras_n;
wire                            cas_n;
wire                            we_n;
wire    [`DSIZE-1:0]            dq;
wire    [`DSIZE/8-1:0]          dqm;
reg     [`ASIZE-1:0]            test_data;
reg     [`DSIZE-1:0]            test_addr;
reg     [11:0]                  mode_reg;

integer                         j;
integer                         x,y,z;
integer                         bl;

// SDR SDRAM controller
sdr_sdram sdr_sdram1 (
               .CLK(clk),
               .RESET_N(reset_n),
               .ADDR(addr),
               .CMD(cmd),
               .CMDACK(cmdack),
               .DATAIN(datain),
               .DATAOUT(dataout),
               .DM(dm),
               .SA(sa),
               .BA(ba),
               .CS_N(cs_n),
               .CKE(cke),
               .RAS_N(ras_n),
               .CAS_N(cas_n),
               .WE_N(we_n),
               .DQ(dq),
               .DQM(dqm)
               );
// micron memory models
mt48lc8m16a2 mem00      (.Dq(dq[15:0]),
                       .Addr(sa[11:0]),
                       .Ba(ba),
                       .Clk(clk2),
                       .Cke(cke),
                       .Cs_n(cs_n[0]),
                       .Cas_n(cas_n),
                       .Ras_n(ras_n),
                       .We_n(we_n),
                       .Dqm(dqm[1:0]));
mt48lc8m16a2 mem01      (.Dq(dq[31:16]),
                       .Addr(sa[11:0]),
                       .Ba(ba),
                       .Clk(clk2),
                       .Cke(cke),
                       .Cs_n(cs_n[0]),
                       .Cas_n(cas_n),
                       .Ras_n(ras_n),
                       .We_n(we_n),
                       .Dqm(dqm[3:2]));
                       
mt48lc8m16a2 mem10      (.Dq(dq[15:0]),
                       .Addr(sa[11:0]),
                       .Ba(ba),
                       .Clk(clk2),
                       .Cke(cke),
                       .Cs_n(cs_n[1]),
                       .Cas_n(cas_n),
                       .Ras_n(ras_n),
                       .We_n(we_n),
                       .Dqm(dqm[1:0]));
mt48lc8m16a2 mem11      (.Dq(dq[31:16]),
                       .Addr(sa[11:0]),
                       .Ba(ba),
                       .Clk(clk2),
                       .Cke(cke),
                       .Cs_n(cs_n[1]),
                       .Cas_n(cas_n),
                       .Ras_n(ras_n),
                       .We_n(we_n),
                       .Dqm(dqm[3:2]));

initial begin
       clk = 1;
       clk2 = 1;
       reset_n = 0;                                             // reset the system
       #100000 reset_n = 1;
end

// system clocks
//133mhz clock always block
always begin
       #2750 clk2 = ~clk2;                                 
       #1000 clk = ~clk;
end
//100mhz clock always block
//always begin
//        #3 clk2 = ~clk2;                                 
//        #2 clk = ~clk;
//end

//      write_burst(address, start_value, data_mask, RCD, BL)
//
//      This task performs a write access of size BL
//      at SDRAM address to the SDRAM controller
//
//      address         :    Address in SDRAM to start the burst access
//      start_value     :    Starting value for the burst write sequence.  The write burst task
//                              simply increments the data values from the start_value.
//      data_mask       :    Byte data mask for all cycles in the burst.
//      RCD             :    RCD value that was set during configuration
//      BL              :    BL is the burst length the devices have been configured for.
task    burst_write;
       input [`ASIZE-1   : 0]    address;
       input [`DSIZE-1   : 0]    start_value;
       input [`DSIZE/8-1 : 0]    data_mask;
       input [1 : 0]             RCD;
       input [3 : 0]             BL;
       integer                 i;
       begin
               addr <= address;
               cmd  <= 3'b010;                             // Issue a WRITEA command
               datain <= start_value;                      // Assert the first data value
               dm     <= data_mask;
               @(cmdack==1);                               // wait for the ack from the controller
               @(posedge clk);
               cmd  <= 3'b000;
               for (i=1 ; i<=(RCD-2); i=i+1)               // wait for RAS to CAS to expire
               @(posedge clk);
               for(i = 1; i <= BL; i = i + 1)              // loop from 1 to BL
               begin
                        #1000;
                       datain <= start_value + i;          // clock the data into the controller
                       @(posedge clk);
                       
               end
               dm <= 0;
       end
endtask

//      burst_read(address, start_value, CL, RCD, BL)
//
//      This task performs a read access of size BL
//      at SDRAM address to the SDRAM controller
//
//      address         :       Address in SDRAM to start the burst access
//      start_value     :       Starting value for the burst read sequence.  The read burst task
//                                simply increments and compares the data values from the start_value.
//      CL              :       CAS latency the sdram devices have been configured for.
//      RCD             :       RCD value the controller has been configured for.
//      BL              :       BL is the burst length the sdram devices have been configured for

task    burst_read;
       input   [`ASIZE-1 : 0]         address;
       input   [`DSIZE-1 : 0]         start_value;
       input   [1 : 0]                CL;
       input   [1 : 0]                RCD;
       input   [3 : 0]                BL;
       integer                        i;
       reg     [`DSIZE-1 : 0]         read_data;
      
       begin
               addr  <= address;
               cmd   <= 3'b001;                            // Issue the READA command
               @(cmdack == 1);                             // wait for an ack from the controller
               @(posedge clk);
               #1000;
               cmd <= 3'b000;                              // Issue a NOP
               for (i=1 ; i<=(CL+RCD+1); i=i+1)            // wait for RAS to CAS to expire
               @(posedge clk);
               for(i = 1; i <= BL; i = i + 1)              // loop from 1 to burst length(BL), collecting and comparing the data
               begin
                       @(posedge clk);
                       read_data <= dataout;
                       #2000;
                       if (read_data !== start_value + i - 1)
                       begin
                               $display("Read error at %h read %h expected %h", (addr+i-1), read_data, (start_value + i -1));
                               $stop;
                       end
               end
               #1000000;
               cmd <= 3'b100;                           // issue a precharge command to close the page                          
               @(posedge clk);
               @(cmdack==1);
               @(posedge clk);
               #1000;   
               cmd  <= 3'b000;
       end
endtask

//      page_write_burst(address, start_value, data_mask, RCD, length)
//
//      This task performs a page write burst access of size length
//      at SDRAM address to the SDRAM controller
//
//      address         :    Address in SDRAM to start the burst access
//      start_value     :    Starting value for the burst write sequence.  The write burst task
//                              simply increments the data values from the start_value.
//      data_mask       :    Byte data mask for all cycles in the burst.
//      RCD             :    RCD value that was set during configuration
//      length          :    burst length of the access.
task    page_write_burst;
       input [`ASIZE-1   : 0]    address;
       input [`DSIZE-1   : 0]    start_value;
       input [`DSIZE/8-1 : 0]    data_mask;
       input [1 : 0]             RCD;
       input [15 : 0]            length;
       integer                 i;
       begin
               addr <= address;
               cmd  <= 3'b010;
               datain <= start_value;
               dm     <= data_mask;
               @(cmdack==1);
               @(posedge clk);
               #1000;   
               cmd  <= 3'b000;
               for (i=1 ; i<=(RCD-2); i=i+1)
               @(posedge clk);
               for(i = 1; i <= length-2; i = i + 1)
               begin
               #1000;
                       datain <= start_value + i;
                       
                       @(posedge clk);
                       
               end
               #1000;
               datain <= start_value + i;               // keep incrementing the data value
               #1000;   
               cmd <= 3'b100;                           // issue a precharge/terminate command to terminate the page burst                        
               @(posedge clk);
               #1000;
               datain <= start_value + i + 1;           // increment the data one more
                  
               @(cmdack == 1)                           // Wait for the controller to ack the command   
               #2000;
               cmd <= 3'b000;                           // Clear the command by issuing a NOP
               
               dm <= 0;
               #1000000;
               cmd <= 3'b100;                           // issue a precharge command to close the page                          
               @(posedge clk);
               @(cmdack==1);
               @(posedge clk);
               #1000;   
               cmd  <= 3'b000;

       end
endtask

//      page_read_burst(address, start_value, CL, RCD, length)
//
//      This task performs a page read access of size length
//      at SDRAM address to the SDRAM controller
//
//      address         :       Address in SDRAM to start the burst access
//      start_value     :       Starting value for the burst read sequence.  The read burst task
//                                simply increments and compares the data values from the start_value.
//      CL              :       CAS latency the sdram devices have been configured for.
//      RCD             :       RCD value the controller has been configured for.
//      length          :       burst length of the access

task    page_read_burst;
       input   [`ASIZE-1 : 0]         address;
       input   [`DSIZE-1 : 0]         start_value;
       input   [1 : 0]                CL;
       input   [1 : 0]                RCD;
       input   [15 : 0]               length;
       integer                        i;
       reg     [`DSIZE-1 : 0]         read_data;
      
       begin
               addr  <= address;
               cmd   <= 3'b001;                                 // issue a read command to the controller
               @(cmdack == 1);                                  // wait for the controller to ack
               @(posedge clk);
               #1000;
               cmd <= 3'b000;
                                                  // NOP on the command input
               for (i=1 ; i<=(CL+RCD+1); i=i+1)                 // Wait for activate and cas latency delays
               @(posedge clk);
               for(i = 1; i <= length; i = i + 1)               // loop and collect the data
               begin
                       @(posedge clk);
                       read_data <= dataout;
                       #2000;
                       if (i == (length-8)) cmd <= 3'b100;      // Terminate the page burst
                       if (cmdack == 1) cmd<=3'b000;            // end the precharge command once the controller has ack'd
                       if (read_data !== start_value + i - 1)
                       begin
                               $display("Read error at %h read %h expected %h", (addr+i-1), read_data, (start_value + i -1));
                               $stop;
                       end
               end
       end
endtask


//      config(bl, cl, rc, pm, ref)
//
//      This task cofigures the SDRAM devices and the controller
//
//      bl         :       Burst length 1,2,4, or 8
//      cl         :       Cas latency, 2 or 3
//      rc         :       Ras to Cas delay.
//      pm         :       page mode setting
//      ref        :       refresh period setting

task    config;
       input   [3 : 0]           bl;
       input   [1 : 0]           cl;
       input   [1 : 0]           rc;
       input                     pm;
       input   [15: 0]           ref;
      
       reg     [`ASIZE-1 : 0]    config_data;
      
       begin
               config_data <= 0;
               @(posedge clk);
               @(posedge clk);
                                                      
               @(posedge clk);
               if (bl == 1)
                       config_data[2:0] <= 3'b000;     // Set the Burst length portion of the mode data
               else if (bl == 2)
                       config_data[2:0] <= 3'b001;
               else if (bl == 4)
                       config_data[2:0] <= 3'b010;
               else if (bl ==
                       config_data[2:0] <= 3'b011;
               else if (bl == 0)
                       config_data[2:0] <= 3'b111;    // full page burst configuration value for bl
                       
               config_data[6:4] <= cl;
      
                                                        // issue precharge before issuing load_mode
               @(posedge clk);
               cmd <= 3'b100;                        
               @(cmdack == 1)                           // Wait for the controller to ack the command   
               #2000;
               cmd <= 3'b000;                           // Clear the command by issuing a NOP
               @(posedge clk);
               #2000;
      
                                                       // load mode register
               cmd <= 3'b101;
               addr[15:0] <= config_data;
               @(cmdack == 1)                          // Wait for the controller to ack the command
               cmd <= 3'b000;                          // Clear the command by issuing a NOP
      
      
               config_data <= 0;
               config_data[15:0] <= ref;
               @(posedge clk);
                                                        // load refresh counter
               @(posedge clk);
               addr[15:0] <= config_data;
               cmd  <= 3'b111;
               @(cmdack == 1 );                         // Wait for the controller to ack the command
               #2000;                          
               cmd  <= 3'b000;                          // Clear the command by issuing a NOP
               addr <= 0;
               config_data <= 0;               
               
               config_data[1:0] <= cl;                  // load contorller reg1
               config_data[3:2] <= rc;
               config_data[8] <= pm;
               config_data[12:9] <= bl;
               @(posedge clk);
               #2000;
               addr[15:0] <= config_data;
               cmd  <= 3'b110;
               @(cmdack == 1)                           // Wait for the controller to ack the command
               #2000;
               cmd  <= 3'b000;                          // Clear the command by issuing a NOP
               addr <= 0;
               config_data <= 0;
      
              
               
       end
endtask
initial begin
       cmd = 0;
       addr = 0;
       ref_ack = 0;
       dm <= 0;
       #3000000;

$display("Testing page burst accesses");
config(0,3,3,1,1526);
#1000000;
$display("Writing a ramp value from 0-29 out to sdram at address 0x0");
page_write_burst(0, 0, 4'h0, 3, 30);
#1000000;
$display("Reading the ramp value from sdram at address 0x0");
page_read_burst(0,0,3,3,30);
#1000000;

$display("Testing data mask inputs");
config(8,3,3,0,1526);
#1000000;

$display("writing pattern 0,1,2,3,4,5,6,7 to sdram at address 0x0");
burst_write(0, 0, 4'b0, 3, 8);

$display("Reading and verifing the pattern 0,1,2,3,4,5,6,7 at sdram address 0x0");
burst_read(0, 0, 3, 3, 8);

$display("Writing pattern 0xfffffff0, 0xfffffff1, 0xfffffff2, 0xfffffff3, 0xfffffff4, 0xfffffff5, 0xfffffff6, 0xfffffff7");
$display("with DM set to 0xf");
burst_write(0, 32'hfffffff0, 4'b1111, 3, 8);

$display("Reading and verifing that the pattern at sdram address 0x0 is");
$display("still 0,1,2,3,4,5,6,7");
burst_read(0, 0, 3, 3, 8);

$display("End of data mask test");



bl = 1;
for (x = 1; x <=4; x = x + 1)
begin
   for (y = 3; y <= 3; y = y + 1)              // at 133mhz cl must be 3,  if 100mhz cl can be 2
   begin
     for (z = 3; z <=3; z = z + 1)             //at 133mhz rc must be 3, if 100mhz rc can be 2
     begin
        $display("configuring for bl = %d   cl = %d   rc = %d",bl,y,z);
        config(bl, y, z, 0, 1526);
               
// perform 1024 burst writes to the first chip select, writing a ramp pattern
       $display("eforming burst write to first sdram bank");
       test_data <= 0;
       test_addr <= 0;
       @(posedge clk);
       @(posedge clk);
       for (j = 0; j < `LOOP_LENGTH; j = j + 1)
       begin
               burst_write(test_addr, test_data, 4'h0, z, bl);
               test_data <= test_data + bl;
               test_addr <= test_addr + bl;
               #50000;
       end
      
// perform 1024 burst reads to the first chip select, verifing the ramp pattern
       $display("erforming burst read, verify ramp values in first sdram bank");
       test_data <= 0;
       test_addr <= 0;
       @(posedge clk);
       @(posedge clk);
       for (j = 0; j < `LOOP_LENGTH; j = j + 1)
       begin
               burst_read(test_addr, test_data, y, z, bl);
               test_data <= test_data + bl;
               test_addr <= test_addr + bl;
       end
      
       #500000;
// perform 1024 burst writes to the second chip select, writing a ramp pattern
       $display("eforming burst write to second sdram bank");
       test_data <= 24'h400000;
       test_addr <= 24'h400000;
       @(posedge clk);
       @(posedge clk);
       for (j = 0; j < `LOOP_LENGTH; j = j + 1)
       begin
               burst_write(test_addr, test_data, 4'h0, z, bl);
               test_data <= test_data + bl;
               test_addr <= test_addr + bl;
               @(posedge clk);
       end
      
// perform 1024 burst reads to the second chip select, verifing the ramp pattern
       $display("Performing burst read, verify ramp values in second sdram bank");
       test_data <= 24'h400000;
       test_addr <= 24'h400000;
       @(posedge clk);
       @(posedge clk);
       for (j = 0; j < `LOOP_LENGTH; j = j + 1)
       begin
               burst_read(test_addr, test_data, y, z, bl);
               test_data <= test_data + bl;
               test_addr <= test_addr + bl;
       end
      
       #500000;
       $display("Test complete");
     end
   end
   bl = bl * 2;
end
$stop;
end
endmodule
发表于 2006-4-3 17:57:33 | 显示全部楼层

求救:如何实现可综合的SDRAM控制器的测试平台

既然是测试平台,那么就不需要综合。
发表于 2006-9-29 13:43:14 | 显示全部楼层
9494:)
testbench又不用syn:)
发表于 2009-2-17 18:21:07 | 显示全部楼层

测试平台

测试平台是不需要综合的,如果要综合的那通常就不是测试平台,而直接是可应用的产品代码了。
发表于 2009-2-18 13:10:51 | 显示全部楼层
题目   就起的有问题!
发表于 2009-2-21 22:18:02 | 显示全部楼层
看不懂哦。...
发表于 2009-2-22 01:06:34 | 显示全部楼层

慢步走

这个贴子挺好看?新加坡留学网收藏起来慢慢看。
发表于 2009-2-26 17:35:42 | 显示全部楼层
楼主辛苦了
看看
发表于 2009-2-26 19:57:00 | 显示全部楼层
就是啊,要是可综合,岂不是芯片上能实现sdram了
发表于 2009-4-15 20:56:37 | 显示全部楼层
搞不懂,新手。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-19 04:16 , Processed in 0.105660 second(s), 12 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表