F5—创建DDR3内存条DIMM读写测试程序2023-05-16

news2024/11/27 0:32:11

本文区别于DDR颗粒的配置,记录几个与颗粒配置不同的地方,具体DDR的原理请查看DDR3的应用总结(一)DDR3的应用总结(二)

1.确认板卡FPGA型号为xc7k325tffg900 -2,据此创建FPGA工程。

2.添加MIG IP核。具体配置如下

①第一页描述当前工程信息

 ②第二页,可设置IP核的名称,保持默认。

 

③第三页 设置兼容情况,保持默认。

④第四页 保持默认选择DDR3 SDRAM

 

 ⑤第五页如图所示配置。其中①指DDR3颗粒的物理时钟,例如一颗16bit位宽的DDR设置为400MHz,则它的传输速度为每一个800MHz(DDR双沿传输的原因)周期传输16bit。这里时钟的范围受到FPGA芯片速度等级和型号的制约,以及与内存条的支持速度也有关。如我用的内存条MT16KTF1G64HZ-1G6,速度范围在1500ps-3000ps之间。②指的是用户时钟,4:1的4指的是①设置的物理时钟。第③部分指的是类型选择,内存条选择SODIMMs。④处是DDR3内存条的型号,如果不在列表需要根据速度参数,位宽大小找一个兼容的型号。⑤处勾选上mask后,如果相应的管脚不连接,会造成DDR3初始化失败。其余配置保持默认即可。

⑥第六页 此处①代表参考时钟,选择200MHz为固定大小。②处如果是内存条就选择RZQ/4,如果是颗粒就选择RZQ/6。

 

⑦第七页,参考时钟和系统时钟均由时钟IP生成给到,因此选择no buffer,其他的按照默认配置即可。

 

⑧DDR3颗粒要勾选DCI Cascade,内存条不用勾选。后面就是选择引脚,其他的都保持默认,即可。

 

3.测试程序

如果需要修改这段程序,需要注意MIG的接口各信号的位宽应该保持一致,另外程序中设计了两个LED灯,读写测试正确的时候,指示灯led1常亮,反之则闪烁。LED2只是容量,当测试到所设置的容量的时候常量。代码中TEST_LENGTH指示的含义是突发次数,也可以说是容量。每一次突发是512bit数据,使用内存的容量除以512bit,即为最大的突发次数。当然使用的芯片的物理位宽不同,例如只有一片16bit位宽的DDR颗粒,那一次突发的数据为8*16bit=128bit,那最大的突发次数就要用容量除以128bit了。

