DDR2接口主要實現用戶數據和實際物理接口之間的連接,實現對大容量數據進行高速緩存。處理高低速傳輸問題。
首先要了解DDR2工作原理,熟悉所連接的內存顆粒說明書瞭解適用範圍,產生適合硬件的DDR2 IP核源文件,查閱DOC下的內核說明書,瞭解內核內容結構,然後做出相應的改動,如時鐘匹配,需匹配爲生成核時工作時鐘,針對用戶的接口除了時鐘之外,主要有三部分接口組成,它們分別是地址命令產生器,寫數據FIFO, 讀數據FIFO接口。地址產生器主要給你選定的突發長度類型產生相應的地址偏移,例如以4的突發長度讀寫,在寫數據時一個CLK 內DDR2根據時鐘邊沿跳變次數會產生兩次寫數據,以長度爲4的突發寫,就需要給一次地址,DDR2控制器會自動寫4次數據,地址偏移依用戶給出的地址依次累加(基址+1),所以用戶控制寫數據,只需每兩個CLK給出一個至少偏移爲4的地址,寫數據如下圖一所示,具體詳情見ip核文件下DOC裏說明書。
圖一
DDR2讀數據,則不同於DDR2寫數據,需要用戶在每個CLK都要給出ADDR地址,讀取數據地址還是以突發讀寫長度爲偏移,每次加4,具體的時序過程如下圖二所示,圖中給出他以4爲長度突發讀連續讀出16次數據,地址輸入佔用4個CLK, 讀數據需要至少8個clk週期。
具體實現過程可以參考ip核列化程序,app應用部分example下的ddr2_tb_test等程序及仿真文件觀察波形可看出數據傳輸過程。
以下是一個RGB信號存儲的簡單地址產生器程序供參考。
//****************************************************************
`timescale 1ns/1ps
module ddr2_tb_addr_gen #
(
// the test module for actual values.
parameter BANK_WIDTH = 3,
parameter COL_WIDTH = 10,
parameter ROW_WIDTH = 14,
parameterone_rgb_cnt=24 //8:0_4_8 28<*3<32//120000-4 //rgb zhong ,R de di zhi fan wen ,EXP: (800*600*8)/32
)
(
input clk,
input rst,
// input rst1,
input addr_ren,
input addr_gen,
input addr_ben,
input wr_addr_en,
//output reg [2:0] app_af_cmd,
output reg [30:0] app_af_addr,
output reg app_af_wren
);
localparam r_star_ad=0;
localparam g_star_ad=41943040;
localparam b_star_ad=134217700;
reg wr_addr_en_r1;
// reg [2:0] af_cmd_r;
reg [30:0] af_addr_r;
reg af_wren_r;
// wire [15:0] ramb_addr;
// wire [35:0] ramb_dout;
reg rst_r
/* synthesis syn_preserve = 1*/;
reg rst_r1
/* synthesis syn_maxfan = 10*/;
reg [30:0] wr_addr_cnt;
reg wr_addr_en_r0;
reg [30:0] wr_addr_allcnt;
// INIP_OO: read 1
// INIP_OO: write 0
//***************************************************************************
// assign ramb_addr = {5'b00000, wr_addr_cnt,5'b00000};
// register backend enables / FIFO enables
// write enable for Command/Address FIFO is generated 2 CC afterWR_ADDR_EN
// (takes 2 CC to come out of test RAM)
always @(posedge clk)
if (rst ) begin
app_af_wren <= 1'b0;
wr_addr_en_r0 <= 1'b0;
wr_addr_en_r1 <= 1'b0;
af_wren_r <= 1'b0;
end else begin
app_af_wren <= wr_addr_en;
end
// address input for RAM
always @ (posedge clk)
if (rst)
begin
wr_addr_cnt <= 0; //8 'h0000_0000;
wr_addr_allcnt<=0; // 9 'h0_0000_0000;
end
else //if (wr_addr_en)
if (wr_addr_en && addr_ren&& !addr_gen && !addr_ben)
begin
if(wr_addr_cnt<one_rgb_cnt) //800*600 R 8 BIT 48_0000*8 //0-R
begin
app_af_addr<=wr_addr_cnt+r_star_ad;
wr_addr_cnt <= wr_addr_cnt + 4;
end
else
begin
wr_addr_cnt <=0;
app_af_addr<=wr_addr_cnt+r_star_ad;
end
end
else
if (wr_addr_en && !addr_ren&& addr_gen && !addr_ben)
begin
if(wr_addr_cnt<one_rgb_cnt) //40-79
begin
app_af_addr<=wr_addr_cnt+g_star_ad;
wr_addr_cnt <=wr_addr_cnt + 4; ////41943040; // R-2R
end
else
begin
wr_addr_cnt <=0;
app_af_addr<=wr_addr_cnt+g_star_ad;
end
end
else
if(wr_addr_en && !addr_ren && !addr_gen && addr_ben)
begin
if (wr_addr_cnt<one_rgb_cnt)//80-119
begin
app_af_addr<=wr_addr_cnt+b_star_ad;
wr_addr_cnt <= wr_addr_cnt+ 4; //83886080; //2R-3R
end
else
begin
wr_addr_cnt <=0;
app_af_addr<=wr_addr_cnt+b_star_ad;
end
end
else
app_af_addr<=31'bx;
endmodule