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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/178172.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

brk和sbrk

在计算机程序中&#xff0c;“program break”通常指的是堆的当前内存边界。当我们改变堆的大小&#xff08;即分配或释放内存&#xff09;&#xff0c;其实就是在命令内核改变进程的“program break”位置。 最初&#xff0c;“program break”正好位于未初始化数据段(bss)末…

vue3中的动态component组件

is属性来指定要渲染的组件(填写组件名&#xff09; 多个子组件通过component标签挂载在同一个父组件中&#xff0c; 可以修改is属性进行动态切换组件。 可以搭配<keep-alive></keep-alive>使用。 父组件代码&#xff1a; <template><div style"fon…

2017年五一杯数学建模A题公交车排班问题解题全过程文档及程序

2017年五一杯数学建模 A题 公交车排班问题 原题再现 随着徐州市经济的快速发展&#xff0c;公交车系统对于人们的出行扮演着越来越重要的角色。在公交车资源有限的情况下&#xff0c;合理的编排公交车的行车计划成为公交公司亟待解决的问题。以下给出公交车排班问题中的部分名…

【NI-RIO入门】为CompactRIO供电

在大多数情况下&#xff0c;您可以使用可直接连接系统的电源&#xff0c;例如墙上的电源插座。但是&#xff0c;某些应用程序或环境缺乏可用电源&#xff0c;您必须使用其他电源&#xff0c;例如电池。无论您是否有可用电源&#xff0c;您可能都希望通过为系统提供一些冗余来确…

洛谷 P1605 USACO迷宫 (详细解析和AC代码)【深搜+打表】

P1605 迷宫 前言题目题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示题目分析注意事项 代码后话王婆卖瓜 题目来源 前言 没什么好说的深搜yyds&#xff01;直接深搜一遍过&#xff01; 题目 题目描述 给定一个 N M N \times M NM 方格的迷宫&#xff0c;迷…

python加速方法:GPU加速(numba库)Demo及编写注意事项

上周使用GPU加速了一个算法&#xff0c;效果特别惊艳&#xff0c;由于算法代码本身没有太大参考价值&#xff0c;所以这里只记录了一些心得体会&#xff0c;以便后续遇到问题进行参考排查 numba加速代码编写注意事项 numba加速代码编写一定要注意&#xff1a; 1、开辟空间&am…

【Java并发】聊聊不安全的HashMap以及ConcurrentHashMap

在实际的开发中&#xff0c;hashmap是比较常用的数据结构&#xff0c;如果所开发的系统并发量不高&#xff0c;那么没有问题&#xff0c;但是一旦系统的并发量增加一倍&#xff0c;那么就可能出现不可控的系统问题&#xff0c;所以在平时的开发中&#xff0c;我们除了需要考虑正…

Python从入门到精通(黑马课程)

目录 运算符 数字运算符 比较运算符 逻辑运算符 转义字符 变量使用 变量定义 变量类型 变量命名 变量函数 input函数 type函数 条件语句 If 格式 案例1&#xff0c;判断年龄 案例2&#xff0c;借钱 案例3&#xff0c;and、or应用 循环语句 for 格式 案例…

如何使用Cloudreve将个人电脑打造为私有云盘并实现远程访问

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 云存储概念兴起后&#xff0c;现在市面上也已经有了很多公有云盘。但一段时间后…

redis基本数据结构

Redis入门&#xff1a;五大数据类型 文章目录 Redis入门&#xff1a;五大数据类型一.概述二.Redis的基本了解三.Redis五大数据类型1.String (字符串)2.List(列表)3.Set集合(元素唯一不重复)4.Hash集合5.zSet(有序集合) 一.概述 什么是Redis Redis&#xff08;Remote Dictiona…

Java 之 lambda 表达式(一)

目录 一. 前言 二. lambda 表达式语法 2.1. 语法1&#xff1a;无参&#xff0c;无返回值 2.2. 语法2&#xff1a;一个参数&#xff0c;无返回值 2.3. 语法3&#xff1a;两个参数&#xff0c;lambda 体中有多条语句 2.4. 语法4&#xff1a;两个以上参数&#xff0c;有返回…

C++ STL-----容器

STL容器就是将运用最广泛的一些数据结构实现出来 常用的数据结构&#xff1a;数组, 链表,树, 栈, 队列, 集合, 映射表 等 这些容器分为序列式容器和关联式容器两种: 序列式容器:强调值的排序&#xff0c;序列式容器中的每个元素均有固定的位置。 关联式容器:二叉树结构&…

深入了解Java8新特性-日期时间API:LocalDateTime类

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概22000多字&#xff0c;预计阅读时间长需要20分钟以上。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&…

c++没有返回值的返回值

上面的函数search没有返回值,因为a不等于1,但是输出的时候会输出6.这恰巧是x的值,如果我们希望a不等于1时返回x,那么这种结果反而是正确的.有时候这种错误的代码可能产生正确的结果反而会加大debug难度 int search(int n) { 00007FF66DB723E0 mov dword ptr [rsp8],e…

简易版扫雷+代码分析

前言&#xff1a; 实验一个简易版的扫雷&#xff0c;也要两百来行的代码&#xff0c;因此为了代码整洁&#xff0c;维护起来方便&#xff0c;这里我们和前期实现的三子棋一样&#xff0c;也弄一个游戏的头文件game.h用来装各种头文件以及函数的声明以及宏定义、预处理信息&…

视频文件+EasyDarwin做摄像机模拟器模拟RTSP流很方便,还能做成系统服务,方法与流程

之前我看到过一家人工智能做算法的企业&#xff0c;用EasyDarwinFFMPEG做了一个摄像机的模拟器&#xff0c;方法大概是&#xff1a; 用ffmpeg读取mp4等类型的视频文件&#xff08;当然ffmpeg啥都能读取&#xff09;&#xff0c;再以RTSP协议的形式推送给EasyDarwin&#xff1b…

为IP地址申请SSL证书

SSL&#xff08;Secure Sockets Layer&#xff09;是一种网络协议&#xff0c;用于在浏览器与服务器之间建立安全、加密的连接。SSL证书是用于证明您的网站身份并启用HTTPS&#xff08;超文本传输安全协议&#xff09;的安全文件。这种协议可以确保用户与您的网站之间的所有通信…

统计学中两组数据如何进行差异性(相关性)分析?

变量说明&#xff1a; 在确定分析方法前&#xff0c;我们需要了解手中的数据类型&#xff0c;这是最基础也是有必要的&#xff0c;在所有的数据类型中&#xff0c;我们将数据类型分为分类变量也为定类变量和连续变量也称为定量变量&#xff0c;那么什么是定类变量&#xff1f;…

C语言--每日选择题--Day25

第一题 1. 对于C/C语言的函数&#xff0c;下列叙述中正确的是&#xff08; &#xff09; A&#xff1a;函数的定义不能嵌套&#xff0c;但函数调用可以嵌套 B&#xff1a;函数的定义可以嵌套&#xff0c;但函数调用不能嵌套 C&#xff1a;函数的定义和调用都不能嵌套 D&#xf…

凝聚数字经济发展新力量,四象科技受邀出席2023全球数商大会

11月25日&#xff0c;2023全球数商大会在上海开幕。本届大会以“数联全球、商通未来”为主题&#xff0c;上海市委副书记、市长龚正出席大会并宣布大会开幕&#xff0c;国家发展改革委党组成员&#xff0c;国家数据局党组书记、局长刘烈宏&#xff0c;上海市副市长陈杰致辞。四…