這裏就沒有形成文檔,直接天馬行空的敲一點關鍵內容吧。
一,參考文檔
1.參考資料
XILINX_DDR3_IP核使用教程,一共仿真,綜合,測試,應用,最終篇 5個,https://download.csdn.net/download/walkmen1990/10180050
2.官方文檔
ug586_7Series_MIS
3. 黑金A7101 開發板 DDR3 例程
4.增加一點說明
在chapter4 LPDDR2 SDRAM Memory Interface Solution裏面有一句話
As shown in Figure 4-59, the maximum delay for a single write between the write data and
the associated write command is two clock cycles. When issuing back-to-back write
commands, there is no maximum delay between the write data and the associated
back-to-back write command, as shown in Figure 4-61.
也就是backtoback的數據(連續多個數據的寫入)不必嚴格對齊,這句話在DDR3的描述裏面沒有出現,但是應該是一樣的
二、代碼解讀
2.1 端口解讀
2.1.1 test與burst文件交互接口
module mem_burst
#(
parameter MEM_DATA_BITS = 64,
parameter ADDR_BITS = 24
)
(
input test,
input rst, /*復位*/
input mem_clk, /*接口時鐘*/
input rd_burst_req, /*讀請求*/
input wr_burst_req, /*寫請求*/
input[9:0] rd_burst_len, /*讀數據長度*/
input[9:0] wr_burst_len, /*寫數據長度*/
input[ADDR_BITS - 1:0] rd_burst_addr, /*讀首地址*/
input[ADDR_BITS - 1:0] wr_burst_addr, /*寫首地址*/
output rd_burst_data_valid, /*讀出數據有效*/
output wr_burst_data_req, /*寫數據信號*/
output[MEM_DATA_BITS - 1:0] rd_burst_data, /*讀出的數據*/
input[MEM_DATA_BITS - 1:0] wr_burst_data, /*寫入的數據*/
output rd_burst_finish, /*讀完成*/
output wr_burst_finish, /*寫完成*/
output burst_finish, /*讀或寫完成*/
......................
這裏有點亂,主要還是這樣
2.1.2 app分類信號
這裏將指令進行分類
【地址系統信號】
app_cmd
app_addr
app_cmd
app_rdy
app_en
【寫數據系統信號】
app_wdf_rdy
app_wdf_wren
app_wdf_data
app_wdf_end
【讀數據】這裏省了吧
2.2 流程解讀
(1)men_test 裏面先拉高wr_burst_req信號 ,使進入MEM_WRITE狀態機
else if(wr_burst_req)
begin
state <= MEM_WRITE;
(2)首先拉高app_en, 給地址,地址系統現行一步
// app_addr_r <= {wr_burst_addr,3'd0};
// app_en_r <= 1'b1; //命令有效
(3)地址系統和數據系統在MEM_WRITE狀態機內分別累加
MEM_WRITE:
begin
//original
// if(app_rdy) //ddr用戶接口空閒
// begin
// app_addr_r <= app_addr_r + 8; //app的數據寬度256,ddr的數據寬度是32位, 地址需要加8
// if(wr_addr_cnt == wr_burst_len - 1) //判斷是否發送了wr_burst_len的地址的寫命令
// begin
// //leoriginal 3
// app_wdf_end_r <= 1'b0;
// app_en_r <= 1'b0; //命令無效
// end
// else
// begin
// wr_addr_cnt <= wr_addr_cnt + 1;
// end
// end
// if(wr_burst_data_req) //寫入ddr數據統計
// begin
// if(wr_data_cnt == wr_burst_len - 1) //等待buart長度的數據寫入到DDR IP的fifo裏
// begin
// state <= MEM_WRITE_WAIT;
// end
// else
// begin
// wr_data_cnt <= wr_data_cnt + 1;
// end
// end
一般情況下,app_wdf_rdy拉低的頻率和時間比app_rdy要少很多,所以數據系統先寫完,進入MEM_WRITE_WAIT狀態
(4)進入MEM_WRITE_WAIT狀態,等待地址寫完
(5)進入WRITE_END狀態,寫完狀態,同時反饋wr_burst_finish ( = state == WRITE_END )信號
(6)進入IDLE 等待
(7)men_test模塊接收wr_burst_finish後進入讀取數據狀態,開始讀數據過程,讀取過程和寫類似
這裏不贅述
2.3 關鍵信號解析
【wr_burst_req】 men_test產生寫數據請求
【wr_burst_data_req】
信號定義://assign wr_burst_data_req = (state == MEM_WRITE ) & app_wdf_rdy ; // 寫ddr數據請求信號 original
信號功能:men_burst.v產生,狀態機MEN_WRITE期間拉高,反饋給men_test.v men_test檢測這個信號爲高就輸出需要寫入的數據;
這個信號可以作爲fifo的讀使能,數據比這個信號慢一拍輸出
【app_wdf_wren_r】
信號定義:else if(app_wdf_rdy)
app_wdf_wren_r <= wr_burst_data_req; //寫DDR數據準備好
信號功能:
功能1,將wr_burst_data_req延時一拍;
功能2,將wr_burst_data_req中間的由於app_wdf_rdy拉低的部分進行重新拉高;
【app_wdf_en】
信號定義:assign app_wdf_wren = app_wdf_wren_r & app_wdf_rdy;
信號功能:app_wdf_en指示數據有效信號
到這裏基本清晰了。紅色信號作爲fifo讀取或者外部數據發生的請求信號
根據紅色信號【wr_burst_data_req】延一拍,平滑中間的0,再和 app_wdf_rdy與一遍,生成綠色的數據有效信號a【app_wdf_wren】
數據比紅色信號【wr_burst_data_req】慢一拍輸出,也就產生了綠色的【app_wdf_data】信號
即數據【app_wdf_data】和信號有效信號【app_wdf_wren】已經完成對齊功能;
SRIO 中 IOTx_tready 的用法可以參考這裏!
另外,地址系統的信號 和紅色信號一起拉高,也就是最開始的時候,地址信號比數據信號提前一個時鐘給DDR控制器
else if(wr_burst_req)
begin
state <= MEM_WRITE;
app_cmd_r <= 3'b000; //寫命令
app_addr_r <= {wr_burst_addr,3'd0};
app_en_r <= 1'b1; //命令有效
------------------------------------------------------分割線------------------------------------------------------
這裏基本上主要模塊分析完了
寫地址命令和讀地址命令並沒有嚴格對齊,有點擔心這裏可能存在風險
可能存在的風險,下一章節進行分析
20200224
:O:O:o: o
【xilinx DDR3 初探2】黑金A7101 DDR3代碼解讀
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.