錢素琴,劉晶華
(東華大學信息科學與技術學院,上海,201600)
隨著數據采集系統的發展,應用于圖像采集和數據傳輸等領域的產品對存儲器的速度要求越來越高。DDR2系列的SDRAM動態存儲器因為其能在時鐘的正負沿進行兩倍速度讀寫[1],同時具有低成本、高速、大容量、運行穩定等高性價比的優點,所以在各個領域中被廣泛使用[2]。比如文獻3采用DDR2來存儲視頻數據[3],文獻4利用DDR2實現了數據量較大的原始紅外圖像的緩存[4],文獻5將DDR2存儲技術應用到了船舶港口物流跟蹤系統中[5]等。
DDR2復雜苛刻的操作時序,造成對應的DDR2控制器電路結構也比較特別。很多FPGA廠商利用其可編程芯片的豐富軟硬件資源設計了DDR2存儲控制器IP核[6],其中Altera公司設計的存儲控制器因其效率最高使用較為廣泛。要實現DDR2控制器的設計,用戶只需了解FPGA芯片專用于連接DDR2的引腳功能及存儲器的工作機制即可。
本設計主控制器選用了Altera公司Cyclone IV系列的EP4CE30F23C8,數據緩存器選用了Micron公司內存為2Gbit大小的MT47H128M16-25E,研究了DDR2 SDRAM的工作原理及控制器IP核解決方案,在現場可編程門陣列芯片FPGA中實現DDR2控制器設計,并在嵌入式邏輯分析儀Signaltap中顯示了雙邊沿時鐘主頻工作下的測試結果,在166.7MHz時鐘頻率下實現了穩定讀寫的目標。
DDR2 SDRAM有許多操作步驟,包括加載模式、自刷新、預充電、激活、讀寫操作和空閑等待。在進行上述操作之前必須要在上電后按照規定的步驟完成初始化。在初始化的過程中主要是對其模式寄存器的值進行配置來完成CAS延遲、突發長度、突發類型、輸出驅動能力、片上端接電阻(ODT)值、伴隨CAS的附加延遲、片外驅動器校準等參數的配置,為之后的讀寫操作做準備。
DDR2讀寫操作前需要對指定段的行進行激活,每個段只允許打開1行進行讀寫操作,如果要對同一段中的其他行進行讀寫操作,則必須先用預充電命令關閉已經打開的行,再用激活命令打開需要進行讀寫操作的行。實際上是鎖定行地址,再進行突發操作,對連續地址單元進行讀寫操作[6]。DDR2可支持突發讀寫,突發讀寫長度為4和8,也稱突發傳輸,簡化了DDR2的讀寫操作并提高了讀寫效率。
Altera為用戶提供了DDR2控制的兩個IP, 一個是DDR2 SDRAM Controller with UniPHY,另一個為DDR2 SDRAM Controller with ALTMEMPHY。DDR2 SDRAM Controller with UniPHY的性能比DDR2 SDRAM Controller with ALTMEMPHY更好一些,兩種IP使用的方法是相同的,但UniPHY不支持Cyclone系列的芯片,所以在Cyclone 系列的FPGA上只能使用ALTMEMPHY IP來實現DDR2。
圖1為本方案的控制器總體結構框圖,主要包括FPGA和DDR2 SDRAM,其中FPGA內部模塊包括參數計算、輸入FIFO、DDR2控制器、輸出FIFO。圖像數據緩存是通過FPGA片內的輸入輸出FIFO資源與片外的DDR2 SDRAM進行的,其中,各個模塊之間數據位寬不一致和數據傳輸速度不匹配的問題可以由輸入輸出FIFO解決,高速大容量的數據緩存可以借助DDR2 SDRAM來實現。

圖1 系統總體結構框圖
系統實現的過程如下:上電后對DDR2存儲器的模式寄存器配置后進行初始化;在讀取數據和寫入數據時,實現存儲器能上下沿傳輸數據和突發傳輸的要求。在寫入數據操作時將待發送的數據和命令轉換成符合存儲器要求的寫指令,然后將數據寫入存儲器;在讀取操作時先將讀地址和數據長度轉換成存儲器要求的讀指令發送給存儲器讀出需要的數據,然后從存儲器將讀出的數據發送給用戶端。
在結構框圖的基礎上,本文進行了硬件和軟件兩個部分的設計。硬件設計為FPGA與DDR2的信號連接,軟件設計為以verilog語言為基礎的FPGA邏輯編程控制DDR2的讀寫。
DDR2 SDRAM控制器的信號連接圖如圖2所示。

