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

相关文章

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Spring Boot中定时任务Cron表达式的终极指南最佳实践记录

《SpringBoot中定时任务Cron表达式的终极指南最佳实践记录》本文详细介绍了SpringBoot中定时任务的实现方法,特别是Cron表达式的使用技巧和高级用法,从基础语法到复杂场景,从快速启... 目录一、Cron表达式基础1.1 Cron表达式结构1.2 核心语法规则二、Spring Boot中定

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)

《国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)》本文给大家利用deepseek模型搭建私有知识问答库的详细步骤和遇到的问题及解决办法,感兴趣的朋友一起看看吧... 目录1. 第1步大家在安装完ollama后,需要到系统环境变量中添加两个变量2. 第3步 “在cmd中