目录
日常·唠嗑
接上一篇Litedram仿真验证(三):AXI接口完成仿真(FPGA/Modelsim)之后,本篇对仿真后的工程进行板级验证。
本次板级验证用到的开发板:Arty-a7,目前已经停产了,某宝上面还有卖,溢价比较严重。
板子资料链接:https://digilent.com/reference/programmable-logic/arty-a7/start
需要科学上网才能打开,因为是官方的板子资料很详细,有需要可以看看。
FPGA:xc7a35tcsg324-1
DDR3:MT41K128M16
一、仿真中遗留的问题
在上一篇文章中,提到AXI读写中,读会读不出来:
因为存在这一错误,所以迟迟没有上板,最近特地对这一问题进行了追踪,发现这一问题主要是出现在DDR3仿真模型的初始化上面:
----------------授人以鱼不如授人以渔,这里讲一下调试过程-----------------------
正确的DDR3初始化过程应该是这样的:
这是我用MIG example跑出来的log信息。
c
relaunch_sim
Command: launch_simulation -simset sim_1 -mode behavioral
INFO: [Vivado 12-5698] Checking validity of IPs in the design for the 'XSim' simulator...
INFO: [Vivado 12-5682] Launching behavioral simulation in 'f:/Fpga/vivado_test2/mig_7series_0_ex/mig_7series_0_ex.sim/sim_1/behav/xsim'
INFO: [Vivado 12-4795] Using compiled simulation libraries for IPs
INFO: [SIM-utils-51] Simulation object is 'sim_1'
INFO: [USF-XSim-7] Finding pre-compiled libraries...
INFO: [USF-XSim-11] File 'E:/Tool/vivado/Vivado/2019.2/data/xsim/xsim.ini' copied to run dir:'f:/Fpga/vivado_test2/mig_7series_0_ex/mig_7series_0_ex.sim/sim_1/behav/xsim'
INFO: [SIM-utils-54] Inspecting design source files for 'sim_tb_top' in fileset 'sim_1'...
INFO: [SIM-utils-43] Exported 'f:/Fpga/vivado_test2/mig_7series_0_ex/mig_7series_0_ex.sim/sim_1/behav/xsim/xsim_run.bat'
INFO: [USF-XSim-97] Finding global include files...
INFO: [USF-XSim-98] Fetching design files from 'sim_1'...
INFO: [USF-XSim-2] XSim::Compile design
INFO: [USF-XSim-61] Executing 'COMPILE and ANALYZE' step in 'f:/Fpga/vivado_test2/mig_7series_0_ex/mig_7series_0_ex.sim/sim_1/behav/xsim'
"xvlog --incr --relax -prj sim_tb_top_vlog.prj"
INFO: [USF-XSim-69] 'compile' step finished in '2' seconds
Command: launch_simulation -simset sim_1 -mode behavioral
INFO: [Vivado 12-5698] Checking validity of IPs in the design for the 'XSim' simulator...
INFO: [Vivado 12-5682] Launching behavioral simulation in 'f:/Fpga/vivado_test2/mig_7series_0_ex/mig_7series_0_ex.sim/sim_1/behav/xsim'
INFO: [Vivado 12-4795] Using compiled simulation libraries for IPs
INFO: [USF-XSim-3] XSim::Elaborate design
INFO: [USF-XSim-61] Executing 'ELABORATE' step in 'f:/Fpga/vivado_test2/mig_7series_0_ex/mig_7series_0_ex.sim/sim_1/behav/xsim'
"xelab -wto db7f1812aaa74905a81e46e866e8f86b --incr --debug typical --relax --mt 2 -L xil_defaultlib -L unisims_ver -L unimacro_ver -L secureip -L xpm --snapshot sim_tb_top_behav xil_defaultlib.sim_tb_top xil_defaultlib.glbl -log elaborate.log"
Vivado Simulator 2019.2
Copyright 1986-1999, 2001-2019 Xilinx, Inc. All Rights Reserved.
Running: E:/Tool/vivado/Vivado/2019.2/bin/unwrapped/win64.o/xelab.exe -wto db7f1812aaa74905a81e46e866e8f86b --incr --debug typical --relax --mt 2 -L xil_defaultlib -L unisims_ver -L unimacro_ver -L secureip -L xpm --snapshot sim_tb_top_behav xil_defaultlib.sim_tb_top xil_defaultlib.glbl -log elaborate.log
Using 2 slave threads.
Starting static elaboration
Pass Through NonSizing Optimizer
WARNING: [VRFC 10-3091] actual bit length 12 differs from formal bit length 4 for port 'pi_dqs_found_lanes' [f:/Fpga/vivado_test2/mig_7series_0_ex/mig_7series_0_ex.srcs/sources_1/ip/mig_7series_0/mig_7series_0/user_design/rtl/phy/mig_7series_v4_2_ddr_mc_phy_wrapper.v:1671]
WARNING: [VRFC 10-3091] actual bit length 12 differs from formal bit length 4 for port 'pi_phase_locked_lanes' [f:/Fpga/vivado_test2/mig_7series_0_ex/mig_7series_0_ex.srcs/sources_1/ip/mig_7series_0/mig_7series_0/user_design/rtl/phy/mig_7series_v4_2_ddr_mc_phy_wrapper.v:1679]
WARNING: [VRFC 10-3091] actual bit length 12 differs from formal bit length 4 for port 'pi_dqs_found_lanes' [f:/Fpga/vivado_test2/mig_7series_0_ex/mig_7series_0_ex.srcs/sources_1/ip/mig_7series_0/mig_7series_0/user_design/rtl/phy/mig_7series_v4_2_ddr_phy_top.v:1340]
WARNING: [VRFC 10-3091] actual bit length 1 differs from formal bit length 2 for port 'axi_wlock' [f:/Fpga/vivado_test2/mig_7series_0_ex/imports/example_top.v:544]
WARNING: [VRFC 10-3091] actual bit length 1 differs from formal bit length 4 for port 'axi_wd_wid' [f:/Fpga/vivado_test2/mig_7series_0_ex/imports/example_top.v:551]
WARNING: [VRFC 10-3091] actual bit length 1 differs from formal bit length 2 for port 'axi_rlock' [f:/Fpga/vivado_test2/mig_7series_0_ex/imports/example_top.v:570]
WARNING: [VRFC 10-5021] port 'complex_oclk_prech_req' is not connected on this instance [f:/Fpga/vivado_test2/mig_7series_0_ex/mig_7series_0_ex.srcs/sources_1/ip/mig_7series_0/mig_7series_0/user_design/rtl/phy/mig_7series_v4_2_ddr_calib_top.v:1318]
Completed static elaboration
INFO: [XSIM 43-4323] No Change in HDL. Linking previously generated obj files to create kernel
INFO: [USF-XSim-69] 'elaborate' step finished in '4' seconds
Vivado Simulator 2019.2
Time resolution is 1 fs
WARNING: file design.txt could not be opened
*** Warning: The analog data file design.txt for XADC instance sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.temp_mon_enabled.u_tempmon.xadc_supplied_temperature.XADC_inst was not found. Use the SIM_MONITOR_FILE parameter to specify the analog data file name or use the default name: design.txt.
############# Write Clocks PLLE2_ADV Parameters #############
nCK_PER_CLK = 4
CLK_PERIOD = 5000
CLKIN1_PERIOD = 5.000
DIVCLK_DIVIDE = 1
CLKFBOUT_MULT = 4
VCO_PERIOD = 1250.0
CLKOUT0_DIVIDE_F = 1
CLKOUT1_DIVIDE = 2
CLKOUT2_DIVIDE = 32
CLKOUT3_DIVIDE = 8
CLKOUT0_PERIOD = 1250
CLKOUT1_PERIOD = 2500
CLKOUT2_PERIOD = 40000
CLKOUT3_PERIOD = 10000
CLKOUT4_PERIOD = 5000
############################################################
############# MMCME2_ADV Parameters #############
MMCM_MULT_F = 8
MMCM_VCO_FREQ (MHz) = 800.000
MMCM_VCO_PERIOD = 1250.000
#################################################
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : BYTE_LANES_B0 = f BYTE_LANES_B1 = 0 DATA_CTL_B0 = 5 DATA_CTL_B1 = 0
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : HIGHEST_LANE = 4 HIGHEST_LANE_B0 = 4 HIGHEST_LANE_B1 = 0
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : HIGHEST_BANK = 1
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : FREQ_REF_PERIOD = 1250.00
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : DDR_TCK = 2500
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_S2_TAPS_SIZE = 9.77
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_CIRC_BUF_EARLY = 1
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_CIRC_BUF_OFFSET = 1219.75
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_CIRC_BUF_META_ZONE = 200.00
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_STG2_FINE_INTR_DLY = 769.25
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_STG2_COARSE_INTR_DLY = 511.00
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_STG2_INTRINSIC_DELAY = 1280.25
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_CIRC_BUF_DELAY = 60
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_INTRINSIC_DELAY = 1280.25
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_DELAY = 1866.19
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PO_OCLK_DELAY = 0
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : L_PHY_0_PO_FINE_DELAY = 60
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PI_STG1_INTRINSIC_DELAY = 0.00
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PI_STG2_INTRINSIC_DELAY = 744.00
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PI_INTRINSIC_DELAY = 744.00
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PI_MAX_STG2_DELAY = 615.23
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PI_OFFSET = -78.00
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : a negative PI_OFFSET means that rclk path is longer than oclk path so rclk will be delayed to next oclk edge and the negedge of rclk may be used.
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : PI_STG2_DELAY = 615.23
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy :PI_STG2_DELAY_CAND = 1172.00
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : DEFAULT_RCLK_DELAY = 63
sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy : RCLK_SELECT_EDGE = 0
WARNING: sim_tb_top.u_ip_top.u_mig_7series_0.u_mig_7series_0_mig.u_memc_ui_top_axi.mem_intfc0.ddr_phy_top0.u_ddr_mc_phy_wrapper.u_ddr_mc_phy: The required delay though the phaser_in to internally match the aux_out clock to ddr clock exceeds the maximum allowable delay. The clock edge will occur at the output registers of aux_out 556.77 ps before the ddr clock edge. If aux_out is used for memory inputs, this may violate setup or hold time.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.reset at time 1347600.0 ps WARNING: 200 us is required before RST_N goes inactive.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task at time 1413314.0 ps WARNING: 500 us is required after RST_N goes inactive before CKE goes active.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 1715814.0 ps INFO: Load Mode 2
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 1715814.0 ps INFO: Load Mode 2 Partial Array Self Refresh = Bank 0-7
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 1715814.0 ps INFO: Load Mode 2 CAS Write Latency = 5
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 1715814.0 ps INFO: Load Mode 2 Auto Self Refresh = Disabled
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 1715814.0 ps INFO: Load Mode 2 Self Refresh Temperature = Normal
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 1715814.0 ps INFO: Load Mode 2 Dynamic ODT = Disabled
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 3015814.0 ps INFO: Load Mode 3
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 3015814.0 ps INFO: Load Mode 3 MultiPurpose Register Select = Pre-defined pattern
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 3015814.0 ps INFO: Load Mode 3 MultiPurpose Register Enable = Disabled
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 4315814.0 ps INFO: Load Mode 1
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 4315814.0 ps INFO: Load Mode 1 DLL Enable = Enabled
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 4315814.0 ps INFO: Load Mode 1 Output Drive Strength = 34 Ohm
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 4315814.0 ps INFO: Load Mode 1 ODT Rtt = 60 Ohm
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 4315814.0 ps INFO: Load Mode 1 Additive Latency = 0
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 4315814.0 ps INFO: Load Mode 1 Write Levelization = Disabled
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 4315814.0 ps INFO: Load Mode 1 TDQS Enable = Disabled
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 4315814.0 ps INFO: Load Mode 1 Qoff = Enabled
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 5615814.0 ps INFO: Load Mode 0
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 5615814.0 ps INFO: Load Mode 0 Burst Length = 8
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 5615814.0 ps INFO: Load Mode 0 Burst Order = Sequential
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 5615814.0 ps INFO: Load Mode 0 CAS Latency = 6
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 5615814.0 ps INFO: Load Mode 0 DLL Reset = Reset DLL
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 5615814.0 ps INFO: Load Mode 0 Write Recovery = 6
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 5615814.0 ps INFO: Load Mode 0 Power Down Mode = DLL off
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 6915814.0 ps INFO: ZQ long = 1
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 6915814.0 ps INFO: Initialization Sequence is complete
PHY_INIT: Memory Initialization completed at 9397600.0 ps
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 9495814.0 ps INFO: Activate bank 0 row 0000
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 10795814.0 ps INFO: Read bank 0 col 000, auto precharge 0
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 10805814.0 ps INFO: Read bank 0 col 000, auto precharge 0
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.data_task: at time 10809564.0 ps INFO: READ @ DQS= bank = 0 row = 0000 col = 00000000 data = xxx
但是,Litedram跑出来的初始化信息是这样的:
c
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.main: at time 2765100.0 ps ERROR: CK and CK_N are not allowed to go to an unknown state.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.reset at time 2775100.0 ps WARNING: 200 us is required before RST_N goes inactive.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.reset: at time 2775100.0 ps ERROR: CKE must be inactive when RST_N goes inactive.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3: at time 2775100.0 ps ERROR: RST_N pulse width violation by 90000.0 ps
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task at time 2776350.0 ps WARNING: 500 us is required after RST_N goes inactive before CKE goes active.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 10646350.0 ps INFO: Precharge All
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 10676350.0 ps INFO: Refresh
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 18466350.0 ps INFO: Precharge All
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 18496350.0 ps INFO: Refresh
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 26286350.0 ps INFO: Precharge All
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 26316350.0 ps INFO: Refresh
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 34106350.0 ps INFO: Precharge All
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 34136350.0 ps INFO: Refresh
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.main: at time 120135100.0 ps ERROR: CK and CK_N are not allowed to go to an unknown state.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.reset at time 120145100.0 ps WARNING: 200 us is required before RST_N goes inactive.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.reset: at time 120145100.0 ps ERROR: CKE must be inactive when RST_N goes inactive.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3: at time 120145100.0 ps ERROR: RST_N pulse width violation by 90000.0 ps
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 120146350.0 ps ERROR: tRFC maximum violation during No Op
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task at time 120146350.0 ps WARNING: 500 us is required after RST_N goes inactive before CKE goes active.
sim_tb_top.mem_rnk[0].mem.gen_mem[0].u_comp_ddr3.cmd_task: at time 200596350.0 ps ERROR: Power Down Failure. Initialization sequence is not complete.
$stop called at time : 200596350 ps
run: Time (s): cpu = 00:00:11 ; elapsed = 00:02:25 . Memory (MB): peak = 1340.203 ; gain = 0.000
很明显几个error,导致DDR3初始化顺序不对:
跟着这个信息提示还有时间,我追到了出错误的波形,发现初始化过程中,DDR颗粒接口信号,会出现1个时钟周期的X态;基于此,我对OSERDES2进行单独仿真,发现该原语的RST信号,只要跳变一次,就会出现1个时钟周期X态,这个问题属于xilinx的固有问题,仿真无法解决,不影响板级测试。MIG仿真这个问题,没有看到是如何克服的,后面如有空余时间,可以解密IP并看一下处理方式;
单独仿真Oserdese2,只要RST跳变,输出就会出现1个时钟周期X态:
仿真文件:
(因为我自己测试用的,一些注释可能没改,不对,还有一些多余的信号也没删,读者在参考的时候,能测试看一下就行,不要过度纠结)
c
`timescale 1ns / 1ps
module oserdese2_wrapper(
input clk_in_20,
input rst_N,
inout [0:0] dq,
output locked,
input main_a7ddrphy_rst_storage,
output ddram_reset_n,
output test
);
wire [7:0] d0 ;
wire [7:0] q0 ;
wire align_ol ;
wire align_il ;
wire geclk_ol ;
wire geclk_90_il ;
wire gsclk_ol ;
wire geclk_il ;
wire gsclk_il ;
wire usr_rst_N ;
wire align_ol_ready ;
wire align_il_ready ;
reg [3:0] cnt ;
reg rst ;
wire clk_out_40;
wire clk_out_20;
wire clk_out_80;
wire clk_out_80_90;
assign test = clk_out_20;
assign usr_rst_N = rst_N & locked;
wire sys_clk;
wire sys4x_clk;
always @(posedge clk_out_20 or negedge usr_rst_N) begin
if (~usr_rst_N) begin
rst <= 1'b1;
end
else
rst <= 1'b0;
end
always @(posedge clk_out_20 or posedge rst) begin
if (rst) begin
cnt <= 4'b1100;
end
else
if(!rst)
cnt <= cnt + 1;
end
reg state_3;
always @(posedge clk_out_20 or posedge rst) begin
if (rst) begin
state_3 <= 1'b1;
end
else
if(cnt== 4'b1111)
state_3 <= 1'b0;
else
if(cnt== 4'b0000)
state_3 <= 1'b0;
else
if(cnt== 4'b0001)
state_3 <= 1'b0;
else
state_3 <= 1'b1;
end
wire TQ;
wire OB;
OSERDESE2 #(
.DATA_RATE_OQ("DDR"),
.DATA_RATE_TQ("BUF"),
.DATA_WIDTH(4'd8),
.SERDES_MODE("MASTER"),
.TRISTATE_WIDTH(1'd1)
) OSERDESE2_1 (
.CLK(sys4x_clk),
.CLKDIV(clk_out_20),
.D1(1'b1),
.D2(1'b1),
.D3(1'b1),
.D4(1'b1),
.D5(1'b1),
.D6(1'b1),
.D7(1'b1),
.D8(1'b1),
.OCE(1'd1),
//.RST((sys_rst | main_a7ddrphy_rst_storage)), wuyuxin debug 240507
.RST(main_a7ddrphy_rst_storage),
.OQ(ddram_reset_n)
);
PLLE2_ADV #(
.CLKFBOUT_MULT(5'd16),//16
.CLKIN1_PERIOD(10.0),//in 20mhz
.CLKOUT0_DIVIDE(4'd2),//20*16/8=40mhz 20*16/2=160mhz
.CLKOUT0_PHASE(1'd0),
.CLKOUT1_DIVIDE(5'd16),//20mhz 20*16/4=80mhz
.CLKOUT1_PHASE(1'd0),
.CLKOUT2_DIVIDE(3'd4),//20*16/1=320mhz
.CLKOUT2_PHASE(1'd0),
.CLKOUT3_DIVIDE(3'd4),
.CLKOUT3_PHASE(7'd90),
.DIVCLK_DIVIDE(1'd1),
.REF_JITTER1(0.01),
.STARTUP_WAIT("FALSE")
) PLLE2_ADV (
.CLKFBIN(pll_no_use),
.CLKIN1(clk_in_20),
.PWRDWN(1'd0),
.RST(~rst_N),
.CLKFBOUT(pll_no_use),
.CLKOUT0(clk_out_40),//iodelay_clk
.CLKOUT1(clk_out_20),//sys_clk
.CLKOUT2(sys4x_clk),//sys4x_clk
.CLKOUT3(clk_out_80_90),//sys4x_dqs_clk
.LOCKED(locked)
);
endmodule
激励文件:
c
`timescale 1ns / 1ps
`define clk_50m 20
`define clk_200m 5
`define clk_data_period 5
module OSERDESE2_TEST_tb( );
reg clk ;//?3???????é?????é??è?¤100MHz???
reg rst ;//?3?????¤???????é??è?¤é????μ?13?????????
reg clk_en ;
reg din1 ;
reg din2 ;
wire dq0;
wire locked;
wire test;
reg main_a7ddrphy_rst_storage;
wire ddram_reset_n;
oserdese2_wrapper x_oserdese2(
.clk_in_20 (clk),
.rst_N (~rst),
.dq (dq0),
.locked (locked),
.main_a7ddrphy_rst_storage (main_a7ddrphy_rst_storage),
.ddram_reset_n (ddram_reset_n),
.test (test)
);
initial begin
clk = 0;
//forever #(CYCLE/2) clk = ~clk;
forever #5 clk = ~clk;
end
initial begin
main_a7ddrphy_rst_storage = 1;
#2755.1;
main_a7ddrphy_rst_storage = 0;
end
initial begin
rst = 1;
#2000;
rst = 0;
#80000;
rst = 1;
$stop;
end
endmodule
二、板级测试
直接在仿真文件的基础上,上一章的example_top.v里面其实已经有读写测试数据了,现在只要包一层wrapper就行了:
c
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/04 10:29:22
// Design Name:
// Module Name: ddr_test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module ddr_test(
// Inouts
inout [15:0] ddr3_dq,
inout [1:0] ddr3_dqs_n,
inout [1:0] ddr3_dqs_p,
// Outputs
output [13:0] ddr3_addr,
output [2:0] ddr3_ba,
output ddr3_ras_n,
output ddr3_cas_n,
output ddr3_we_n,
output ddr3_reset_n,
output [0:0] ddr3_ck_p,
output [0:0] ddr3_ck_n,
output [0:0] ddr3_cke,
output [0:0] ddr3_cs_n,
output [1:0] ddr3_dm,
output [0:0] ddr3_odt,
// Inputs
input clk,
input sys_rst,
// Outputs
output uart_tx,
output tg_compare_error,
output init_calib_complete
);
wire sys_clk_i;
example_top u_ip_top
(
.ddr3_dq (ddr3_dq ),
.ddr3_dqs_n (ddr3_dqs_n ),
.ddr3_dqs_p (ddr3_dqs_p ),
.ddr3_addr (ddr3_addr ),
.ddr3_ba (ddr3_ba ),
.ddr3_ras_n (ddr3_ras_n ),
.ddr3_cas_n (ddr3_cas_n ),
.ddr3_we_n (ddr3_we_n ),
.ddr3_reset_n (ddr3_reset_n),
.ddr3_ck_p (ddr3_ck_p ),
.ddr3_ck_n (ddr3_ck_n ),
.ddr3_cke (ddr3_cke ),
.ddr3_cs_n (ddr3_cs_n ),
.ddr3_dm (ddr3_dm ),
.ddr3_odt (ddr3_odt ),
.sys_clk_i (clk ),
.init_calib_complete (init_calib_complete),
.tg_compare_error (tg_compare_error),
.uart_tx (uart_tx),
.sys_rst (sys_rst )
);
endmodule
三、ILA及逻分抓波形
ILA抓了几个波形,相比于仿真,数据很正常。
c
ila_0 ila_debug (
.clk(clk), // input wire clk
.probe0(s_axi_awaddr), // input wire [27:0] probe0
.probe1(s_axi_araddr), // input wire [27:0] probe1
.probe2(s_axi_wdata[9:0]), // input wire [9:0] probe2
.probe3(s_axi_rdata[9:0]), // input wire [9:0] probe3
.probe4(s_axi_rid), // input wire [3:0] probe4
.probe5(s_axi_rresp), // input wire [1:0] probe5
.probe6(s_axi_rvalid), // input wire [0:0] probe6
.probe7(s_axi_rready) // input wire [0:0] probe7
);
用逻辑分析仪抓了几个,也是比较正常:
目前抓的都是AXI用户接口的,DDR3的不太好抓,后面把过孔撬开,抓了,再更新一次。
四、工程获取及交流
这个项目,网上资料少,作者又是法国人,基本前前后后自己摸索了一年多,趟过一堆坑,哎,一言难尽。后面我会继续更进一下这个软核的training机制,有兴趣的可以留意关注一下。
有需要仿真工程或者技术交流的可以私信我:
邮箱:bumianzhe@126.com
(工程和经验,生命换来的,有偿,拒绝白嫖,非诚勿扰,理解一下🐄🐎)