本文设计思想采用明德扬至简设计法。在高速信号处理场合下,很短时间内就要缓存大量的数据,这时片内存储资源已经远远不够了。DDR SDRAM因其极高的性价比几乎是每一款中高档FPGA开发板的首选外部存储芯片。DDR操作时序非常复杂,之所以在FPGA开发中用途如此广泛,都要得意于MIG IP核。网上关于MIG控制DDR的资料很多,因此本文只讲述个人认为较重要的内容。由于MIG IP核用户接口时序较复杂,这里给出扩展接口模块用于进一步简化接口时序。

先来看看MIG IP核的架构:

了解下存储芯片侧重要接口:

ddr_addr             DDR3的行列地址

ddr_ba                DDR3的bank地址

ddr_cas_n ddr_ras_n ddr_we_n   命令控制

ddr_ck ddr_ck_n           差分时钟

ddr_dm               数据输入屏蔽

ddr_o_dt            片上终端使能,用于使能和禁止片内终端电阻

ddr_reset_n             DDR3复位

ddr_dqs ddr_dqs_n         数据同步信号

ddr_dq                传输数据

之后我们从IP核配置开始说起。Controller Options这页最为重要,其中包括时钟策略和外部DDR芯片参数配置。首先时钟周期选择为400MHz,此时PHY to Controller Clock Ratio只能是4:1,也就是说MIG用户侧时钟为100MHz。下半部分是选择合适的DDR芯片型号和参数,要再三确认无误。

Memory Options这页输入时钟周期选择为200MHz,根据Controller Options页的选项,该时钟经过PLL分频和倍频后的时钟分别作为用户侧时钟100MHz和DDR接口时钟400MHz。

这里有个参考时钟选项,如果Memory Options页PLL输入时钟频率选为200MHz,此处可以直接选择Use System Clock,从而简化接口。

以上是MIG IP核配置过程中较为重要的部分,实际上上述配置也可通过修改工程代码中参数来重定义。IP核配置完成,打开example design工程顶层文件,我们来重点关注下用户侧接口功能和时序。

这是本人写的注释,更具体清晰的说明还是要查看官方文档UG586.接下来看看写数据和读数据的接口时序图(时钟比例4:1,burst length = 8为例):

指令通道:

写数据:

从时序图可以看出,指令地址和数据使用两套时序,彼此相互独立。为了便于设计,直接将两套时序严格对齐(情况1)也可以正常工作。

读数据:

为什么说“时钟比例4:1,burst length = 8为例”?这一点特别关键。此时用户时钟周期是DDR接口时钟周期的4倍,也就是一个用户时钟信号上升沿对应8个DDR时钟边沿。burst length可以理解为MIG连续操作DDR地址的个数,故在4:1时钟比例下,一个用户时钟周期正好对8个地址进行了读/写操作,256bit数据分8次(32bit)写入DDR中。由此分析,在写数据时让app_wdf_end = app_wdf_wren即可,并且读/写操作时地址递增步长为8.

虽然MIG IP核提供了用户接口,但读写指令通道复用且需要实时关注两个rdy信号造成了时序操作上的不方便。为此我们需要对接口进一步封装,保证写操作时只关注:写使能user_wdata_en 写地址user_waddr 写数据user_wdata和写准备就绪信号user_wdata_rdy,读操作时只关注:读使能user_rdata_en 读地址user_raddr 读数据user_rdata 读数据有效user_rdata_vld和读操作准备就绪user_rdata_rdy。

利用扩展接口模块,将读通道和写通道接口分离,并分别例化一个FIFO缓存地址和数据。当读/写指令同时有效时,通过MIG侧的优先级轮换逻辑轮流读取其中一个FIFO,每次选一个FIFO读取直至FIFO为空再重新选择。其工程结构和核心代码如下:

读侧逻辑核心代码:

1 //读侧--------------------------------------------------------------

2

3 always @(posedge clk or negedge rst_n )begin

