DDR-MIG 学习记录

2023-11-29 02:36
文章标签 学习 记录 ddr mig

本文主要是介绍DDR-MIG 学习记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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 interface 的output 反馈:

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信号一直没有拉高)。

设计时注意位宽参数的参数传递,确保对应位宽正确;根据资料,DDR3的burst 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 )
(   //systeminput clk ,input rst_n ,    input memc_init_done ,//userinput 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 ,//cmdinput memc_cmd_rdy ,output wire memc_en ,output wire[2:0]app_cmd ,output wire[ADDR_WIDTH - 1:0]memc_addr ,//writeinput 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 ,//readinput 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
)
(// Inoutsinout [15:0]                         ddr3_dq,inout [1:0]                        ddr3_dqs_n,inout [1:0]                        ddr3_dqs_p,// Outputsoutput [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 clockinput 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 DQSparameter 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 Operationlocalparam real TPROP_DQS_RD       = 0.00;// Delay for DQS signal during Read Operationlocalparam real TPROP_PCB_CTRL     = 0.00;// Delay for Address and Ctrl signalslocalparam real TPROP_PCB_DATA     = 0.00;// Delay for data signal during Write operationlocalparam real TPROP_PCB_DATA_RD  = 0.00;// Delay for data signal during Read operationlocalparam 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;generatefor (r = 0; r < CS_WIDTH; r = r + 1) begin: mem_rnkif(DQ_WIDTH/16) begin: memfor (i = 0; i < NUM_COMP; i = i + 1) begin: gen_memddr3_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]));endendif (DQ_WIDTH%16) begin: gen_mem_extrabitsddr3_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]));endendendgenerateinitialsys_clk_i = 1'b0;alwayssys_clk_i = #(CLKIN_PERIOD/2.0) ~sys_clk_i;initial beginwr_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)beginwait(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)beginwait(app_en);rd_sig = 1 ;rd_addr = rd_addr + 8   ;#10000;rd_sig = 0 ;end#5000000;$finish;endalways @( * ) beginddr3_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;endalways @( * )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 generationassign 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 BUSgenvar dqwd;generatefor (dqwd = 1;dqwd < DQ_WIDTH;dqwd = dqwd+1) begin : dq_delayWireDelay #(.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));endWireDelay #(.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));endgenerategenvar dqswd;generatefor (dqswd = 0;dqswd < DQS_WIDTH;dqswd = dqswd+1) begin : dqs_delayWireDelay #(.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

这篇关于DDR-MIG 学习记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/431135

相关文章

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明

将sqlserver数据迁移到mysql的详细步骤记录

《将sqlserver数据迁移到mysql的详细步骤记录》:本文主要介绍将SQLServer数据迁移到MySQL的步骤,包括导出数据、转换数据格式和导入数据,通过示例和工具说明,帮助大家顺利完成... 目录前言一、导出SQL Server 数据二、转换数据格式为mysql兼容格式三、导入数据到MySQL数据

关于rpc长连接与短连接的思考记录

《关于rpc长连接与短连接的思考记录》文章总结了RPC项目中长连接和短连接的处理方式,包括RPC和HTTP的长连接与短连接的区别、TCP的保活机制、客户端与服务器的连接模式及其利弊分析,文章强调了在实... 目录rpc项目中的长连接与短连接的思考什么是rpc项目中的长连接和短连接与tcp和http的长连接短

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

Servlet中配置和使用过滤器的步骤记录

《Servlet中配置和使用过滤器的步骤记录》:本文主要介绍在Servlet中配置和使用过滤器的方法,包括创建过滤器类、配置过滤器以及在Web应用中使用过滤器等步骤,文中通过代码介绍的非常详细,需... 目录创建过滤器类配置过滤器使用过滤器总结在Servlet中配置和使用过滤器主要包括创建过滤器类、配置过滤

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

python与QT联合的详细步骤记录

《python与QT联合的详细步骤记录》:本文主要介绍python与QT联合的详细步骤,文章还展示了如何在Python中调用QT的.ui文件来实现GUI界面,并介绍了多窗口的应用,文中通过代码介绍... 目录一、文章简介二、安装pyqt5三、GUI页面设计四、python的使用python文件创建pytho

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert