您现在的位置是:主页 > Web前端技术 > Web前端技术

怎么分析FPGA设计中的DDR2开发技术

IDCBT2022-01-11服务器技术人已围观

简介今天给大家介绍一下怎么分析FPGA设计中的DDR2。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读

今天给大家介绍一下怎么分析FPGA设计中的DDR2。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。

    DDR2 IP系统框图

2. IP参数设置

1) 时钟设置

PLL reference clock freqency是参考输入时钟,一般由外部晶振或外部PLL输出提供

Memory clock freqency是DDR时钟,一般CYCLONE IV最快只能支持200M,根据不同的型号和BANK而不同

Controller data rate有Full和Half模式,选择Half模式后,Local interface width会增加一倍

2)选择Memory Presets

根据电路中DDR2的型号选择对应的presets,这里只重点介绍Full rate下地址的设置。

在Full rate下:

local_address is 25 bits wide

local_address[23:11] = row address[13:0]

local_address[10:9] = bank address  [1:0]

local_address [8:0] = column address [9:1]

local data宽度是总线data宽度的两倍,所以IP核忽略了column的最低位

3) 设置local参数

Local-to-Memory Address Mapping: 设置地址映射,需要和上面的地址映射说明一致

Local Maximum Burst Count:设置成32,提高读写效率

3. 例化IP核

ddr2_64bit ddr2_64bit_inst (
				.local_address(local_address),
				.local_write_req(local_write_req),
				.local_read_req(local_read_req),
				.local_burstbegin(local_burstbegin),
				.local_wdata(local_wdata),
				.local_be(16'hffff),
				.local_size(BURST_LEN),
				.global_reset_n(rst_n),
				.pll_ref_clk(ref_clk),
				.soft_reset_n(rst_n),
				.local_ready(local_ready),
				.local_rdata(local_rdata),
				.local_rdata_valid(local_rdata_valid),
				.local_refresh_ack(),
				.local_init_done(local_init_done),
				.reset_phy_clk_n(),			
				.phy_clk(phy_clk),
				.aux_full_rate_clk(),
				.aux_half_rate_clk(),
				.reset_request_n(),
				.mem_odt(mem_odt),
				.mem_cs_n(mem_cs_n),
				.mem_cke(mem_cke),
				.mem_addr(mem_addr),
				.mem_ba(mem_ba),
				.mem_ras_n(mem_ras_n),
				.mem_cas_n(mem_cas_n),
				.mem_we_n(mem_we_n),
				.mem_dm(mem_dm),
				.mem_clk(mem_clk),
				.mem_clk_n(mem_clk_n),
				.mem_dq(mem_dq),
				.mem_dqs(mem_dqs)
	);

4. 设计读写测试模块

//-----------ddr2 read and write operation---------
reg   [25 :0]     local_address;
reg               local_burstbegin;
reg               local_read_req;
reg               local_write_req;
reg   [127 :0]    local_wdata;

reg [2:0] local_state;
reg [7:0] local_cnt;
reg [127:0] local_readdata;

parameter IDLE			 = 0,
			 IDLE0 		 = 1,
			 BURST_WRITE = 2,
			 IDLE1		 = 3,
			 BURST_READ	 = 4,
			 END		 = 5;		 
			 
always @(posedge phy_clk)
	if(~rst_n)
	begin
		local_state <= IDLE0;
		local_cnt	<= 0;
	end
	else
		case(local_state)
		IDLE:
		begin
			if(local_init_done & local_ready)
				local_state <= IDLE0;
			else
				local_state <= IDLE;
			local_burstbegin <= 1'b0;
			local_write_req  <= 1'b0;
			local_cnt		  <= 0;
			local_wdata		  <= 128'h0;	
			local_address	  <= 26'd32;	
		end
		IDLE0:
		begin
			if(local_init_done & local_ready)
				local_state <= BURST_WRITE;
			else
				local_state <= IDLE0;
			local_burstbegin <= 1'b0;
			local_write_req  <= 1'b0;
			local_cnt		  <= local_cnt;
			local_wdata		  <= local_wdata;
			local_address	  <= local_address;
		end
		BURST_WRITE:
		begin
			if(local_cnt<=0)
				local_burstbegin <= 1'b1;
			else
				local_burstbegin <= 1'b0;
				
			local_write_req  <= 1'b1;
			local_wdata      <= local_wdata + 1;
			local_read_req	  <= 1'b0;
			local_address	  <= 26'd32;
			
				
			if(local_cnt>=(BURST_LEN-1))
			begin
				local_state <= IDLE1;
				local_cnt <= 0;
			end
			else
			begin
				local_state <= BURST_WRITE;
				local_cnt <= local_cnt + 1'b1;
			end
		end
		IDLE1:
		begin
			if(local_init_done & local_ready)
				local_state <= BURST_READ;
			else
				local_state <= IDLE1;
			local_burstbegin <= 1'b0;
			local_write_req  <= 1'b0;
			local_cnt		  <= local_cnt;	
			local_address	  <= 26'h0;		
		end
		BURST_READ:
		begin
			local_burstbegin <= 1'b1;
			local_write_req  <= 1'b0;
			local_read_req	  <= 1'b1;
			local_cnt		  <= local_cnt;
			local_state		  <= END;
			local_address	  <= 26'd32;
		end
		END:
		begin
			local_burstbegin <= 0;
			local_write_req  <= 0;
			local_read_req   <= 0;
			local_address	  <= 0;
			
			if(local_cnt>=8'h7f)
			begin
					local_state <= IDLE;
					local_cnt   <= 0;
			end
			else
			begin
					local_state <= END;
					local_cnt <= local_cnt + 1'b1;
			end
			
			if(local_rdata_valid)
				local_readdata <= local_rdata;
			else
				local_readdata <= 0;
				
		end
		default: 
		begin
			local_burstbegin <= 1'b0;
			local_write_req  <= 1'b0;
			local_read_req	  <= 1'b0;
			local_cnt		  <= 0;
			local_state		  <= IDLE0;
			local_address	  <= 26'h0;
		end
		endcase

标签:

很赞哦! ()

本栏推荐