本文介绍: (testbench最好直接copy测试工程的,然后替换我们设计控制模块,否则跟我一样仅仅例化了ddr3模块并连线,得到的结果init_calib_done信号一直没有拉高)。app_ecc_single_err[7:0] : 该信号启用ECC时适用,并且与app_rd_data_vali一起有效。为了进行逻辑设计,先打开ip的例化模板(instance module),查看它的IO口,以确定需要设计哪些信号(不要关注太多信号,容易懵,看与所需功能相关的就好);在示例设计中,该信号总是与1绑定

MIG调试总结

       对vivado软件用于控制DDR2 / DDR3 的 控制器MIG(Memory Interface Generator)IP核进行了仿真测试,以学习如何用IP核来控制FPGA板载SDRAM的读写我们需要学会MIG的接口控制可以

       ①配置IP核

Xilinx 的 DDR 控制器名称简写为 MIG(Memory Interface Generator),在 Vivado 左侧窗口点击 IP Catalog然后在 IP Catalog 窗口直接搜索关键字mig”,就可以很容易的找到

MIG IP核有user interface 和 AXI4 interface两种接口以供选择我们可以选择熟悉的接口控制MIG。这里选择user interface

创建完IP核后,可以通过观察它的仿真模型波形学习控制信号的设计,vivado提供的仿真例子下图中打开:

       打开后会创建一个新的工程文件,找到该工程便可直接进行simulation,进行波形的观察。

为了进行逻辑设计,先打开ip的例化模板(instance module),查看它的IO口,以确定需要设计哪些信号(不要关注太多信号,容易懵,看与所需功能相关的就好);或者直接打开此IP核的user guide查看它的接口对应注释如下

根据仿真波形的观察和user guide注释,确定input的作用和output时序,进行总结

①根据mig IP的user interfaceoutput 反馈

