王維平,張正炳,賀東芹 (長江大學(xué)電子信息學(xué)院,湖北荊州434023)
DDR SDRAM(Double Data Rate Synchronous Dynamic Random Access Memory,雙倍速率隨機存儲器)采用2.5V的工作電壓,在核心時鐘的上升沿和下降沿傳輸數(shù)據(jù),具有比SDR(single data rate)SDRAM多一倍的傳輸速率的優(yōu)點。FPGA(Field-Programmable Gate Array)是一種可編程器件,在FPGA上可以實現(xiàn)任意數(shù)字電路功能。在電子通訊領(lǐng)域,數(shù)據(jù)量越來越大,對存儲器的需求也越來越大;FPGA具有并行性、可編程等優(yōu)點,它的應(yīng)用場合也越來越廣,在FPGA板卡上嵌入SDRAM已經(jīng)應(yīng)用在很多系統(tǒng)中,因此研究在FPGA平臺上來實現(xiàn)DDR讀寫控制的方法具有重要的實際意義。下面,筆者在分析DDRSDRAM基本操作特性的基礎(chǔ)上,根據(jù)DDR的時序要求,提出了一種基于VerilogHDL語言的控制器實現(xiàn)方案。
筆者采用的DDR具有4個BANK(就是被分為4個塊)、15根地址總線、16根數(shù)據(jù)總線 (DQ15~DQ0)、2根數(shù)據(jù)捕獲探針 (DQS,雙向信號線)、2根寫掩碼信號 (DM1~DM0,可一直設(shè)置為0)、1對相位相反的主控時鐘線 (CLK_P,CLK_N)、1根時鐘使能信號 (CKE)、4根命令信號線:CS_N(片選信號),RAS_N(行地址使能信號),CAS_N(列地址使能信號)和WE_N(寫使能信號)。
DDR的指令與SDR的指令基本一致,主要由CS_N,RAS_N,CAS_N和WE_N 4個信號控制,真值表如表1所示。命令是在主時鐘的上升沿捕獲。

表1 DDR的基本指令真值表
1)CL CAS latency,列地址有效到讀出數(shù)據(jù)的延時,是在讀數(shù)據(jù)時讀命令到數(shù)據(jù)輸出的時間長度,它由廠商確定,主要有2,2.5,3(時鐘周期個數(shù))3個數(shù)值,可以通過寄存器配置。
2)tRCD RAS to CAS latency,行地址 (ACT命令)有效到列地址有效的最小延時,不可配置。
3)tRAS 行有效 (ACT命令)到預(yù)充電命令的最小時延。
4)tRP 預(yù)充電命令到行有效的最小時延。
DDR的讀寫數(shù)據(jù)是在DQS信號下捕捉的,數(shù)據(jù)的位數(shù)決定了DQS的位數(shù),一位DQS信號負責(zé)捕捉8位數(shù)據(jù)信號。寫操作時,DQS在數(shù)據(jù)信號DQ的中心捕獲數(shù)據(jù);讀操作時,DQS在數(shù)據(jù)信號的邊沿捕獲數(shù)據(jù)。在數(shù)據(jù)讀寫之前,需要先進行行有效操作,即ACT命令,然后經(jīng)過tRCD的時間,執(zhí)行讀或?qū)懖僮髅睢T谧x操作中,讀命令后還要經(jīng)過CL(CAS latency)時間才開始讀取數(shù)據(jù)。
筆者設(shè)計的DDR控制器主要有3個模塊,分別是狀態(tài)轉(zhuǎn)換控制模塊、指令譯碼模塊和時鐘模塊,如圖1所示。控制器的用戶控制信號有CMD(用戶發(fā)送的指令)與ADDR(用戶地址)、DATAIN(DDR的輸入數(shù)據(jù))和DATAOUT(DDR的輸出數(shù)據(jù))。時鐘模塊提供DDR主時鐘和控制器系統(tǒng)內(nèi)部的數(shù)據(jù)時鐘 (CLK_X2)。在使用時,用戶首先發(fā)送1個CMD到狀態(tài)轉(zhuǎn)換模塊進行狀態(tài)轉(zhuǎn)換,然后控制器返回1個CMDACK響應(yīng)用戶,在第2個時鐘周期將這個命令狀態(tài)標(biāo)志輸入到指令譯碼模塊進行指令譯碼,控制指令信號,完成相應(yīng)的操作。伴隨著狀態(tài)的轉(zhuǎn)換,相應(yīng)的地址信號也鎖存進 DDR。REF_CLK與RESET_N是系統(tǒng)時鐘和全局復(fù)位信號,除了這2個信號與前述的用戶控制信號外,圖1中剩下的接口信號就是DDR的接口信號了。

