记altera ddr3 controller ip配置调试

  1. 配置ip参数要按照ddr的datasheet来配置
  2. 仿真环境先读懂示例工程的仿真环境
  3. 直接copy ddr的test memory module
  4. 要写自己的avalon data_wr_ad控制模块
  5. 再写testbeach
  6. 下载调试

详细记录如下:
1.熟悉ddr 基础知识
1.1地址线复用概念
bank
raw 行地址
column 列地址
例如:以下图1GB(128Mx64)为例
addr [13:0]
raw 地址为13bit
column 地址为 10bit
当发送地址信息时先传输raw 地址信息,后传输column地址信息,他们都是使用的addr这个14bit bus线的

记altera ddr3 controller ip配置调试_第1张图片

1.2理解数据容量
上图128Mx64=1GB
数据构成如下:2^(raw width + cloumn width+ bank width +log2 (ddr颗粒数) +log2(最小单元比特数))即可
示例:2^(14+10+3+3+3)
=2^33=8Gb=1GB

1.3 ddr3 基本指令构成
记altera ddr3 controller ip配置调试_第2张图片
重要端口介绍:
记altera ddr3 controller ip配置调试_第3张图片
如图:
mem_cs_n 芯片片选,低有效
mem_we_n 芯片写使能,低有效
mem_ras_n raw地址片选,低有效
mem_cas_n column地址片选,低有效
mem_cke 时钟使能,高有效
mem_dq 数据data
mem_addr 地址
mem_dm 数据掩码 在写命令时起作用
mem_dqs&mem_dqs_n 数据采集沿 差分使得采集在数据中间,ddr是双沿采集

2 quartus ddr3 ip 基本熟悉
端口例化如下:

