zoukankan      html  css  js  c++  java
  • FPGA基于ISE的DDR3读写循环校验的实现以及波形的抓取(8)

                 上一节已经实现了能够顺利的实现队DDR 3 写入16个递增数和把写入的递增数成功地读出来后,那么接下来就是对DDR3芯片的所有地址都进行读写测试,验证FPGA与DDR3芯片的链路是否正常。方法就是通过比较读出来的数据与写入进去的数据进行比较,看是否是一致的。

               如上图所示,是DDR的规格说明书。我们用到的型号是MT41J64M16—8Meg  x  16  x 8Banks,具体含义是:8Meg 表示含有8M个地址,位宽是16个BIT,8个bank。

                计算字节地址:8*8*2=128M字节地址(乘2是因为每个地址可以存放2个字节的数据),一个字节=8个bit 

                计算字节数据: 8*1024*1024*16=134217728byte

                总的突发次数:134217728/16/8=1048576

    时序设计图

             

    各个端口的介绍

              在此实验中,我所设计的是P0端口用来向DDR中写入数据,P1的端口用来读取写入的数据:

              p0_wr_en :写入数据的使能信号,

              wr_cnt  : 对写入的数据的个数计数寄存器,即突发一次写入16个数据,在p0_wr_en 有效时开始进行计数,16个数据后,清零同时p0_wr_en拉低,一次写数据的突发操作完成;

              wr_data :写入的数据寄存器,在此仅仅为测试DDR的各个链路的读写是否存在问题,所以写入的数就是从0 开始是递增的一串递增数,写数据寄存器要先于写数据命令到来之前准备好,因为对DDR写入数据时相当于对一个写FIFO进行操作,对于这个FIFO来说就是读取数据,如果没有数据事先准备好的话,会出现读空的现象。

              p0_cmd_en:写数据命令使能,当此信号到来的时候,DDR的写数据的相关命令,便开始进行配置;此信号一般在写入数据寄存器的数据准备好后再拉高;

              p1_cmd_en:,读数据命令使能,当此信号到来的时候,DDR的读数据的相关命令,便开始进行配置;此信号一般在 p0_cmd_en写命令使能拉高后再拉高;

              rd_flag : 读数据的操作标志信号,所有的读数据相关的操作,都在此使能条件下完成,可以看成是读操作的总开关;在写命令拉高后就可以;

              rd_cnt: 读操作的计数器,此计数器不仅仅包括了16个数据的读数据突发个数,还包括了,从的安全完成写入数据,到有效读数据的所需要的准备时间;这里的准备时间不同的板子是不一样的,即使板子的时钟是一样的,需要根据仿真时序来一步一步调试;

              rd_en: 与p0_wr_en 信号是对应的,此信号的拉高时间周期个数要满足读数据的一次突发个数;即16个

              byte_addr:地址位,读数据突发一次是16个数据,每个数据是8字节,所以突发一次16*8=128个地址;

              check_data: 校验数据,这里使用来检测与独处的数据是否一致,所以在rd_en 有效的时候进行自加;

              burst_cnt:突发次数,需要知道测试一遍要突发多少次,能够与把所有的地址检测完;

              error_flag:错误标志位,在chaeck_data与读出来的数据不一致的时候,此标志信号拉高;

              error_num: 错误的个数,error_flag信号拉高一次,此信号加一次;

          编写代码:    

             

      1 module    ddr_drive(
      2 
      3      // system signals
      4         input                   sclk                    ,       
      5         input                   s_rst_n                 ,       
      6         // DDR3 User Interfaces
      7         output  reg             p0_cmd_en               ,       
      8         output  wire    [ 2:0]  p0_cmd_instr            ,       
      9         output  wire    [ 5:0]  p0_cmd_bl               ,       
     10         output  wire    [29:0]  p0_byte_addr            ,
     11         output  reg             p0_wr_en                ,       
     12         output  wire    [ 7:0]  p0_wr_mask              ,       
     13         output  reg     [63:0]  p0_wr_data              ,
     14         output  reg             p1_cmd_en               ,       
     15         output  wire    [ 2:0]  p1_cmd_instr            ,       
     16         output  wire    [ 5:0]  p1_cmd_bl               ,       
     17         output  reg     [29:0]  p1_byte_addr            ,
     18         output  reg             p1_rd_en                ,       
     19         input           [63:0]  p1_rd_data                    
     20         // Debug
     21  //        input                   wr_trig                        
     22 );
     23 
     24 //========================================================================
     25 // =========== Define Parameter and Internal signals =========== 
     26 //========================================================================/
     27 localparam      RD_END          =       'd45                    ;
     28 
     29 localparam      BURST_NUM_END   =       1048575                 ;
     30 // localparam      BURST_NUM_END   =       9                       ;
     31 
     32 reg     [ 3:0]                  wr_cnt                          ;       
     33 reg                             rd_flag                         ;       
     34 reg     [ 5:0]                  rd_cnt                          ;       
     35 
     36 reg     [63:0]                  check_data                      ;       
     37 reg     [20:0]                  burst_cnt                       ;       
     38 reg                             error_flag                      ;       
     39 reg     [15:0]                  error_num                       ;
     40 
     41 reg                             wr_trig                         ;       
     42 
     43 //=============================================================================
     44 //**************    Main Code   **************
     45 //=============================================================================
     46 assign  p0_cmd_instr    =       3'b000;
     47 assign  p0_cmd_bl       =       'd15;
     48 assign  p0_byte_addr    =       p1_byte_addr;
     49 assign  p0_wr_mask      =       8'h0;
     50 assign  p1_cmd_instr    =       3'b001;
     51 assign  p1_cmd_bl       =       'd15;
     52 
     53 
     54 always  @(posedge sclk or negedge s_rst_n) begin
     55         if(s_rst_n == 1'b0)
     56                 p0_wr_en        <=      1'b0;
     57         else if(wr_trig == 1'b1)
     58                 p0_wr_en        <=      1'b1;
     59         else if(rd_cnt == RD_END && burst_cnt < BURST_NUM_END)
     60                 p0_wr_en        <=      1'b1;
     61         else if(wr_cnt == 'd15)
     62                 p0_wr_en        <=      1'b0;
     63 end
     64 
     65 always  @(posedge sclk or negedge s_rst_n) begin
     66         if(s_rst_n == 1'b0)
     67                 wr_cnt  <=      'd0;
     68         else if(p0_wr_en == 1'b1)
     69                 wr_cnt  <=      wr_cnt + 1'b1;
     70 end
     71 
     72 always  @(posedge sclk or negedge s_rst_n) begin
     73         if(s_rst_n == 1'b0)
     74                 p0_wr_data      <=      64'h0;
     75         else if(p0_wr_en == 1'b1)
     76                 p0_wr_data      <=      p0_wr_data + 1'b1;
     77 end
     78 
     79 always  @(posedge sclk or negedge s_rst_n) begin
     80         if(s_rst_n == 1'b0)
     81                 p0_cmd_en       <=      1'b0;
     82         else if(wr_cnt == 'd15)
     83                 p0_cmd_en       <=      1'b1;
     84         else
     85                 p0_cmd_en       <=      1'b0;
     86 end
     87 
     88 //------------------------------------------------------------------
     89 always  @(posedge sclk or negedge s_rst_n) begin
     90         if(s_rst_n == 1'b0)
     91                 rd_flag <=      1'b0;
     92         else if(rd_cnt == RD_END)
     93                 rd_flag <=      1'b0;
     94         else if(p0_cmd_en == 1'b1)
     95                 rd_flag <=      1'b1;
     96 end
     97 
     98 always  @(posedge sclk or negedge s_rst_n) begin
     99         if(s_rst_n == 1'b0)
    100                 p1_cmd_en       <=      1'b0;
    101         else if(rd_cnt == 'd19)
    102                 p1_cmd_en       <=      1'b1;
    103         else
    104                 p1_cmd_en       <=      1'b0;
    105 end
    106 
    107 always  @(posedge sclk or negedge s_rst_n) begin
    108         if(s_rst_n == 1'b0)
    109                 rd_cnt  <=      'd0;
    110         else if(rd_flag == 1'b1)
    111                 rd_cnt  <=      rd_cnt + 1'b1;
    112         else
    113                 rd_cnt  <=      'd0;
    114 end
    115 
    116 always  @(posedge sclk or negedge s_rst_n) begin
    117         if(s_rst_n == 1'b0)
    118                 p1_rd_en        <=      1'b0;
    119         else if(rd_cnt == 'd29)
    120                 p1_rd_en        <=      1'b1;
    121         else if(rd_cnt == RD_END)
    122                 p1_rd_en        <=      1'b0;
    123 end
    124 
    125 always  @(posedge sclk or negedge s_rst_n) begin
    126         if(s_rst_n == 1'b0)
    127                 check_data      <=      64'h0;
    128         else if(p1_rd_en == 1'b1)
    129                 check_data      <=      check_data + 1'b1; 
    130 end
    131 
    132 always  @(posedge sclk or negedge s_rst_n) begin
    133         if(s_rst_n == 1'b0)
    134                 p1_byte_addr    <=      'd0;
    135         else if(p1_cmd_en == 1'b1)
    136                 p1_byte_addr    <=      p1_byte_addr + 'd128;
    137         else if(wr_trig == 1'b1)
    138                 p1_byte_addr    <=      'd0;
    139 end
    140 
    141 always  @(posedge sclk or negedge s_rst_n) begin
    142         if(s_rst_n == 1'b0)
    143                 burst_cnt       <=      'd0;
    144         else if(rd_cnt == RD_END)
    145                 burst_cnt       <=      burst_cnt + 1'b1;
    146         else if(wr_trig == 1'b1)
    147                 burst_cnt       <=      'd0;
    148 end
    149 
    150 always  @(posedge sclk or negedge s_rst_n) begin
    151         if(s_rst_n == 1'b0)
    152                 error_flag      <=      1'b0;
    153         else if(p1_rd_data != check_data &&  p1_rd_en == 1'b1)
    154                 error_flag      <=      1'b1;
    155         else 
    156                 error_flag      <=      1'b0;
    157 end
    158 
    159 always  @(posedge sclk or negedge s_rst_n) begin
    160         if(s_rst_n == 1'b0)
    161                 error_num       <=      'd0;
    162         else if(error_flag == 1'b1)
    163                 error_num       <=      error_num + 1'b1;
    164         else if(wr_trig == 1'b1)
    165                 error_num       <=      'd0;
    166 end

    使用chiop_scop 抓取波形:

     1 wire    [35:0]                  CONTROL0                        ;       
     2 wire    [35:0]                  CONTROL1                        ;       
     3 wire    [243:0]                 ila_data                        ;       
     4 wire                            vio_out                         ;       
     5 reg                             vio_out_r1                      ;       
     6 reg                             vio_out_r2                      ;       
     7 
     8 assign  ila_data[0]     =       wr_trig;
     9 assign  ila_data[16:1]  =       error_num;
    10 assign  ila_data[17]    =       error_flag;
    11 assign  ila_data[18]    =       p0_cmd_en;
    12 assign  ila_data[19]    =       p1_cmd_en;
    13 assign  ila_data[49:20] =       p1_byte_addr;
    14 assign  ila_data[50]    =       p0_wr_en;
    15 assign  ila_data[114:51]=       p0_wr_data;
    16 assign  ila_data[115]   =       p1_rd_en;
    17 assign  ila_data[179:116] =     p1_rd_data;
    18 assign  ila_data[243:180] =     check_data;
    19 
    20 always  @(posedge sclk) begin
    21         vio_out_r1      <=      vio_out;
    22         vio_out_r2      <=      vio_out_r1;
    23 end
    24 
    25 always  @(posedge sclk or negedge s_rst_n) begin
    26         if(s_rst_n == 1'b0)
    27                 wr_trig <=      1'b0;
    28         else
    29                 wr_trig <=      vio_out_r2 ^ vio_out_r1;
    30 end
    31 
    32 
    33 chipscope_icon chipscope_icon_inst (
    34         .CONTROL0               (CONTROL0               ),// INOUT BUS [35:0]
    35         .CONTROL1               (CONTROL1               )// INOUT BUS [35:0]
    36 );
    37  
    38 
    39 chipscope_ila chipscope_ila_inst (
    40         .CONTROL                (CONTROL0               ), // INOUT BUS [35:0]
    41         .CLK                    (sclk                   ), // IN
    42         .TRIG0                  (ila_data               )// IN BUS [35:0]
    43 );
    44 
    45 chipscope_vio chipscope_vio_inst (
    46         .CONTROL                (CONTROL1               ), // INOUT BUS [35:0]
    47         .CLK                    (sclk                   ), // IN
    48         .SYNC_OUT               (vio_out                )// OUT BUS [0:0]
    49 );
    View Code

    利用上一节写好的tb文件,稍作修改;

      1 `timescale    1ps/1ps
      2 
      3 
      4 module      tb_ddr_top ;
      5 
      6 reg                                      ddr3_ref_clk         ;
      7 reg                                      ddr3_rst_n           ;
      8 //bebug   signals 
      9 reg                                      wr_trig              ;
     10 wire                                     c3_calib_done        ;
     11 
     12 //ddr3 interface 
     13 wire [15:0]                               mcb3_dram_dq        ;
     14 wire [12:0]                               mcb3_dram_a         ;
     15 wire [2:0]                                mcb3_dram_ba        ;
     16 wire                                      mcb3_dram_ras_n     ;
     17 wire                                      mcb3_dram_cas_n     ;
     18 wire                                      mcb3_dram_we_n      ;
     19 wire                                      mcb3_dram_odt       ;
     20 wire                                      mcb3_dram_reset_n   ;
     21 wire                                      mcb3_dram_cke       ;
     22 wire                                      mcb3_dram_dm        ;
     23 wire                                      mcb3_dram_udqs      ;
     24 wire                                      mcb3_dram_udqs_n    ;
     25 wire                                      mcb3_rzq            ;
     26 wire                                      mcb3_zio            ;
     27 wire                                      mcb3_dram_udm       ;
     28 wire                                      mcb3_dram_dqs       ;
     29 wire                                      mcb3_dram_dqs_n     ;
     30 wire                                      mcb3_dram_ck        ;
     31 wire                                      mcb3_dram_ck_n      ;
     32 
     33 
     34 
     35 
     36 parameter C3_MEMCLK_PERIOD     = 20000;
     37 
     38 
     39 initial    begin
     40     
     41         ddr3_ref_clk     =     1;
     42         ddr3_rst_n       =     0;
     43         #20000;
     44         ddr3_rst_n       =     1;    
     45     
     46     
     47 end 
     48 
     49 
     50 
     51 
     52 //produce debug  signals 
     53 initial    begin
     54           wr_trig      <=     0;
     55           @(posedge c3_calib_done)
     56           #100000
     57           wr_trig      <=     1;
     58           #25600
     59           wr_trig      <=     0;
     60 end 
     61 
     62 
     63 
     64 
     65 always   #(C3_MEMCLK_PERIOD/2)  ddr3_ref_clk     =     ~ddr3_ref_clk ;
     66 
     67 
     68  ddr_top   ddr_top_inst(
     69 
     70    
     71    
     72    //sysyterm  interface
     73    .c3_sys_clk                               (ddr3_ref_clk       ),  
     74    .c3_sys_rst_i                             (ddr3_rst_n         ), 
     75    //ddr3 interface 
     76    .mcb3_dram_dq                             (mcb3_dram_dq       ),
     77    .mcb3_dram_a                              (mcb3_dram_a        ),
     78    .mcb3_dram_ba                             (mcb3_dram_ba       ),
     79    .mcb3_dram_ras_n                          (mcb3_dram_ras_n    ),
     80    .mcb3_dram_cas_n                          (mcb3_dram_cas_n    ),
     81    .mcb3_dram_we_n                           (mcb3_dram_we_n     ),
     82    .mcb3_dram_odt                            (mcb3_dram_odt      ),
     83    .mcb3_dram_reset_n                        (mcb3_dram_reset_n  ),
     84    .mcb3_dram_cke                            (mcb3_dram_cke      ),
     85    .mcb3_dram_dm                             (mcb3_dram_dm       ),
     86    .mcb3_dram_udqs                           (mcb3_dram_udqs     ),
     87    .mcb3_dram_udqs_n                         (mcb3_dram_udqs_n   ),
     88    .mcb3_rzq                                 (mcb3_rzq           ),
     89    .mcb3_zio                                 (mcb3_zio           ),
     90    .mcb3_dram_udm                            (mcb3_dram_udm      ),
     91    .mcb3_dram_dqs                            (mcb3_dram_dqs      ),
     92    .mcb3_dram_dqs_n                          (mcb3_dram_dqs_n    ),
     93    .mcb3_dram_ck                             (mcb3_dram_ck       ),
     94    .mcb3_dram_ck_n                           (mcb3_dram_ck_n     ),
     95    //debug   signals 
     96    .wr_trig                                   (wr_trig)          ,
     97    .c3_calib_done                            (c3_calib_done)
     98 
     99 );
    100 
    101  ddr3_model_c3 u_mem_c3(                             
    102   .ck         (mcb3_dram_ck),                        
    103   .ck_n       (mcb3_dram_ck_n),                      
    104   .cke        (mcb3_dram_cke),                       
    105   .cs_n       (1'b0),                                
    106   .ras_n      (mcb3_dram_ras_n),                     
    107   .cas_n      (mcb3_dram_cas_n),                  
    108   .we_n       (mcb3_dram_we_n),                      
    109   .dm_tdqs    ({mcb3_dram_udm,mcb3_dram_dm}),        
    110   .ba         (mcb3_dram_ba),                        
    111   .addr       (mcb3_dram_a),                         
    112   .dq         (mcb3_dram_dq),                        
    113   .dqs        ({mcb3_dram_udqs,mcb3_dram_dqs}),      
    114   .dqs_n      ({mcb3_dram_udqs_n,mcb3_dram_dqs_n}),  
    115   .tdqs_n     (),                                    
    116   .odt        (mcb3_dram_odt),                       
    117   .rst_n      (mcb3_dram_reset_n)                    
    118   ); 
    119   
    120 // The PULLDOWN component is connected to the ZIO signal primarily to avoid the    
    121 // unknown state in simulation. In real hardware, ZIO should be a no connect(NC) pin. 
    122    PULLDOWN zio_pulldown3 (.O(zio3));   PULLDOWN rzq_pulldown3 (.O(rzq3));            
    123                                                                                       
    124 
    125   
    126      endmodule                                                 
    View Code

    注意:

            在进行板级操作之前,我们需要对时钟在进行一些先关操作,我的板载时钟是单口50MHZ,但在先前的仿真过程中和实际操作中DDR3我们设置的是312.5MHZ,在以下路径:F:STUDAY_FPGAUSB_DDRusb2.0_read_ddrPNise_prjusb_readipcore_dirmig_39_2user_design tlmig_39_2.v

    localparam C3_CLKFBOUT_MULT = 25; //原来是1
    localparam C3_DIVCLK_DIVIDE = 2;//原来是0;

    计算公式:312.5/50=12.5

                      25/2= 12.5   

    抓取到的波形

     OK完成,有问题加微信交流:

  • 相关阅读:
    排序算法【java实现】(二)冒泡排序和简单选择排序
    排序算法【java实现】(一)直接插入排序
    Html中行内元素和块级元素有哪些?
    设计模式--单例模式(二)双重校验锁模式
    设计模式--单例模式(一)懒汉式和饿汉式
    给定一个字符串数组{"nba","abc","cba","zz","qq","haha"},请按照字典顺序进行从小到大的排序。
    请统计"nba"在字符串"nbaernbatynbauinbaopnba"中出现的次数
    java string方法
    css中的颜色值
    jquery动画效果中,避免持续反应用户的连续点击
  • 原文地址:https://www.cnblogs.com/lgy-gdeu/p/11614428.html
Copyright © 2011-2022 走看看