标签:testbench 工作 总线 sig nts setting rda 目录 ati
DDR2难度比 SDRAM 复杂,自己写控制器不现实,直接用 IP 核比较靠谱。本篇博客记录一下 QuartusII 13.0 软件下的 DDR2 IP 核的官方例程仿真。
注意事项
1、关闭 Windows 的防火墙和电脑里的各种奇葩电脑管家。
2、以“管理员身份”打开 Quartus II 13.0。
3、所建工程要和 Quartus II 13.0 的安装盘符不同。
4、DDR2 IP 创建于工程目录下,否则仿真出错。
一、建工程
建立文件夹 DDR2_test,管理员身份打开 Quartus II,创建工程 DDR2_test,不引入任何 .v 文件。
二、IP调用
1、 打开 IP 创建界面:Tools ---> MegaWizard Plug-in Menager。
2、找到 DDR2 IP 并命名。
3、点击 OK,等待约 10 秒则会弹出 IP 核配置界面。
4、若 IP 核界面显示不完整,可查看文档《小梅哥DDR2简明教程》寻找解决办法。
5、设置 IP 参数,先设置第 1 个界面。
6、一路 next,直到 EDA 选项界面,勾选 Generate Simulation model,生成仿真模型。
7、点击 Finish,等待 1 分钟,生成 IP 完毕。如果等了 3 分钟还未生成,表明生成 IP 失败,请删除工程,检查注意事项后重新操作。
三、添加例程
1、点击 Quartus II 界面的 File,将例程添加进来。
(1)DDR2_example_top.v
(2)DDR2_example_driver.v
2、将 DDR2_example_top 右键设为顶层模块。
3、代码解释
例程可以帮我们理解 DDR2 IP 的使用,具体的解释可以查看设计文档《emi_ddr_ug.pdf》》。生成的代码有些乱,注释很少,我稍微整理了一下:
1 //************************************************************************** 2 // *** 名称 : DDR2_example_top.v 3 // *** 作者 : xianyu_FPGA 4 // *** 博客 : https://www.cnblogs.com/xianyufpga/ 5 // *** 日期 : 2020-6-9 6 // *** 工具 : Quartus 13.0 7 // *** 芯片 : Cyclone IV E 8 // *** 型号 : EP4CE30F23C6 9 // *** 描述 : DDR2_IP官方仿真例程的顶层模块 10 //************************************************************************** 11 12 module DDR2_example_top 13 //========================< 端口 >========================================== 14 ( 15 //inputs -------------------------------------------- 16 input wire clock_source , //时钟 17 input wire global_reset_n , //复位 18 //outputs ------------------------------------------- 19 output wire [ 15: 0] mem_addr , //DDR2地址总线 20 output wire [ 2: 0] mem_ba , //DDR2组地址总线 21 output wire mem_cas_n , //DDR2列地址选择 22 output wire mem_cke , //DDR2时钟使能 23 inout wire mem_clk , //DDR2时钟 24 inout wire mem_clk_n , //DDR2时钟反相 25 output wire mem_cs_n , //DDR2片选 26 output wire [ 1: 0] mem_dm , //DDR2掩码 27 inout wire [ 15: 0] mem_dq , //DDR2数据总线 28 inout wire [ 1: 0] mem_dqs , //DDR2数据源同步 29 output wire mem_odt , //DDR2片内终止控制 30 output wire mem_ras_n , //DDR2行地址选择 31 output wire mem_we_n , //DDR2写使能 32 output wire pnf , //数据正确指示(pass not fail) 33 output wire [ 3: 0] pnf_per_byte , //数据正确指示(字节) 34 output wire test_complete , //DDR2测试完成指示 35 output wire [ 7: 0] test_status //DDR2测试状态 36 ); 37 //========================< 连线 >========================================== 38 wire [ 0: 0] cs_n ; 39 wire local_burstbegin_sig ; 40 wire mem_aux_full_rate_clk ; 41 wire mem_aux_half_rate_clk ; 42 wire [ 27: 0] mem_local_addr ; 43 wire [ 3: 0] mem_local_be ; 44 wire [ 9: 0] mem_local_col_addr ; 45 wire mem_local_cs_addr ; 46 wire [ 31: 0] mem_local_rdata ; 47 wire mem_local_rdata_valid ; 48 wire mem_local_read_req ; 49 wire mem_local_ready ; 50 wire [ 2: 0] mem_local_size ; 51 wire [ 31: 0] mem_local_wdata ; 52 wire mem_local_write_req ; 53 wire phy_clk ; 54 wire reset_phy_clk_n ; 55 wire tie_high ; 56 wire tie_low ; 57 //========================================================================== 58 //== code 59 //========================================================================== 60 assign mem_cs_n = cs_n; //多次一举,直接连线mem_cs_n即可 61 assign tie_high = 1‘b1; //拉高 62 assign tie_low = 1‘b0; //拉低 63 //========================================================================== 64 //== DDR2 IP 65 //========================================================================== 66 DDR2 DDR2_inst 67 ( 68 .aux_full_rate_clk (mem_aux_full_rate_clk ), //全速率时钟 69 .aux_half_rate_clk (mem_aux_half_rate_clk ), //半速率时钟 70 .global_reset_n (global_reset_n ), //全局异步复位 71 //----------------------------------------------- 72 .local_address (mem_local_addr ), //用户_地址总线 73 .local_be (mem_local_be ), //用户_字节使能标志 74 .local_burstbegin (local_burstbegin_sig ), //用户_突发起始 75 .local_init_done ( ), //用户_初始化完成 76 .local_rdata (mem_local_rdata ), //用户_读数据总线 77 .local_rdata_valid (mem_local_rdata_valid ), //用户_读数据有效 78 .local_read_req (mem_local_read_req ), //用户_读数据请求 79 .local_ready (mem_local_ready ), //用户_读写请求被接收指示 80 .local_refresh_ack ( ), //用户_刷新请求 81 .local_size (mem_local_size ), //用户_突发大小 82 .local_wdata (mem_local_wdata ), //用户_写数据总线 83 .local_write_req (mem_local_write_req ), //用户_写数据请求 84 //----------------------------------------------- 85 .mem_addr (mem_addr[15 : 0] ), //DDR2地址总线 86 .mem_ba (mem_ba ), //DDR2组地址总线 87 .mem_cas_n (mem_cas_n ), //DDR2列地址选择 88 .mem_cke (mem_cke ), //DDR2时钟使能 89 .mem_clk (mem_clk ), //DDR2时钟 90 .mem_clk_n (mem_clk_n ), //DDR2时钟反相 91 .mem_cs_n (cs_n ), //DDR2片选 92 .mem_dm (mem_dm[1 : 0] ), //DDR2掩码 93 .mem_dq (mem_dq ), //DDR2数据总线 94 .mem_dqs (mem_dqs[1 : 0] ), //DDR2数据源同步 95 .mem_odt (mem_odt ), //DDR2片内终止控制 96 .mem_ras_n (mem_ras_n ), //DDR2行地址选择 97 .mem_we_n (mem_we_n ), //DDR2写使能 98 //----------------------------------------------- 99 .phy_clk (phy_clk ), //DDR2工作时钟 100 .pll_ref_clk (clock_source ), //IP核中的PLL输入时钟 101 .reset_phy_clk_n (reset_phy_clk_n ), //IP核提供的复位 102 .reset_request_n ( ), //IP核中的PLL锁定 103 .soft_reset_n (tie_high ) //全局异步复位信号(不复位PLL) 104 ); 105 //========================================================================== 106 //== 连接列地址位,因为2:1的数据速率,从示例驱动程序输出中删除1位 107 //========================================================================== 108 assign mem_local_addr[8 : 0] = mem_local_col_addr[9 : 1]; 109 //========================================================================== 110 //== DDR2 控制器 111 //========================================================================== 112 DDR2_example_driver driver 113 ( 114 .clk (phy_clk ), //DDR2工作时钟 115 .local_bank_addr (mem_local_addr[27 : 25]), //用户_地址总线 116 .local_be (mem_local_be ), //用户_字节使能标志 117 .local_burstbegin (local_burstbegin_sig ), //用户_突发起始 118 .local_col_addr (mem_local_col_addr ), //用户_地址总线 119 .local_cs_addr (mem_local_cs_addr ), //未用到 120 .local_rdata (mem_local_rdata ), //用户_读数据总线 121 .local_rdata_valid (mem_local_rdata_valid ), //用户_读数据有效 122 .local_read_req (mem_local_read_req ), //用户_读数据请求 123 .local_ready (mem_local_ready ), //用户_读写请求被接收指示 124 .local_row_addr (mem_local_addr[24 : 9] ), //用户_地址总线 125 .local_size (mem_local_size ), //用户_突发大小 126 .local_wdata (mem_local_wdata ), //用户_写数据总线 127 .local_write_req (mem_local_write_req ), //用户_写数据请求 128 .pnf_per_byte (pnf_per_byte[3 : 0] ), //数据正确指示(字节) 129 .pnf_persist (pnf ), //数据正确指示 130 .reset_n (reset_phy_clk_n ), //IP核提供的复位 131 .test_complete (test_complete ), //DDR2测试完成指示 132 .test_status (test_status ) //DDR2测试的运行状态 133 ); 134 135 136 endmodule
四、仿真搭建
1、Modelsim 软件的路径设置。打开Quartus ii,点击Tools --- Options --- EDA Tool Optinons,将modelsim的安装路径填写进去。我这用的是QuestaSim,和Modelsim是完全没有区别的。为了防止遗漏,我把下面三个位置都填上:
2、Quartus ii 关联 Modelsim,一开始建立工程时就可以设置,如果忘记了或者设置错了也可以再次更改。点击Assignments --- Setings --- Eda Tool Setings,将仿真工具选择好即可。(我的是QuastaSim,就填的QuastaSim)
3、点击Assignments --- Setings --- EDA Tool Setings下的simulation,将 Tool name 选择好,然后点击 Compile testbench,之后点击Test Benches。
4、填写 New Test Bench Settings,添加仿真文件。
(1)DDR2_mem_model.v,DDR2 仿真模型;
(2)DDR2_example_top_tb,DDR2 仿真文件;
5、回到 Quartus II 界面,综合编译后点击 RTL Simulation 执行仿真。
五、波形展现
经过一小段时间的等待,波形就出来了。
六、补充说明
参考资料:小梅哥DDR2简明教程.pdf
DDR2(1):Quartus DDR2 IP 官方例程仿真
标签:testbench 工作 总线 sig nts setting rda 目录 ati
原文地址:https://www.cnblogs.com/xianyufpga/p/13074382.html