DDR2 IP核调式记录2

本文相对简单,只供自己看看就行。从其它的博客找了个代码,然后记录下仿真波形。

1. 功能

        直接使用quartus生成的DDR2 IP核,然后实现循环 -->写入burst长度的数据后读出。

        代码数据的传输是32位,实际使用了两片IC。因此IP核也是32位交互。

2.信号分析

        burst=4,是IC固有的=预取值。而代码中LEN为用户一次想要读取数据的长度的。与local_size和burst_length无关。

        分为4个状态: IDLE、WRITER、WRITING、READR、READING。WRITER和READR状态下,开始读写burst的第一个数据,其余的在WRITING和READING状态读写。

         local_ready:很重要的一个指示信号。要进行读写操作,必须在IP核(ddr2)准备好的情况下进行。因此,需要一直对此信号进行检测判断。

        写入地址(mem_local_addr),一开始为1,当读到的数据长度rdatalen=5时(初始值=1),mem_local_addr <= mem_local_addr + 4;

命令

连续写

连续读

读完写

3. 仿真波形分析

如下图所示:每次先写入连续4个数据,(例如1,2,3,4),然后再依次读出。

读过程及下一次写

4. 附代码

顶层代码:

module ddr2wrtest (input 					clk 			,    // Clockinput 					global_reset_n 	,  // Asynchronous reset active lowoutput  [ 12: 0]		mem_addr 		,	output  [  2: 0] 		mem_ba 			,	output					mem_cas_n 		,	output					mem_cke 		,	inout					mem_clk 		,	inout 					mem_clk_n 		,	output 					mem_cs_n 		,	output 	[  1: 0]		mem_dm 			,	inout	[ 15: 0]		mem_dq 			,	inout	[  1: 0]		mem_dqs 		,	output					mem_odt 		,	output					mem_ras_n 		,	output					mem_we_n 			);parameter 			LEN 	= 8; 				// 突发长度 4parameter 			IDEL 		= 5'b00001;		// 空闲态parameter 			WRITER 		= 5'b00010;		// 准备写parameter 			WRITING 	= 5'b00100;		// 写状态parameter 			READR 	 	= 5'b01000;		// 准备读parameter 			READING 	= 5'b10000;		// 读状态reg	 [  5: 0]		state;
//**********************与IP相连部分********************//reg [ 24: 0]	mem_local_addr		=1	;wire 				mem_local_init_done		;	wire 				local_burstbegin_sig	;								wire [ 31: 0]	mem_local_rdata 		;wire 				mem_local_rdata_valid	;wire 				mem_local_read_req		;wire 				mem_local_ready			;							wire [  3: 0]	mem_local_size			;reg  [ 31: 0]	mem_local_wdata			;wire 				mem_local_write_req		;wire 				phy_clk 				;wire 				reset_phy_clk_n 		;
//*****************************************************//wire 				rst_n 					;reg  [  3: 0] 		rdatalen 				; // 读突发长度计数器reg  [  3: 0] 		wdatalen 				; // 写突发长度计数器reg  [100: 0]		state_name				; // 状态名assign rst_n = reset_phy_clk_n&&mem_local_init_done;assign mem_local_size = LEN;assign local_burstbegin_sig = ((state == WRITER&&mem_local_ready) || (state == READR&&mem_local_ready))?1:0;assign mem_local_write_req  = (state == WRITING)?1:0;assign mem_local_read_req 	= (state == READR&&mem_local_ready)?1:0;ddr2 ddr2_inst(
//==============================《				   》===============================.aux_full_rate_clk 	(						),	//全速率时钟.aux_half_rate_clk 	(						),	//半速率时钟
//==============================《    用户操作信号   》===============================.global_reset_n		(global_reset_n 		),	//全局复位.local_address 		(mem_local_addr			),	//当前操作地址.local_be 			(8'hff					),	//数据掩码.local_burstbegin 	(local_burstbegin_sig	),	//突发起始信号.local_init_done 		(mem_local_init_done	),	//初始化完成信号.local_rdata 			(mem_local_rdata 		),	//读数据总线.local_rdata_valid 	(mem_local_rdata_valid	),	//读有效标志.local_read_req 		(mem_local_read_req		),	//读请求,保持一个时钟周期.local_ready 			(mem_local_ready		),	//接受到请求.local_refresh_ack 	(						),	//自动刷新.local_size 			(mem_local_size			),	//突发长度.local_wdata 			(mem_local_wdata		),	//写数据总线.local_write_req 		(mem_local_write_req	),	//写请求
//==============================《  与DDR2相连的信号  》===============================.mem_addr 			(mem_addr 				),	//地址总线.mem_ba 				(mem_ba					),	//bank地址.mem_cas_n 			(mem_cas_n				),	//行选通.mem_cke 				(mem_cke				),	//时钟使能.mem_clk 				(mem_clk 				),	//操作时钟.mem_clk_n 			(mem_clk_n				),	//反向时钟.mem_cs_n 			(mem_cs_n 				),	//片选信号.mem_dm 				(mem_dm 				),	//DDR2数据屏蔽信号.mem_dq 				(mem_dq 				),	//数据总线.mem_dqs 				(mem_dqs 				),	//数据选取脉冲信号.mem_odt 				(mem_odt 				),	//片内终结信号.mem_ras_n 			(mem_ras_n 				),	//行选通.mem_we_n 			(mem_we_n 				),	//使能
//==============================《    用户操作信号    》===============================.phy_clk 				(phy_clk 				),	//提供给用户的操作时钟.pll_ref_clk 			(clk 					),	//给ddr2的输入时钟.reset_phy_clk_n 		(reset_phy_clk_n 		),	//提供给用户的复位信号.reset_request_n 		(						),	//当PLL锁定后为低电平.soft_reset_n 		(1'b1 					)	//软复位,不包括PLL的复位);always@(*)case (state)IDEL  	:	state_name = "IDEL";WRITER 	:	state_name = "WRITER"		;		WRITING	:	state_name = "WRITING"		;		READR 	:	state_name = "READR"		;			READING	:	state_name = "READING";default : /* default */;endcasealways@(posedge phy_clk or negedge rst_n)begin if(!rst_n)state <= IDEL;elsecase (state)IDEL 	:	state <= WRITER;WRITER 	: 	if(mem_local_ready)state <= WRITING;elsestate <= WRITER;WRITING : 	if(wdatalen == LEN)state <= READR;elsestate <= state;READR 	: 	if(mem_local_ready)state <= READING;elsestate <= READR;READING : 	if(rdatalen == LEN)state <= IDEL;elsestate <= state;		default : state <= state;endcaseend// 写的数据自加1always@(posedge phy_clk or negedge rst_n)begin if(!rst_n)mem_local_wdata <= 1;else if(state == WRITING && mem_local_ready)mem_local_wdata <= mem_local_wdata + 1;elsemem_local_wdata <= mem_local_wdata;end// 当前写的数据突发长度always@(posedge phy_clk or negedge rst_n)begin if(!rst_n) wdatalen <= 1;else if(state == WRITING && mem_local_ready)wdatalen <= wdatalen + 1;else if(state == WRITING && !mem_local_ready)wdatalen <= wdatalen ;elsewdatalen <= 1;end// 当前读的数据突发长度always@(posedge phy_clk or negedge rst_n)begin if(!rst_n) rdatalen <= 1;else if(state == READING && mem_local_rdata_valid)rdatalen <= rdatalen + 1;elserdatalen <= 1;end// 操作地址自加always@(posedge phy_clk or negedge rst_n)begin if(!rst_n)mem_local_addr <= 1;else if(rdatalen == LEN)mem_local_addr <= mem_local_addr + LEN;endendmodule

测试代码

`timescale 1ns/1ps
module test_tb ();reg				clk 		;
reg				global_reset_n;wire  	[ 12: 0]	mem_addr 	;
wire  	[  2: 0] 	mem_ba 		;
wire				mem_cas_n 	;
wire				mem_cke 	;
wire				mem_clk 	;
wire 				mem_clk_n 	;
wire 				mem_cs_n 	;
wire 	[  1: 0]	mem_dm 		;
wire	[ 15: 0]	mem_dq 		;
wire	[  1: 0]	mem_dqs 	;
wire				mem_odt 	;
wire				mem_ras_n 	;
wire				mem_we_n 	;ddr2wrtest u1 (.clk 			(clk 			),    // Clock.global_reset_n (global_reset_n ) ,  // Asynchronous reset active low.mem_addr 		(mem_addr 		),	.mem_ba 		(mem_ba 		),	.mem_cas_n 		(mem_cas_n 		),	.mem_cke 		(mem_cke 		),	.mem_clk 		(mem_clk 		),	.mem_clk_n 		(mem_clk_n 		),	.mem_cs_n 		(mem_cs_n 		),	.mem_dm 		(mem_dm 		),	.mem_dq 		(mem_dq 		),	.mem_dqs 		(mem_dqs 		),	.mem_odt 		(mem_odt 		),	.mem_ras_n 		(mem_ras_n 		),	.mem_we_n 		(mem_we_n 		)	);ddr2_mem_model mem (.mem_dq      (mem_dq),.mem_dqs     (mem_dqs),.mem_dqs_n   (mem_dqs_n),.mem_addr    (mem_addr),.mem_ba      (mem_ba),.mem_clk     (mem_clk),.mem_clk_n   (mem_clk_n),.mem_cke     (mem_cke),.mem_cs_n    (mem_cs_n),.mem_ras_n   (mem_ras_n),.mem_cas_n   (mem_cas_n),.mem_we_n    (mem_we_n),.mem_dm      (mem_dm),.mem_odt     (mem_odt));
always #10 clk = ~clk;
initial begin clk = 0;global_reset_n = 0;@(posedge clk);@(posedge clk);@(posedge clk);@(posedge clk);@(posedge clk);@(posedge clk);@(posedge clk);@(posedge clk);@(posedge clk);global_reset_n = 1;
end
endmodule

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt鼠标点击事件处理:显示鼠标点击位置(完整示例)

Qt 入门实战教程&#xff08;目录&#xff09; 前驱文章&#xff1a; Qt Creator 创建 Qt 默认窗口程序&#xff08;推荐&#xff09; 什么是事件 事件是对各种应用程序需要知道的由应用程序内部或者外部产生的事情或者动作的通称。 事件&#xff08;event&#xff09;驱动…

python-wordcloud词云

导入模块 from wordcloud import WordCloud import jieba import imageio import matplotlib.pyplot as plt from PIL import ImageGrab import numpy as npwordcloud以空格为分隔符号&#xff0c;来将文本分隔成单词 PIL pillow模块 img imageio.imread(image.png)这行代码…

无需公网IP,实现远程访问群晖Drive并挂载为电脑磁盘的方法

文章目录 前言1.群晖Synology Drive套件的安装1.1 安装Synology Drive套件1.2 设置Synology Drive套件1.3 局域网内电脑测试和使用 2.使用cpolar远程访问内网Synology Drive2.1 Cpolar云端设置2.2 Cpolar本地设置2.3 测试和使用 3. 结语 前言 群晖作为专业的数据存储中心&…

Redis 缓存预热+缓存雪崩+缓存击穿+缓存穿透

面试题&#xff1a; 缓存预热、雪萌、穿透、击穿分别是什么&#xff1f;你遇到过那几个情况&#xff1f;缓存预热你是怎么做的&#xff1f;如何造免或者减少缓存雪崩&#xff1f;穿透和击穿有什么区别&#xff1f;他两是一个意思还是载然不同&#xff1f;穿适和击穿你有什么解…

ctfhub ssrf(3关)

文章目录 内网访问伪协议读取文件扫描端口 内网访问 根据该题目&#xff0c;是让我们访问127.0.0.1/falg.php&#xff0c;访问给出的链接后用bp抓包&#xff0c;修改URL&#xff0c;发送后得到flag&#xff1a; 伪协议读取文件 这题的让我们用伪协议&#xff0c;而网站的目录…

汽车电子系统网络安全解决方案

声明 本文是学习GB-T 38628-2020 信息安全技术 汽车电子系统网络安全指南. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 汽车电子系统网络安全范围 本标准给出了汽车电子系统网络安全活动框架&#xff0c;以及在此框架下的汽车电子系统网络安全活动…

RT-Thread UART

UART 简介 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;通用异步收发传输器&#xff0c;UART 作为异步串口通信协议的一种&#xff0c;工作原理是将传输数据的每个字符一位接一位地传输。是在应用程序开发过程中使用频率最高的数据总线。 UART …

安装使用electron

一、安装node和npm 运行cmd查看是否安装及版本号 npm -v node -v 二、安装electron npm直接安装会报错缺少什么文件&#xff0c;使用cnpm进行安装 直接安装cnmp后&#xff0c;再用cnmp命令安装可能会报错Error: Cannot find module ‘node:util’ 原因是npm版本与cnpm版本…

LinkedList(4):多线程LinkedList 不安全情况

多线程不安全演示&#xff0c;线程越多&#xff0c;现象越明显&#xff0c;这边只启了四个线程。 package com.example.demo;import java.util.LinkedList; import java.util.UUID;public class LInkedListThread {public static void main(String[] args) {final LinkedList&…

【AI理论学习】语言模型:掌握BERT和GPT模型

语言模型&#xff1a;掌握BERT和GPT模型 BERT模型BERT的基本原理BERT的整体架构BERT的输入BERT的输出 BERT的预训练掩码语言模型预测下一个句子 BERT的微调BERT的特征提取使用PyTorch实现BERT GPT模型GPT模型的整体架构GPT的模型结构GPT-2的Multi-Head与BERT的Multi-Head之间的…

华为云 异构数据迁移

数据库和应用迁移 UGO&#xff08;Database and Application Migration UGO&#xff0c;以下简称为UGO&#xff09;是专注于异构数据库结构迁移的专业服务。可将源数据库中的DDL、DML和DCL一键自动转换为华为云GaussDB/RDS的SQL语法&#xff0c;通过数据库评估、对象迁移两大核…

Java连接websocket优雅断线、重连功能

为了实现优雅重连和重试&#xff0c;您需要在代码中添加一些逻辑来处理连接失败或断开连接的情况。 实现代码如下&#xff1a; import javax.websocket.*; import java.io.IOException;ClientEndpoint public class WebSocketClientEndpoint {private Session userSession n…