其他分享
首页 > 其他分享> > DDR2(1):Quartus DDR2 IP 官方例程仿真

DDR2(1):Quartus DDR2 IP 官方例程仿真

作者:互联网

  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,不引入任何 .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 执行仿真。

 

五、波形展现

  经过一小段时间的等待,波形就出来了。

 

六、补充说明

  如果使用的 Quartus II 是13.0 以上的版本,在执行仿真这一步会报错:   “仿真需要调用一个叫 cycloneiii_ver 的库,结果找不到这个库,为啥找不到呢?可能这个 IP 核的工程模型是基于 cycloneiii 器件设计的,仿真的时候默认还是调用 cyclone iii 的器件模型,但是从 Quartus II 13.0 以后,Quartus II 软件已经不再支持 cyclone iii 软件,里面也不再提供 cyclone iii 的器件模型,因此仿真时候无法找到这个模型,当然无法开始仿真了。” ——小梅哥   小梅哥没有给出解决办法,但是看到一篇博客里记录了 QuartusII 15.0 仿真 DDR2 官方例程的全过程,链接如下:https://blog.csdn.net/linker00/article/details/98034776  

参考资料:小梅哥DDR2简明教程.pdf

 

标签:wire,clk,DDR2,IP,例程,local,mem
来源: https://www.cnblogs.com/xianyufpga/p/13074382.html