4 if(rst_n==0) begin

5 rd_flag <= (0) ;6 end

7 else if(rd_flag == 0 && mig_rdy && mig_wdf_rdy && !rdempty1 && (rdempty0 || (!rdempty0 && priority == 0)))begin

8 rd_flag <= (2'b01) ;//读取 写指令FIFO

9 end

10 else if(rd_flag == 0 && mig_rdy && !rdempty0 && (rdempty1 || (!rdempty1 && priority == 1)))begin

11 rd_flag <= (2'b10) ;//读取 读指令FIFO

12 end

13 else if((rd_flag == 2'b01 && rdempty1)||(rd_flag == 2'b10 &&rdempty0))14 rd_flag <= 0;15 end

16

17 //同时非空时轮换优先级

18 always @(posedge clk or negedge rst_n )begin

19 if(rst_n==0) begin

20 priority <= (0) ;21 end

22 else if(rd_flag == 0 && !rdempty0 && !rdempty1)begin

23 priority <= (!priority) ;24 end

25 end

为了方便测试,设计样式生成模块与扩展接口模块用户侧连接,不断向一段地址写入固定数据序列并在一段时间后读回。

1 `timescale 1ns /1ps2 /*

3 该模块功能:4 周期性向一段地址执行读写操作 产生固定样式待写入数据用户测试目的5 测试完毕后删除该模块,开发用户接口6

7 具体为:8 1 写从0开始之后的10个用户地址(80个DDR地址):0~9递增序列9 2 等待20个时钟周期10 3 读取写入的10个用户地址11 4 等待20个时钟周期12 5 重复上述步骤13

14 说明:15 1 每个步骤之间有一个时钟周期空闲16 2 由于burst_len = 8 4:1时钟模式下一个用户时钟周期写入数据对应同样时间内8个DDR时钟边沿写入数据,17 因此地址递增步长为818 */

19 moduletraffic_gen20 #(parameter DATA_WIDTH = 32,21 ADDR_WIDTH = 29)22 (23 inputclk ,24 inputrst_n ,25

26 output reggen_wdata_en ,27 output reg [ ADDR_WIDTH-1:0] gen_waddr ,28 output reg [ DATA_WIDTH-1:0] gen_wdata ,29 input gen_wdata_rdy ,//写指令和数据通道准备就绪

30

31 output reggen_rdata_en ,32 output reg [ ADDR_WIDTH-1:0] gen_raddr ,33 input [ DATA_WIDTH-1:0] gen_rdata ,34 inputgen_rdata_vld ,35 input gen_rdata_rdy //读指令通道准备就绪

36 );37

38

39 reg [ (8-1):0] cnt0 ;40 wireadd_cnt0 ;41 wireend_cnt0 ;42 reg [ (2-1):0] cnt1 ;43 wireadd_cnt1 ;44 wireend_cnt1 ;45

46 reg [ DATA_WIDTH-1:0] gen_rdata_r ;47 reggen_rdata_vld_r ;48 regcom_flag ;49

50 wirewri_state;51 wirerd_state;52 wirecom_change_t;53

54 //操作周期计数器,计数值为欲操作用户地址段长度+1(需要一个时钟周期空闲)

55 always @(posedge clk or negedge rst_n) begin

56 if (rst_n==0) begin

57 cnt0 <= 0;58 end

59 else if(add_cnt0) begin

60 if(end_cnt0)61 cnt0 <= 0;62 else

63 cnt0 <= cnt0+1;64 end

65 end

66 assign add_cnt0 = (com_flag == 0 && gen_wdata_rdy) || (com_flag == 1 &&gen_rdata_rdy);67 assign end_cnt0 = add_cnt0 && cnt0 == (30)-1;68

69 //指令标志位 先是0--写 再是1--读

70 always @(posedge clk or negedge rst_n )begin

71 if(rst_n==0) begin

72 com_flag <= (0) ;73 end

74 else if(com_change_t)begin

75 com_flag <= (!com_flag) ;76 end

77 end

78

79 assign com_change_t = add_cnt0 && cnt0 == 10 - 1;80

81 //写操作---------------------------------------------

82 always @(posedge clk or negedge rst_n )begin

83 if(rst_n==0) begin

84 gen_wdata_en <= (0) ;85 end

86 else if(wri_state)begin

87 gen_wdata_en <= (1'b1) ;

88 end

89 else begin

90 gen_wdata_en <= (0) ;91 end

92 end

93

94 assign wri_state = add_cnt0 && cnt0 <= 10-1 && com_flag == 0;95 assign rd_state = add_cnt0 && cnt0 <= 10-1 && com_flag == 1;96

97 always @(posedge clk or negedge rst_n )begin

98 if(rst_n==0) begin

99 gen_wdata <= (0) ;100 end

101 else begin

102 gen_wdata <=(cnt0) ;103 end

104 end

105

106 always@(posedge clk or negedge rst_n)begin

107 if(rst_n == 0)108 gen_waddr <= 0;109 else if(wri_state)110 gen_waddr <= gen_waddr + 29'd8;

111 else

112 gen_waddr <= 0;113 end

114 //读操作----------------------------------------------

115

116 always @(posedge clk or negedge rst_n )begin

117 if(rst_n==0) begin

118 gen_rdata_en <= (0) ;119 end

120 else if(rd_state)begin

121 gen_rdata_en <= (1'b1) ;

122 end

123 else begin

124 gen_rdata_en <= (0) ;125 end

126 end

127

128 always@(posedge clk or negedge rst_n)begin

129 if(rst_n == 0)130 gen_raddr <= 0;131 else if(rd_state)132 gen_raddr <= gen_raddr + 29'd8;

133 else

134 gen_raddr <= 0;135 end

136

137 always @(posedge clk or negedge rst_n )begin

138 if(rst_n==0) begin

139 gen_rdata_r <= (0) ;140 end

141 else begin

142 gen_rdata_r <=(gen_rdata) ;143 end

144 end

145

146 always @(posedge clk or negedge rst_n )begin

147 if(rst_n==0) begin

148 gen_rdata_vld_r <= (0) ;149 end

150 else if(gen_rdata_vld)begin

151 gen_rdata_vld_r <= (1'b1) ;

152 end

153 else begin

154 gen_rdata_vld_r <= (0) ;155 end

156 end

157

158 endmodule

将traffic_gen和extend_interface模块例化在MIG的example design中,利用ILA抓取MIG IP核用户接口信号。

向地址8~80写入数据0~9,再从此段地址中读回数据,0~9被正确读出,MIG IP核控制DDR3读写测试完毕。

vfifo控制mig_MIG IP控制DDR3读写测试相关推荐

  1. 使用VIVADO中的MIG控制DDR3(AXI接口)四——MIG配置及DDR3读写测试

    在之前的内容里,讲述了AXI和DDR3的基本知识,也做了一个用AXI IP核读写BRAM的测试实验.接下来,我们就将这些部分结合在一起,做一个用AXI IP核对DDR3进行读写测试的实验.因为DDR3 ...

  2. Xilinx 7系列例化MIG IP core DDR3读写

    DDR3读写在工程上多是通过例化MIG,调用生成IPcore的HDL FunctionalModel.DDR读写数据可以用到状态机,后期再添砖加瓦吧,当下先对比一下网上找的一段程序和自己例化后的程序. ...

  3. lattice fpga ddr3 读写控制

    Lattice FPGA ECP5 DDR3 调试报告 环境:WIN10.Diamond 3.11 (64-bit).Verilog语言. 一.创建Diamond工程 1.创建一个存放工程的文件夹.根 ...

  4. 快速上手Xilinx DDR3 IP核(2)----MIG IP核的官方例程与读写测试模块(Native接口)

    写在前面 接上一篇文章(配置MIG IP过程): 快速上手Xilinx DDR3 IP核(1)----MIG IP核的介绍及配置(Native接口) DDR3系列文章: 快速上手Xilinx DDR3 ...

  5. DDR3基本的读写测试,适用于verilog语言学习

    近期学习使用Verilog编写DDR3接口读写测试,在编写过程中遇到许多问题,最终功夫不负有心人,实现了DDR3数据写入和数据读取功能.同时在问题排查过程中,也学习到了很多新的东西. 现将我实现DDR ...

  6. FPGA学习之DDR3读写实验

    FPGA学习之DDR3读写实验 原理 简介 配置原理 程序代码 约束文件 设计文件 参考正点原子视频 原理 简介 DDR3 SDRAM常 简称 DDR3 是当今较为常见的一种储存器,在计算机及嵌入式产 ...

  7. 基于MIG控制器的DDR3读写控制详解

    基于MIG控制器的DDR3读写控制详解 目的:详细介绍FPGA中基于MIG IP核控制的DDR3详细控制及内部逻辑 平台:AX7350-Xilinx 软件:Vivado 2017.4 1.MIG IP ...

  8. 基于Vivado MIG IP核的DDR3读写实验(top_rom_ddr/ddr_top)

    一.前言 关于Vivado MIG IP核详细配置可以参考我之前的文章:基于Vivado MIG IP核的DDR3控制器(DDR3_CONTROL) 关于MIG IP核的用户端的接口时序可以参考这篇文 ...

  9. Xilinx DDR3 —— MIG IP核的读写仿真(APP接口)

    在上一篇中Xilinx DDR3 -- MIG IP核的配置(APP接口),已经观看了Xilinx官方提供的MIG IP核读写例程仿真波形,本着学习的目的,本篇开始自己编写MIG IP核读写程序,用于 ...

最新文章

  1. VIM的snipMate的继承设置
  2. BS文件夹上传操作(二) ——基本功能实现
  3. Android面试:Java相关
  4. iOS酷我音乐导出工具使用说明和原理介绍(提供下载链接及project源代码)
  5. 【解决办法】pandas画出时序数据(股票数据)横轴不是时间
  6. 几款好用超赞的Google Chrome插件
  7. 410. Split Array Largest Sum 分割数组的最大值
  8. Linq之隐式类型、自动属性、初始化器、匿名类
  9. C++11 多线程相关知识的学习
  10. Asp.net 自定义config文件读取
  11. mysql cluster 用户_mysql cluster统一用户权限
  12. 【心电信号】基于matlab NLM时间序列心电信号去噪【含Matlab源码 1547期】
  13. sublime text 安装及使用
  14. 南京大学计算机专业推免生,南大计算机系招收2014级研究生外校推免生复试名单...
  15. Linux重定向console口控制台,Linux重定向console口控制台(Fedora)
  16. wamp+php+下载,WAMP(Windows+Apache+Mysql+PHP) 下载配置一条龙
  17. 解决每次弹出“是否允许XX录制/投射您的屏幕”(享做笔记、王者荣耀等)手把手教程
  18. 特种浓缩分离:倒极电渗析技术工作原理介绍
  19. 自动驾驶漫谈之二:无人驾驶与高精度地图
  20. unhandled exception in XXX:0xC0000005:access violation问题

热门文章

  1. 个人对于架构设计的理解
  2. android开发控件水波纹,Android实现水波纹控件的方法
  3. mysql -uroot -proot tc -e select * from merchandise limit 1这个-E的命令作用是什么,用来什么什么的?
  4. python需要配置环境变量吗_教你手动设置python环境变量
  5. tp5 iis7 404 解决方案
  6. 计算机组成与结构第二章ppt,计算机组成原理(华科版)第二章 运算方法与运算器.ppt...
  7. 各种实用的 PHP 开源库推荐
  8. windows常用命令netstat
  9. 不会英语能学oracle吗,英语非常差该怎么学啊?
  10. oracle创建表时创建序列号,oracle表中怎么建序列