圖2 信號連接圖
在本方案中的設計的測試模塊中有時鐘輸入信號CLK和置位信號RST。功能驗證的部分包含初始化模塊、讀寫控制模塊和數據傳輸模塊的驗證。
DDR2 SDRAM與FPGA開發板上的FPGA相連的是BANK3和BANK4的IO,相連的硬件引腳具體為:系統時鐘差分時鐘信號(CK、CK#)、時鐘使能信號(CKE#)、行列地址復用總線(A[13:0])、段地址選擇線(BA[2:0])、數據總線(DQ[15:0])、隨路時鐘信號(DQS)、片選信號(CS#)、行地址選通信號(CAS#)、列地址選通信號(RAS#)、寫使能信號(WE#)、數據屏蔽信號(DM)和片內終端電阻控制線(ODT)等[7]。
DDR2 SDRAM的電平電壓為1.8V,參考電壓VREF為電源電壓的一半。由于外部由5V電源供電,所以采用MP1482芯片將外部的5V電源電壓轉換成DDR2需要的1.8V電壓。具體電路參考MP1482使用手冊,本文不再贅述。
DDR2的硬件設計需要嚴格考慮信號完整性[8],在電路設計和PCB設計的時候需要充分考慮匹配電阻/終端電阻、走線阻抗控制和走線等長控制,保證DDR2的高速穩定的工作。
DDR2 SDRAM控制器的主要功能是實現存儲器芯片的初始化、讀寫操作和數據傳輸,它將存儲器復雜的讀寫時序隱藏起來,轉化成簡單易行的操作,通過控制器,只需控制簡單的接口信號,就可以對存儲器芯片進行讀寫操作。寫入數據的時候,只要控制寫請求信號wr_burst_req、寫長度wr_burst_len、寫地址wr_burst_add和寫數據wr_burst_data。同樣,讀數據的時候,只要控制讀請求信號rd_burst_req、讀長度rd_burst_len、讀地址rd_burst_add、讀數據有效rd_burst_data_valid和讀數據rd_burst_data。本設計的命令參數是根據表1的命令真值表和圖3的狀態轉換圖進行邏輯設計的。

表1 DDR2 SDRAM基本操作的命令真值表

圖3 DDR2 SDRAM控制器狀態轉換圖
圖3的狀態轉換圖顯示了DDR2 SDRAM控制器把外部的burst 讀請求和寫請求轉化成 DDR2 IP接口的Local Bus的所需的信號和時序的流程。具體的讀和寫流程如下:
Burst讀:當程序在IDLE狀態接收到讀請求(rd_burst_req為高)時,會進入MEM_READ狀態并發送Local Bus的讀請求命令,讀請求的長度為rd_burst_len。發送Local Bus的讀請求結束后進入MEM_READ_WAIT狀態,等待數據全部讀出完成。讀數據完成后會返回IDLE狀態,并發送rd_burst_finish信號。
Burst寫:當程序在IDLE狀態接收到寫請求(wr_burst_req為高)時,會先進入MEM_WRITE_FIRST狀態,再輪流進入MEM_WRITE_BURST_BEGIN狀態和MEM_WRITE狀態。在MEM_WRITE_BURST_BEGIN狀態,會置位Local Bus的local_burst_begin信號為高,說明這是一個burst的寫命令,burst長度為local_size。在MEM_WRITE狀態,不需要發送 local_burst_begin信號。在MEM_WRITE_BURST_BEGIN狀態和MEM_WRITE狀態里,Local Bus的local_write_req信號一直為高,直到寫入的數據完成返回到IDLE狀態,并發送wr_burst_finish 信號。
根據DDR2 SDRAM控制器狀態轉換圖用硬件開發語言verilog進行FPGA邏輯編程,編譯仿真后連接JTAG將程序燒錄到FPGA開發裝置中,測試是否產生讀寫請求信號,以及地址和測試數據,并校驗讀和寫的數據是否正確,并將結果在SignalTap中顯示出來。
本方案具體驗證流程如下:
(1)在Quartus II中生成ALTMEMPHY IP核,在該過程中設置了Device family、Speed grade、DDR2的輸入參考時鐘頻率和DDR2時鐘頻率等參數;
(2)編寫mem_burst_v2.v程序完成對DDR2 IP的封裝;
(3)編寫ddr2_test.v測試程序實現兩個功能,一個功能是產生讀寫請求信號、地址和測試數據并校驗讀和寫的數據是否正確,另一個功能是例化mem_burst_v2模塊和第一步中生成的DDR2 IP頂層模塊ddr2.v;
(4)程序編譯完成之后會用Quartus II的對應仿真軟件Modelsim將程序的運行結果進行仿真觀察是否能達到預期的結果,仿真完成之后連接JTAG將程序燒錄到FPGA開發板中,使用SignalTap工具來測試和觀察DDR2讀寫的時序和信號狀態。
開發的程序在Quartus II中編譯后的資源報告如圖4所示,資源報告內容主要包括項目名ddr_test、頂層文件名ddr_test、FPGA系列名Cyclone IV E、FPGA型號EP4CE30F23C8、總邏輯模塊數7907、引腳數49以及鎖相環數1。

圖4 資源報告
連接JTAG將程序燒錄到FPGA開發板中,使用SignalTap工具來測試和觀察DDR2讀寫的時序和信號狀態,采樣時鐘使用DDR2 IP產生的phy_clk,具體波形如圖5、圖6和圖7所示。
首先可以觀察一下圖5中DDR burst寫入數據的波形,這里波形顯示向DDR2的地址空間E830A6的地址開始寫入01010101,02020202...的數據。因為這里的DDR2的burst寫length為2,所以地址信號local_address是每寫入2個數據就加2, local_burst_begin信號為第一個數據寫的時候為高,第二個數據寫的時候為低。

圖5 寫入數據圖
這里需要注意:只有當local_ready為高和local_write_req信號都為高時,寫入的數據才是有效的數據,如果local_ready信號為低,local_write_req和數據需要一直保持,等待local_ready 信號為高才行。
接下去可以觀察一下圖6中DDR2的burst讀的時序,在local_ready信號為高和local_read_req信號為高時,依次讀取地址信號local_address為E830A6,E830A8…的數據。

圖6 數據地址及信號有效圖
這里也同樣:只有當local_ready為高和local_read_req信號都為高時,burst讀才是有效的,如果local_ready信號為低,local_read_req和地址local_address需要一直保持,等待local_ready 信號為高才行。
繼續觀察讀出的數據是否跟之前寫入的數據一致,local_read_req信號請求為高等待一段時間后,local_rddata_valid信號會變高,這里DDR2輸出有效的數據01010101,02020202....,如圖7所示,DDR2讀出的數據正是之前寫入到DDR2中的數據。

圖7 讀數據圖
根據以上的DDR2測試,可以得到在Intel的FPGA Cyclone IV系列開發板上的DDR2部分能夠穩定地在166.7MHz時鐘頻率下工作,因為DDR2采用上下沿數據讀寫,所以數據讀寫傳輸達到330MHz的頻率。在編程時,IP核的封裝模塊即本方案中的mem_burst_v2模塊非常重要,可以簡化對DDR2 IP接口和時序控制的難度,并且能方便后續的其他模塊如讀寫模塊的使用,也能為程序的移植帶來便捷。
本文首先介紹了DDR2 SDRAM的工作機制,包括DDR2 SDRAM的初始化、工作方式和IP核;之后根據DDR2 SDRAM的操作原理設計了DDR2 SDRAM的控制器,包括硬件設計和軟件設計兩個方面;硬件設計給出了信號連接圖,軟件設計給出了整個控制器系統的狀態轉換圖,包括突發模式下讀寫操作的狀態轉換;最后對設計的DDR2 SDRAM控制器進行了驗證,證明了在166.7MHz時鐘頻率下讀寫操作以及local_ready和local_read_req等控制信號都可以正常作用,并且數據正確。通過本文對DDR2 SDRAM控制器的設計,大大簡化了DDR2 SDRAM的讀寫操作功能。