DDR3quartus141仿真教程Word文档下载推荐.docx
《DDR3quartus141仿真教程Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《DDR3quartus141仿真教程Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。
vhdl"
TosimulatetheexampledesignusingModelsimAE/SE:
1)Moveintothedirectory./verilog/mentoror./vhdl/mentor
2)StartModelsimandrunthe"
run.do"
script:
inModelsim,enter"
dorun.do"
4,仿真开始
用quartus14.1按第3步操作后,会得到
此时,我们利用自带的modelsim_altera,cd进入到上图目录,执行run.do,等待几分钟。
5,查看仿真结果
从图中可以看到,在经历了173.49us后,init_done信号拉高了,这说明DDR3初始化成功了,同时也可以看到自校准模式成功信号也在这时刻拉高,从这以后开始进行DDR3读写测试,突发测试,具体测试就没有细看了,可以结合自己需要到时候修改成自己的case。
经历一个10来分钟的等待,我就是利用这个等待时间完成了这份简单的教程,会看到打印信息如下,说明仿真结束了,特别注意结束时会弹出一个对话框问你是否要关闭modelsim,点击否,不然所有活都白干了,啥也没有看到。
写操作,如下图所示:
此时cs=0ras=1cas=0we=0写入的数据DQ是0
读操作,如下图所示:
此时cs=0ras=1cas=0we=1读出的数据DQ是f40019b2,593c00d9
6,详细分析
先看仿真的顶层:
ddr3_ctrl_example_sim
【时钟处理】
altera_avalon_clock_source#(
.CLOCK_RATE(50000000),//我板子上为50M,根据实际配置
.CLOCK_UNIT
(1)
)pll_ref_clk(
.clk(pll_ref_clk_clk_clk)//clk.clk
);
【复位处理】
altera_avalon_reset_source#(
.ASSERT_HIGH_RESET(0),
.INITIAL_RESET_CYCLES(5)
)global_reset(
.reset(global_reset_reset_reset),//reset.reset_n
【DDR3控制器主体】
【check功能】
这个功能模块的具体功能可以打开altera_mem_if_checker_no_ifdef_params.v进行查看,
可以看到,这里几个信号主要是根据IP核来的一些信息,来判断初始化成功与否并打印相关log记录,但是回到顶层,发现只有一组数据接了实际信号,而其他接的是常值,那是因为我们只使用了一个DDR3,如果在稍微复杂点的设计就会4pcs或者更多,貌似max是6个DDR3,那么就可以根据实际情况接入了。
【case测试】
我们可以把alt_mem_if_ddr3_mem_model_top_ddr3_mem_if_dm_pins_en_mem_if_dqsn_en
理解成一个case_gen,产生DDR3读写测试的各种case,类似信号源,里面我也没有细看,然后就有了我们仿真波形在init_done信号起来的那写case波形。
6,tcl脚本分析
首先先看下我们执行的run.do,
Altera里面的run.do文件如下:
if{[fileexistsmsim_setup.tcl]}{
sourcemsim_setup.tcl
dev_com
com
#the"
elab_debug"
macroavoidsoptimizationswhichpreservessignalssothattheymaybeaddedtothewaveviewer
elab_debug
addwave"
ddr3_ctrl_example_sim/*"
run-all
}else{
error"
Themsim_setup.tclscriptdoesnotexist.PleasegeneratetheexampledesignRTLandsimulationscripts.See../../README.txtforhelp."
}
Run.do文件主要是取搜索msim_setup.tcl文件,进而再链接到其他操作,这个和xilinx的风格不一样,从xilinxIP生成的exampledesign来看,xilinx喜欢把modelsim要做的事情都直接的写到run.do里面,避免altera这种生成IP后还要再单独用quartus再打开仿真的qdf工程,再执行脚本,再生成仿真的文件,而xilinx在生成ip及example后就直接出来所有东西,你所要做的事情就是执行下run.do,简化了许多。
上面第4步我们提到生成的msim_setup.tcl,主要就是modelsim在仿真做了些啥事,如果我们自己来写类型xilinx里面的run.do的话,要怎么个写法。
【先来一些判断处理】
#Initializevariables
if!
[infoexistsSYSTEM_INSTANCE_NAME]{
setSYSTEM_INSTANCE_NAME"
"
}elseif{!
[stringmatch"
$SYSTEM_INSTANCE_NAME]}{
/$SYSTEM_INSTANCE_NAME"
[infoexistsTOP_LEVEL_NAME]{
setTOP_LEVEL_NAME"
ddr3_ctrl_example_sim"
[infoexistsQSYS_SIMDIR]{
setQSYS_SIMDIR"
./../"
[infoexistsQUARTUS_INSTALL_DIR]{
setQUARTUS_INSTALL_DIR"
D:
/altera/14.1/quartus/"
#----------------------------------------
#Initializesimulationproperties-DONOTMODIFY!
setELAB_OPTIONS"
setSIM_OPTIONS"
*-64vsim*"
[vsim-version]]{
#CopyROM/RAMfilestosimulationdirectory
aliasfile_copy{
echo"
\[exec\]file_copy"
filecopy-force$QSYS_SIMDIR/submodules/ddr3_ctrl_example_sim_e0_if0_s0_sequencer_mem.hex./
filecopy-force$QSYS_SIMDIR/submodules/ddr3_ctrl_example_sim_e0_if0_s0_AC_ROM.hex./
filecopy-force$QSYS_SIMDIR/submodules/ddr3_ctrl_example_sim_e0_if0_s0_inst_ROM.hex./
【库操作】
主要指的是添加altera的元件库,创建work库,编译库
#Createcompilationlibraries
procensure_lib{lib}{if!
[fileisdirectory$lib]{vlib$lib}}
ensure_lib./libraries/
ensure_lib./libraries/work/
vmapwork./libraries/work/
vmapwork_lib./libraries/work/
*ModelSimALTERA*"
ensure_lib./libraries/altera_ver/
vmapaltera_ver./libraries/altera_ver/
ensure_lib./libraries/lpm_ver/
vmaplpm_ver./libraries/lpm_ver/
ensure_lib./libraries/sgate_ver/
vmapsgate_ver./libraries/sgate_ver/
ensure_lib./libraries/altera_mf_ver/
vmapaltera_mf_ver./libraries/altera_mf_ver/
ensure_lib./libraries/altera_lnsim_ver/
vmapaltera_lnsim_ver./libraries/altera_lnsim_ver/
ensure_lib./libraries/cyclonev_ver/
vmapcyclonev_ver./libraries/cyclonev_ver/
ensure_lib./libraries/cyclonev_hssi_ver/
vmapcyclonev_hssi_ver./libraries/cyclonev_hssi_ver/
ensure_lib./libraries/cyclonev_pcie_hip_ver/
vmapcyclonev_pcie_hip_ver./libraries/cyclonev_pcie_hip_ver/
#Compiledevicelibraryfiles
aliasdev_com{
\[exec\]dev_com"
if!
vlog"
$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_primitives.v"
-workaltera_ver
……
【编译设计文件】
#Compilethedesignfilesincorrectorder
aliascom{
\[exec\]com"
vlog-sv"
$QSYS_SIMDIR/submodules/verbosity_pkg.sv"
$QSYS_SIMDIR/submodules/ddr3_ctrl_example_sim_e0_if0_dmaster_p2b_adapter.sv"
【仿真激励引入】其实我也不知道这个过程该叫扫描,就叫仿真激励引入吧
注意$TOP_LEVEL_NAME如果前面有宏定义的话可以保持不变,如果未定义的话,就应该以实际的仿真*_tb
#Elaboratetopleveldesign
aliaselab{
\[exec\]elab"
evalvsim-tps$ELAB_OPTIONS-Lwork-Lwork_lib-Laltera_ver-Llpm_ver-Lsgate_ver-Laltera_mf_ver-Laltera_lnsim_ver-Lcyclonev_ver-Lcyclonev_hssi_ver-Lcyclonev_pcie_hip_ver$TOP_LEVEL_NAME
#Elaboratethetopleveldesignwithnovoptoption
aliaselab_debug{
\[exec\]elab_debug"
evalvsim-novopt-tps$ELAB_OPTIONS-Lwork-Lwork_lib-Laltera_ver-Llpm_ver-Lsgate_ver-Laltera_mf_ver-Laltera_lnsim_ver-Lcyclonev_ver-Lcyclonev_hssi_ver-Lcyclonev_pcie_hip_ver$TOP_LEVEL_NAME
#Compileallthedesignfilesandelaboratethetopleveldesign
aliasld"
elab
#Compileallthedesignfilesandelaboratethetopleveldesignwith-novopt
aliasld_debug"
【打印信息】
#Printoutusercommmandlinealiases
aliash{
ListOfCommandLineAliases"
echo
file_copy--CopyROM/RAMfilestosimulationdirectory"
dev_com--Compiledevicelibraryfiles"
com--Compilethedesignfilesincorrectorder"
elab--Elaboratetopleveldesign"
elab_debug--Elaboratethetopleveldesignwithnovoptoption"
ld--Compileallthedesignfilesandelaboratethetopleveldesign"
ld_debug--Compileallthedesignfilesandelaboratethetopleveldesignwith-novopt"
echo
ListOfVariables"
TOP_LEVEL_NAME--Toplevelmodulename."
SYSTEM_INSTANCE_NAME--Instantiatedsystemmodulenameinsidetoplevelmodule."
QSYS_SIMDIR--Qsysbasesimulationdirectory."
QUARTUS_INSTALL_DIR--Quartusinstallationdirectory."
file_copy
h
7,如何仿真自己的设计
前面提到quartusDDR3ip核自带的仿真顶层里面有个类似信号源的模块,其实这就已经是用户文件了,要仿真自己的设计只需要替换自己的设计即可。
但是问题又来了,自己的设计如何控制写入DDR3呢,因为从仿真的顶层上看,就只有DDR3的一些数据接口及一些控制信号,对于读写控制,突发控制都是没有的。
要解决这个问题就要再查看ddr3_ctrl_example_sim_e0.v这个文件了,因为是仿真的缘故,这个文件里面的所有接口信号没有全部引出,这也是为什么我们会有上面疑问了。
查看ddr3_ctrl_example_sim_e0.v文件里面,你会看到里面有这么一个模块,看到了熟悉avalon_MM总线,这就是我们所关心的了,实际使用中可以对这个文件进行修改,当然,我初步看了下要修改下还是有点麻烦的,仿造ddr3_ctrl_example_sim_e0_d0.v的接口即可。
当然,也可以借鉴下特权同学的DDR2读写测试demo改写个DDR3的读写测试,如:
ddr3_ctrlU_ddr3_ctrl(
.pll_ref_clk(ext_clk),
.global_reset_n(sys_rst_n),
.soft_reset_n(1'
b1),
.afi_clk(afi_clk),
.afi_half_clk(afi_half_clk),
.afi_reset_n(afi_reset_n),
.afi_reset_export_n(),
.mem_a(DDR_ADDR),
.mem_ba(DDR_BA),
.mem_ck(DDR_CLK_P),
.mem_ck_n(DDR_CLK_N),
.mem_cke(DDR_CKE),
.mem_cs_n(DDR_CS_N),
.mem_dm(DDR_DM),
.mem_ras_n(DDR_RAS_N),
.mem_cas_n(DDR_CAS_N),
.mem_we_n(DDR_WE_N),
.mem_reset_n(DDR_RESET),
.mem_dq(DDR_DQ),
.mem_dqs(DDR_DQS_P),
.mem_dqs_n(DDR_DQS_N),
.mem_odt(DDR_ODT),
.avl_ready_0(local_ready),
.avl_burstbegin_0(local_read_req|local_write_req),
.avl_addr_0(local_address),
.avl_rdata_valid_0(local_rdata_valid),
.avl_rdata_0(local_rdata[31:
0]),
.avl_wdata_0(local_wdata[31:
.avl_be_0(8'
hff),
.avl_read_req_0(local_read_req),
.avl_write_req_0(local_write_req),
.avl_size_0(3'
d1),
.mp_cmd_clk_0_clk(clk_50m),
.mp_cmd_reset_n_0_reset_n(sys_rst_n),
.mp_rfifo_clk_0_clk(afi_clk),
.mp_rfifo_reset_n_0_reset_n(sys_rst_n),
.mp_wfifo_clk_0_clk(afi_clk),
.mp_wfifo_reset_n_0_reset_n(sys_rst_n),
.local_init_done(ddr3_init_done),
.local_cal_success(ddr3_cal_success),
.local_cal_fail(ddr3_cal_fail),
.oct_rzqin(DDR_OCT),
.pll_mem_clk(),
.pll_write_