【DDR】DDR4学习记录

  这里以美光DDR4芯片 MT40A512M16HA-075E datasheet 为例,说明DDR4存储器的原理及仿真。
  根据开发板手册ug1302,在vcu128(xcvu37p)开发板上,共具有5块DDR4芯片,在数据信号上4块DDR4具有16位数据线,1块DDR4具有8位数据线,共同构成72位数据线,在控制信号上共享相同信号线。

Xilinx MIG

  在默认配置下,MIG配置如图所示。
在这里插入图片描述
通过展开IP层级,可以看到MIG的源码。
在这里插入图片描述
其中:

  • u_mig_ddr4_phy为ddr4的物理层接口,主要负责IObuf、bitslice相关原语的配置例化、时钟生成、接口数据的输入输出。
  • u_ddr_mc、u_ddr_ui、u_ddr4_cal_top负责ddr4读写指令的生成,将用户的输入的非AXI内存读写指令转换为ddr4的操作指令
  • u_ddr_cal_riu为ddr4管理模块,其中包含一个microblaze软核用于控制ddr4的初始化、上板过程ddr4用户界面相关内容展示等操作。

DDR4初始化、读写操作

  DDR4的基本操作过程与DDR3类似,这里根据使用verilog对DDR4的初始化、读写操作进行测试,可通过仿真模型测试,代码如下

  • micron_ddr4_phy.sv 为顶层模块。
