最近針對黑金的光纖開發板上的DDR3進行了代碼學習及板級調試。該模塊功能流程已經搞清楚,以后針對DDR3的控制模塊可以直接修改調用了,哦也!
有幾個需要注意的細節列舉如下:
(1)整個DDR3控制模塊的架構要清楚,方便以后使用(數據的產生源和消耗源);

首先說明整個DDR3的工程模塊是個啥。
DDR3的模塊代碼層次結構如上圖所示,ddr2fifo_top是DDR3模塊的頂層,下分3個子模塊,分別是ddr_ctrl.v、dcfifo_ctrl.v、bank_switch.v。接着說這3個子模塊。
ddr_ctrl.v:包含mem_burst.v模塊,該模塊具體實現DDR用戶接口層的操作,用戶接口信號如下圖所示。另外還有個MIG 的IP核調用模塊,它是最底層操作DDR時序的模塊,有對應的用戶接口(app_xxx)留出給用戶使用,該模塊需要在IP catlog里生成,注意生成的設置項選擇。

dcfifo_ctrl.v:封住兩個FIFO,分別是wrfifo和rdfifo。其中wrfifo是數據源產生模塊對接DDR的數據寫入緩存,rdfifo是DDR的數據讀出對接數據消耗模塊的緩存。兩個異步FIFO的讀寫位寬均設置為256bit,深度均設置為512。
bank_switch.v是DDR3的BANK切換,該代碼在MIG生成時,地址方式選擇的是Bank+Row+Column方式,因此在實現乒乓操作時,通過切換Bank即可。DDR3的Bank地址有3bit,即有8個bank,代碼只使用了其中的4個bank,代碼里是將一幀圖像寫在一個Bank里,一幀圖像的字節總數=1280x720x2(RGB565模式),寫完一幀圖像后通過bank_switch來切換BANK。
下面說明數據源的產生及數據消耗模塊是個啥。
數據源的產生來自OV5640的相機數據,該相機采用的是RGB565的輸出模式,即一個像素點是2個字節,每次在數據產生模塊(相機模塊里),都是湊到32個字節,發起wrfifo的寫入操作,當分辨率設置的是1280x720,因此一個Bank內的最大寫入地址wr_max_addr=1280x720x2x8bit/256bit=57600。放在低位上,高位是Bank地址,如下圖所示。

(2)地址遞增的原因要搞清楚,若改變讀寫FIFO的位寬或硬線位寬,會影響遞增值;
具體是在mem_burst.v模塊里地址的app_addr的每次遞增是8,另外在該模塊的狀態機初始態Idle下,每次reload 起始地址時,起始地址都做了左移3bit,即x8。這個原因要搞清楚,方便以后復用。
原因先寫下,以免年紀大了又忘了。原因是因為每次突發寫的長度為128,而每次從FIFO讀出的數據位寬是256bit(即app_wr_data的位寬是256bit),而板上的DDR3的數據線硬線位寬是32位(2片DDR3控制線復用,數據線並用,擴展了數據線位寬),因此在一次突發寫的過程中,每次app_addr需要加8(256bit/32bit=8),而當突發完一次128 length后,下一個起始地址都要加上128x8。
然而在代碼里的起始地址ddr_wraddr是在dcfifo_ctrl.v模塊里產生的,該地址在每次ddr_wr_finish(對應mem_burst.v模塊里的wr_burst_finish信號)拉高時,地址加上128。因此到了mem_burst.v模塊里需要將起始地址左移3bit,即x8。同理,讀操作的地址變化也是這么個過程。
(3)為啥讀寫的突發長度的設置是128(1280x720的分辨率)
(4)讀寫FIFO的位寬是256bit,即32個字節,這個可以更改,當然更改了會影響后面的地址遞增,還有硬線位寬也影響地址的遞增變化;256/32bit,這個公式會變化
(5)讀寫地址的產生方式,這個在dcfifo_ctrl.v模塊里,注意一些信號的使用技巧,可借鑒。如下圖所示:
代碼里的wr_flag,用來執行每次256bit數據塊的寫操作完成標記。寫完以后拉低,重新判斷wrf_use是否大於一個128長度。
(6)MIG核輸出了一個時鍾,phy_clk的頻率是200M,根據MIG兩端的帶寬是匹配的,來推斷出phy_clk的頻率是200M。
(200Mx256bit SDR )---> MIG ---> (800Mx32bitx2 DDR)
(7)讀寫FIFO的計數判斷,wr_fifo用的rd_cnt,rd_fifo用的wr_cnt。