ui_clk : 此UI时钟必须是DRAM时钟的一半或四分之一。(用来设计读写逻辑

ui_clk_sync_rst : This is the active-High UI reset.(有用,1-指示用户逻辑复位

       init_calib_complete : PHY在校准完成(初始化ddr3完成,(要用,指示可以开始读写了))

       app_rdy : 1 – UI可以接收命令 (要用)

       app_rd_data : 读取数据 (要用)

       app_rd_data_valid : 高电平表示读出的数据有效 (要用)

       app_wdf_rdy : 该输出表示写入数据FIFO已准备接收数据。当app_wdf_rdy=1′b1和app_wdf_wren=1’b1时,接受写入数据 (要用)

       app_sr_active : 此输出是保留的。(暂时不用

app_rd_data_end : 暂时不知道是否用到,看波形一直为1,注释也不太清楚(暂时不用

       app_ref_ack : 1-表示内存控制器已将请求刷新命令发送到PHY接口暂时不用

       app_zq_ack : 1-指示存储器控制器已将所请求的ZQ校准命令发送到PHY接口。(暂时不用

app_ecc_multiple_err[7:0] : This signal should only be used when ECC is enabled 当ECC被启用并且与app_rd_data_valid一起有效时,该信号适用。如果来自外部存储器读取数据读取突发的每个节拍具有两个比特错误,则app_ecc_multiple_err[3:0]信号为非零。SECDED算法校正相应的读取数据,并在此信号上设置一个非零值,以通知UI上损坏的读取数据。(暂时不用

app_ecc_single_err[7:0] : 该信号在启用ECC时适用,并且与app_rd_data_vali一起有效。如果来自外部存储器的读取数据在读取突发的每个节拍具有单个比特错误,则app_ecc_single_err信号为非零(暂时不用

②设计mig输入信号:

       app_addr : 当前请求地址

       app_cmd : 当前请求命令 :001-读 ; 000 – 写

       app_en : 这是app_addr、app_cmd、app_sz、app_hi_pri信号的选通信

app_wdf_data : 要写的数据

app_wdf_wren : 选通app_wdf_data ;

app_wdf_end : 该活动的高输入表示当前时钟周期是app_wdf_data[]上输入数据最后一个周期。从仿真波形上看,与app_adf_wren保持一致即可

app_hi_pri : 高输入提高当前请求优先级简单操作的话应该用不上?(不管,置0)

app_sz : 此输入是保留的,应绑定到0(置0)

app_sr_req : 此输入是保留的,应绑定到0(置0)

app_wdf_mask : 这为app_wdf_data[]提供了掩码(先不管,置0)

app_ref_req :高输入请求向DRAM发出刷新命令。(刷新用的,暂时不用,置0

app_zq_req : 高输入请求向DRAM发出ZQ校准命令 (校准用的,先不用,置0)

app_correct_en_i : 当断言时,该有效的高信号校正比特数据错误。只有在GUI中启用ECC时,此输入才有效。在示例设计中,该信号总是与1绑定。(校正比特数据,只有启动ECC时有效,置1即可)

根据以上总结设计控制信号如下:

       memc_en即app_en,其他同理。wr_sig和rd_sig自己设计的由外部输入的读信号和写信号,根据这两个信号来启动读和写操作

       app_cmd :000 为写 , 001 为读。

       app_wr_en : 写信号产生且写准备高电平时置高,否则为低。

       app_wr_end : 与app_wr_en一致。

       app_addr : 读信号高时为读地址,否则为写地址

       app_en : 写状态时:写准备高电平命令准备高电平时置高;

状态:命令准备信号高电平时置高。

       设计完控制信号后,完成模块间的连线,然后设计测试模块。

       从vivado提供的测试工程复制出ddr3仿真模型wire_delay模块,在test_bench中完成连线,并从例子复制出对应的逻辑。(testbench最好直接copy测试工程的,然后替换我们设计的控制模块,否则跟我一样仅仅例化了ddr3模块并连线,得到的结果init_calib_done信号一直没有拉高)。

设计时注意位宽参数参数传递,确保对应位宽正确;根据资料DDR3burst length(突发长度固定为8,所以我们可能不需要进行模式寄存器加载?目前还不知怎么用user interface加载模式寄存器

       输入激励信号进行测试:值得注意的是,每次ddr3读写8个数据,对于mig端来说,意味着读写一个数据,地址需要改变8(因为mig端数据位宽是ddr3读写位宽的8倍)。

读写地址位改变小于8会造成重复读写,导致出错(没错就是我)。

仿真结果如下:

可以看到,72没有在wren高电平写入,所以读出来不是72(而是ddr3原本存的数据)。

结尾:本次测试mig的user interface接口引入读写信号wr_sig和rd_sig,设计的app逻辑如下:

       结果符合要求。后续根据设计要求,增删wr_sig和rd_sig信号,对上述信号进行逻辑设计即可。

PS:

如果需要查看IP核的user guide点击下图

如果跳出网页

则直接通过前面网址进入官网然后搜索最后圈出来的文件即可找到。

//
// Create Date: 2023/11/25 17:44:55
//
`timescale 1ps/1ps
module mig_ctrl #(
    parameter DATA_WIDTH = 64,
    parameter ADDR_WIDTH = 32 
    )
(   //system
    input clk ,
    input rst_n ,    
    input memc_init_done ,
    
    //user
    input wr_sig ,
    input rd_sig ,    
    input [ADDR_WIDTH - 1:0]wr_addr ,
    input [ DATA_WIDTH - 1 : 0]wr_data, 
    input [ADDR_WIDTH - 1:0]rd_addr ,
    
    //cmd
    input memc_cmd_rdy ,
    output wire memc_en ,
    output wire[2:0]app_cmd ,
    output wire[ADDR_WIDTH - 1:0]memc_addr ,
    
    //write
    input memc_wr_rdy ,
    output wire memc_wr_en ,
    output wire memc_wr_end ,
    output wire [ DATA_WIDTH - 1 : 0]memc_wr_data ,
    output wire [ DATA_WIDTH/8 - 1 : 0]memc_wr_mask ,
    
    //read
    input memc_rd_data,
    input memc_rd_valid
    );
 
localparam wr_cmd = 3'b000;
localparam rd_cmd = 3'b001;    

assign memc_en = (app_cmd == wr_cmd)?(memc_init_done && memc_wr_rdy && memc_cmd_rdy ):(memc_cmd_rdy);
assign app_cmd = ((memc_init_done && rd_sig))?rd_cmd:wr_cmd;
assign memc_addr = (memc_init_done && rd_sig)?rd_addr:(wr_sig?wr_addr:0);
assign memc_wr_en = (memc_init_done && memc_wr_rdy && memc_cmd_rdy && wr_sig )?1:0;
assign memc_wr_end = memc_wr_en;
assign memc_wr_mask = 0 ;
assign memc_wr_data = (memc_init_done && memc_wr_rdy && wr_sig)?wr_data:0;
    
endmodule

//
// Create Date: 2023/11/25 20:18:42
//
`timescale 1ps/1ps
module mig_test #(
   //***************************************************************************
   parameter PORT_MODE             = "BI_MODE",
   parameter DATA_MODE             = 4'b0010,
   parameter TST_MEM_INSTR_MODE    = "R_W_INSTR_MODE",
   parameter EYE_TEST              = "FALSE",
   parameter DATA_PATTERN          = "DGEN_ALL",
   parameter CMD_PATTERN           = "CGEN_ALL",
   parameter CMD_WDT               = 'h3FF,
   parameter WR_WDT                = 'h1FFF,
   parameter RD_WDT                = 'h3FF,
   parameter SEL_VICTIM_LINE       = 0,
   parameter BEGIN_ADDRESS         = 32'h00000000,
   parameter END_ADDRESS           = 32'h00ffffff,
   parameter PRBS_EADDR_MASK_POS   = 32'hff000000,
   parameter CK_WIDTH              = 1,
   parameter nCS_PER_RANK          = 1,
   parameter CKE_WIDTH             = 1,
   parameter DM_WIDTH              = 2,
   parameter ODT_WIDTH             = 1,
   parameter BANK_WIDTH            = 3,
   parameter COL_WIDTH             = 10,
   parameter CS_WIDTH              = 1,
   parameter DQ_WIDTH              = 16,
   parameter DQS_WIDTH             = 2,
   parameter DQS_CNT_WIDTH         = 1,
   parameter DRAM_WIDTH            = 8,
   parameter ECC                   = "OFF",
   parameter ECC_TEST              = "OFF",
   //parameter nBANK_MACHS           = 4,
   parameter nBANK_MACHS           = 4,
   parameter RANKS                 = 1,
   parameter ROW_WIDTH             = 14,
   parameter ADDR_WIDTH            = 28,
   parameter BURST_MODE            = "8",
   parameter CLKIN_PERIOD          = 5000,
   parameter CLKFBOUT_MULT         = 4,
   parameter DIVCLK_DIVIDE         = 1,
   parameter CLKOUT0_PHASE         = 0.0,
   parameter CLKOUT0_DIVIDE        = 1,
   parameter CLKOUT1_DIVIDE        = 2,
   parameter CLKOUT2_DIVIDE        = 32,
   parameter CLKOUT3_DIVIDE        = 8,
   parameter MMCM_VCO              = 800,
   parameter MMCM_MULT_F           = 8,
   parameter MMCM_DIVCLK_DIVIDE    = 1,
   parameter SIMULATION            = "FALSE",
   parameter TCQ                   = 100,
   parameter DRAM_TYPE             = "DDR3",
   parameter nCK_PER_CLK           = 4,
   parameter DEBUG_PORT            = "OFF",
   parameter RST_ACT_LOW           = 1
)
(
     // Inouts
   inout [15:0]                         ddr3_dq,
   inout [1:0]                        ddr3_dqs_n,
   inout [1:0]                        ddr3_dqs_p,

   // Outputs
   output [13:0]                       ddr3_addr,
   output [2:0]                      ddr3_ba,
   output                                       ddr3_ras_n,
   output                                       ddr3_cas_n,
   output                                       ddr3_we_n,
   output                                       ddr3_reset_n,
   output [0:0]                        ddr3_ck_p,
   output [0:0]                        ddr3_ck_n,
   output [0:0]                       ddr3_cke,
   output [0:0]                       ddr3_cs_n,
   output [1:0]                        ddr3_dm,
   output [0:0]                       ddr3_odt,

   // Inputs
   // Single-ended system clock
   input wr_sig ,
   input rd_sig ,    
   input [ADDR_WIDTH-1:0] wr_addr ,
   input [APP_DATA_WIDTH-1:0] wr_data , 
   input [ADDR_WIDTH-1:0] rd_addr ,
     
   input                                        sys_clk_i,
   output                                       init_calib_complete,
   output app_en ,
   // System reset - Default polarity of sys_rst pin is Active Low.
   // System reset polarity will change based on the option 
   // selected in GUI.
   input                                        sys_rst
    );
 localparam DATA_WIDTH            = 16;
  localparam PAYLOAD_WIDTH         = (ECC_TEST == "OFF") ? DATA_WIDTH : DQ_WIDTH;
  localparam APP_DATA_WIDTH        = 2 * nCK_PER_CLK * PAYLOAD_WIDTH;
  localparam APP_MASK_WIDTH        = APP_DATA_WIDTH / 8;
  localparam MASK_SIZE             = DATA_WIDTH/8;

  wire [ADDR_WIDTH-1:0]                 app_addr;
  wire [2:0]                            app_cmd;
  //wire                                  app_en;
  wire                                  app_rdy;
  wire [APP_DATA_WIDTH-1:0]             app_rd_data;
  wire                                  app_rd_data_end;
  wire                                  app_rd_data_valid;
  wire [APP_DATA_WIDTH-1:0]             app_wdf_data;
  wire                                  app_wdf_end;
  wire [APP_MASK_WIDTH-1:0]             app_wdf_mask;
  wire                                  app_wdf_rdy;
  wire                                  app_sr_active;
  wire                                  app_ref_ack;
  wire                                  app_zq_ack;
  wire                                  app_wdf_wren;
wire ui_clk ;
wire ui_clk_sync_rst;
    
 mig_16b u_mig_16b (
    // Memory interface ports
    .ddr3_addr                      (ddr3_addr),  // output [13:0]		ddr3_addr
    .ddr3_ba                        (ddr3_ba),  // output [2:0]		ddr3_ba
    .ddr3_cas_n                     (ddr3_cas_n),  // output			ddr3_cas_n
    .ddr3_ck_n                      (ddr3_ck_n),  // output [0:0]		ddr3_ck_n
    .ddr3_ck_p                      (ddr3_ck_p),  // output [0:0]		ddr3_ck_p
    .ddr3_cke                       (ddr3_cke),  // output [0:0]		ddr3_cke
    .ddr3_ras_n                     (ddr3_ras_n),  // output			ddr3_ras_n
    .ddr3_reset_n                   (ddr3_reset_n),  // output			ddr3_reset_n
    .ddr3_we_n                      (ddr3_we_n),  // output			ddr3_we_n
    .ddr3_dq                        (ddr3_dq),  // inout [15:0]		ddr3_dq
    .ddr3_dqs_n                     (ddr3_dqs_n),  // inout [1:0]		ddr3_dqs_n
    .ddr3_dqs_p                     (ddr3_dqs_p),  // inout [1:0]		ddr3_dqs_p

    .init_calib_complete            (init_calib_complete),  // output			init_calib_complete

      
	.ddr3_cs_n                      (ddr3_cs_n),  // output [0:0]		ddr3_cs_n
    .ddr3_dm                        (ddr3_dm),  // output [1:0]		ddr3_dm
    .ddr3_odt                       (ddr3_odt),  // output [0:0]		ddr3_odt

    // Application interface ports
    .app_addr                       (app_addr),  // input [27:0]		app_addr
    .app_cmd                        (app_cmd),  // input [2:0]		app_cmd
    .app_en                         (app_en),  // input				app_en
    .app_wdf_data                   (app_wdf_data),  // input [127:0]		app_wdf_data
    .app_wdf_end                    (app_wdf_end),  // input				app_wdf_end
    .app_wdf_wren                   (app_wdf_wren),  // input				app_wdf_wren
    .app_rd_data                    (app_rd_data),  // output [127:0]		app_rd_data
    .app_rd_data_end                (app_rd_data_end),  // output			app_rd_data_end
    .app_rd_data_valid              (app_rd_data_valid),  // output			app_rd_data_valid
    .app_rdy                        (app_rdy),  // output			app_rdy
    .app_wdf_rdy                    (app_wdf_rdy),  // output			app_wdf_rdy
    .app_sr_req                     ('b0),  // input			app_sr_req
    .app_ref_req                    ('b0),  // input			app_ref_req
    .app_zq_req                     ('b0),  // input			app_zq_req
    .app_sr_active                  (app_sr_active),  // output			app_sr_active
    .app_ref_ack                    (app_ref_ack),  // output			app_ref_ack
    .app_zq_ack                     (app_zq_ack),  // output			app_zq_ack
    .ui_clk                         (ui_clk),  // output			ui_clk
    .ui_clk_sync_rst                (ui_clk_sync_rst),  // output			ui_clk_sync_rst
    .app_wdf_mask                   (app_wdf_mask),  // input [15:0]		app_wdf_mask

    // System Clock Ports
    .sys_clk_i                       (sys_clk_i),
    .sys_rst                        (sys_rst) // input sys_rst
    );


mig_ctrl #(
    .DATA_WIDTH(APP_DATA_WIDTH),
    .ADDR_WIDTH(ADDR_WIDTH)
    )
mig_ctrl_inst(   //system
    .clk(ui_clk) ,
    .rst_n(~ui_clk_sync_rst) ,    
    .memc_init_done(init_calib_complete) ,

    .wr_sig(wr_sig) ,
    .rd_sig(rd_sig) ,    
    .wr_addr(wr_addr) ,
    .wr_data(wr_data), 
    .rd_addr(rd_addr) ,


    .memc_cmd_rdy(app_rdy) ,
    .memc_en(app_en) ,
    .app_cmd(app_cmd) ,
    .memc_addr(app_addr) ,


    .memc_wr_rdy(app_wdf_rdy) ,
    .memc_wr_en(app_wdf_wren) ,
    .memc_wr_end(app_wdf_end) ,
    .memc_wr_data(app_wdf_data) ,
    .memc_wr_mask(app_wdf_mask) ,

    .memc_rd_data(app_rd_data),
    .memc_rd_valid(app_rd_data_valid)
    );
    
    
endmodule

`timescale 1ps/100fs
//
// Create Date: 2023/11/26 13:20:38
//


module mig_test_tb(    );

  parameter COL_WIDTH             = 10;
                                     // # of memory Column Address bits.
   parameter CS_WIDTH              = 1;
                                     // # of unique CS outputs to memory.
   parameter DM_WIDTH              = 2;
                                     // # of DM (data mask)
   parameter DQ_WIDTH              = 16;
                                     // # of DQ (data)
   parameter DQS_WIDTH             = 2;
   parameter DQS_CNT_WIDTH         = 1;
                                     // = ceil(log2(DQS_WIDTH))
   parameter DRAM_WIDTH            = 8;
                                     // # of DQ per DQS
   parameter ECC                   = "OFF";
   parameter RANKS                 = 1;
                                     // # of Ranks.
   parameter ODT_WIDTH             = 1;
                                     // # of ODT outputs to memory.
   parameter ROW_WIDTH             = 14;
                                     // # of memory Row Address bits.
   parameter ADDR_WIDTH            = 28;
   parameter CLKIN_PERIOD          = 5000;
  parameter REFCLK_FREQ           = 200.0;
  parameter tCK                   = 2500;
  parameter CA_MIRROR             = "OFF";
  wire                               ddr3_reset_n;
  wire [DQ_WIDTH-1:0]                ddr3_dq_fpga;
  wire [DQS_WIDTH-1:0]               ddr3_dqs_p_fpga;
  wire [DQS_WIDTH-1:0]               ddr3_dqs_n_fpga;
  wire [ROW_WIDTH-1:0]               ddr3_addr_fpga;
  wire [3-1:0]                       ddr3_ba_fpga;
  wire                               ddr3_ras_n_fpga;
  wire                               ddr3_cas_n_fpga;
  wire                               ddr3_we_n_fpga;
  wire [1-1:0]                       ddr3_cke_fpga;
  wire [1-1:0]                       ddr3_ck_p_fpga;
  wire [1-1:0]                       ddr3_ck_n_fpga;
  wire [DQ_WIDTH-1:0]                ddr3_dq_sdram;
  reg [ROW_WIDTH-1:0]                ddr3_addr_sdram [0:1];
  reg [3-1:0]               ddr3_ba_sdram [0:1];
  reg                                ddr3_ras_n_sdram;
  reg                                ddr3_cas_n_sdram;
  reg                                ddr3_we_n_sdram;
  wire [(CS_WIDTH*1)-1:0] ddr3_cs_n_sdram;
  wire [ODT_WIDTH-1:0]               ddr3_odt_sdram;
  reg [1-1:0]                ddr3_cke_sdram;
  wire [DM_WIDTH-1:0]                ddr3_dm_sdram;
  wire [DQS_WIDTH-1:0]               ddr3_dqs_p_sdram;
  wire [DQS_WIDTH-1:0]               ddr3_dqs_n_sdram;
  reg [1-1:0]                 ddr3_ck_p_sdram;
  reg [1-1:0]                 ddr3_ck_n_sdram;  
  reg [ODT_WIDTH-1:0]                ddr3_odt_sdram_tmp;
  wire                               init_calib_complete;
  wire [(CS_WIDTH*1)-1:0] ddr3_cs_n_fpga; 
  wire [DM_WIDTH-1:0]                ddr3_dm_fpga;
  wire [ODT_WIDTH-1:0]               ddr3_odt_fpga;
  
   reg                     sys_clk_i;
   reg sys_rst;
   reg [DM_WIDTH-1:0]                 ddr3_dm_sdram_tmp;
   reg wr_sig ;
   reg rd_sig ;
   reg [ADDR_WIDTH-1:0]wr_addr ;
   reg [127:0]wr_data ;
   reg [ADDR_WIDTH-1:0]rd_addr ;
   reg [(CS_WIDTH*1)-1:0] ddr3_cs_n_sdram_tmp;
     // Local parameters Declarations
  //**************************************************************************//

  localparam real TPROP_DQS          = 0.00;
                                       // Delay for DQS signal during Write Operation
  localparam real TPROP_DQS_RD       = 0.00;
                       // Delay for DQS signal during Read Operation
  localparam real TPROP_PCB_CTRL     = 0.00;
                       // Delay for Address and Ctrl signals
  localparam real TPROP_PCB_DATA     = 0.00;
                       // Delay for data signal during Write operation
  localparam real TPROP_PCB_DATA_RD  = 0.00;
                       // Delay for data signal during Read operation

  localparam MEMORY_WIDTH            = 16;
  localparam NUM_COMP                = DQ_WIDTH/MEMORY_WIDTH;
  localparam ECC_TEST 		   	= "OFF" ;
  localparam ERR_INSERT = (ECC_TEST == "ON") ? "OFF" : ECC ;
  

  localparam real REFCLK_PERIOD = (1000000.0/(2*REFCLK_FREQ));
  localparam RESET_PERIOD = 200000; //in pSec  
  localparam real SYSCLK_PERIOD = tCK;
   
   wire app_en ;
   
mig_test mig_test_inst
(
     // Inouts
   .ddr3_dq(ddr3_dq_fpga),
   .ddr3_dqs_n(ddr3_dqs_n_fpga),
   .ddr3_dqs_p(ddr3_dqs_p_fpga),

   // Outputs
   .ddr3_addr(ddr3_addr_fpga),
   .ddr3_ba(ddr3_ba_fpga),
   .ddr3_ras_n(ddr3_ras_n_fpga),
   .ddr3_cas_n(ddr3_cas_n_fpga),
   .ddr3_we_n(ddr3_we_n_fpga),
   .ddr3_reset_n(ddr3_reset_n),
   .ddr3_ck_p(ddr3_ck_p_fpga),
   .ddr3_ck_n(ddr3_ck_n_fpga),
   .ddr3_cke(ddr3_cke_fpga),
   .ddr3_cs_n(ddr3_cs_n_fpga),
   .ddr3_dm(ddr3_dm_fpga),
   .ddr3_odt(ddr3_odt_fpga),

   // Inputs
   // Single-ended system clock
   .wr_sig(wr_sig) ,
   .rd_sig(rd_sig) ,    
   .wr_addr(wr_addr) ,
   .wr_data(wr_data) , 
   .rd_addr(rd_addr) ,
   
   .sys_clk_i(sys_clk_i),
   .init_calib_complete(init_calib_complete),
   .app_en(app_en),
   // System reset - Default polarity of sys_rst pin is Active Low.
   // System reset polarity will change based on the option 
   // selected in GUI.
   .sys_rst(sys_rst)
    );
  genvar r,i;
  generate
    for (r = 0; r < CS_WIDTH; r = r + 1) begin: mem_rnk
      if(DQ_WIDTH/16) begin: mem
        for (i = 0; i < NUM_COMP; i = i + 1) begin: gen_mem
          ddr3_model u_comp_ddr3
            (
             .rst_n   (ddr3_reset_n),
             .ck      (ddr3_ck_p_sdram),
             .ck_n    (ddr3_ck_n_sdram),
             .cke     (ddr3_cke_sdram[r]),
             .cs_n    (ddr3_cs_n_sdram[r]),
             .ras_n   (ddr3_ras_n_sdram),
             .cas_n   (ddr3_cas_n_sdram),
             .we_n    (ddr3_we_n_sdram),
             .dm_tdqs (ddr3_dm_sdram[(2*(i+1)-1):(2*i)]),
             .ba      (ddr3_ba_sdram[r]),
             .addr    (ddr3_addr_sdram[r]),
             .dq      (ddr3_dq_sdram[16*(i+1)-1:16*(i)]),
             .dqs     (ddr3_dqs_p_sdram[(2*(i+1)-1):(2*i)]),
             .dqs_n   (ddr3_dqs_n_sdram[(2*(i+1)-1):(2*i)]),
             .tdqs_n  (),
             .odt     (ddr3_odt_sdram[r])
             );
        end
      end
      if (DQ_WIDTH%16) begin: gen_mem_extrabits
        ddr3_model u_comp_ddr3
          (
           .rst_n   (ddr3_reset_n),
           .ck      (ddr3_ck_p_sdram),
           .ck_n    (ddr3_ck_n_sdram),
           .cke     (ddr3_cke_sdram[r]),
           .cs_n    (ddr3_cs_n_sdram[r]),
           .ras_n   (ddr3_ras_n_sdram),
           .cas_n   (ddr3_cas_n_sdram),
           .we_n    (ddr3_we_n_sdram),
           .dm_tdqs ({ddr3_dm_sdram[DM_WIDTH-1],ddr3_dm_sdram[DM_WIDTH-1]}),
           .ba      (ddr3_ba_sdram[r]),
           .addr    (ddr3_addr_sdram[r]),
           .dq      ({ddr3_dq_sdram[DQ_WIDTH-1:(DQ_WIDTH-8)],
                      ddr3_dq_sdram[DQ_WIDTH-1:(DQ_WIDTH-8)]}),
           .dqs     ({ddr3_dqs_p_sdram[DQS_WIDTH-1],
                      ddr3_dqs_p_sdram[DQS_WIDTH-1]}),
           .dqs_n   ({ddr3_dqs_n_sdram[DQS_WIDTH-1],
                      ddr3_dqs_n_sdram[DQS_WIDTH-1]}),
           .tdqs_n  (),
           .odt     (ddr3_odt_sdram[r])
           );
      end
    end
  endgenerate

  initial
    sys_clk_i = 1'b0;
  always
    sys_clk_i = #(CLKIN_PERIOD/2.0) ~sys_clk_i;

  initial begin
    wr_sig = 0 ;
    rd_sig = 0 ;
    wr_addr = 0 ;
    rd_addr = 0 ;
    wr_data = 0 ;
    sys_rst = 0 ;
    #1000;
    sys_rst = 1;
    wait(init_calib_complete);
    wr_sig = 1 ;
    repeat(32)begin
    wait(app_en);
    wr_sig = 1 ;
    wr_addr = wr_addr + 8 ;
    wr_data = wr_data + 8 ;
    #10000;
    wr_sig = 0 ;
    end 
    #80000;
    wr_addr = 0;
    wr_sig = 0 ; 
    #200000 ;
    rd_sig = 1 ;
    repeat(32)begin
     wait(app_en);
     rd_sig = 1 ;
     rd_addr = rd_addr + 8   ;
    #10000;
    rd_sig = 0 ;
    end
    #5000000;
    $finish;
    
  end
    
    


  always @( * ) begin
    ddr3_ck_p_sdram      <=  #(TPROP_PCB_CTRL) ddr3_ck_p_fpga;
    ddr3_ck_n_sdram      <=  #(TPROP_PCB_CTRL) ddr3_ck_n_fpga;
    ddr3_addr_sdram[0]   <=  #(TPROP_PCB_CTRL) ddr3_addr_fpga;
    ddr3_addr_sdram[1]   <=  #(TPROP_PCB_CTRL) (CA_MIRROR == "ON") ?
                                                 {ddr3_addr_fpga[ROW_WIDTH-1:9],
                                                  ddr3_addr_fpga[7], ddr3_addr_fpga[8],
                                                  ddr3_addr_fpga[5], ddr3_addr_fpga[6],
                                                  ddr3_addr_fpga[3], ddr3_addr_fpga[4],
                                                  ddr3_addr_fpga[2:0]} :
                                                 ddr3_addr_fpga;
    ddr3_ba_sdram[0]     <=  #(TPROP_PCB_CTRL) ddr3_ba_fpga;
    ddr3_ba_sdram[1]     <=  #(TPROP_PCB_CTRL) (CA_MIRROR == "ON") ?
                                                 {ddr3_ba_fpga[3-1:2],
                                                  ddr3_ba_fpga[0],
                                                  ddr3_ba_fpga[1]} :
                                                 ddr3_ba_fpga;
    ddr3_ras_n_sdram     <=  #(TPROP_PCB_CTRL) ddr3_ras_n_fpga;
    ddr3_cas_n_sdram     <=  #(TPROP_PCB_CTRL) ddr3_cas_n_fpga;
    ddr3_we_n_sdram      <=  #(TPROP_PCB_CTRL) ddr3_we_n_fpga;
    ddr3_cke_sdram       <=  #(TPROP_PCB_CTRL) ddr3_cke_fpga;
  end
    

  always @( * )
    ddr3_cs_n_sdram_tmp   <=  #(TPROP_PCB_CTRL) ddr3_cs_n_fpga;
  assign ddr3_cs_n_sdram =  ddr3_cs_n_sdram_tmp;
    

  always @( * )
    ddr3_dm_sdram_tmp <=  #(TPROP_PCB_DATA) ddr3_dm_fpga;//DM signal generation
  assign ddr3_dm_sdram = ddr3_dm_sdram_tmp;
    

  always @( * )
    ddr3_odt_sdram_tmp  <=  #(TPROP_PCB_CTRL) ddr3_odt_fpga;
  assign ddr3_odt_sdram =  ddr3_odt_sdram_tmp;
    

// Controlling the bi-directional BUS

  genvar dqwd;
  generate
    for (dqwd = 1;dqwd < DQ_WIDTH;dqwd = dqwd+1) begin : dq_delay
      WireDelay #
       (
        .Delay_g    (TPROP_PCB_DATA),
        .Delay_rd   (TPROP_PCB_DATA_RD),
        .ERR_INSERT ("OFF")
       )
      u_delay_dq
       (
        .A             (ddr3_dq_fpga[dqwd]),
        .B             (ddr3_dq_sdram[dqwd]),
        .reset         (sys_rst_n),
        .phy_init_done (init_calib_complete)
       );
    end
          WireDelay #
       (
        .Delay_g    (TPROP_PCB_DATA),
        .Delay_rd   (TPROP_PCB_DATA_RD),
        .ERR_INSERT ("OFF")
       )
      u_delay_dq_0
       (
        .A             (ddr3_dq_fpga[0]),
        .B             (ddr3_dq_sdram[0]),
        .reset         (sys_rst_n),
        .phy_init_done (init_calib_complete)
       );
  endgenerate

  genvar dqswd;
  generate
    for (dqswd = 0;dqswd < DQS_WIDTH;dqswd = dqswd+1) begin : dqs_delay
      WireDelay #
       (
        .Delay_g    (TPROP_DQS),
        .Delay_rd   (TPROP_DQS_RD),
        .ERR_INSERT ("OFF")
       )
      u_delay_dqs_p
       (
        .A             (ddr3_dqs_p_fpga[dqswd]),
        .B             (ddr3_dqs_p_sdram[dqswd]),
        .reset         (sys_rst_n),
        .phy_init_done (init_calib_complete)
       );

      WireDelay #
       (
        .Delay_g    (TPROP_DQS),
        .Delay_rd   (TPROP_DQS_RD),
        .ERR_INSERT ("OFF")
       )
      u_delay_dqs_n
       (
        .A             (ddr3_dqs_n_fpga[dqswd]),
        .B             (ddr3_dqs_n_sdram[dqswd]),
        .reset         (sys_rst_n),
        .phy_init_done (init_calib_complete)
       );
    end    
endgenerate
endmodule

原文地址:https://blog.csdn.net/qq_44366923/article/details/134673557

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_25746.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注