1. MIG配置
1.1. xilinx FPGA芯片分类
1.1.1. A7 K7 (纯FPGA)
MIG IP核有两种接口 native和AXI4接口
-
native接口
-
axi4接口
1.1.2. ZYNQ (异构)
2. 配置
输入时钟周期 一般设为200Mhz
2.1. 如何选择系统的200M时钟?
1、外部50Mhz,通过FPGA的PLL锁相环 输出稳定的200M时钟
此时选择 no buffer【PLL输出默认勾选buffer】
2、如果外部直接输入 不通过pll
如果是差分的就使用diff 如果是单端就使用single ended
2.2. 如何选择参考时钟?
一般默认是200M 是固定死的 直接使用系统时钟就可以
2.3. XADC
1、监控开发板温度
2、模拟型号转化位数字信号
注意:XADC只能使用一次,在一个模块使用了XADC,在其他的模块就不能再使用了
3. 配置细节
3.1. 带宽
- 上图中两个双向箭头处的数据带宽是一样的
- 我们实际上就是在写左边的双线箭头部分的接口
带宽的计算:
- 用户端
- 200M * (4 * 32)
- axi端
- 800M * 16 * 2
3.2. no buffer是什么意思
no buffer就是MIG IP核内部没有例化IBUF原语
原语:
4. 使用MIG IP核
4.1. 信号参数:
// Memory interface ports 与axi进行数据交互的 不用管这部分的信号
.ddr3_addr (ddr3_addr ),// output [13:0] addr3_addr
.ddr3_ba (ddr3_ba ),// output [2:0] ddr3_ba
.ddr3_cas_n (ddr3_cas_n ),// output ddr3_cas_n
.ddr3_ck_n (ddr3_ck_n ),// output [0:0] ddr3_ck_n
.ddr3_ck_p (ddr3_ck_p ),// output [0:0] ddr3_ck_p
.ddr3_cke (ddr3_cke ),// output [0:0] ddr3_cke
.ddr3_ras_n (ddr3_ras_n ),// output ddr3_ras_n
.ddr3_reset_n (ddr3_reset_n ),// output ddr3_reset_n
.ddr3_we_n (ddr3_we_n ),// output ddr3_we_n
.ddr3_dq (ddr3_dq ),// inout [15:0] ddr3_dq
.ddr3_dqs_n (ddr3_dqs_n ),// inout [1:0] ddr3_dqs_n
.ddr3_dqs_p (ddr3_dqs_p ),// inout [1:0] ddr3_dqs_p
.ddr3_cs_n (ddr3_cs_n ),// output [0:0] ddr3_cs_n
.ddr3_dm (ddr3_dm ),// output [1:0] ddr3_dm
.ddr3_odt (ddr3_odt ),// output [0:0] ddr3_odt
//MIG IP核初始化信号
.init_calib_complete (init_calib_complete ),// output init_calib_complete
// Application interface ports 命令信号
.app_addr (app_addr ),// input [27:0] app_addr
.app_cmd (app_cmd ),// input [2:0] app_cmd
.app_en (app_en ),// input app_en
.app_rdy (app_rdy ),// output app_rdy
//写数据相关的信号
.app_wdf_data (app_wdf_data ),// input [127:0] app_wdf_data
.app_wdf_end (app_wdf_end ),// input app_wdf_end
.app_wdf_wren (app_wdf_wren ),// input app_wdf_wren
.app_wdf_rdy (app_wdf_rdy ),// output app_wdf_rdy
.app_wdf_mask (app_wdf_mask ),// input [15:0] app_wdf_mask
.app_rd_data (app_rd_data ),// output [127:0] app_rd_data
.app_rd_data_end (app_rd_data_end ),// output app_rd_data_end
.app_rd_data_valid (app_rd_data_valid ),// output app_rd_data_valid
//下面的信号的作用不是特别大 可以直接把输入信号置零
.app_ref_req (app_ref_req ),// input app_ref_req 信号的刷新请求
.app_ref_ack (app_ref_ack ),// output app_ref_ack 信号的刷新响应
.app_zq_req (app_zq_req ),// input app_zq_req 校准请求
.app_zq_ack (app_zq_ack ),// output app_zq_ack 校准响应
.app_sr_req (app_sr_req ),// input app_sr_req
.app_sr_active (app_sr_active ),// output app_sr_active
//与XADC信号有关 一般直接将这个信号置零就可以了
.device_temp_i (device_temp_i ),// input [11:0] device_temp_i
//ip核提供给用户端使用的时钟
.ui_clk (ui_clk ),// output ui_clk
.ui_clk_sync_rst (ui_clk_sync_rst ),// output ui_clk_sync_rst
// Reference Clock Ports
.clk_ref_p (clk_ref_p ),// input clk_ref_p
.clk_ref_n (clk_ref_n ),// input clk_ref_n
// System Clock Ports
.sys_clk_i (sys_clk_i ),
.sys_rst (sys_rst ) // input sys_rst
4.2. 时序图
4.2.1. 写时序
注意:
- 不支持突发 一个地址一个数据
- 写地址和写数据的顺序可以互换 三种方式都可以
4.2.2. 读时序
4.3. MIG IP 核用户端的 app_addr 地址信号如何与 DDR3 芯片的地址对应起来?
下面举一个例子:
bank | 23 = 8 |
---|---|
row | 215 = 32k |
col | 210 = 1k |
按照上面的数据写就行 也就实现了app_addr和DDR3芯片的地址对齐的操作
5. 补充ddr与sdram关系
-
最开始就是sdram,然后为了提高数据传输效率,就把sdram改成了双沿传输数据,所以第二代sdram就叫ddr了,要适应双沿传输数据
-
ddr就在sdram的基础上增加了一些控制和存储。其实自刷新,back,突发传输,潜伏期这些跟sdram的原理都是一样的。
-
ddr现在大多都是用ip核开发,反而是sdram一般都是自己写驱动,所以开始的入门的时候还是建议读一下sdram的手册,然后自己写一个sdram控制器,你就知道这些数据的含义了,后面ddr主要看下增加的内容,调用ip核设置参数就行了。
-
如果写过sdram控制器,对写ddr控制器也是有帮助的。sdram接口相比spi,uart还是要复杂很多的,对前期练习状态机之类的帮助极大,写过和没写过,区别还是很大的