圖1 DDR控制器框圖
圖2是各種操作的狀態(tài)轉(zhuǎn)化圖,是指指令之間轉(zhuǎn)換的可能操作。

圖2 DDR狀態(tài)轉(zhuǎn)換圖
根據(jù)DDR的時序要求,一共采用了3個時鐘,分別是DDR的1對反相時鐘 (DDR_CLK_P,DDR_CLK_N)和數(shù)據(jù)控制時鐘(CLK_X2,由時鐘模塊產(chǎn)生)。根據(jù)DDR的要求,指令信號要在DDR_CLK_P的上升沿采樣,所以采用其反相時鐘信號DDR_CLK_N來同步命令邏輯,使DDR_CLK_P的上升沿恰好在命令的中心。根據(jù)DDR讀寫數(shù)據(jù)的要求,采用了1個DDR系統(tǒng)時鐘頻率2倍的數(shù)據(jù)時鐘,用來處理讀寫數(shù)據(jù)。時序參見圖3和圖4。
DQS是雙向信號,在讀數(shù)據(jù)時由DDR本身產(chǎn)生,在寫數(shù)據(jù)時需要控制器來產(chǎn)生。因為在DDR中DQS與其系統(tǒng)時鐘保持一致,只不過是有個偏差范圍,所以采用DDR_CLK_P的開關(guān)時鐘作為DQS信號,寫操作中產(chǎn)生DQS信號 (數(shù)據(jù)位寬為16,DQS位寬則為2)的Verilog代碼:

DDR的控制器主要有讀、寫、預(yù)充電、刷新、配置模式寄存器等操作,如圖2所示。DDR在工作時主要分為2個階段:上電初始化和讀寫過程。初始化很重要,主要完成時鐘穩(wěn)定與寄存器配置的過程,它是一些指令的順序執(zhí)行過程。筆者采用的DDR是Hynix公司的產(chǎn)品。不同廠家的DDR初始化過程不盡相同,其寄存器配置的參數(shù)可能也不同,為了提高控制器的通用性,可以在控制器外來配置初始化操作。因為DDR的地址線是有限的,讀寫的時候是采用時分復(fù)用技術(shù)來實現(xiàn)完全的尋址過程的。DDR的地址線有15根,其中2根是BANK地址 (BA1~BA0),剩下的是行列地址 (13根,A12~A0),其中行地址為A12~A0,列地址為A8~A0,行地址與列地址分時復(fù)用,這樣等效尋址線就是24根 (2+13+9),尋址空間正好是16M。在初始化完成以后就可以進行讀寫了,按照DDR的時序要求,先進行行鎖定 (ACT命令),然后經(jīng)過tRCD的時間,再執(zhí)行讀/寫操作,同時鎖定列地址。圖3和圖4分別是在Modelsim仿真中的寫、讀時序圖,突發(fā)長度為8(一次讀/寫8個數(shù)據(jù)),CL為3,tRCD時間大約為3個時鐘周期;在ACT命令周期 (CS_N=0,RAS_N=0,CAS_N=1,WE_N=1),鎖定行地址,即將圖中的SA=0000H賦給A12~A0地址線;經(jīng)過tRCD時間執(zhí)行讀/寫命令,注意在讀寫命令時,列地址SA=0425H,實際上此時的列地址是0025H,只不過此時讀寫方式是帶預(yù)充電的讀寫方式 (A10=1,加上A8~A0=0025H,所以整個SA=0425H)。如圖3所示,DQ是在CLK_X2時鐘下產(chǎn)生的,正好在DQS的邊沿鎖存。在讀數(shù)據(jù)時DQ與DQS是邊沿對齊;如圖4所示,數(shù)據(jù)時鐘(CLK_X2)的上升沿正好在數(shù)據(jù)的中心,符合DDR時序要求。

圖3 寫時序仿真結(jié)果

