【xilinx DDR3 初探2】黑金A7101 DDR3代碼解讀

這裏就沒有形成文檔,直接天馬行空的敲一點關鍵內容吧。

一,參考文檔
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章