`timescale 1ns / 1ps
//
// Company: 
// Engineer:  wjh776a68
// 
// Create Date: 01/17/2024 07:24:52 PM
// Design Name: 
// Module Name: micron_ddr4
// Project Name: 
// Target Devices:  xcvu37p
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//// MT40A512M16LY-075E reference: https://media-www.micron.com/-/media/client/global/documents/products/data-sheet/dram/ddr4/8gb_ddr4_sdram.pdf?rev=74679247a1e24e57b6726071152f1384
// ddr4 2666 16 18-18-18
// 2 bank group, 4 bank, 64k row, 1k column
/*********************************************************************************
* p367 timing parameters
* p41 reset time diagram
* tCK(DLL_ON) [0.75ns, 1.9ns]
* tAA   13.50ns
* tRCD  13.50ns
* tRP   13.50ns
*
*********************************************************************************/
module micron_ddr4_phy(input clk_p // 100MHz,input clk_n,output       [16 : 0]     addr,output       [1 : 0]      ba      ,output       [0 : 0]      cke    ,output       [1 : 0]      cs_n   ,inout        [8 : 0]      dm_dbi_n,inout        [71 : 0]     dq      ,inout        [8 : 0]      dqs_c    ,inout        [8 : 0]      dqs_t    ,output       [0 : 0]      odt     ,output       [0 : 0]      bg      ,output                    reset_n         ,output                    act_n           ,output       [0 : 0]      ck_c    ,output       [0 : 0]      ck_t    );wire clk_I; // 100MHzwire mmcm_clk_I, mmcm_clk_o_I, mmcm_clk6_o_I; // 100MHzwire mmcm_clk_locked;wire ctrl_udata_pll_clk_I; // 1333.333MHzwire ctrl_udata_pll_clk_locked;wire ctrl_udata_pll_clkfbout;reg  ctrl_udata_pll_phyclk_en = 1'b0;wire mdata_pll_clk_I; // 1333.333MHzwire mdata_pll_clk_locked;wire mdata_pll_clkfbout;reg  mdata_pll_phyclk_en = 1'b0;wire ldata_pll_clk_I; // 1333.333MHzwire ldata_pll_clk_locked;wire ldata_pll_clkfbout;reg  ldata_pll_phyclk_en = 1'b0;wire usr_clk_p, usr_clk_n; // 333.333MHzwire ctrl_udata_riu_clk_p, ctrl_udata_riu_clk_n; // 250MHzwire mdata_riu_clk_p, mdata_riu_clk_n; wire ldata_riu_clk_p, ldata_riu_clk_n; reg clk_rst = 1;//, mmcm_clk_rst = 1, pll_clk_rst = 1;(* srl_style = "srl_reg" *) reg [31:0] clk_rst_slr32 = {32{1'b1}};(* srl_style = "srl_reg" *) reg [31:0] pll_clk_rst_slr32 = {32{1'b1}};wire mmcm_clk_rst = clk_rst_slr32[31];wire pll_clk_rst = pll_clk_rst_slr32[31];wire ctrl_itf_rst_done, data_itf_rst_done;wire itf_rst_done = ctrl_itf_rst_done & data_itf_rst_done; // byte initialization finishalways @(posedge clk_I) beginclk_rst_slr32 <= {clk_rst_slr32[30:0], clk_rst}; clk_rst <= 1'b0;endalways @(posedge clk_I) beginif (mmcm_clk_locked) beginpll_clk_rst_slr32 <= {pll_clk_rst_slr32[30:0], 1'b0}; end else beginpll_clk_rst_slr32 <= {32{1'b1}};endendIBUFDS IBUFDS_inst (.O(clk_I),   // 1-bit output: Buffer output.I(clk_p),   // 1-bit input: Diff_p buffer input (connect directly to top-level port).IB(clk_n)  // 1-bit input: Diff_n buffer input (connect directly to top-level port)); wire mmcm_clk_CLKFBOUT;MMCME4_BASE #(.BANDWIDTH("OPTIMIZED"),    // Jitter programming.CLKFBOUT_MULT_F(10.0),      // Multiply value for all CLKOUT.CLKFBOUT_PHASE(0.0),       // Phase offset in degrees of CLKFB.CLKIN1_PERIOD(10.0),        // Input clock period in ns to ps resolution (i.e., 33.333 is 30 MHz)..CLKOUT0_DIVIDE_F(6.0),     // Divide amount for CLKOUT0.CLKOUT0_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT0.CLKOUT0_PHASE(0.0),        // Phase offset for CLKOUT0.CLKOUT1_DIVIDE(6),         // Divide amount for CLKOUT (1-128).CLKOUT1_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT1_PHASE(0.0),        // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT2_DIVIDE(1),         // Divide amount for CLKOUT (1-128).CLKOUT2_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT2_PHASE(0.0),        // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT3_DIVIDE(1),         // Divide amount for CLKOUT (1-128).CLKOUT3_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT3_PHASE(0.0),        // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT4_CASCADE("FALSE"),  // Divide amount for CLKOUT (1-128).CLKOUT4_DIVIDE(1),         // Divide amount for CLKOUT (1-128).CLKOUT4_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT4_PHASE(0.0),        // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT5_DIVIDE(1),         // Divide amount for CLKOUT (1-128).CLKOUT5_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT5_PHASE(0.0),        // Phase offset for CLKOUT outputs (-360.000-360.000)..CLKOUT6_DIVIDE(6),         // Divide amount for CLKOUT (1-128).CLKOUT6_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT outputs (0.001-0.999)..CLKOUT6_PHASE(0.0),        // Phase offset for CLKOUT outputs (-360.000-360.000)..DIVCLK_DIVIDE(1),          // Master division value.IS_CLKFBIN_INVERTED(1'b0), // Optional inversion for CLKFBIN.IS_CLKIN1_INVERTED(1'b0),  // Optional inversion for CLKIN1.IS_PWRDWN_INVERTED(1'b0),  // Optional inversion for PWRDWN.IS_RST_INVERTED(1'b0),     // Optional inversion for RST.REF_JITTER1(0.02),          // Reference input jitter in UI (0.000-0.999)..STARTUP_WAIT("FALSE")      // Delays DONE until MMCM is locked)MMCME4_BASE_inst ( // 100MHz to 1000MHz(VCO) -> 166.667MHz.CLKFBOUT(mmcm_clk_CLKFBOUT),   // 1-bit output: Feedback clock pin to the MMCM.CLKFBOUTB(), // 1-bit output: Inverted CLKFBOUT.CLKOUT0(mmcm_clk_o_I),     // 1-bit output: CLKOUT0.CLKOUT0B(),   // 1-bit output: Inverted CLKOUT0.CLKOUT1(),     // 1-bit output: CLKOUT1.CLKOUT1B(),   // 1-bit output: Inverted CLKOUT1.CLKOUT2(),     // 1-bit output: CLKOUT2.CLKOUT2B(),   // 1-bit output: Inverted CLKOUT2.CLKOUT3(),     // 1-bit output: CLKOUT3.CLKOUT3B(),   // 1-bit output: Inverted CLKOUT3.CLKOUT4(),     // 1-bit output: CLKOUT4.CLKOUT5(),     // 1-bit output: CLKOUT5.CLKOUT6(mmcm_clk6_o_I),     // 1-bit output: CLKOUT6.LOCKED(mmcm_clk_locked),       // 1-bit output: LOCK.CLKFBIN(mmcm_clk_CLKFBOUT),     // 1-bit input: Feedback clock pin to the MMCM.CLKIN1(clk_I),       // 1-bit input: Primary clock.PWRDWN(1'b0),       // 1-bit input: Power-down.RST(mmcm_clk_rst)              // 1-bit input: Reset);  BUFGCE #(.CE_TYPE("SYNC"),               // ASYNC, HARDSYNC, SYNC.IS_CE_INVERTED(1'b0),          // Programmable inversion on CE.IS_I_INVERTED(1'b0),           // Programmable inversion on I.SIM_DEVICE("ULTRASCALE_PLUS")  // ULTRASCALE, ULTRASCALE_PLUS)BUFGCE_pll_inst (.O(mmcm_clk_I),   // 1-bit output: Buffer.CE(mmcm_clk_locked), // 1-bit input: Buffer enable.I(mmcm_clk_o_I)    // 1-bit input: Buffer);BUFGCE #(.CE_TYPE("SYNC"),               // ASYNC, HARDSYNC, SYNC.IS_CE_INVERTED(1'b0),          // Programmable inversion on CE.IS_I_INVERTED(1'b0),           // Programmable inversion on I.SIM_DEVICE("ULTRASCALE_PLUS")  // ULTRASCALE, ULTRASCALE_PLUS)BUFGCE_riu_inst (.O(),   // 1-bit output: Buffer.CE(mmcm_clk_locked), // 1-bit input: Buffer enable.I(mmcm_clk6_o_I)    // 1-bit input: Buffer);PLLE4_BASE #(.CLKFBOUT_MULT(8),          // Multiply value for all CLKOUT.CLKFBOUT_PHASE(0.0),       // Phase offset in degrees of CLKFB.CLKIN_PERIOD(6.0),         // Input clock period in ns to ps resolution (i.e., 33.333 is 30 MHz)..CLKOUT0_DIVIDE(8),         // Divide amount for CLKOUT0.CLKOUT0_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT0.CLKOUT0_PHASE(0.0),        // Phase offset for CLKOUT0.CLKOUT1_DIVIDE(4),         // Divide amount for CLKOUT1.CLKOUT1_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT1.CLKOUT1_PHASE(0.0),        // Phase offset for CLKOUT1.CLKOUTPHY_MODE("VCO_2X"),  // Frequency of the CLKOUTPHY.DIVCLK_DIVIDE(1),          // Master division value.IS_CLKFBIN_INVERTED(1'b0), // Optional inversion for CLKFBIN.IS_CLKIN_INVERTED(1'b0),   // Optional inversion for CLKIN.IS_PWRDWN_INVERTED(1'b0),  // Optional inversion for PWRDWN.IS_RST_INVERTED(1'b0),     // Optional inversion for RST.REF_JITTER(0.02),           // Reference input jitter in UI.STARTUP_WAIT("FALSE")      // Delays DONE until PLL is locked)PLLE4_BASE_ctrl_udata_inst ( // 166.667MHz to 2666.6MHz (PHY) and 1333.3/4 MHz (usr_clk).CLKFBOUT(ctrl_udata_pll_clkfbout),       // 1-bit output: Feedback clock.CLKOUT0(ctrl_udata_riu_clk_p), //ctrl_udata_riu_clk_p),         // 1-bit output: General Clock output.CLKOUT0B(), //ctrl_udata_riu_clk_n),       // 1-bit output: Inverted CLKOUT0.CLKOUT1(usr_clk_p),         // 1-bit output: General Clock output 1333.333/8MHz user clock for riu clk(<260MHz).CLKOUT1B(usr_clk_n),       // 1-bit output: Inverted CLKOUT1.CLKOUTPHY(ctrl_udata_pll_clk_I),     // 1-bit output: Bitslice clock.LOCKED(ctrl_udata_pll_clk_locked),           // 1-bit output: LOCK.CLKFBIN(ctrl_udata_pll_clkfbout),         // 1-bit input: Feedback clock.CLKIN(mmcm_clk_I),             // 1-bit input: Input clock.CLKOUTPHYEN(ctrl_udata_pll_phyclk_en), // 1-bit input: CLKOUTPHY enable.PWRDWN(1'b0),           // 1-bit input: Power-down.RST(pll_clk_rst)                  // 1-bit input: Reset);PLLE4_BASE #(.CLKFBOUT_MULT(8),          // Multiply value for all CLKOUT.CLKFBOUT_PHASE(0.0),       // Phase offset in degrees of CLKFB.CLKIN_PERIOD(6.0),         // Input clock period in ns to ps resolution (i.e., 33.333 is 30 MHz)..CLKOUT0_DIVIDE(8),         // Divide amount for CLKOUT0.CLKOUT0_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT0.CLKOUT0_PHASE(0.0),        // Phase offset for CLKOUT0.CLKOUT1_DIVIDE(4),         // Divide amount for CLKOUT1.CLKOUT1_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT1.CLKOUT1_PHASE(0.0),        // Phase offset for CLKOUT1.CLKOUTPHY_MODE("VCO_2X"),  // Frequency of the CLKOUTPHY.DIVCLK_DIVIDE(1),          // Master division value.IS_CLKFBIN_INVERTED(1'b0), // Optional inversion for CLKFBIN.IS_CLKIN_INVERTED(1'b0),   // Optional inversion for CLKIN.IS_PWRDWN_INVERTED(1'b0),  // Optional inversion for PWRDWN.IS_RST_INVERTED(1'b0),     // Optional inversion for RST.REF_JITTER(0.0),           // Reference input jitter in UI.STARTUP_WAIT("FALSE")      // Delays DONE until PLL is locked)PLLE4_BASE_mdata_inst ( // 500MHz to 2666.6MHz (PHY) and 1333.3/4 MHz (usr_clk).CLKFBOUT(mdata_pll_clkfbout),       // 1-bit output: Feedback clock.CLKOUT0(mdata_riu_clk_p),         // 1-bit output: General Clock output.CLKOUT0B(mdata_riu_clk_n),       // 1-bit output: Inverted CLKOUT0.CLKOUT1(),         // 1-bit output: General Clock output 1333.333/8MHz user clock for riu clk(<260MHz).CLKOUT1B(),       // 1-bit output: Inverted CLKOUT1.CLKOUTPHY(mdata_pll_clk_I),     // 1-bit output: Bitslice clock.LOCKED(mdata_pll_clk_locked),           // 1-bit output: LOCK.CLKFBIN(mdata_pll_clkfbout),         // 1-bit input: Feedback clock.CLKIN(mmcm_clk_I),             // 1-bit input: Input clock.CLKOUTPHYEN(mdata_pll_phyclk_en), // 1-bit input: CLKOUTPHY enable.PWRDWN(1'b0),           // 1-bit input: Power-down.RST(pll_clk_rst)                  // 1-bit input: Reset);PLLE4_BASE #(.CLKFBOUT_MULT(8),          // Multiply value for all CLKOUT.CLKFBOUT_PHASE(0.0),       // Phase offset in degrees of CLKFB.CLKIN_PERIOD(6.0),         // Input clock period in ns to ps resolution (i.e., 33.333 is 30 MHz)..CLKOUT0_DIVIDE(8),         // Divide amount for CLKOUT0.CLKOUT0_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT0.CLKOUT0_PHASE(0.0),        // Phase offset for CLKOUT0.CLKOUT1_DIVIDE(4),         // Divide amount for CLKOUT1.CLKOUT1_DUTY_CYCLE(0.5),   // Duty cycle for CLKOUT1.CLKOUT1_PHASE(0.0),        // Phase offset for CLKOUT1.CLKOUTPHY_MODE("VCO_2X"),  // Frequency of the CLKOUTPHY.DIVCLK_DIVIDE(1),          // Master division value.IS_CLKFBIN_INVERTED(1'b0), // Optional inversion for CLKFBIN.IS_CLKIN_INVERTED(1'b0),   // Optional inversion for CLKIN.IS_PWRDWN_INVERTED(1'b0),  // Optional inversion for PWRDWN.IS_RST_INVERTED(1'b0),     // Optional inversion for RST.REF_JITTER(0.02),           // Reference input jitter in UI.STARTUP_WAIT("FALSE")      // Delays DONE until PLL is locked)PLLE4_BASE_ldata_inst ( // 500MHz to 2666.6MHz (PHY) and 1333.3/4 MHz (usr_clk).CLKFBOUT(ldata_pll_clkfbout),       // 1-bit output: Feedback clock.CLKOUT0(ldata_riu_clk_p),         // 1-bit output: General Clock output.CLKOUT0B(ldata_riu_clk_n),       // 1-bit output: Inverted CLKOUT0.CLKOUT1(),         // 1-bit output: General Clock output 1333.333/8MHz user clock for riu clk(<260MHz).CLKOUT1B(),       // 1-bit output: Inverted CLKOUT1.CLKOUTPHY(ldata_pll_clk_I),     // 1-bit output: Bitslice clock.LOCKED(ldata_pll_clk_locked),           // 1-bit output: LOCK.CLKFBIN(ldata_pll_clkfbout),         // 1-bit input: Feedback clock.CLKIN(mmcm_clk_I),             // 1-bit input: Input clock.CLKOUTPHYEN(ldata_pll_phyclk_en), // 1-bit input: CLKOUTPHY enable.PWRDWN(1'b0),           // 1-bit input: Power-down.RST(pll_clk_rst)                  // 1-bit input: Reset);(* srl_style = "srl_reg" *) reg [63:0] pll_clk_rst_fin_slr64 = {64{1'b0}};wire pll_clk_rst_fin = pll_clk_rst_fin_slr64[63];always @(posedge mmcm_clk_I) beginif (ctrl_udata_pll_clk_locked & mdata_pll_clk_locked & ldata_pll_clk_locked) beginpll_clk_rst_fin_slr64[31:0]  <= {pll_clk_rst_fin_slr64[31 - 1 : 0],  1'b1};pll_clk_rst_fin_slr64[63:32] <= {pll_clk_rst_fin_slr64[63 - 1 : 32], pll_clk_rst_fin_slr64[31]};end else beginpll_clk_rst_fin_slr64[31:0]  <= {32{1'b0}};pll_clk_rst_fin_slr64[63:32] <= {32{1'b0}};endendlogic          delay_rst = 0;logic          ctrl_rst = 0;always @(posedge mmcm_clk_I) beginif (pll_clk_rst_fin) beginctrl_udata_pll_phyclk_en    <= 1'b1;mdata_pll_phyclk_en         <= 1'b1;ldata_pll_phyclk_en         <= 1'b1;end else beginctrl_udata_pll_phyclk_en    <= 1'b0;mdata_pll_phyclk_en         <= 1'b0;ldata_pll_phyclk_en         <= 1'b0;endendalways @(posedge mmcm_clk_I) beginif (ctrl_udata_pll_clk_locked & mdata_pll_clk_locked & ldata_pll_clk_locked) begindelay_rst <= 1'b0;ctrl_rst <= 1'b0;end else begindelay_rst <= 1'b1;ctrl_rst <= 1'b1;endendlogic    [7:0]   addr_o_I[16:0];logic    [7:0]   ba_o_I[1:0];logic    [7:0]   bg_o_I;logic    [7:0]   cs_n_o_I[1:0];logic    [7:0]   cke_o_I;logic    [7:0]   act_n_o_I;logic    [7:0]   odt_o_I;logic    [7:0]   ck_o_I;logic    [7:0]   reset_n_o_I;micron_ddr4_ctrl #(.CLK_FREQ(2666.666) // 4 * 333.333) micron_ddr4_ctrl_inst(.pll_clk(ctrl_udata_pll_clk_I),.riu_clk(ctrl_udata_riu_clk_p),.delay_rst(delay_rst), // async.ctrl_rst(ctrl_rst),   // async.itf_rst_done(ctrl_itf_rst_done), //.addr(addr),.ba(ba),.bg(bg),.cke(cke),.cs_n(cs_n[1]),.act_n(act_n),.odt(odt),.ck_t(ck_t),.ck_c(ck_c),.reset_n(reset_n),.addr_o_I(addr_o_I),.ba_o_I(ba_o_I),.bg_o_I(bg_o_I),.cs_n_o_I(cs_n_o_I[1:1]),.cke_o_I(cke_o_I),.act_n_o_I(act_n_o_I),.odt_o_I(odt_o_I),.ck_o_I(ck_o_I),.reset_n_o_I(reset_n_o_I));logic  [3:0]   TRI_TBYTE_IN[8:0];logic  [3:0]   PHY_RDEN[8:0];logic  [3:0]   lo_TRI_TBYTE_IN[8:0];logic  [3:0]   hi_TRI_TBYTE_IN[8:0];reg    [3:0]   lo_PHY_RDEN[8:0],hi_PHY_RDEN[8:0];reg            cs_n_T_IN = 0;logic  [7:0]   dm_dbi_n_o_I[8:0];logic          dm_dbi_n_FIFO_EMPTY[8:0];logic          dm_dbi_n_FIFO_RD_CLK[8:0];logic          dm_dbi_n_FIFO_RD_EN[8:0];logic  [7:0]   dq_o_I[71:0];logic          dq_FIFO_EMPTY[71:0];logic          dq_FIFO_RD_CLK[71:0];logic          dq_FIFO_RD_EN[71:0];logic  [7:0]   dqs_o_I[8:0];logic          dqs_FIFO_EMPTY[8:0];logic          dqs_FIFO_RD_CLK[8:0];logic          dqs_FIFO_RD_EN[8:0];// logic  [7:0]   cs_n_o_I[0:0] = {0};logic  [7:0]   dm_dbi_n_i_I[8:0];logic  [7:0]   dq_i_I[71:0];logic  [7:0]   dqs_i_I[8:0];micron_ddr4_data #(.CLK_FREQ(2666.666) // 4 * 333.333  * 2) micron_ddr4_data_inst (.pll_clk_bank0(ldata_pll_clk_I),.pll_clk_bank1(mdata_pll_clk_I),.pll_clk_bank2(ctrl_udata_pll_clk_I),.riu_clk_bank0(ldata_riu_clk_p), //ldata_riu_clk_p),.riu_clk_bank1(mdata_riu_clk_p), //mdata_riu_clk_p),.riu_clk_bank2(ctrl_udata_riu_clk_p),.delay_rst(delay_rst),.ctrl_rst(ctrl_rst),.itf_rst_done(data_itf_rst_done),.dm_dbi_n(dm_dbi_n),.dq(dq),.dqs_t(dqs_t),.dqs_c(dqs_c),.cs_n(cs_n[0]),.lo_TRI_TBYTE_IN(lo_TRI_TBYTE_IN),.hi_TRI_TBYTE_IN(hi_TRI_TBYTE_IN), .lo_PHY_RDEN(lo_PHY_RDEN),.hi_PHY_RDEN(hi_PHY_RDEN),.cs_n_T_IN(1'b1),.dm_dbi_n_o_I(dm_dbi_n_o_I),.dq_o_I(dq_o_I),.dqs_o_I(dqs_o_I),.cs_n_o_I(cs_n_o_I[0:0]),.dm_dbi_n_i_I(dm_dbi_n_i_I),.dm_dbi_n_FIFO_EMPTY(dm_dbi_n_FIFO_EMPTY),.dm_dbi_n_FIFO_RD_CLK(dm_dbi_n_FIFO_RD_CLK),.dm_dbi_n_FIFO_RD_EN(dm_dbi_n_FIFO_RD_EN),.dq_i_I(dq_i_I),.dq_FIFO_EMPTY(dq_FIFO_EMPTY),.dq_FIFO_RD_CLK(dq_FIFO_RD_CLK),.dq_FIFO_RD_EN(dq_FIFO_RD_EN),.dqs_i_I(dqs_i_I),.dqs_FIFO_EMPTY(dqs_FIFO_EMPTY),.dqs_FIFO_RD_CLK(dqs_FIFO_RD_CLK),.dqs_FIFO_RD_EN(dqs_FIFO_RD_EN));always @(*) beginfor (int j = 0; j < 9; j++) begindm_dbi_n_FIFO_RD_CLK[j] = usr_clk_p;dqs_FIFO_RD_CLK[j] = usr_clk_p;for (int i = 0; i < 8; i++) begindq_FIFO_RD_CLK[8 * j + i] = usr_clk_p;endendendalways @(*) begin // test1 for (int j = 0; j < 9; j++) beginfor (int i = 0; i < 8; i++) begindq_FIFO_RD_EN[8 * j + i] = ~dq_FIFO_EMPTY[8 * j];enddqs_FIFO_RD_EN[j] = ~dq_FIFO_EMPTY[8 * j];dm_dbi_n_FIFO_RD_EN[j] = ~dq_FIFO_EMPTY[8 * j];endend//    always @(posedge usr_clk_p) begin  // follow ug571
//        for (int j = 0; j < 9; j++) begin
//            for (int i = 0; i < 8; i++) begin
//                dq_FIFO_RD_EN[8 * j + i] <= ~dq_FIFO_EMPTY[8 * j];
//            end
//            dqs_FIFO_RD_EN[j] <= ~dq_FIFO_EMPTY[8 * j];
//            dm_dbi_n_FIFO_RD_EN[j] <= ~dq_FIFO_EMPTY[8 * j];
//        end
//    endalways @(*) beginfor (int i = 0; i < 9; i++) beginlo_TRI_TBYTE_IN[i] =   TRI_TBYTE_IN[i];hi_TRI_TBYTE_IN[i] =   TRI_TBYTE_IN[i];lo_PHY_RDEN[i]     =   PHY_RDEN[i];hi_PHY_RDEN[i]     =   PHY_RDEN[i];endendlogic dm_dbi_n_i_valid[8:0], dq_i_valid[71:0], dqs_i_valid[8:0];always @(posedge usr_clk_p) beginfor (int i = 0; i < 9; i++) begindm_dbi_n_i_valid[i] <= dm_dbi_n_FIFO_RD_EN[i];for (int j = 0; j < 8; j++) begindq_i_valid[j + 8 * i] <= dq_FIFO_RD_EN[j + 8 * i];enddqs_i_valid[i] <= dqs_FIFO_RD_EN[i];endendlogic          ram_clk;logic  [29:0]  ram_addr;logic  [575:0] ram_rd_data;logic          ram_en;logic  [575:0] ram_wr_data;logic          ram_wr;logic          ram_rdy;micron_ddr4_fabric micron_ddr4_fabric_inst(.usr_clk(usr_clk_p),.itf_rst_done(itf_rst_done),.TRI_TBYTE_IN(TRI_TBYTE_IN),.PHY_RDEN(PHY_RDEN),.addr_o_data(addr_o_I),.ba_o_data(ba_o_I),.bg_o_data(bg_o_I),.cs_n_o_data(cs_n_o_I),.cke_o_data(cke_o_I),.act_n_o_data(act_n_o_I),.odt_o_data(odt_o_I),.ck_o_data(ck_o_I),.reset_n_o_data(reset_n_o_I),.dm_dbi_n_o_data(dm_dbi_n_o_I),.dq_o_data(dq_o_I),.dqs_o_data(dqs_o_I),.dm_dbi_n_i_data(dm_dbi_n_i_I),.dm_dbi_n_i_valid(dm_dbi_n_i_valid),.dq_i_data(dq_i_I),.dq_i_valid(dq_i_valid),.dqs_i_data(dqs_i_I),.dqs_i_valid(dqs_i_valid),.ram_clk(ram_clk),.ram_addr(ram_addr),.ram_rd_data(ram_rd_data),.ram_en(ram_en),.ram_wr_data(ram_wr_data),.ram_wr(ram_wr),.ram_rdy(ram_rdy));micron_ddr4_usr micron_ddr4_usr_inst(.ram_clk(ram_clk),.ram_addr(ram_addr),.ram_rd_data(ram_rd_data),.ram_en(ram_en),.ram_wr_data(ram_wr_data),.ram_wr(ram_wr),.ram_rdy(ram_rdy));endmodule
  • micron_ddr4_fabric.sv 为控制模块,包含初始化操作,同时根据输入读写指令进行读写操作
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 02/01/2024 05:07:15 PM
// Design Name: 
// Module Name: micron_ddr4_fabric
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//// MT40A512M16LY-075E reference: https://media-www.micron.com/-/media/client/global/documents/products/data-sheet/dram/ddr4/8gb_ddr4_sdram.pdf?rev=74679247a1e24e57b6726071152f1384
// ddr4 2666 16 18-18-18
// 2 bank group, 4 bank, 64k row, 1k column
/*********************************************************************************
* p367 timing parameters
* p41 reset time diagram
* p69 truth table
* tCK(DLL_ON) [0.75ns, 1.9ns]
* tAA   13.50ns
* tRCD  13.50ns
* tRP   13.50ns
*
*********************************************************************************//**************************  MACRO  *********************************************/
//`define TIMEUS_INT(a) int(a * 1000 / CYCLE)
//`define TIMEMS_INT(a) int(a * 1000000 / CYCLE)// vcu128 using five(precisely 4.5) ddr4 chips with x16 datawidth (REF UG1302)
module micron_ddr4_fabric #(parameter   CYCLE       = 3,    // 0.75ns * 4parameter   CYCLE_1US   = 1000 / CYCLE,parameter   CYCLE_1MS   = 1000000 / CYCLE,parameter   tXPR = 360,parameter   tMRD = 6,parameter   tMOD = 18,parameter   tDLLK = 640.5,parameter   tZQinit = 768
) (input usr_clk,input itf_rst_done,output reg  [3:0]   TRI_TBYTE_IN[8:0],output reg  [3:0]   PHY_RDEN[8:0],output reg  [7:0]   addr_o_data[16:0],output reg  [7:0]   ba_o_data[1:0],output reg  [7:0]   bg_o_data,output reg  [7:0]   cs_n_o_data[1:0],output reg  [7:0]   cke_o_data,output reg  [7:0]   act_n_o_data,output reg  [7:0]   odt_o_data,output reg  [7:0]   ck_o_data,output reg  [7:0]   reset_n_o_data,output reg  [7:0]   dm_dbi_n_o_data[8:0],output reg  [7:0]   dq_o_data[71:0],output reg  [7:0]   dqs_o_data[8:0],input       [7:0]   dm_dbi_n_i_data[8:0],input               dm_dbi_n_i_valid[8:0],input       [7:0]   dq_i_data[71:0],input               dq_i_valid[71:0],input       [7:0]   dqs_i_data[8:0],input               dqs_i_valid[8:0],output              ram_clk,input       [29:0]  ram_addr,output  reg [575:0] ram_rd_data,input               ram_en,input       [575:0] ram_wr_data,input               ram_wr,output  reg         ram_rdy);assign ram_clk = usr_clk;function [31:0] TIMENS_INT(input [31:0] a);return (a - CYCLE)/ CYCLE + 1; // ceilendfunctionfunction [31:0] TIMEUS_INT(input [31:0] a);return (1000 * a - CYCLE) / CYCLE + 1; // ceilendfunction(* MARK_DEBUG="true" *) reg [5:0] cs = 0, ns;(* ASYNC_REG="true" *) reg itf_rst_done_ff = 1'b0, itf_rst_done_ff2 = 1'b0;     // riu_clk domain to usr_clk domainreg ddr_reset_fin_r             = 1'b0, ddr_init_fin_r              = 1'b0,ddr_activate_delay_fin_r    = 1'b0,ddr_rd_delay_fin_r          = 1'b0,ddr_rddata_delay_fin_r_all_r      = 1'b0,ddr_wr_delay_fin_r          = 1'b0,ddr_wrdata_delay_fin_r      = 1'b0,ddr_precharge_delay_fin_r   = 1'b0;always @(posedge usr_clk) beginitf_rst_done_ff <= itf_rst_done;itf_rst_done_ff2 <= itf_rst_done_ff;endalways @(posedge usr_clk, negedge itf_rst_done_ff2) beginif (~itf_rst_done_ff2) begin cs <= 0;end else begincs <= ns;endendalways @(*) begincase (cs)0: begin            // hardware io banks resetns = 1;end1: beginns = 2;end2: begin            // ddr resetif (ddr_reset_fin_r) beginns = 3;end else beginns = 2;endend3: begin            // ddr initialization seqif (ddr_init_fin_r) beginns = 4;end else beginns = 3;endend4: begin            // ddr idle statecase ({ram_en, ram_wr})2'b10: ns = 6;2'b11: ns = 10;default: begin// if (ddr_idle_fin_r) begin  // goto refresh//     ns = 5;// end else beginns = 4;// endendendcaseend5: begin            // ddr refreshns = 4;end6: begin            // ddr activate if (ddr_activate_delay_fin_r) beginns = 7;end else beginns = 6;endend7: begin            // ddr send rd commandif (ddr_rd_delay_fin_r) beginns = 8;end else beginns = 7;endend   8: begin            // ddr get dataif (ddr_rddata_delay_fin_r_all_r) beginns = 9;end else beginns = 8;endend9: begin            // ddr prechargeif (ddr_precharge_delay_fin_r) beginns = 4;end else beginns = 9;endend10: begin   // ddr activateif (ddr_activate_delay_fin_r) beginns = 11;end else beginns = 10;endend11: begin   // ddr send wr commandif (ddr_wr_delay_fin_r) beginns = 12;end else beginns = 11;endend12: begin // ddr put datans = 13;end13: begin // ddr put rest datans = 14;end14: begin   // ddr prechargeif (ddr_precharge_delay_fin_r) beginns = 4;end else beginns = 14;endenddefault: beginns = 0;endendcaseend/********************  function definitions begin  *****************************/task io_bank_reset();PHY_RDEN <= {4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000};TRI_TBYTE_IN <= {4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000};for (int i = 0; i < 17; i++) beginaddr_o_data[i]     <= 8'b00000000;endfor (int i = 0; i < 2; i++) beginba_o_data[i]       <= 8'b00000000;endbg_o_data          <= 8'b00000000;for (int i = 0; i < 2; i++) begincs_n_o_data[i]     <= 8'b11111111;endcke_o_data         <= 8'b00000000;act_n_o_data       <= 8'b00000000;odt_o_data         <= 8'b00000000;ck_o_data          <= 8'b00000000;reset_n_o_data     <= 8'b00000000;for (int i = 0; i < 9; i++) begindqs_o_data[i]   <= 8'b00000000;dm_dbi_n_o_data[i] <= 8'b00000000;endfor (int i = 0; i < 72; i++) begindq_o_data[i] <= 8'b00000000;endendtasktask CMD_MRS(input [1:0] _cs_n, input _bg, input [1:0] _ba, input [13:0] _opcode);ck_o_data       <= 8'b10101010;cke_o_data      <= 8'b11111111;for (int i = 0; i < 2; i++) begincs_n_o_data[i] <= {_cs_n[i], _cs_n[i], 6'b111111};endact_n_o_data    <= 8'b11111111;addr_o_data[16] <= 8'b00111111;addr_o_data[15] <= 8'b00111111;addr_o_data[14] <= 8'b00111111;bg_o_data  <= {_bg, _bg, 6'b0};for (int i = 0; i < 2; i++) beginba_o_data[i]  <= {_ba[i], _ba[i], 6'b0};endfor (int i = 0; i < 14; i++) begin addr_o_data[i] <= {_opcode[i], _opcode[i], 6'b0};endendtasktask CMD_DES();ck_o_data       <= 8'b10101010;cke_o_data      <= 8'b11111111;for (int i = 0; i < 2; i++) begincs_n_o_data[i]     <= 8'b11111111;endact_n_o_data    <= 8'b11111111;addr_o_data[16] <= 8'b00111111;addr_o_data[15] <= 8'b00111111;addr_o_data[14] <= 8'b00111111;endtasktask CMD_ZQCL(input [1:0] _cs_n);ck_o_data       <= 8'b10101010;cke_o_data      <= 8'b11111111;for (int i = 0; i < 2; i++) begincs_n_o_data[i] <= {_cs_n[i], _cs_n[i], 6'b111111};endact_n_o_data    <= 8'b11111111;addr_o_data[16] <= 8'b11111111;addr_o_data[15] <= 8'b11111111;addr_o_data[14] <= 8'b00111111;addr_o_data[10] <= 8'b11000000;endtask task CMD_NOP();ck_o_data       <= 8'b10101010;cke_o_data      <= 8'b11111111;for (int i = 0; i < 2; i++) begincs_n_o_data[i]     <= 8'b00111111;endact_n_o_data    <= 8'b11111111;addr_o_data[16] <= 8'b11111111;addr_o_data[15] <= 8'b11111111;addr_o_data[14] <= 8'b11111111;endtasktask CMD_NUL();ck_o_data       <= 8'b10101010;cke_o_data      <= 8'b11111111;for (int i = 0; i < 2; i++) begincs_n_o_data[i]     <= 8'b11111111;endact_n_o_data    <= 8'b11111111;addr_o_data[16] <= 8'b11111111;addr_o_data[15] <= 8'b11111111;addr_o_data[14] <= 8'b11111111;endtasktask CMD_ACT(input _bg, input [1:0] _ba, input [16:0] _ra);ck_o_data       <= 8'b10101010;cke_o_data      <= 8'b11111111;for (int i = 0; i < 2; i++) begincs_n_o_data[i]     <= 8'b00111111;endact_n_o_data    <= 8'b00111111;addr_o_data[16] <= {_ra[16], _ra[16], 6'b111111};addr_o_data[15] <= {_ra[15], _ra[15], 6'b111111};addr_o_data[14] <= {_ra[14], _ra[14], 6'b111111};addr_o_data[12] <= {_ra[13], _ra[13], 6'b111111};addr_o_data[13] <= {_ra[12], _ra[12], 6'b111111};addr_o_data[11] <= {_ra[11], _ra[11], 6'b111111};for (int i = 0; i < 11; i++) beginaddr_o_data[i] <= {_ra[i], _ra[i], 6'b111111};endbg_o_data  <= {_bg, _bg, 6'b0};for (int i = 0; i < 2; i++) beginba_o_data[i]  <= {_ba[i], _ba[i], 6'b0};endendtasktask CMD_WR(input _bg, input [1:0] _ba, input [9:0] _ca);ck_o_data       <= 8'b10101010;cke_o_data      <= 8'b11111111;for (int i = 0; i < 2; i++) begincs_n_o_data[i]     <= 8'b00111111;endact_n_o_data    <= 8'b11111111;addr_o_data[16] <= 8'b11111111;addr_o_data[15] <= {2'b00, 6'b111111};addr_o_data[14] <= {2'b00, 6'b111111};addr_o_data[12] <= {2'bxx, 6'b111111};addr_o_data[13] <= {2'bxx, 6'b111111};addr_o_data[11] <= {2'bxx, 6'b111111};addr_o_data[10] <= {2'b00, 6'b111111};for (int i = 0; i < 10; i++) beginaddr_o_data[i] <= {_ca[i], _ca[i], 6'b111111};endbg_o_data  <= {_bg, _bg, 6'b0};for (int i = 0; i < 2; i++) beginba_o_data[i]  <= {_ba[i], _ba[i], 6'b0};endendtasktask CMD_RD(input _bg, input [1:0] _ba, input [9:0] _ca);ck_o_data       <= 8'b10101010;cke_o_data      <= 8'b11111111;for (int i = 0; i < 2; i++) begincs_n_o_data[i]     <= 8'b00111111;endact_n_o_data    <= 8'b11111111;addr_o_data[16] <= 8'b11111111;addr_o_data[15] <= {2'b00, 6'b111111};addr_o_data[14] <= {2'b11, 6'b111111};addr_o_data[12] <= {2'bxx, 6'b111111};addr_o_data[13] <= {2'bxx, 6'b111111};addr_o_data[11] <= {2'bxx, 6'b111111};addr_o_data[10] <= {2'b00, 6'b111111};for (int i = 0; i < 10; i++) beginaddr_o_data[i] <= {_ca[i], _ca[i], 6'b111111};endbg_o_data  <= {_bg, _bg, 6'b0};for (int i = 0; i < 2; i++) beginba_o_data[i]  <= {_ba[i], _ba[i], 6'b0};endendtasktask CMD_PRE(input _bg, input [1:0] _ba);ck_o_data       <= 8'b10101010;cke_o_data      <= 8'b11111111;for (int i = 0; i < 2; i++) begincs_n_o_data[i]     <= 8'b00111111;endact_n_o_data    <= 8'b11111111;addr_o_data[16] <= 8'b00111111;addr_o_data[15] <= {2'b11, 6'b111111};addr_o_data[14] <= {2'b00, 6'b111111};addr_o_data[12] <= {2'bxx, 6'b111111};addr_o_data[13] <= {2'bxx, 6'b111111};addr_o_data[11] <= {2'bxx, 6'b111111};addr_o_data[10] <= {2'b00, 6'b111111};for (int i = 0; i < 10; i++) beginaddr_o_data[i] <= {2'bxx, 6'b111111};endbg_o_data  <= {_bg, _bg, 6'b0};for (int i = 0; i < 2; i++) beginba_o_data[i]  <= {_ba[i], _ba[i], 6'b0};endendtask/*****************  function definitions end  ***********************//******************  reset related logic start  **********************/reg [31:0] ddr_reset_fin_cnt_r = 32'b0;reg [1:0] ddr_reset_stage_r = 2'b0;always @(posedge usr_clk) begincase (ns)default: beginddr_reset_fin_cnt_r <= TIMEUS_INT(698); //32'b0; //XILINX_SIMULATORend2: beginddr_reset_fin_cnt_r <= ddr_reset_fin_cnt_r + 1;endendcaseendalways @(posedge usr_clk) begin // usr_clk 0.75ns * 4 -> case (ddr_reset_fin_cnt_r)TIMEUS_INT(0): begin // Ta: 0ddr_reset_stage_r <= 2'b00;endTIMEUS_INT(200): begin // Tb: tPW_RESET_L : 200 usddr_reset_stage_r <= 2'b01;endTIMEUS_INT(698): begin // Tc: tPW_RESET_L + 500us - tCKSRX : 700us - min(5CK, 10ns) -> max(699us)ddr_reset_stage_r <= 2'b10;endTIMEUS_INT(699): begin // Td-: tPW_RESET_L + 500us - tIS : 700us - 55ps -> 699usddr_reset_stage_r <= 2'b11;enddefault: beginddr_reset_stage_r <= ddr_reset_stage_r;endendcaseendalways @(posedge usr_clk) begincase (ddr_reset_fin_cnt_r)TIMEUS_INT(700 + 3): begin // Td: 700usddr_reset_fin_r <= 1'b1; enddefault: beginddr_reset_fin_r <= 1'b0;endendcaseend/************************** reset related logic end  ******************//********************** initialization related logic ******************/reg [31:0]  ddr_init_fin_cnt_r      = 32'b0;reg [4:0]   ddr_init_stage_r        = 5'b00000;reg         ddr_init_stage_fresh_r  = 1'b0;always @(posedge usr_clk) begincase (ns)default: beginddr_init_fin_cnt_r <= 32'b0;end3: beginddr_init_fin_cnt_r <= ddr_init_fin_cnt_r + 1;endendcaseendalways @(posedge usr_clk) begincase (ddr_init_fin_cnt_r)TIMENS_INT(tXPR): begin                             // Te : tXPR : min(tRFC1 + 10ns) -> min 360nsddr_init_stage_r        <= 5'b00000;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + tMRD): begin                             // Tf : tXPR + tMRD : 360ns + 8CK -> 366nsddr_init_stage_r        <= 5'b00001;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 2 * tMRD): begin                             // Tg : tXPR + 2 * tMRD -> 372nsddr_init_stage_r        <= 5'b00010;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 3 * tMRD): begin                             // Th : tXPR + 3 * tMRD -> 378nsddr_init_stage_r        <= 5'b00011;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 4 * tMRD): begin                             // Th : tXPR + 4 * tMRD -> 384nsddr_init_stage_r        <= 5'b00100;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 5 * tMRD): begin                             // Th : tXPR + 5 * tMRD -> 390nsddr_init_stage_r        <= 5'b00101;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD): begin                             // Th : tXPR + 6 * tMRD -> 396nsddr_init_stage_r        <= 5'b00110;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tMOD): begin                             // Ti : tXPR + 6 * tMRD + tMOD : min(306ns + max(24nCK, 15ns)) -> 414nsddr_init_stage_r        <= 5'b00111;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tDLLK): begin                           // Tj : tXPR + 6 * tMRD + tDLLK -> 324ns + 854CK -> 1036.5nsddr_init_stage_r        <= 5'b01000;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tMOD + tZQinit): begin                             // Tk : tXPR + 6 * tMRD + tMOD + tZQinit : 324ns + 1024CK -> 1182nsddr_init_stage_r        <= 5'b10000;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tMOD + tZQinit + tMRD): begin                             // T0 : Tk + tMRD : 1092ns + 8CK -> 1188nsddr_init_stage_r        <= 5'b10001;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tMOD + tZQinit + 2 * tMRD): begin                             // T1 : Tk + 2 * tMRD -> 1194nsddr_init_stage_r        <= 5'b10010;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tMOD + tZQinit + 3 * tMRD): begin                             // T2 : Tk + 3 * tMRD -> 1200nsddr_init_stage_r        <= 5'b10011;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tMOD + tZQinit + 4 * tMRD): begin                             // T3 : Tk + 4 * tMRD -> 1206nsddr_init_stage_r        <= 5'b10100;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tMOD + tZQinit + 5 * tMRD): begin                             // T4 : Tk + 5 * tMRD -> 1212nsddr_init_stage_r        <= 5'b10101;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tMOD + tZQinit + 6 * tMRD): begin                             // T5 : Tk + 6 * tMRD -> 1218nsddr_init_stage_r        <= 5'b10110;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tMOD + tZQinit + 6 * tMRD + tMOD): begin                             // T6 : Tk + 6 * tMRD + tMOD : min(1128ns + max(24nCK, 15ns)) -> 1236nsddr_init_stage_r        <= 5'b10111;ddr_init_stage_fresh_r  <= 1'b1;endTIMENS_INT(tXPR + 6 * tMRD + tMOD + tZQinit + 6 * tMRD + tDLLK): begin                           // T7 : Tk + 6 * tMRD + tDLLK -> 1128ns + 854CK -> 1840.5nsddr_init_stage_r        <= 5'b11000;ddr_init_stage_fresh_r  <= 1'b1;enddefault: beginddr_init_stage_r        <= ddr_init_stage_r;ddr_init_stage_fresh_r  <= 1'b0;endendcaseendalways @(posedge usr_clk) begincase (ddr_init_fin_cnt_r)TIMENS_INT(tXPR + 6 * tMRD + tMOD + tZQinit + 6 * tMRD + tMOD + tZQinit): begin                             // T9 : T0 + 6 * tMRD + tMOD + tZQinit : 1146ns + 1024CK -> 2004nsddr_init_fin_r <= 1'b1;enddefault: beginddr_init_fin_r <= 1'b0;endendcaseend/************  initialization related logic end  *********************//************  activate related logic start  *********************/reg [31:0]  ddr_activate_delay_fin_cnt_r    = 32'b0;reg         ddr_activate_delay_fresh_r      = 1'b0;always @(posedge usr_clk) begincase (ns)default: beginddr_activate_delay_fin_cnt_r <= 32'b0;end6, 10: beginddr_activate_delay_fin_cnt_r <= ddr_activate_delay_fin_cnt_r + 1;endendcaseendalways @(posedge usr_clk) begincase (ddr_activate_delay_fin_cnt_r)1: beginddr_activate_delay_fresh_r <= 1'b1;ddr_activate_delay_fin_r <= 1'b0;end10: begin    // tRCD-ALddr_activate_delay_fresh_r <= 1'b0;ddr_activate_delay_fin_r <= 1'b1;enddefault: beginddr_activate_delay_fresh_r <= 1'b0;ddr_activate_delay_fin_r <= 1'b0;endendcaseend
/************  activate related logic end  *********************//************  rd related logic start  *********************/reg [31:0]  ddr_rd_delay_fin_cnt_r  = 32'b0;reg         ddr_rd_delay_fresh_r    = 1'b0;always @(posedge usr_clk) begincase (ns)default: beginddr_rd_delay_fin_cnt_r <= 32'b0;end7: beginddr_rd_delay_fin_cnt_r <= ddr_rd_delay_fin_cnt_r + 1;endendcaseendalways @(posedge usr_clk) begincase (ddr_rd_delay_fin_cnt_r)1: beginddr_rd_delay_fresh_r <= 1'b1;ddr_rd_delay_fin_r <= 1'b0;end4: beginddr_rd_delay_fresh_r <= 1'b0;ddr_rd_delay_fin_r <= 1'b1;enddefault: beginddr_rd_delay_fresh_r <= 1'b0;ddr_rd_delay_fin_r <= 1'b0;endendcaseend
/************  rd related logic end  *********************//************  rddata related logic start  *********************/reg [31:0]  ddr_rddata_delay_fin_cnt_r[71:0];reg [71:0]  ddr_rddata_delay_fresh_r;reg [71:0]  ddr_rddata_delay_fin_r;generate for (genvar i = 0; i < 72; i++) begininitial beginddr_rddata_delay_fin_cnt_r[i] = 1'b0;ddr_rddata_delay_fresh_r[i] = 1'b0;ddr_rddata_delay_fin_r[i] = 1'b0;endalways @(posedge usr_clk) begincase (ns)default: beginddr_rddata_delay_fin_cnt_r[i] <= 32'b0;end8: beginif (dq_i_valid[i]) beginddr_rddata_delay_fin_cnt_r[i] <= ddr_rddata_delay_fin_cnt_r[i] + 1;endendendcaseendalways @(posedge usr_clk) beginif (ddr_rddata_delay_fin_cnt_r[i] == 3'd0 && dq_i_valid[i] == 1'b1) beginddr_rddata_delay_fin_r[i] <= 1'b1; end else beginddr_rddata_delay_fin_r[i] <= 1'b0;endfor (int j = 0; j < 8; j++) beginif (dq_i_valid[i]) beginram_rd_data[8 * i + j] <= dq_i_data[i][j];endendendendendgeneratealways @(posedge usr_clk) beginif (ddr_rddata_delay_fin_r == 72'b111111111111111111111111111111111111111111111111111111111111111111111111) beginddr_rddata_delay_fin_r_all_r <= 1'b1;end else beginddr_rddata_delay_fin_r_all_r <= 1'b0;endend
/************  rddata related logic end  *********************//************  precharge related logic start  *********************/reg [31:0]  ddr_precharge_delay_fin_cnt_r  = 32'b0;reg         ddr_precharge_delay_fresh_r    = 1'b0;always @(posedge usr_clk) begincase (ns)default: beginddr_precharge_delay_fin_cnt_r <= 32'b0;end9, 14: beginddr_precharge_delay_fin_cnt_r <= ddr_precharge_delay_fin_cnt_r + 1;endendcaseendalways @(posedge usr_clk) begincase (ddr_precharge_delay_fin_cnt_r)1: beginddr_precharge_delay_fresh_r <= 1'b0;ddr_precharge_delay_fin_r <= 1'b0;end31: beginddr_precharge_delay_fresh_r <= 1'b1;ddr_precharge_delay_fin_r <= 1'b0;end61: beginddr_precharge_delay_fresh_r <= 1'b0;ddr_precharge_delay_fin_r <= 1'b1;enddefault: beginddr_precharge_delay_fresh_r <= 1'b0;ddr_precharge_delay_fin_r <= 1'b0;endendcaseend
/************  precharge related logic end  *********************//************  wr related logic start  *********************/reg [31:0]  ddr_wr_delay_fin_cnt_r  = 32'b0;reg         ddr_wr_delay_fresh_r    = 1'b0;always @(posedge usr_clk) begincase (ns)default: beginddr_wr_delay_fin_cnt_r <= 32'b0;end11: beginddr_wr_delay_fin_cnt_r <= ddr_wr_delay_fin_cnt_r + 1;endendcaseendalways @(posedge usr_clk) begincase (ddr_wr_delay_fin_cnt_r)1: beginddr_wr_delay_fresh_r <= 1'b1;ddr_wr_delay_fin_r <= 1'b0;end4: begin // tCCD_L(WR)ddr_wr_delay_fresh_r <= 1'b0;ddr_wr_delay_fin_r <= 1'b1;enddefault: beginddr_wr_delay_fresh_r <= 1'b0;ddr_wr_delay_fin_r <= 1'b0;endendcaseend
/************  wr related logic end  *********************//************  wrdata related logic start  *********************/reg [31:0]  ddr_wrdata_delay_fin_cnt_r  = 32'b0;reg         ddr_wrdata_delay_fresh_r    = 1'b0;always @(posedge usr_clk) begincase (ns)default: beginddr_wrdata_delay_fin_cnt_r <= 32'b0;end12: beginddr_wrdata_delay_fin_cnt_r <= ddr_wrdata_delay_fin_cnt_r + 1;endendcaseendalways @(posedge usr_clk) begincase (ddr_wrdata_delay_fin_cnt_r)1: beginddr_wrdata_delay_fresh_r <= 1'b1;ddr_wrdata_delay_fin_r <= 1'b0;end20: begin   // tRASddr_wrdata_delay_fresh_r <= 1'b0;ddr_wrdata_delay_fin_r <= 1'b1;enddefault: beginddr_wrdata_delay_fresh_r <= 1'b0;ddr_wrdata_delay_fin_r <= 1'b0;endendcaseend
/************  wrdata related logic end  *********************//************  ram ready indicator logic start  ****************/always @(posedge usr_clk) begincase (ns)default: ram_rdy <= 1'b0;4: ram_rdy <= 1'b1;endcaseend/************  ram ready indicator logic end  ****************//************  wrdata logic start  ****************/always @(posedge usr_clk) begincase (ns)12: beginfor (int i = 0; i < 9; i++) begindqs_o_data[i]   <= 8'b10101010;dm_dbi_n_o_data[i] <= 8'b11111111;PHY_RDEN[i] <= 4'b0001;TRI_TBYTE_IN[i] <= 4'b1110;endfor (int i = 0; i < 72; i++) begindq_o_data[i] <= {ram_wr_data[8 * i + 5], ram_wr_data[8 * i + 4], ram_wr_data[8 * i + 3], ram_wr_data[8 * i + 2], ram_wr_data[8 * i + 1], ram_wr_data[8 * i + 0], ram_wr_data[8 * i + 7], ram_wr_data[8 * i + 6]}; //  8'b11100101};endend13: beginfor (int i = 0; i < 9; i++) beginPHY_RDEN[i] <= 4'b1100;TRI_TBYTE_IN[i] <= 4'b0011;endenddefault: beginfor (int i = 0; i < 9; i++) beginPHY_RDEN[i] <= 4'b1111;TRI_TBYTE_IN[i] <= 4'b0000;endendendcaseend/************  wrdata logic end  ****************/always @(posedge usr_clk, negedge itf_rst_done_ff2) begin // cdcif (~itf_rst_done_ff2) beginio_bank_reset();end else begincase (ns)0, 1: beginio_bank_reset();end2: beginPHY_RDEN <= {4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000};TRI_TBYTE_IN <= {4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000};case (ddr_reset_stage_r)2'b00: beginck_o_data       <= 8'b00000000;reset_n_o_data  <= 8'b00000000;cke_o_data      <= 8'b00000000;end2'b01: beginck_o_data       <= 8'b00000000;reset_n_o_data  <= 8'b11111111;cke_o_data      <= 8'b00000000;end2'b10: beginck_o_data       <= 8'b10101010;reset_n_o_data  <= 8'b11111111;cke_o_data      <= 8'b00000000;end2'b11: begin                        CMD_DES();endendcaseend3: beginPHY_RDEN <= {4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000};TRI_TBYTE_IN <= {4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000, 4'b0000};if (ddr_init_stage_fresh_r) begincase (ddr_init_stage_r)5'b00000: beginCMD_MRS(2'b10, 1'b0, 2'b11, 14'h0400);end5'b00001: beginCMD_MRS(2'b10, 1'b1, 2'b10, 14'h0c14);end5'b00010: beginCMD_MRS(2'b10, 1'b1, 2'b01, 14'h0000);end5'b00011: beginCMD_MRS(2'b10, 1'b1, 2'b00, 14'h0000);end5'b00100: beginCMD_MRS(2'b10, 1'b0, 2'b10, 14'h0020);end5'b00101: beginCMD_MRS(2'b10, 1'b0, 2'b01, 14'h0301);end5'b00110: beginCMD_MRS(2'b10, 1'b0, 2'b00, 14'h0b40);end5'b00111: beginCMD_ZQCL(2'b10);end5'b01000: beginCMD_DES();end5'b10000: beginCMD_MRS(2'b01, 1'b0, 2'b11, 14'h0400);end5'b10001: beginCMD_MRS(2'b01, 1'b1, 2'b01, 14'h240c);end5'b10010: beginCMD_MRS(2'b01, 1'b1, 2'b10, 14'h0000);end5'b10011: beginCMD_MRS(2'b01, 1'b1, 2'b00, 14'h0000);end5'b10100: beginCMD_MRS(2'b01, 1'b0, 2'b01, 14'h0040);end5'b10101: beginCMD_MRS(2'b01, 1'b0, 2'b10, 14'h0281);end5'b10110: beginCMD_MRS(2'b01, 1'b0, 2'b00, 14'h22a0);end5'b10111: beginCMD_ZQCL(2'b01);end5'b11000: beginCMD_DES();endendcaseend else begin // NOP commandCMD_NUL();endend4: beginCMD_NUL();end6: beginif (ddr_activate_delay_fresh_r) beginCMD_ACT(ram_addr[19], ram_addr[18:17], ram_addr[16:0]);end else beginCMD_NUL();endend7: beginif (ddr_rd_delay_fresh_r) beginCMD_RD(ram_addr[19], ram_addr[18:17], ram_addr[29:20]);end else beginCMD_NUL();endend8: beginCMD_NUL();end9: beginif (ddr_precharge_delay_fresh_r) beginCMD_PRE(ram_addr[19], ram_addr[18:17]);end else beginCMD_NUL();endend10: beginif (ddr_activate_delay_fresh_r) beginCMD_ACT(ram_addr[19], ram_addr[18:17], ram_addr[16:0]);end else beginCMD_NUL();endend11: beginif (ddr_wr_delay_fresh_r) beginCMD_WR(ram_addr[19], ram_addr[18:17], ram_addr[29:20]);end else beginCMD_NUL();endend12, 13: beginCMD_NUL();end14: beginif (ddr_precharge_delay_fresh_r) beginCMD_PRE(ram_addr[19], ram_addr[18:17]);end else beginCMD_NUL();endendendcaseendendendmodule
  • micron_ddr4_usr.sv 为输入读写指令生成模块,这里在确认ddr初始化完成后进行了一次写操作和一次读操作。
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 03/05/2024 11:23:10 PM
// Design Name: 
// Module Name: micron_ddr4_usr
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module micron_ddr4_usr(input               ram_clk,output  reg [29:0]  ram_addr,input       [575:0] ram_rd_data,output  reg         ram_en,output  reg [575:0] ram_wr_data,output  reg         ram_wr,input               ram_rdy);initial beginram_addr = 32'b0;ram_en = 1'b0;ram_wr_data = 'd0;ram_wr = 1'b0;end(* MARK_DEBUG="true" *) reg [5:0] state_r = 'd0, state_s;always @(posedge ram_clk) beginstate_r <= state_s;endalways @(*) begincase (state_r)0: beginif (ram_rdy) beginstate_s = 1;end else beginstate_s = 0;endend1: beginstate_s = 2;end2: beginif (ram_rdy) state_s = 3;else         state_s = 2;end3: beginstate_s = 4;end4: state_s = 4;default: state_s = 0;endcaseendalways @(posedge ram_clk) begincase (state_s)0: beginram_addr    <= 30'h0;ram_en      <= 1'b0;ram_wr      <= 1'b0;ram_wr_data <= 'd0;end1: beginram_en      <= 1'b1;ram_wr      <= 1'b1;ram_wr_data  <= 576'h574a48776a68;end2: beginram_en      <= 1'b0;end3: beginram_en      <= 1'b1;ram_wr      <= 1'b0;end4: beginram_en      <= 1'b0;endendcaseendendmodule
  • const.xdc 约束文件,包含DDR4引脚约束及用于时序收敛添加的约束
set_property PACKAGE_PIN BH51 [get_ports clk_p]
set_property IOSTANDARD LVDS [get_ports clk_p]
set_property IOSTANDARD LVDS [get_ports clk_n]set_property IOSTANDARD POD12_DCI [get_ports {dq[7]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[6]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[5]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[4]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[3]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[2]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[1]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[0]}]set_property IOSTANDARD POD12_DCI [get_ports {dm_dbi_n[8]}]
set_property IOSTANDARD POD12_DCI [get_ports {dm_dbi_n[7]}]
set_property IOSTANDARD POD12_DCI [get_ports {dm_dbi_n[6]}]
set_property IOSTANDARD POD12_DCI [get_ports {dm_dbi_n[5]}]
set_property IOSTANDARD POD12_DCI [get_ports {dm_dbi_n[4]}]
set_property IOSTANDARD POD12_DCI [get_ports {dm_dbi_n[3]}]
set_property IOSTANDARD POD12_DCI [get_ports {dm_dbi_n[2]}]
set_property IOSTANDARD POD12_DCI [get_ports {dm_dbi_n[1]}]
set_property IOSTANDARD POD12_DCI [get_ports {dm_dbi_n[0]}]set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_c[8]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_c[7]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_c[6]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_c[5]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_c[4]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_c[3]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_c[2]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_c[1]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_c[0]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_t[8]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_t[7]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_t[6]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_t[5]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_t[4]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_t[3]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_t[2]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_t[1]}]
set_property IOSTANDARD DIFF_POD12_DCI [get_ports {dqs_t[0]}]#set_property PACKAGE_PIN BM28 [get_ports dm_dbi_n]
#set_property PACKAGE_PIN BN29 [get_ports dqs_t]
create_clock -period 10.000 -name ddr4_clk -waveform {0.000 5.000} [get_ports clk_p]# set_false_path -from [get_pins micron_ddr4_data_inst/BITSLICE_CONTROL_hi_halfbyte_inst/RIU_CLK] -to [get_pins micron_ddr4_data_inst/hi_DLY_RDY_ff_reg/D]
# set_false_path -from [get_pins micron_ddr4_data_inst/BITSLICE_CONTROL_lo_halfbyte_inst/RIU_CLK] -to [get_pins micron_ddr4_data_inst/lo_DLY_RDY_ff_reg/D]
# set_false_path -from [get_cells *BITSLICE_CONTROL_.*_inst] -to [get_cells *DLY_RDY_ff_reg]set_property PACKAGE_PIN BK48 [get_ports {cs_n[1]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {cs_n[1]}]
set_property PACKAGE_PIN BH49 [get_ports {odt[0]}]
set_property PACKAGE_PIN BH50 [get_ports reset_n]
set_property IOSTANDARD LVCMOS12 [get_ports reset_n]
set_property IOSTANDARD SSTL12_DCI [get_ports {odt[0]}]
set_property PACKAGE_PIN BG52 [get_ports act_n]
set_property PACKAGE_PIN BH52 [get_ports {cke[0]}]
set_property PACKAGE_PIN BK53 [get_ports {ck_t[0]}]
set_property PACKAGE_PIN BH54 [get_ports {addr[15]}]
set_property PACKAGE_PIN BJ54 [get_ports {addr[16]}]
set_property PACKAGE_PIN BG53 [get_ports {addr[14]}]
set_property PACKAGE_PIN BG54 [get_ports {bg[0]}]
set_property PACKAGE_PIN BE53 [get_ports {ba[1]}]
set_property PACKAGE_PIN BE54 [get_ports {ba[0]}]
set_property PACKAGE_PIN BF53 [get_ports {addr[6]}]
set_property IOSTANDARD SSTL12_DCI [get_ports act_n]
set_property IOSTANDARD SSTL12_DCI [get_ports {cke[0]}]
set_property IOSTANDARD DIFF_SSTL12_DCI [get_ports {ck_t[0]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[15]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[16]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[14]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {bg[0]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {ba[1]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {ba[0]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[6]}]
set_property PACKAGE_PIN BG48 [get_ports {addr[2]}]
set_property PACKAGE_PIN BG49 [get_ports {addr[11]}]
set_property PACKAGE_PIN BF50 [get_ports {addr[0]}]
set_property PACKAGE_PIN BG50 [get_ports {addr[7]}]
set_property PACKAGE_PIN BF51 [get_ports {addr[8]}]
set_property PACKAGE_PIN BF52 [get_ports {addr[13]}]
set_property PACKAGE_PIN BF47 [get_ports {addr[10]}]
set_property PACKAGE_PIN BF48 [get_ports {addr[12]}]
set_property PACKAGE_PIN BE49 [get_ports {addr[4]}]
set_property PACKAGE_PIN BE50 [get_ports {addr[3]}]
set_property PACKAGE_PIN BD51 [get_ports {addr[1]}]
set_property PACKAGE_PIN BE51 [get_ports {addr[5]}]
set_property PACKAGE_PIN BG47 [get_ports {addr[9]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[2]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[11]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[0]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[7]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[8]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[13]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[10]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[12]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[4]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[3]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[1]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[5]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {addr[9]}]set_property PACKAGE_PIN BP49 [get_ports {cs_n[0]}]
set_property IOSTANDARD SSTL12_DCI [get_ports {cs_n[0]}]
set_property DRIVE 8 [get_ports reset_n]set_property PACKAGE_PIN BM28 [get_ports {dm_dbi_n[4]}]
set_property PACKAGE_PIN BP28 [get_ports {dq[35]}]
set_property PACKAGE_PIN BP29 [get_ports {dq[33]}]
set_property PACKAGE_PIN BN31 [get_ports {dq[38]}]
set_property PACKAGE_PIN BP31 [get_ports {dq[34]}]
set_property PACKAGE_PIN BN29 [get_ports {dqs_t[4]}]
set_property PACKAGE_PIN BL30 [get_ports {dq[39]}]
set_property PACKAGE_PIN BM30 [get_ports {dq[37]}]
set_property PACKAGE_PIN BN32 [get_ports {dq[36]}]
set_property PACKAGE_PIN BP32 [get_ports {dq[32]}]
set_property PACKAGE_PIN BM34 [get_ports {dm_dbi_n[5]}]
set_property PACKAGE_PIN BN34 [get_ports {dq[42]}]
set_property PACKAGE_PIN BP34 [get_ports {dq[41]}]
set_property PACKAGE_PIN BL32 [get_ports {dq[40]}]
set_property PACKAGE_PIN BM33 [get_ports {dq[46]}]
set_property PACKAGE_PIN BL35 [get_ports {dqs_t[5]}]
set_property PACKAGE_PIN BK31 [get_ports {dq[47]}]
set_property PACKAGE_PIN BL31 [get_ports {dq[44]}]
set_property PACKAGE_PIN BK33 [get_ports {dq[43]}]
set_property PACKAGE_PIN BL33 [get_ports {dq[45]}]
set_property PACKAGE_PIN BH32 [get_ports {dm_dbi_n[6]}]
set_property PACKAGE_PIN BJ33 [get_ports {dq[52]}]
set_property PACKAGE_PIN BJ34 [get_ports {dq[48]}]
set_property PACKAGE_PIN BG34 [get_ports {dq[54]}]
set_property PACKAGE_PIN BG35 [get_ports {dq[49]}]
set_property PACKAGE_PIN BK34 [get_ports {dqs_t[6]}]
set_property PACKAGE_PIN BF35 [get_ports {dq[53]}]
set_property PACKAGE_PIN BF36 [get_ports {dq[55]}]
set_property PACKAGE_PIN BH34 [get_ports {dq[50]}]
set_property PACKAGE_PIN BH35 [get_ports {dq[51]}]
set_property PACKAGE_PIN BG29 [get_ports {dm_dbi_n[7]}]
set_property PACKAGE_PIN BH29 [get_ports {dq[62]}]
set_property PACKAGE_PIN BH30 [get_ports {dq[57]}]
set_property PACKAGE_PIN BF31 [get_ports {dq[56]}]
set_property PACKAGE_PIN BG32 [get_ports {dq[59]}]
set_property PACKAGE_PIN BJ29 [get_ports {dqs_t[7]}]
set_property PACKAGE_PIN BF32 [get_ports {dq[61]}]
set_property PACKAGE_PIN BF33 [get_ports {dq[63]}]
set_property PACKAGE_PIN BH31 [get_ports {dq[60]}]
set_property PACKAGE_PIN BJ31 [get_ports {dq[58]}]
set_property PACKAGE_PIN BN42 [get_ports {dm_dbi_n[0]}]
set_property PACKAGE_PIN BN47 [get_ports {dq[6]}]
set_property PACKAGE_PIN BP47 [get_ports {dq[2]}]
set_property PACKAGE_PIN BP43 [get_ports {dq[7]}]
set_property PACKAGE_PIN BP44 [get_ports {dq[1]}]
set_property PACKAGE_PIN BN46 [get_ports {dqs_t[0]}]
set_property PACKAGE_PIN BM44 [get_ports {dq[4]}]
set_property PACKAGE_PIN BN44 [get_ports {dq[5]}]
set_property PACKAGE_PIN BM45 [get_ports {dq[0]}]
set_property PACKAGE_PIN BN45 [get_ports {dq[3]}]
set_property PACKAGE_PIN BL47 [get_ports {dm_dbi_n[1]}]
set_property PACKAGE_PIN BL45 [get_ports {dq[8]}]
set_property PACKAGE_PIN BL46 [get_ports {dq[10]}]
set_property PACKAGE_PIN BL42 [get_ports {dq[14]}]
set_property PACKAGE_PIN BL43 [get_ports {dq[12]}]
set_property PACKAGE_PIN BK45 [get_ports {dqs_t[1]}]
set_property PACKAGE_PIN BK43 [get_ports {dq[11]}]
set_property PACKAGE_PIN BK44 [get_ports {dq[9]}]
set_property PACKAGE_PIN BJ43 [get_ports {dq[15]}]
set_property PACKAGE_PIN BJ44 [get_ports {dq[13]}]
set_property PACKAGE_PIN BH42 [get_ports {dm_dbi_n[2]}]
set_property PACKAGE_PIN BH44 [get_ports {dq[19]}]
set_property PACKAGE_PIN BH45 [get_ports {dq[20]}]
set_property PACKAGE_PIN BJ41 [get_ports {dq[23]}]
set_property PACKAGE_PIN BK41 [get_ports {dq[16]}]
set_property PACKAGE_PIN BH46 [get_ports {dqs_t[2]}]
set_property PACKAGE_PIN BG42 [get_ports {dq[18]}]
set_property PACKAGE_PIN BG43 [get_ports {dq[22]}]
set_property PACKAGE_PIN BG44 [get_ports {dq[17]}]
set_property PACKAGE_PIN BG45 [get_ports {dq[21]}]
set_property PACKAGE_PIN BD41 [get_ports {dm_dbi_n[3]}]
set_property PACKAGE_PIN BF45 [get_ports {dq[29]}]
set_property PACKAGE_PIN BF46 [get_ports {dq[31]}]
set_property PACKAGE_PIN BF42 [get_ports {dq[25]}]
set_property PACKAGE_PIN BF43 [get_ports {dq[27]}]
set_property PACKAGE_PIN BE45 [get_ports {dqs_t[3]}]
set_property PACKAGE_PIN BC42 [get_ports {dq[26]}]
set_property PACKAGE_PIN BD42 [get_ports {dq[28]}]
set_property PACKAGE_PIN BE43 [get_ports {dq[24]}]
set_property PACKAGE_PIN BE44 [get_ports {dq[30]}]
set_property PACKAGE_PIN BP48 [get_ports {dm_dbi_n[8]}]
set_property PACKAGE_PIN BN50 [get_ports {dq[66]}]
set_property PACKAGE_PIN BN51 [get_ports {dq[64]}]
set_property PACKAGE_PIN BM48 [get_ports {dq[68]}]
set_property PACKAGE_PIN BN49 [get_ports {dq[70]}]
set_property PACKAGE_PIN BM49 [get_ports {dqs_t[8]}]
set_property PACKAGE_PIN BL51 [get_ports {dq[71]}]
set_property PACKAGE_PIN BM52 [get_ports {dq[65]}]
set_property PACKAGE_PIN BL52 [get_ports {dq[67]}]
set_property PACKAGE_PIN BL53 [get_ports {dq[69]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[71]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[70]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[69]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[68]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[67]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[66]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[65]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[64]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[63]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[62]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[61]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[60]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[59]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[58]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[57]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[56]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[55]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[54]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[53]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[52]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[51]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[50]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[49]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[48]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[47]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[46]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[45]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[44]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[43]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[42]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[41]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[40]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[39]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[38]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[37]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[36]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[35]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[34]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[33]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[32]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[31]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[30]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[29]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[28]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[27]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[26]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[25]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[24]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[23]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[22]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[21]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[20]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[19]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[18]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[17]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[16]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[15]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[14]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[13]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[12]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[11]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[10]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[9]}]
set_property IOSTANDARD POD12_DCI [get_ports {dq[8]}]# set_false_path -through [get_pins -hierarchical -regexp .*byte_inst/DLY_RDY.*]
# set_false_path -through [get_pins -hierarchical -regexp .*byte_inst/VTC_RDY.*]# set_property LOC MMCM_X0Y1 [get_cells MMCME4_BASE_inst]
set_property LOC PLL_X0Y4 [get_cells PLLE4_BASE_ctrl_udata_inst]
set_property LOC PLL_X0Y2 [get_cells PLLE4_BASE_mdata_inst]
set_property LOC PLL_X0Y0 [get_cells PLLE4_BASE_ldata_inst]# wpws closure
set_property LOC BUFGCE_X0Y4 [get_cells ldata_riu_clk_p_BUFG_inst] set_clock_groups -name mdata_clock_group -asynchronous -group [get_clocks -of_objects [get_pins PLLE4_BASE_mdata_inst/CLKOUT0]] -group [get_clocks -of_objects [get_pins PLLE4_BASE_mdata_inst/CLKOUTPHY]]
set_clock_groups -name ldata_clock_group -asynchronous -group [get_clocks -of_objects [get_pins PLLE4_BASE_ldata_inst/CLKOUT0]] -group [get_clocks -of_objects [get_pins PLLE4_BASE_ldata_inst/CLKOUTPHY]]
set_clock_groups -name ctrl_udata_clock_group -asynchronous -group [get_clocks -of_objects [get_pins PLLE4_BASE_ctrl_udata_inst/CLKOUT0]] -group [get_clocks -of_objects [get_pins PLLE4_BASE_ctrl_udata_inst/CLKOUTPHY]]

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

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

相关文章

OpenCV实战--人脸识别的三种方法(人脸识别具体到某个人)

1、前言 Opencv 中提供了三种人脸识别的方法,分别是 Eigenfaces、Fisherfaces和LBPH 三种方法都是通过对比样本特征最终实现人脸识别 因为三种算法特征提取的方式不一样,侧重点均有不同,并不能说那种方式优越,这里对三种方法进行讲解和实验 这里类似于深度学习模式,通过…

CSS 弹性盒子模型

CSS3弹性盒内容 弹性盒子由弹性容器(Flex container)和弹性子元素(Flex item)组成弹性容器通过设置display属性的值为flex将其定义为弹性容器弹性容器内包含了一个或多个弹性子元素 温馨提示&#xff1a;弹性容器外及弹性子元素内是正常渲染的。弹性盒子只定义了弹性子元素如何…

记事小本本

记事小本本 实现效果 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</titl…

【Linux进阶之路】HTTP协议

文章目录 一、基本概念1.HTTP2.域名3.默认端口号4.URL 二、请求与响应1.抓包工具2.基本框架3.简易实现3.1 HttpServer3.2 HttpRequest3.2.1 version13.2.2 version23.2.3 version3 总结尾序 一、基本概念 常见的应用层协议&#xff1a; HTTPS (HyperText Transfer Protocol Sec…

DVWA靶场-暴力破解

DVWA是一个适合新手锻炼的靶机&#xff0c;是由PHP/MySQL组成的 Web应用程序&#xff0c;帮助大家了解web应用的攻击手段 DVWA大致能分成以下几个模块&#xff0c;包含了OWASP Top 10大主流漏洞环境。 Brute Force——暴力破解 Command Injection——命令注入 CSRF——跨站请…

JVM内存结构介绍

1. 什么是JVM 我们都知道在 Windows 系统上一个软件包装包是 exe 后缀的&#xff0c;而这个软件包在苹果的 Mac OSX 系统上是无法安装的。类似地&#xff0c;Mac OSX 系统上软件安装包则是 dmg 后缀&#xff0c;同样无法在 Windows 系统上安装。 Java 代码为什么可以在 Windows…

2024年了,SEO优化是不是已经穷途末路了呢?(川圣SEO)蜘蛛池

baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; 2024年了&#xff0c;SEO优化是不是已经穷途末路了呢&#xff1f;#蜘蛛池SEO SEO优化并没有穷途末路。虽然随…

element---tree树形结构(返回的数据与官方的不一样)

项目中要用到属性结构数据&#xff0c;后端返回的数据不是官方默认的数据结构&#xff1a; <el-tree:data"treeData":filter-node-method"filterNode":props"defaultProps"node-click"handleNodeClick"></el-tree>这是文档…

算法练习:二分查找

目录 1. 朴素二分查找2. 在排序数组中查找元素的第一个和最后一个位置3. 搜索插入位置4. x的平方根5. 山脉数组的峰值索引6. 寻找峰值7. 寻找旋转排序数组中的最小值8. 点名 1. 朴素二分查找 题目信息&#xff1a; 题目链接&#xff1a; 二分查找二分查找的使用前提为数据具有&…

5.Java并发编程—JUC线程池架构

JUC线程池架构 在Java开发中&#xff0c;线程的创建和销毁对系统性能有一定的开销&#xff0c;需要JVM和操作系统的配合完成大量的工作。 JVM对线程的创建和销毁&#xff1a; 线程的创建需要JVM分配内存、初始化线程栈和线程上下文等资源&#xff0c;这些操作会带来一定的时间和…

大型网站要怎样去建立SEO体系呢?(川圣SEO)蜘蛛池

baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; 大型网站要怎样去建立SEO体系呢&#xff1f;#蜘蛛池SEO川圣 大公司建立SEO体系还是比较难的&#xff0c;因为…

【论文阅读】Natural Adversarial Examples 自然对抗的例子

文章目录 一、文章概览&#xff08;一&#xff09;摘要&#xff08;二&#xff09;导论&#xff08;三&#xff09;相关工作 二、IMAGENET-A 和 IMAGENET-O&#xff08;一&#xff09;数据集构造方式&#xff08;二&#xff09;数据收集过程 三、模型的故障模式四、实验&#x…

[MYSQL数据库]--表内操作(CURD)

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、表的 Cre…

介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用。

Docker 是一种开源的容器化平台&#xff0c;可以将应用程序及其所有依赖项打包成一个独立的容器&#xff0c;从而实现快速部署、运行和扩展应用程序的能力。 Docker官网地址&#xff1a;https://www.docker.com/ 1.Docker 基本概念 1.1 镜像&#xff08;Image&#xff09; 镜…

Rust 安装与版本更新

Rust 简介 Rust &#xff0c;一门赋予每个人构建可靠且高效软件能力的语言&#xff0c;主打内存安全。 2024年2月&#xff0c;在一份 19 页的报告《回归基础构件&#xff1a;通往安全软件之路》中&#xff0c;白宫国家网络主任办公室&#xff08;ONCD&#xff09;呼吁开发者使…

git svn混用

背景 项目代码管理初始使用的svn, 由于svn代码操作&#xff0c;无法在本地暂存&#xff0c;有诸多不便&#xff0c;另外本人习惯使用git. 所以决定迁移至git管理 迁移要求&#xff1a; 保留历史提交记录 迁移流程 代码检出 git svn svn_project_url git代码提交 修改本…

读取txt文件并统计每行最长的单词以及长度

读取txt文件并统计每行最长的单词以及长度 题目 在 D:\\documant.txt 文本中,文件中有若干行英文文本,每行英文文本中有若干个单词&#xff0c;每个单词不会跨行出现每行至多包含100个字符,要求编写一个程序,处理文件,分析各行中的单词,找到每行中的最长单词&#xff0c;分别…

selenium元素定位问题

一、按钮点击 具体网页信息如下&#xff1a; 定位的时候driver.find_element(By.CLASS_NAME, 方法搞不定。 定位方法&#xff1a; 方法一&#xff1a;通过文本定位 driver.find_element(By.XPATH, "//*[text()高分一号]").click() time.sleep(3) 如果是部分文字…

day08_Mybatis

文章目录 前言一、快速入门1.1 入门程序分析1.2 入门程序实现1.2.1 准备工作1.2.1.1 创建springboot工程1.2.1.2 数据准备 1.2.2 配置Mybatis1.2.3 编写SQL语句1.2.4 单元测试1.3 解决SQL警告与提示 二、JDBC介绍2.1 介绍2.2 代码2.3 问题分析2.4 技术对比 三、数据库连接池3.1…

LeetCode[题解] 1261. 在受污染的二叉树中查找元素

首先我们看原题 给出一个满足下述规则的二叉树&#xff1a; root.val 0如果 treeNode.val x 且 treeNode.left ! null&#xff0c;那么 treeNode.left.val 2 * x 1如果 treeNode.val x 且 treeNode.right ! null&#xff0c;那么 treeNode.right.val 2 * x 2 现在这个…