圖4 讀時序仿真結(jié)果
DDR需要定時刷新指令與預(yù)充電指令,所以合理地處理這2個指令可以有效地提高讀寫的效率。刷新是周期性操作,預(yù)充電是在地址換行時需要執(zhí)行的操作,所以提高效率的主要方法就是合理的安排預(yù)充電命令。讀寫操作有2種方式:一種是帶預(yù)充電的讀寫,一種是普通的讀寫。在采用普通讀寫時需要在地址換行的時候用預(yù)充電命令來重新進行行使能。2種讀寫方式在指令上的區(qū)別就是:帶預(yù)充電的讀寫命令在ACT命令 (此時,地址輸入為DDR的行地址)時,將A10置高;而普通讀寫不需要將A10置高。
DDR的數(shù)據(jù)突發(fā)模式只有2、4、8三種,尋址一個完整地址都要進行ACT到 READ/WRITE的過程,如果讀寫數(shù)據(jù)在一個行時可以省去后續(xù)數(shù)據(jù)讀寫的ACT過程。筆者采用了突發(fā)為2的DDR讀寫方式,只在第一組數(shù)據(jù)時執(zhí)行一個ACT命令,它可以實現(xiàn)一個行內(nèi)的任意偶數(shù)個數(shù)據(jù)的連續(xù)讀寫。例如視頻領(lǐng)域經(jīng)常對一幀圖像數(shù)據(jù)進行處理 (如去隔行處理[1]),存儲器就可以連續(xù)的處理大批量的數(shù)據(jù),時鐘效率是比較高的。
當(dāng)數(shù)據(jù)地址隨機且經(jīng)常跨越一行地址時,如果還是采用普通讀寫方式的話,需要經(jīng)常在行地址變化時執(zhí)行預(yù)充電命令,就會導(dǎo)致讀寫的效率下降。例如在視頻編碼中,預(yù)測編碼是去冗余的最有效方法,預(yù)測就需要圖像幀區(qū)域搜索[2],這時在存儲器中表現(xiàn)為數(shù)據(jù)地址的隨機性。這種情況下可以采用帶預(yù)充電的讀寫命令,這樣每個指令中都會進行預(yù)充電,就不必擔(dān)心在地址換行的時候發(fā)生錯誤了。但是,每個指令之間必須有一定的間隔 (突發(fā)長度/2+tRP),例如采用突發(fā)為8的讀寫時,每個指令之間的間隔就要最少有4+tRP個周期,所以設(shè)置突發(fā)模式為8時效率比較高。
在硬件調(diào)試前,軟件仿真是非常重要的,一般在仿真中時序吻合的情況下是可以實現(xiàn)既定功能要求的,在FPGA設(shè)計尤其是高速設(shè)計中,調(diào)試前的時序分析與時序收斂至關(guān)重要,只有滿足了時序收斂,設(shè)計才具有穩(wěn)定性。筆者在代碼綜合階段采用了FPGA常用方法提高了設(shè)計的速度,比如增加流水線級數(shù)與消除亞穩(wěn)態(tài)的方式[3],使CLK_X2達到333M,DDR時鐘167M,還有時序余量,滿足時序要求。
ALTERA提供一個集成于QUART USII軟件中的FPGA片上debug工具:SignaltapII,它可以捕獲和顯示實時信號,觀察在系統(tǒng)設(shè)計中的硬件和軟件之間的互相作用。它的原理就是設(shè)定采樣周期,實時采樣數(shù)據(jù)并存儲到PFGA內(nèi)RAM中,然后通過JTAG接口傳送到QUARTUSII來顯示。正是因為SignaltapII的實時性,在調(diào)試時需要注意讀寫驗證的方法。初始化的配置過程很難觀察到,只能驗證后面的讀寫過程。因為RAM的容量有限,一次捕捉到的數(shù)據(jù)也是有限的,在板級調(diào)試時,需要以循環(huán)的方式進行讀寫數(shù)據(jù)指令的執(zhí)行,以便在邏輯分析儀中捕捉到數(shù)據(jù)。筆者采用先將數(shù)據(jù)寫入一段地址中,然后在相同的地址中讀出來,并且比較相同地址寫入數(shù)據(jù)與讀出數(shù)據(jù)是否相同的方法來驗證DDR控制器是否正常工作。為了保證讀寫的可靠性,循環(huán)的方式采用遍歷所有地址范圍的方法,觀察結(jié)果發(fā)現(xiàn)寫入與讀出的數(shù)據(jù)是完全吻合的。如圖5、圖6所示,寫入數(shù)據(jù)與讀出數(shù)據(jù)一致。

圖5 SignaltapII捕獲的寫入數(shù)據(jù)時序圖

圖6 SignaltapII捕獲的讀出數(shù)據(jù)時序圖
通過對DDR時序的分析,給出了一種DDR控制器的設(shè)計方案。并且針對不同的尋址方式,給出了不同的讀寫方法,提高了讀寫效率。最終,控制器在ALTERA公司的cycloneIII系列芯片上實現(xiàn),在板卡上能夠控制Hynix公司的DDR芯片穩(wěn)定地讀寫數(shù)據(jù)。存儲器工作頻率達到167M,數(shù)據(jù)穩(wěn)定可靠,讀寫效率較高。
[1]余兆明,査日勇,黃磊,等.圖像編碼標(biāo)準(zhǔn)H.264技術(shù) [M].北京:人民郵電出版社,2005.
[2]畢厚杰.新一代視頻壓縮編碼標(biāo)準(zhǔn)——H.264/AVC[M].北京:人民郵電出版社,2005.
[3]Kilts S.高級FPGA設(shè)計結(jié)構(gòu)、實現(xiàn)和優(yōu)化 [M].孟憲元譯.北京:機械工業(yè)出版社,2009.