基于K7-325T的DDR3读写仿真实验
1、 IP核设置注意事项
⭐时钟选500MHz-即DQS频率为500MHz。
⭐Phy to controller clock ratio选择4:1-此处4代表的是DQS时钟,1代表逻辑收发时钟,此处为4:1的关系,即逻辑收发时钟为500/4=125MHz。此设置也会影响数据端口的位宽,如下分别为4:1和2:1时的UI数据位宽和DDR数据位宽的关系,本实验DDR数据位宽为32位,由于时上下沿采样,所以4:1的关系实际为8:1,所以对应的UI数据位宽位32*8=256bit。
⭐此处注意Input Clock Period 此时钟为输入FPGA的主时钟,也就是system clock,此处有很多值可以选择,本实验选择200MHz,选择这个时钟频率的好处是Reference clock可以直接选择使用system clock。
IP核设置的注意事项到此完毕。
2.读写时序分别如下图所示,此处注意DDR3的burst length 只能为8
下面是读写状态机:
module DDR_TEST(output reg[255:0] read_data,input sys_clk_p,input sys_clk_n,input sys_rst,output [14:0] ddr3_addr, // output [14:0] ddr3_addroutput [2:0] ddr3_ba, // output [2:0] ddr3_baoutput ddr3_cas_n, // output ddr3_cas_noutput [0:0] ddr3_ck_n, // output [0:0] ddr3_ck_noutput [0:0] ddr3_ck_p, // output [0:0] ddr3_ck_poutput [0:0] ddr3_cke, // output [0:0] ddr3_ckeoutput ddr3_ras_n, // output ddr3_ras_n output ddr3_reset_n, // output ddr3_reset_noutput ddr3_we_n, // output ddr3_we_ninout [31:0] ddr3_dq, // inout [31:0] ddr3_dqinout [3:0] ddr3_dqs_n, // inout [3:0] ddr3_dqs_ninout [3:0] ddr3_dqs_p, // inout [3:0] ddr3_dqs_poutput init_calib_complete, // output init_calib_complete output [0:0] ddr3_cs_n, // output [0:0] ddr3_cs_n output [3:0] ddr3_dm, // output [3:0] ddr3_dm output ddr3_odt // output [0:0] ddr3_odt );
reg [28:0] app_addr;
reg [2:0] app_cmd;
reg app_en;
reg [255:0] app_wdf_data;
reg app_wdf_end;
reg app_wdf_wren;wire [255:0] app_rd_data;
wire app_rd_data_end;
wire app_rd_data_valid;
wire app_rdy;
wire app_wdf_rdy;reg [2:0] state_c;
reg [2:0] state_n;
reg [28:0] cnt;
wire add_cnt;
wire end_cnt;
wire rst_h;
wire clk;
wire idl2write_start;
wire write2read_start;
wire read2idle_start;
wire write_vld;
wire read_vld;assign rst_n = !rst_h;
assign write_vld = app_rdy && app_wdf_rdy;
assign read_vld = app_rdy;
///
localparam IDLE = 3'b001;
localparam READ = 3'b010;
localparam WRITE = 3'b100;
///
always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt <= 0;endelse if(add_cnt)beginif(end_cnt)cnt <= 0;elsecnt <= cnt + 8;end
endassign add_cnt = (state_c==WRITE && write_vld)||(state_c==READ && read_vld && app_rd_data_valid);
assign end_cnt = add_cnt && cnt== 64-8;
//第一段:
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginstate_c <= IDLE;endelse beginstate_c <= state_n;end
end//第二段:
always@(*)begincase(state_c)IDLE:beginif(idl2write_start)beginstate_n = WRITE;endelse beginstate_n = state_c;endendWRITE:beginif(write2read_start)beginstate_n = READ;endelse beginstate_n = state_c;endendREAD:beginif(read2idle_start)beginstate_n = IDLE;endelse beginstate_n = state_c;endenddefault:beginstate_n = IDLE;endendcase
end
//第三段:
assign idl2write_start = state_c==IDLE && init_calib_complete && write_vld;
assign write2read_start = state_c==WRITE && end_cnt && read_vld;
assign read2idle_start = state_c==READ && end_cnt;//--app_addralways @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginapp_addr <= 29'h0;endelse if(state_c!=IDLE && (write_vld ||read_vld)) beginapp_addr <= cnt;end
end
//--app_cmd
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginapp_cmd<=3'h0;endelse if (state_c==WRITE && write_vld)beginapp_cmd<=3'h0;endelse if (state_c==READ && read_vld)beginapp_cmd<=3'h1;end
end
//--app_enalways @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginapp_en <=1'b0;endelse if(state_c!=IDLE && (write_vld ||read_vld))beginapp_en <=1'b1;endelse if(state_c == IDLE)beginapp_en <=1'b0;//app_en need to hold, in case the app_rdy pull down suddenlyend
end
//--app_wdf_data
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginapp_wdf_data<=256'd0;endelse if (state_c==WRITE && write_vld)begincase(cnt)29'd0:app_wdf_data<=256'd1;29'd8:app_wdf_data<=256'd2;29'd16:app_wdf_data<=256'd3;29'd24:app_wdf_data<=256'd4;29'd32:app_wdf_data<=256'd5;29'd40:app_wdf_data<=256'd6;29'd48:app_wdf_data<=256'd7;29'd56:app_wdf_data<=256'd8;default: app_wdf_data<=256'd0;endcaseend
end
//--app_wdf_endalways @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginapp_wdf_end <=1'b0;endelse if(state_c==WRITE)beginapp_wdf_end <=1'b1;endelse beginapp_wdf_end <=1'b0;end
end
//--app_wdf_wrenalways @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginapp_wdf_wren <=1'b0;endelse if(state_c==WRITE && write_vld)beginapp_wdf_wren <=1'b1;endelse beginapp_wdf_wren <=1'b0;end
end
//--read_data
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginread_data <=1'b0;endelse if(app_rd_data_valid)beginread_data <=app_rd_data;end
endmig_7series_0 u_mig_7series_0 (// Memory interface ports.ddr3_addr (ddr3_addr ), // output [14:0] ddr3_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 [31:0] ddr3_dq.ddr3_dqs_n (ddr3_dqs_n ), // inout [3:0] ddr3_dqs_n.ddr3_dqs_p (ddr3_dqs_p ), // inout [3:0] ddr3_dqs_p.init_calib_complete (init_calib_complete), // output init_calib_complete.ddr3_cs_n (ddr3_cs_n ), // output [0:0] ddr3_cs_n.ddr3_dm (ddr3_dm ), // output [3:0] ddr3_dm.ddr3_odt (ddr3_odt ), // output [0:0] ddr3_odt// Application interface ports.app_addr (app_addr ), // input [28:0] app_addr.app_cmd (app_cmd ), // input [2:0] app_cmd.app_en (app_en ), // input app_en.app_wdf_data (app_wdf_data ), // input [255: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_rd_data (app_rd_data ), // output [255: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_rdy (app_rdy ), // output app_rdy,This output indicates that the UI is ready to accept commands.app_wdf_rdy (app_wdf_rdy ), // output app_wdf_rdy,This output indicates that the write data FIFO is ready to receive data.app_sr_req (1'b0 ), // input app_sr_req.app_ref_req (1'b0 ), // input app_ref_req.app_zq_req (1'b0 ), // input app_zq_req.app_sr_active ( ), // output app_sr_active.app_ref_ack ( ), // output app_ref_ack.app_zq_ack ( ), // output app_zq_ack.ui_clk (clk ), // output ui_clk 500M/4=125M.ui_clk_sync_rst (rst_h ), // output ui_clk_sync_rst.app_wdf_mask (32'b0 ), // input [31:0] app_wdf_mask// System Clock Ports.sys_clk_p (sys_clk_p ), // input sys_clk_p 200M.sys_clk_n (sys_clk_n ), // input sys_clk_n.sys_rst (sys_rst ) // input sys_rst
);
endmodule
状态机对从0开始的连续8个地址分别写入1-8的数字,写完成后再读出。
3、仿真
DDR的仿真需要DDR的Module,模型可以通过example design获得,但直接拿过来并不能用,需要进行修改,后面会给出包括TB的完整工程链接,这里就不做过多阐述,下面是仿真结果:可以看到结果完全符合预期。
包括仿真文件的完整工程见下面链接:
https://download.csdn.net/download/weixin_45002573/11998076
基于K7-325T的DDR3读写仿真实验相关推荐
- 基于MIG控制器的DDR3读写控制详解
基于MIG控制器的DDR3读写控制详解 目的:详细介绍FPGA中基于MIG IP核控制的DDR3详细控制及内部逻辑 平台:AX7350-Xilinx 软件:Vivado 2017.4 1.MIG IP ...
- 基于virtuoso IC 618的LDO仿真实验
前言: 这里是我的LDO仿真记录帖. 往后各种结构的LDO仿真记录就存放在这个帖子里了. 不定期更新. 基于virtuoso IC 618的LDO仿真实验 目录 序 LDO学习 0.1 仿真参数 ...
- 【基于参数估计的ISAR定标MATLAB仿真实验】
本章内容简介:分析了CPF(三次相位函数法),CICPF(相干三次相位函数法)和ICPF(积分三次相位函数法)三种LFM信号调频率估计方法,分析了基于LOG算子(高斯拉普拉斯)的散射点提取方法,进行仿 ...
- 基于matlab仿真的功率因数测定方法研究,基于MATLAB的高功率因数整流器仿真实验平台研究...
1 概述 简单系统可直接建立模型,并分析模块之间的相互关系以及模块输入输出关系.但对相对复杂的系统,Simulink包含多个模块,使得各个模块之间的相互关系非常复杂,不利于分析.为此,可将具有一 ...
- 基于matlab的升压斩波实验,实验二、基于Simulink的直流斩波电路的仿真实验报告...
仲恺农业工程学院实验报告纸 自动化(院.系)自动化专业 112 班组电力电子技术课实验二.基于Simuilink的直流斩波电路仿真实验 一.实验目的 (1)加深理解直流斩波电路的工作原理. (2)学会 ...
- DDR3 AXI4 IP核读写仿真实验(2)
上篇blog中记录了DDR3 AXI4接口的IP配置详情,这一文章则是记录自己在项目工程以及学习中对于DDR3的读写测试.先讲一下大概的工程架构:产生16位的自加数写进写FIFO中,当FIFO中的数达 ...
- matlab上能仿真功率吗,基于MATLAB的高功率因数整流器仿真实验平台
4 基于仿真模块的三相VSR系统的仿真 整个系统是由一个电压环和2个电流环组成的双内环单外环的双环控制结构,电压环不仅控制直流输出电压,并将电压环调节器的输出作为有功电流id的给定,无功电流iq的给定 ...
- matlab画一个电动机系统图,基于MATLABGUI的电机学仿真实验系统设计
38 2009年第17期(总第87期) E-mail:cmee@http://www.doczj.com/doc/ee4e2bdfb7360b4c2f3f6479.html 基于MATLAB GUI的 ...
- 系统仿真基础与计算机实现,计算机综合仿真实验系统的研究与开发
摘要: 计算机仿真实验系统是实验教学的理想平台.目前,我国高校因扩招而出现实验教学与理论教学比例失衡的问题,且现有自控原理实验设备已不能满足过程控制仿真要求.针对这一现状,本文在对国内外仿真实验室建设 ...
最新文章
- Java 命名规范(非常全面)
- OpsRamp推出以服务为中心的AIOps和云监控功能
- KMP经典算法与变形的应用(字符串parttern匹配问题)
- elasticsearch的增删改查
- HDU 1114(没有变形的完全背包)
- proe4.0安装教程
- 【视频】vue $watch监控数据的变化
- MySQL条件运算符的使用
- H5添加QQ好友的链接
- 重载(overload)与重写(override)的区别
- java 原子量Atomic举例(AtomicReference)
- Typescript Mixins(混合)
- 字节实习成功提前转正啦!
- 丢失的遗传力--Missing heritability
- CD 20 打气球的最大分数
- 高校最低分数录取线c语言,全国: 2018年普通高等学校招生录取最低控制分数线...
- 赛尔无人机 | 航测新标杆 Phantom 4 RTK
- 希尔伯特变换在MATLAB中的应用
- Refused to display ‘https://xxx.com.cn‘ in a frame because it set ‘X-Frame-Options‘ to ‘sameorigin‘
- 社区医疗app-Ui设计
热门文章
- 小车自动往返工作原理_小车自动往返.ppt
- html5ie11缩放,如何设置缩放级别Internet Explorer 9 - Browsers | Microsoft Docs
- mysql 分桶_mysql的分组和过滤桶where的组合运用
- 黑基网博客——网络安全、工具软件、无线智能设备、编程开发、网赚分享与交流基地
- MacBook设置中国时区时间
- 优化CSP模式 手游也能站着把钱挣了
- 这个杀手不太冷(一)
- php导出成word试卷,依据word模板批量生成试卷
- bnuoj 44359 快来买肉松饼
- 南通大学计算机学院顾飘,解密通大软件专业“学霸”们的考研之路_南通大学...