module dimm_top(
    input              sys_clk_p,
    input              sys_clk_n,       
	inout  [63:0]      ddr3_dq			, 
	inout  [7:0]       ddr3_dqs_n		, 
	inout  [7:0]       ddr3_dqs_p		,   
	output [15:0]      ddr3_addr		, 
	output [2:0]       ddr3_ba			, 
	output             ddr3_ras_n		, 
	output             ddr3_cas_n		, 
	output             ddr3_we_n		, 
	output             ddr3_reset_n	, 
	output [1:0]       ddr3_ck_p		, 
	output [1:0]       ddr3_ck_n		, 
	output [1:0]       ddr3_cke		    , 
	output [1:0]       ddr3_cs_n		, 
	output [7:0]       ddr3_dm			, 
	output [1:0]       ddr3_odt         , 
    output reg         led1,              
    output reg         led2        
    );         
    wire                clk_rst;                            
    wire                clk_200;
    reg     [29:0]      app_addr_begin=0;
    wire                app_en;              //写命令使能
    wire    [2:0]       app_cmd;             //用户读写命令
    wire                app_wdf_wren;        //DDR3写使能
    wire                app_wdf_end;         //突发写最后一个数标识
    wire    [29:0]      app_addr;            //用户平面地址
    wire                app_rdy;             //设备接收准备就绪   
    wire                app_wdf_rdy;         //写响应
    wire    [511:0]     app_rd_data;         //用户读数据
    wire                app_rd_data_end;     //突发读当前时钟最后一个数据
    wire                app_rd_data_valid;   //读数据有效
    wire    [511:0]     app_wdf_data;        //用户写数据
    wire                app_sr_active;       //保留
    wire                app_ref_ack;         //刷新请求
    wire                app_zq_ack;          //ZQ 校准请求
    wire        		init_calib_complete; //校准完成信号
    wire                ui_clk ;             //用户时钟
    wire                ui_clk_sync_rst;              
    clk_wiz_0 u_clk_wiz_0(.clk_out1(clk_200), .reset(1'b0), .locked(clk_rst), .clk_in1_p(sys_clk_p),.clk_in1_n(sys_clk_n)); 

    mig_7series_0 mig_JC (
    // Memory interface ports
    .ddr3_addr                      (ddr3_addr), 		// output [15:0]	
    .ddr3_ba                        (ddr3_ba),  		// output [2:0]
    .ddr3_cas_n                     (ddr3_cas_n), 		// output			
    .ddr3_ck_n                      (ddr3_ck_n),  		// output [1:0]		
    .ddr3_ck_p                      (ddr3_ck_p),  		// output [1:0]		
    .ddr3_cke                       (ddr3_cke),  		// output [1:0]		
    .ddr3_ras_n                     (ddr3_ras_n),  		// output		
    .ddr3_reset_n                   (ddr3_reset_n),  	// output			
    .ddr3_we_n                      (ddr3_we_n),  		// output		
    .ddr3_dq                        (ddr3_dq),  		// inout [63:0]	
    .ddr3_dqs_n                     (ddr3_dqs_n),  		// inout [7:0]		
    .ddr3_dqs_p                     (ddr3_dqs_p),  		// inout [7:0]		
    .init_calib_complete            (init_calib_complete),  // output		
	.ddr3_cs_n                      (ddr3_cs_n),  		// output [1:0]		
    .ddr3_dm                        (ddr3_dm),  		// output [7:0]	
    .ddr3_odt                       (ddr3_odt),  		// output [1:0]		
    // Application interface ports
    .app_addr                       (app_addr), 		 // input [29:0]		
    .app_cmd                        (app_cmd),  		 // input [2:0]		
    .app_en                         (app_en),  			 // input	
    .app_wdf_data                   (app_wdf_data), 	 // input [511:0]	
    .app_wdf_end                    (app_wdf_end), 		 // input			
    .app_wdf_wren                   (app_wdf_wren),  	 // input				
    .app_rd_data                    (app_rd_data),  	 // output [511:0]		
    .app_rd_data_end                (app_rd_data_end),   // output		
    .app_rd_data_valid              (app_rd_data_valid), // output	
    .app_rdy                        (app_rdy),  		 // output		
    .app_wdf_rdy                    (app_wdf_rdy),  	 // output			
    .app_sr_req                     (1'b0),  			 // input			
    .app_ref_req                    (1'b0),  			 // input		
    .app_zq_req                     (1'b0),              // input			
    .app_sr_active                  (app_sr_active),     // output			
    .app_ref_ack                    (app_ref_ack), 		 // output		
    .app_zq_ack                     (app_zq_ack),  	   	 // output		
    .ui_clk                         (ui_clk),  			 // output用户时钟输出,其实是通过IP配置自己配出来的 	 
    .ui_clk_sync_rst                (ui_clk_sync_rst),   // output		
    .app_wdf_mask                   (64'b0),  			 // input [63:0] //写数据屏蔽
    .sys_clk_i                      (clk_200),//输入IP的时钟
    // Reference Clock Ports
    .clk_ref_i                      (clk_200),//参考时钟		
    .sys_rst                        (clk_rst) // input sys_rst
    );
parameter  TEST_LENGTH = 27'd134200000; //每一次突发是512bit 8GB可以支持134217728次突发 99.98%
// parameter  TEST_LENGTH = 32'd60000000;
//**************1.先写后读状态机state machine
parameter  IDLE  = 2'd0;           
parameter  WRITE = 2'd1;          
parameter  WAIT  = 2'd2;           
parameter  READ  = 2'd3;   
reg [511:0]my_512_data;
reg [26:0] wr_addr_cnt;
reg [26:0] rd_addr_cnt;
reg [1:0]  state;
 always @(posedge ui_clk or negedge rst_n) begin
     if((~rst_n)||(error_flag)) begin 
         state    <= IDLE;          
         my_512_data <= 512'd0;     
         wr_addr_cnt  <= 27'd0;      
         rd_addr_cnt  <= 27'd0;       
         app_addr_begin<= 30'd0;         
     end
     else if(init_calib_complete)begin               //MIG IP核初始化完成
         case(state)
            IDLE:begin
                state    <= WRITE;
                my_512_data <= 512'd0;   
                wr_addr_cnt  <= 27'd0;     
                rd_addr_cnt  <= 27'd0;       
                app_addr_begin     <= 30'd0; 
            end
            WRITE:begin
                if((wr_addr_cnt == TEST_LENGTH-1) &&(app_rdy && app_wdf_rdy))
                    state    <= WAIT;                  //写到设定的长度跳到等待状态
                else if(app_rdy && app_wdf_rdy)begin   //写条件满足
                    my_512_data <= my_512_data + 1;  //写数据自增
                    wr_addr_cnt  <= wr_addr_cnt + 1;   //写计数自增
                    app_addr_begin<= app_addr_begin + 8;      //DDR3 地址自增
                end else begin          //写条件不满足,保持当前状态
                     my_512_data <= my_512_data;      
                     wr_addr_cnt  <= wr_addr_cnt;
                     app_addr_begin<= app_addr_begin; 
                end
            end
            WAIT:begin                                                 
                state   <= READ;                     //下一个时钟,跳到读状态
                rd_addr_cnt <= 27'd0;                //读地址复位
                app_addr_begin<= 30'd0;                //DDR3读从地址0
            end
            READ:begin                               //读到设定的地址长度    
                if((rd_addr_cnt == TEST_LENGTH -1 ) && app_rdy)
                    state   <= IDLE;                   //则跳到空闲状态 
                else if(app_rdy)begin                  //若MIG已经准备就绪,则开始读
                    rd_addr_cnt <= rd_addr_cnt + 1'd1; //用户地址每次加一
                    app_addr_begin    <= app_addr_begin + 8;       //DDR3地址加8
                end else begin   //若MIG没准备好,则保持原
                    rd_addr_cnt <= rd_addr_cnt;
                    app_addr_begin    <= app_addr_begin; 
                end
            end
            default:begin
                state    <= IDLE;
                my_512_data  <= 512'd0;
                wr_addr_cnt  <= 27'd0;
                rd_addr_cnt  <= 27'd0;
                app_addr_begin <= 30'd0;
            end
         endcase
     end
 end   
//**************2.根据状态机与MIG指示信号为app信号赋值
 assign app_en  =((state == WRITE && (app_rdy && app_wdf_rdy))||(state == READ && app_rdy)) ? 1'b1:1'b0;             
 assign app_cmd =(state == READ) ? 3'd1 :3'd0;  
 assign app_wdf_wren=(state == WRITE && (app_rdy && app_wdf_rdy)) ? 1'b1:1'b0;
 assign app_wdf_end =app_wdf_wren; 
 assign app_addr    =app_addr_begin;
 assign app_wdf_data=my_512_data;   
//*******************3.用户判错逻辑
reg     [26:0]   rd_cnt;
wire             rst_n;     //复位,低有效
reg              error_flag;
parameter  L_TIME = 28'd200_000_000;
reg     [27:0]   led_cnt;    //led计数
wire             error;     //读写错误标记
assign rst_n = ~ui_clk_sync_rst;//&&myrst
always @(posedge ui_clk or negedge rst_n) begin
     if(~rst_n) 
        rd_cnt  <= 0;              //若计数到读写长度,且读有效,地址计数器则�?0                                    
     else if(app_rd_data_valid&&(rd_cnt == TEST_LENGTH - 1))
        rd_cnt <= 0;              //其他条件只要读有效,每个时钟自增1
     else if (app_rd_data_valid)
        rd_cnt <= rd_cnt + 1;
 end
//判断错误,读出数据应为计数递增数据
assign error = (app_rd_data_valid && (rd_cnt!=app_rd_data));
always @(posedge ui_clk or negedge rst_n) begin
    if(~rst_n)
        led2<=0;
    else if(rd_cnt==32'd134200000-1)
        led2<=1;
end 
always @(posedge ui_clk or negedge rst_n) begin
     if(~rst_n) 
         error_flag <= 0;
     else if(error)
         error_flag <= 1;
  end
//读写测试正确,指示灯led1常亮,反之则闪烁
always @(posedge ui_clk or negedge rst_n) begin
      if((~rst_n) || (~init_calib_complete )) begin
         led_cnt <= 28'd0;
         led1 <= 1'b0;
     end
     else begin
         if(~error_flag)   //常亮代表正常,闪烁代表故障                            
             led1 <= 1'b1;                     
         else begin                            
             led_cnt <= led_cnt + 28'd1;
             if(led_cnt == L_TIME - 1'b1) begin
             led_cnt <= 25'd0;
             led1 <= ~led1;                     
             end                    
        end
    end
end
endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/533728.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

干货|SPSS方差分析中的简单效应检验(上)

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐~ 今天和大家分享的是包寒吴霜博士生介绍的 SPSS 方差分析中的简单效应检验系列中的第一部分 —— SPSS 方差分析中的简单效应检验&#xff1a;完整教程。 SPSS 是一个入门级的统计分析软件&…

【论文笔记】数据增强系列.1

本文介绍简单数据增强、好处以及常见的增强方式&#xff0c;也介绍几篇关于数据增强的工作&#xff1a; CutMix&#xff08;ICCV2019&#xff09;&#xff0c;ContrastMask&#xff08;CVPR2022&#xff09;&#xff0c;BCP&#xff08;CVPR2023&#xff09;。 数据增强简介&a…

Nginx缓存优雅清除缓存

1.Nginx缓存 前面我们知道Nginx可以对浏览器缓存进行配置&#xff0c;让一些静态资源缓存到用户本地存储&#xff0c;以提高页面的响应速度&#xff0c;也能降低服务端的压力。浏览器执行缓存的流程如下&#xff1a; 试想一下&#xff0c;如果用户主动清空了本地的浏览器缓存&…

HNU-操作系统-讨论课6

讨论题目&#xff1a; 以一种程序设计语言为例&#xff0c;如 Java、C、Python等介绍其为实现并发控制提供的各种锁机制

doxygen: 在Windows上源码编译(施工中)

文章目录 1. 目的2. 思路3. 安装 Chocolatey4. 用 choco 安装 bison 和 flex安装 gs:安装 libiconv 5. 编译报错 1. 目的 在 windows 上源码编译 doxygen&#xff0c; 改代码加功能。 2. 思路 doxygen 依赖 flex 和 bison&#xff0c; 手动编译 flex 和 bison 很麻烦可以用…

【华为OD机试c++】九宫格游戏【2023 Q1 A卷|200分】

■ 题目描述 九宫格是一款广为流传的游戏,起源于河图洛书。 游戏规则是:1到9九个数字放在33的格子中,要求每行、 每列以及两个对角线上的三数之和都等于15. 在金麻名著《射雕英雄传》中黃蓉曾给九宫格的一种解法,口诀: 戴九恩一,左三右七,二四有肩,八六为足,五居…

通过命令行体验长安链

通过命令行体验长安链 1 、概述2、环境依赖2.1、硬件依赖2.2、软件依赖2.3、git安装2.4、golang安装2.5、gcc 3、环境搭建3.1、源码下载3.2、 源码编译3.3、编译及安装包制作3.4、启动节点集群3.5、查看节点启动使用正常 官方文档 https://docs.chainmaker.org.cn/v2.3.1/html/…

亿信BI专有名词讲解

数据库连接池主题域/主题集/主题表维/ 维表报表模板组件容器布局计算参数分析区浮动门户EasyOlap领导驾驶舱(Dashboard) 1.数据库连接池 连接池就是存储资源和数据的地方。BI一定会有一个缺省连接池&#xff0c;BI服务器的系统表都是在缺省连接池下面&#xff0c;初次部署BI服…

30.SSM框架整合

目录 一、SSM框架整合。 &#xff08;1&#xff09;核心笔记。 &#xff08;1.1&#xff09;Spring、SpringMVC、MyBatis三者的配置。 &#xff08;1.2&#xff09;请求字符集格式与响应字符集格式。 &#xff08;2&#xff09;原始方式整合。 &#xff08;2.1&#xff…

路径规划算法:基于郊狼算法的路径规划算法- 附代码

路径规划算法&#xff1a;基于郊狼优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于郊狼优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法郊狼…

带你实现初阶扫雷小游戏—【C语言】

目录 1. 扫雷游戏实现的思路 注意点1 注意点2 2. 函数实现扫雷功能 2.1 初始化棋盘 2.2 显示棋盘 2.3 设置雷 2.4 排查雷 2.5 返回附近雷的个数 3.源码 3.1 game.h 3.2 game.c 3.3 test.c 1. 扫雷游戏实现的思路 注意点1 我们这里拿9*9的棋盘&#xff08;其中…

Java的基操,基操(二)

&#x1f525;常量(Constant)&#x1f525;基本数据类型(primitive data type)&#x1f525;整型&#x1f525;浮点型(Floating Point Number)&#x1f525;字符型&#x1f525;布尔型(boolean)&#x1f525;运算符(operator)&#x1f525;逻辑运算符&#x1f525;数据类型的转…

【C++初阶】:动态管理

动态管理 一.new和delete&#xff08;一般使用&#xff09;二.operator new与operator delete函数&#xff08;底层&#xff09;三.new和delete的实现原理四.定位new&#xff08;placement-new&#xff09;五.malloc和new的区别 前置知识&#xff08;堆区&#xff09;&#xff…

什么样的项目适合UI自动化测试?

我们在考虑做自动化测试之前&#xff0c;一定要先分析一下&#xff0c;这个项目到底适不适合做自动化测试&#xff0c;避免在不太适合自动化测试的项目中痛苦挣扎&#xff0c;既浪费了大量的人力和时间&#xff0c;又收效甚微。下面简单列举一下评估一下项目是否适合做自动化的…

【JavaEE初阶】网络编程

文章目录 网络编程基础网络资源网络编程网络编程中的基本概念发送端和接收端请求和响应客户端和服务端常见的客户端服务端模型 Socket套接字了解UDP和TCPUDP数据报套接字编程DatagramSocket APIDatagramPacket APIInetSocketAddress APIUDP版本的客户端服务器程序 TCP流套接字编…

try catch finally 里面有return的执行顺序

目录 实例结论 实例 1.try和catch中有return时&#xff0c;finally里面的语句会被执行吗 我们可以来分别看看 (1)执行try中的return时 public class Solution {public static int show() {try {return 1;}finally{System.out.println("finally模块被执行");}}publi…

第7章链接:如何动态连接共享库、从应用程序中加载和链接共享库

文章目录 7.10 动态链接共享库静态库的缺点何为共享库共享库的"共享"的含义动态链接过程 7.11 从应用程序中加载和链接共享库运行时动态加载和连接共享库的接口 dlopen函数 dlsym函数 dlclose函数 dlerror动态加载和链接共享库的应用程序示例 7.10 动态链接共享库 静…

强化学习路线规划之深度强化学习代码

虽然说很多代码都有问题&#xff0c;但是不管它们&#xff0c;我不是为了去debug&#xff0c;紧盯住自己的目标&#xff0c;目标是整理出一条通常的强化学习之路&#xff0c;让自己以及看到这些博客的大家在学习的时候能够少走一些弯路。所以从q-learning和Sarsa开始&#xff0…

buuctf9

目录 web [ZJCTF 2019]NiZhuanSiWei misc [BJDCTF2020]认真你就输了 刷新过的图片 crypto 篱笆墙的影子 RSA web [ZJCTF 2019]NiZhuanSiWei 1.启动环境 <?php $text $_GET["text"]; $file $_GET["file"]; $password $_GET["password…

UE4与MATLAB联合仿真环境配置中遇到的问题及解决办法

UE4与MATLAB联合仿真环境配置中遇到的问题及解决办法 目录 UE4与MATLAB联合仿真环境配置中遇到的问题及解决办法前言问题及解决办法1. The following modules are missing or built with a different engine version: MathWorksAerospace MathWorksSimulation MathWorksUAV Eng…