ddr3 ddr3x(
.pll_ref_clk (clk_50), // pll_ref_clk.clk
.global_reset_n (reset_n), // global_reset.reset_n
.soft_reset_n (reset_n), // soft_reset.reset_n
// .pll_ref_clk (pll_ref_clk), // pll_ref_clk.clk
// .global_reset_n (global_reset_n), // global_reset.reset_n
// .soft_reset_n (global_reset_n), // soft_reset.reset_n

.afi_clk								(afi_clk),  	    // afi_clk.clk
.afi_half_clk						(afi_half_clk),    // afi_half_clk.clk
.afi_reset_n						(afi_reset_n),     // afi_reset.reset_n
.afi_reset_export_n				(),                // afi_reset_export.reset_n //signal for monitor

///
///ddr module例化
.mem_a (mem_a), //.memory.mem_a
.mem_ba (mem_ba), //.mem_ba
.mem_ck (mem_ck), //.mem_ck
.mem_ck_n (mem_ck_n), //.mem_ck_n
.mem_cke (mem_cke), //.mem_cke
.mem_cs_n (mem_cs_n), //.mem_cs_n
.mem_dm (mem_dm), //.mem_dm
.mem_ras_n (mem_ras_n), //.mem_ras_n
.mem_cas_n (mem_cas_n), //.mem_cas_n
.mem_we_n (mem_we_n), //.mem_we_n
.mem_reset_n (mem_reset_n), //.mem_reset_n
.mem_dq (mem_dq), //.mem_dq
.mem_dqs (mem_dqs), //.mem_dqs
.mem_dqs_n (mem_dqs_n), //.mem_dqs_n

.mem_odt								(mem_odt),		    // .mem_odt
这些引脚在ddrsocket上都有实际对应的pin



//
application interface port	,avlon总线握手应用协议
.avl_ready       			       (avl_ready),       //avl.waitrequest_n
.avl_burstbegin 				   (1‘b0),  // .beginbursttransfer
.avl_addr						   (avl_addr),                // .address
.avl_rdata_valid  			   (avl_rdata_valid),                    //  .readdatavalid

.avl_rdata       			      (avl_rdata),                    // .readdata
.avl_wdata       			      (avl_wdata),           // .writedata
.avl_be          			      (avl_be),        // .byteenable
.avl_read_req    			      (avl_read_req),                    // .read
.avl_write_req   			      (avl_write_req),           // .write

.avl_size        			      (3'b1),                //.burstcount
/这里使用burstcount为1时则可以不使用begintranfer,将其都设为固定值即可,若实际应用场景有变则使用begintranfer功能,那么应用设计要复杂些,简单的应用只需和大多数总线一样在握手时给读写命令即可,若使用的到burst功能表示一次命令的会连续执行size的次数,其间其他读写命令不用管。
.local_init_done					(local_init_done),                    //status.local_init_done,important,状态标识信号
.local_cal_success				(),                    // .local_cal_success
.local_cal_fail					(),                    // .local_cal_fail

//下板子必须要进行约束的引脚,具体参考示例工程锁定的哪个pin(差分对pin即可)
.oct_rdn (), // oct.rdn /not care/
.oct_rup (), //.rup /not care/

.pll_mem_clk						(),                    // pll_sharing.pll_mem_clk
.pll_write_clk					   (),                    //.pll_write_clk
.pll_locked						   (),                    //.pll_locked
.pll_write_clk_pre_phy_clk		(), 					     // .pll_write_clk_pre_phy_clk
.pll_addr_cmd_clk				   (),                    //.pll_addr_cmd_clk

.pll_avl_clk (), // .pll_avl_clk
.pll_config_clk () //.pll_config_clk
);

调试心得记录:
1.可以选择仿真时间vsim -t 时间精度,注意时间精度的不同会导致结果错误,default 值是-t 1ps

记录调试技巧
1.记 signal tap ii抓数据,要将signal 进行clock domain的分类,采样clock选取触发时钟即可,不要采集时钟切记,否则signal tap ii 抓取的波形将毫无参考价值

2.signal 采集设置处要勾选segmented:可以采集电平触发拼接的功能

3.跨时钟域时一定要将信号在本时钟域进行打拍输出进行同步,这种操作多是针对reset和一些初始化标识信号才行,数据信号不能这样同步的,数据打拍操作一定是同一时钟域才行

4.时序设计时一定要时刻记住数据对齐的节拍顺序,画图画图画图

5.组合逻辑是导致代码时序不好的主要原因,所以在设计时要避免太长的组合逻辑,且signal tap 抓取信号时多是抓取寄存器的信号,线网型信号大多是被优化抓取不到的,要想被抓取要进行寄存器型输出且此寄存器要被使用否则也要被优化掉

5.进行长宽度的数据操作时,要懂得合理比特位group信号,可以提高观测性

6.先排除逻辑代码错误,仿真仿真仿真,后判断时序错误/

7.clk_delay和pix_delay的关系

1.系列定位为fifo问题,后利用双口ramt替换该处逻辑,但调试还是与仿真结果不一致,后继续debug,记: signal tap 采集自己确定时钟jiter问题,jiter会导致无法修复的时序问题,signal tap显示为0,若有参差代表是时钟有问题
2.记约束sdc的编写意义:在创建base时钟时占空比也会影响到时序,其频率要大于实际频率(asic时),fpga一般设成和实际频率一致即可,千万不能小于实际频率,其余量为百分之10,板子走线会尽量满足你写的约束去走线,约束的意义就是要告诉板子它所不知道的事情。
3.记各个子板见也会有相应的关系,sensor子板必须先配置才提供其相应可用的时钟
4.记大ip的pin planner及仿真都会有其相应的tcl,要利用其相应的环境设置,ddr配置是自己按照以往的方法,照着手册手动去布置会通过不了的,要手动结合tcl才能正确通过
5.记pin planner相应设计最好使用统一bank或者相邻bank的时钟
6.总结步骤:写rtl,后仿真,上板子。调试先用signal tap ii 分clock domain来确定调试实际板子效果,若仿真通过板子上操作与仿真不一致,先考虑时钟问题,看时钟质量是否可行。操作方法使用时钟采集自己看是否出现抖动,若无错误,在看波形出现的bug问题查看时序问题还是逻辑问题,一般来说自己设计的rtl在设计阶段不会使用错误,但引用别的ip很有可以自己使用配置不当,会一直出现错误

设计代码领悟
1.每一段逻辑尽可以的编写相对应的测试逻辑
2.

你可能感兴趣的:(fpga)