DDR2 IP核调式记录2

这篇具有很好参考价值的文章主要介绍了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;

命令

DDR2 IP核调式记录2,fpga开发

连续写

DDR2 IP核调式记录2,fpga开发

连续读

DDR2 IP核调式记录2,fpga开发

读完写

DDR2 IP核调式记录2,fpga开发

3. 仿真波形分析

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

DDR2 IP核调式记录2,fpga开发

读过程及下一次写

DDR2 IP核调式记录2,fpga开发

4. 附代码

顶层代码:

module ddr2wrtest (
	input 					clk 			,    // Clock
	input 					global_reset_n 	,  // Asynchronous reset active low


	output  [ 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; 				// 突发长度 4

	parameter 			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 */;
	    endcase

		always@(posedge phy_clk or negedge rst_n)begin 
		if(!rst_n)
			state <= IDEL;
		else
			case (state)
				IDEL 	:	state <= WRITER;

				WRITER 	: 	if(mem_local_ready)
								state <= WRITING;
							else
								state <= WRITER;

				WRITING : 	if(wdatalen == LEN)
								state <= READR;
							else
								state <= state;
				READR 	: 	if(mem_local_ready)
								state <= READING;
							else
								state <= READR;

				READING : 	if(rdatalen == LEN)
								state <= IDEL;
							else
								state <= state;		
				default : state <= state;
			endcase
		end

		// 写的数据自加1
		always@(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;
		else
			mem_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 ;
		else
			wdatalen <= 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;
		else
			rdatalen <= 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;
		end

endmodule

测试代码文章来源地址https://www.toymoban.com/news/detail-702850.html

`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

到了这里,关于DDR2 IP核调式记录2的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Xilinx FPGA DDR3设计(三)DDR3 IP核详解及读写测试

    引言 :本文我们介绍下Xilinx DDR3 IP核的重要架构、IP核信号管脚定义、读写操作时序、IP核详细配置以及简单的读写测试。 7系列FPGA DDR接口解决方案如图1所示。 图1、7系列FPGA DDR3解决方案 1.1 用户FPGA逻辑(User FPGA Logic) 如图1中①所示,用户FPGA逻辑块是任何需要连接到外部

    2024年02月06日
    浏览(45)
  • FPGA入门 —— DDR3(MIG IP 核) 入门

    DDR 简介 DDR=Double Data Rate双倍速率同步动态随机存储器。严格的说DDR应该叫DDR SDRAM,人们习惯称为DDR,其中,SDRAM 是Synchronous Dynamic Random Access Memory的缩写,即同步动态随机存取存储器。而DDR SDRAM是Double Data Rate SDRAM的缩写,是双倍速率同步动态随机存储器的意思。 SDRAM在一个时

    2024年01月16日
    浏览(47)
  • 【Xilinx FPGA】DDR3 MIG IP 仿真

    Memory Interface Generator (MIG 7 Series)是 Xilinx 为 7 系列器件提供的 Memory 控制器 IP,使用该 IP 可以很方便地进行 DDR3 的读写操作。本文主要记录 Xilinx DDR3 MIG IP 的仿真过程,包括 IP 配置和 DDR3 读写仿真两部分内容。 目录 1 MIG IP 配置 2 DDR3 读写仿真         在 Vivado 开发平台 IP C

    2024年02月09日
    浏览(42)
  • FPGA通过PCIe读写DDR4仿真IP核

    环境:Vivado 17.4 根据个人所需选择器件库,创建好空的工程文件夹。 添加第一个IP:utility buffer 双击模块进入配置,选择差分时钟; 第二个IP,直接搜索DMA ,双击添加; 添加之后同样双击模块,进入配置:  配置完成。  第三个IP:AXI Interconnect,双击模块进入配置,将主从接

    2023年04月19日
    浏览(38)
  • DDR原理及MIG IP核使用记录

    资料参考 1、Xilinx FPGA平台DDR3设计保姆式教程(汇总篇)——看这一篇就够了这篇写的很全面详细 2、快速上手Xilinx DDR3 IP核----汇总篇(MIG) 该系列介绍了Xilinx 控制DDR3的IP核----MIG IP核的基本构成和使用方法,在MIG 接口的基础上在外部 封装了FIFO ,使得操作时序更加简单,并

    2024年02月04日
    浏览(25)
  • FPGA开发-ddr测试

    文章目录 概要 整体架构流程 技术名词解释 技术细节 小结 提示:这里可以添加技术概要 例如: 本文以米联科开发板为例,介绍ddr测试相关例程。 提示:这里可以添加技术整体架构 提示:这里可以添加技术名词解释 例如: app _addr:表示正在提交给用户界面的请求的地址。聚

    2024年02月08日
    浏览(37)
  • 紫光FPGA DDR3 IP使用和注意事项(axi4协议)

    紫光DDR3 IP使用 对于紫光ddr3 IP核的使用需要注意事情。 阅读ddr ip手册: 1、注意:对于写地址通道,axi_awvalid要一直拉高,axi_awready才会拉高。使用的芯片型号时PG2L100H-6FBG676,不同的型号IP核接口和axi的握手协议也不一样(一定要注意),这点要注意,这也给我挖了一个很大的

    2024年04月12日
    浏览(45)
  • 【FPGA】十三、Vivado MIG IP核实现DDR3控制器(1)

    文章目录 前言 一、DDR3基础知识 二、MIG  IP核的配置 三、DDR3 IP核用户端接口时序 1、DDR3 IP核接口说明 2、DDR3 IP核读写时序 ① 写命令时序:  ② 写数据时序:  ③ 读数据时序: 总结         我们在进行FPGA开发应用当中,经常会用到存储器来保存数据,常用的存储器有RO

    2024年02月16日
    浏览(67)
  • FPGA实战开发-基于DDR的图像缓存(下)

    文章目录 概要 整体架构流程 技术名词解释 技术细节 小结 例如: 基于米联科的学习资料,分享和学习同步,欢迎大家一起探讨。 提示:这里可以添加技术整体架构 例如:       image_data_gen产生了测试图片,之后进入过W0 FIFO进行视频缓存。每次缓存1024个像素,就往通过F

    2024年02月17日
    浏览(33)
  • FPGA实战开发-基于的ddr图像缓存设计(上)

    目录 概要 整体架构流程 技术名词解释 技术细节 ​编辑 小结 提示:这里可以添加技术概要 本文主要基于DDR的图像缓存设计。 提示:这里可以添加技术整体架构 先用图像产生模块产生一个1080P60Hz的测试图像,然后经过FDMA进入ddr3,缓存3帧后在读出来。然后在经过HDMI显示。

    2024年02月08日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包