天天看點

DDR3總結筆記

部落客的微信公衆号:FPGA動力聯盟

部落客的個人微信:fpga_start

部落格原文連結:https://item.taobao.com/item.htm?ft=t&id=649445848757

該篇文章記錄了基于FPGA的DDR3開發所需要的一些細節,一方面是對自己工作的詳細總結,友善日後遺忘了重新查閱,另一方面希望所有讀了這篇文章的人都能夠掌握DDR3開發所需的基本知識。

 本篇将分成四個部分來循序漸進的描述DDR3相關的開發知識,其中第一部分介紹DDR3原理,第二部分具體介紹DDR3晶片,第三部分介紹FPGA-DDR3硬體設計,第四部分介紹DDR3- FPGA讀寫邏輯~

第一部分:DDR3原理

在介紹DDR3之前,先介紹一下存儲器(memory)的分類,存儲器一般可以分為内部存儲器(記憶體)、外部存儲器(外存)、緩沖存儲器(緩存)以及閃存這幾個大類:

記憶體也稱為主存儲器,位于系統主機闆上,可以同CPU/FPGA直接進行資訊交換,其主要特點是運作速度快,容量小。

外存也稱為輔助存儲器,不能與CPU之間直接進行資訊交換。其主要特點是:存取速度相對記憶體要慢得多,存儲容量大。記憶體與外存本質差別是,一個是内部運作提供緩存和處理的功能;而外存主要是針對儲存檔案、圖檔、視訊、文字等資訊的載體,也可以了解為儲存空間。

緩存就是資料交換的緩沖區(稱作Cache),當某一硬體要讀取資料時,會首先從緩存中查找需要的資料,如果找到了則直接執行,找不到的話則從記憶體中找。由于緩存的運作速度比記憶體快得多,故緩存的作用就是幫助硬體更快地運作。

閃存(Flash Memory)是一種長壽命的非易失性(在斷電情況下仍能保持所存儲的資料資訊)的存儲器,資料删除不是以單個的位元組為機關而是以固定的區塊為機關(注意:NOR Flash 為位元組存儲),區塊大小一般為256KB到20MB。閃存是電子可擦除隻讀存儲器(EEPROM)的變種,閃存與EEPROM不同的是,EEPROM能在位元組水準上進行删除和重寫而不是整個晶片擦寫,而閃存中的大部分晶片需要塊擦除。由于其斷電時仍能儲存資料,閃存通常被用來儲存設定資訊,如在電腦的BIOS(基本程式)、數位相機中儲存資料等。

 存儲器的詳細分類如下圖所示:                     

DDR3總結筆記

圖1:存儲器分類

記憶體中的随機存儲器(Random Access Memory,RAM)是一種存儲單元内容可按需随意取出或存入,且存取的速度與存儲單元位置無關的存儲器。這種存儲器在斷電時将丢失其存儲内容,故主要用于存儲短時間使用的程式或資料。按照存儲資訊的不同,随機存儲器又分為靜态随機存儲器(Static RAM,SRAM)和動态随機存儲器(Dynamic RAM,DRAM):

靜态随機存儲器SRAM(Static RAM)不需要重新整理電路就能儲存它内部存儲的資料。除此以外,還有一種随機存儲器SSRAM(Synchronous SRAM)即同步靜态随機存取存儲器。同步是指Memory工作需要同步時鐘,内部的指令的發送與資料的傳輸都以它為基準;随機是指資料不是線性依次存儲,而是由指定位址進行資料讀寫。對于SSRAM的所有通路都在時鐘的上升/下降沿啟動,位址、資料輸入和其它控制信号均與時鐘信号相關。這一點與異步SRAM不同,異步SRAM的通路獨立于時鐘,資料輸入和輸出都由位址的變化控制。

動态随機存儲器DRAM(Dynamic RAM)則每隔一段時間,要重新整理充電一次,否則内部的資料會消失。綜上所述,SRAM具有較高的性能,但是SRAM也有它的缺點,即它的內建度較低,相同容量的DRAM記憶體可以設計為較小的體積,但是SRAM卻需要很大的體積,且功耗較大。是以在主機闆上SRAM存儲器要占用一部分面積。SRAM的速率高、性能好,它常應用于CPU與主存之間的高速緩存。有一種動态随機存儲器SDRAM(Synchronous DRAM)即同步動态随機存取存儲器。同步是指 Memory工作需要同步時鐘,内部指令的發送與資料的傳輸都以它為基準;動态是指存儲陣列需要不斷的重新整理來保證資料不丢失;随機是指資料不是線性依次存儲,而是自由指定位址進行資料讀寫,DDR,DDR2、DDR3以及DDR4就屬于SDRAM的一類。

SDRAM從發展到現在已經經曆了五代,分别是:第一代SDRSDRAM,第二代DDRSDRAM,第三代DDR2SDRAM,第四代DDR3 SDRAM,第五代DDR4 SDRAM。第一代SDRAM采用單端(Single-Ended)時鐘信号,而且是時鐘上升沿采樣。而第二代、第三代與第四代DDR由于時鐘上下沿采樣,是以工作頻率比SDR翻倍,是以采用可降低幹擾的差分時鐘信号作為同步時鐘。

 DDR2以及DDR3可以看作是DDR技術标準的一種更新和擴充:DDR的核心頻率(DDR晶片内部進行邏輯處理的時鐘頻率)與工作頻率(工作頻率指的是DDR晶片管腳的時鐘頻率)相等,但傳輸頻率(指的是DDR晶片讀寫的頻率)為時鐘頻率的兩倍,也就是說在一個時鐘周期内必須傳輸兩次資料。而DDR2采用“4bit Prefetch (4位預取)”機制,核心頻率為傳輸頻率的1/4,這樣即使核心頻率還為200MHz,DDR2記憶體的資料傳輸頻率也能達到800MHz,也就是所謂的DDR2-800。DDR3采用“8bit Prefetch(8位預取)”機制,這樣DRAM的核心頻率隻有傳輸頻率的1/8,是以DDR3-800的核心頻率隻有100MHz,如果核心頻率為200MHz,DDR3記憶體的資料傳輸頻率能達到1600MHz,資料傳輸頻率為DDR2的兩倍,即DDR3-1600。總得來說,需要知道DDR3三個頻率之間的關系:

工作頻率=資料傳輸頻率/2。因為DDR是利用時鐘的上升沿與下降沿均傳輸資料,是以DDR晶片的工作頻率(時鐘引腳的頻率)為傳輸頻率的一半。

核心頻率=資料傳輸頻率/DDR的預取數。對于DDR來說,預取數為2;對于DDR2來說,預取數為4;對于DDR3來說,預取數為8。

下面具體介紹DDR3:

DDR3 SDRAM(Double-Data-Rate Synchronous Dynamic Random Access Memory)屬于上文提到的SDRAM類。DDR3 在DDR2的基礎上繼承發展而來,其資料傳輸速度為 DDR2的兩倍。同時,DDR3 标準可以使單顆記憶體晶片的容量更為擴大,達到 512Mb 至 8Gb,進而使采用 DDR3 晶片的記憶體條容量擴大到最高16GB。此外,DDR3的工作電壓降低為1.5V,比采用1.8V的DDR2省電30%左右。說到底,這些名額上的提升在技術上最大的支撐來自于晶片制造技術的提升,90nm 甚至更先進的45nm制造技術使得同樣功能的 MOS 管可以制造的更小,進而帶來更快、更密、更省電的技術提升。DDR3現今是并行 SDRAM 家族中速度最快的成熟标準,JEDEC标準規定的DDR3最高速度可達1600MT/s (1MT/s 即為每秒鐘一百萬次傳輸)。不僅如此,記憶體廠商還可以生産速度高于 JEDEC 标準的DDR3産品,如速度為2000MT/s 的DDR3産品,甚至有報道稱其最高速度可高達 2500MT/s。

DDR3相較于DDR2而言主要有如下幾個特點:

1.突發長度(Burst Length,BL):由于DDR3的預取為8bit,是以突發傳輸周期(Burst Length,BL)也固定為8。預取為8bit意味着DDR3内部時鐘在一次讀/寫資料時,操作8bit資料,在相同時間内接口為了能夠處理得過來,其接口讀寫資料速度必須為内部核心時鐘頻率的8倍。是以就有了DDR3-1600的晶片接口讀寫速率(也就是資料傳輸速率)為1600MT/s,其實内部時鐘為200MHz。

2.尋址時序(Timing):就像DDR2從DDR轉變而來後延遲周期數增加一樣,DDR3的CL周期也将比DDR2有所提高。DDR2的CL範圍一般在2~5之間,而DDR3則在5~11之間,且附加延遲(AL)的設計也有所變化。DDR2時AL的範圍是0~4,而DDR3時AL有三種選項,分别是0、CL-1和CL-2。另外,DDR3還新增加了一個時序參數-寫入延遲(CWD),這一參數将根據具體的工作頻率而定。

3.DDR3新增的重置(Reset)功能:重置是DDR3新增的一項重要功能,并為此專門準備了一個引腳。DRAM業界很早以前就要求增加這一功能,如今終于在DDR3上實作了。這一引腳将使DDR3的初始化處理變得簡單。當Reset指令有效時,DDR3記憶體将停止所有操作,并切換至最少量活動狀态,以節約電力。在Reset期間,DDR3記憶體将關閉内在的大部分功能,所有資料接收與發送器都将關閉,所有内部的程式裝置将複位,DLL(延遲鎖相環路)與時鐘電路将停止工作,而且不理睬資料總線上的任何動靜。這樣一來,将使DDR3達到最節省電力的目的。

4.DDR3新增ZQ校準功能:ZQ也是一個新增的腳,在這個引腳上接有一個240歐姆的低公差參考電阻。這個引腳通過一個指令集,通過片上校準引擎(On-Die Calibration Engine,ODCE)來自動校驗資料輸出驅動器導通電阻與ODT的終結電阻值。當系統發出這一指令後,将用相應的時鐘周期(在加電與初始化之後用512個時鐘周期,在退出自重新整理操作後用256個時鐘周期、在其他情況下用64個時鐘周期)對導通電阻和ODT電阻進行重新校準。

5.參考電壓分成兩個:在DDR3系統中,對于記憶體系統工作非常重要的參考電壓信号VREF将分為兩個信号,即為指令與位址信号服務的VREFCA和為資料總線服務的VREFDQ。

6.邏輯Bank數量:DDR2 SDRAM中有4Bank和8Bank的設計,目的就是為了應對未來大容量晶片的需求。而DDR3很可能将從2Gb容量起步,是以起始的邏輯Bank就是8個,另外還為未來的16個邏輯Bank做好了準備。

7.封裝(Packages):DDR3由于新增了一些功能,是以在引腳方面會有所增加,8bit晶片采用78球FBGA封裝,16bit晶片采用96球FBGA封裝,而DDR2則有60/68/84球FBGA封裝三種規格。并且DDR3必須是綠色封裝,不能含有任何有害物質。

8.降低功耗:DDR3記憶體在達到高帶寬的同時,其功耗反而可以降低,其核心工作電壓從DDR2的1.8V降至1.5V,相關資料預測DDR3将比現時DDR2節省30%的功耗,當然發熱量我們也不需要擔心,不但記憶體帶寬大幅提升,功耗表現也比上代更好

記憶體技術從SDR,DDR,DDR2,DDR3一路發展而來,傳輸速度以指數遞增,除了晶圓制造技術的提升因素之外,還因為采用了Double Data Rate以及Prefetch(預取)兩項技術。實際上,無論是SDR還是DDR或DDR2、DDR3,記憶體晶片内部的核心時鐘頻率基本上是保持一緻的,都是100MHz到200MHz(某些廠商生産的超頻記憶體除外)。DDR即Double Data Rate技術使資料傳輸速度較SDR提升了一倍。如下圖所示, SDR僅在時鐘的上升沿傳輸資料,而DDR在時鐘信号上、下沿同時傳輸資料。例如同為133MHz時鐘,DDR卻可以達到266Mb/s的資料傳傳輸速度。

DDR3總結筆記

圖2:SDR與DDR的核心時鐘頻率與接口傳輸頻率比較

Double Data Rate技術使資料外傳速度提升了一倍,而晶片内部資料傳輸速度的提升則是通過Prefetch(預取)技術實作的。所謂Prefetch(預取)簡單的說就是在一個核心時鐘周期同時尋址多個存儲單元并将這些資料以并行的方式統一傳輸到IO Buffer中,之後以更高的外傳速度将IO Buffer中的資料傳輸出去。這個更高的速度在DDR中就是通過Double Data Rate實作的,也正因為如此,DDR晶片時鐘管腳的時鐘頻率與晶片内部的核心頻率是一緻的。如下圖所示為DDR的Prefetch過程中,在16位的記憶體晶片中一次将2個16bit資料從核心傳輸到外部MUX單元,之後分别在Clock信号的上、下沿分兩次将這2個16bit資料傳輸給FPGA或其他記憶體控制器,整個過程經曆的時間恰好為一個核心時鐘周期。

發展到DDR2,晶片核心每次Prefetch (預取) 4倍的資料至IO Buffer中,為了進一步提高外傳速度,晶片的核心時鐘與外部接口時鐘(即DDR晶片的Clock管腳時鐘)不再是同一時鐘,外部Clock時鐘頻率變為核心時鐘的2倍。同理,DDR3每次Prefetch 8倍的資料,其晶片Clock頻率為核心頻率(100MHz至200MHz)的4倍,即JEDEC标準(JESD79-3)規定的400MHz至800MHz,再加上在Clock信号上、下跳變沿同時傳輸資料,DDR3的資料傳輸速率便達到了800MT/s到1600MT/s。具體到記憶體條速度,我們以PC3-12800為例,其采用的DDR3-1600晶片的核心頻率為200MHz,經過Prefetch後在800MHz Clock信号工作頻率的雙邊沿(Double Data Rate)作用下,使晶片的資料傳輸速率為1600 MT/s,記憶體條每次傳輸64比特或者說8位元組資料,1600x8便得到12800MB/s的峰值比特率。

下表列出了JEDEC标準(JESD79-3)規定的DDR3晶片以及記憶體條相關參數。需要說明的是,如前所述,并不是所有的記憶體産品都完全遵從JEDEC标準,有些廠家會生産速度更高速的DDR3晶片,一般情況下這些晶片是從晶片檢測流程中篩選出來的頻率動态範圍更大的晶片,或者是可加壓超頻工作的晶片。

名稱 核心頻率 核心時鐘周期 管腳時鐘頻率 資料傳輸速率 對應記憶體條名稱 記憶體條峰值比特率
DDR3-800 100MHz 10ns 400MHz 800MT/s PC3-6400 6400MB/
DDR3-1066 133MHz 7.5ns 533MHz 1066MT/s PC3-8500 8533MB/s
DDR3-1333 166MHz 6ns 667MHz 1333MT/s PC3-10600 10667MB/s
DDR3-1600 200MHz 5ns 800MHz 1600MT/s PC3-12800 12800MB/s

注意:Clock管腳時鐘頻率就是DDR的工作頻率。最後,在了解了DDR的上面基礎知識的前提下,下表列出了不同DDR晶片的相關特性:

SDRAM器件比較
條目 DDR3   DDR2  DDR  
工作頻率 400/533/667/800  MHz 200/266/333/400  MHz 100/133/166/200  MHz
資料傳輸速率 800/1066/1333/1600  MT/s 400/533/667/800  MT/s 200/266/333/400  MT/s
預取位寬 8-bit 4-bit 2-bit
輸入時鐘類型 差分時鐘 差分時鐘 差分時鐘
突發長度 8, 4 4,8 2,4,8
DQS 差分資料選通 差分資料選通 單端資料選通
電源電壓 1.5V 1.8V 2.5V
資料電平标準 SSTL_15 SSTL_18 SSTL_2
CL 5,6,7,8,9時鐘 3,4,5時鐘 2,2.5,3時鐘
ODT 支援 支援 不支援
晶片封裝 FBGA FBGA TSOP(II)/FBGA/LQFP

 下面介紹DDR3的原理:

DDR3的内部是一個存儲陣列,将資料“填”進去,你可以它想象成一張表格,如下圖所示。和表格的檢索原理一樣,先指定一個行(Row),再指定一個列(Column),我們就可以準确地找到所需要的單元格,這就是記憶體晶片尋址的基本原理。對于記憶體,這個單元格可稱為存儲單元,那麼這個表格(存儲陣列)就是邏輯Bank(Logical Bank,下面簡稱Bank,與之對應的還有一種叫做實體BANK(又稱RANK)。 

DDR3總結筆記

DDR3内部的BANK可以看做是一個M×N的陣列,B代表Bank編号,C代表列位址編号,R代表行位址編号。如果尋址指令是B1、R2、C6,就能确定位址是圖中紅格的位置,進而讀寫該位址所在的記憶體空間。

目前DDR3記憶體晶片基本上都是8個Bank設計,也就是說一共有8個這樣的“表格”。尋址的流程也就是先指定Bank位址,再指定行位址,然後指定列位址,最終确定尋址單元。

對DDR3系統而言,還存在實體Bank的概念,這是對記憶體子系統的一個相關術語,并不針對記憶體晶片。記憶體為了保證CPU正常工作,必須一次傳輸完CPU 在一個傳輸周期内所需要的資料。而CPU在一個傳輸周期能接受的資料容量就是CPU資料總線的位寬,機關是bit(位)。控制記憶體與CPU之間資料交換的FPGA晶片也是以将記憶體總線的資料位寬等同于CPU資料總線的位寬,這個位寬就稱為實體Bank(Physical Bank,有的資料稱之為Rank)的位寬。目前這個位寬基本為64bit。

附:實體Bank解釋

傳統記憶體系統為了保證CPU的正常工作,必須一次傳輸完CPU在一個傳輸周期内所需要的資料。而CPU在一個傳輸周期能接收的資料容量就是CPU資料總線的位寬,機關是bit(位)。記憶體與CPU之間的資料交換通過主機闆上的FPGA晶片進行,記憶體總線的資料位寬等同于CPU資料總線的位寬,這個位寬就稱之為實體Bank(Physical Bank,簡稱rank)的位寬。以目前主流的DDR系統為例,CPU與記憶體之間的接口位寬是64bit,也就意味着CPU在一個周期内會向記憶體發送或從記憶體讀取64bit的資料,那麼這一個64bit的資料集合就是一個記憶體條Bank。一條記憶體條的實體Bank是由所采用的記憶體顆粒的位寬決定的,各個晶片位寬之和為64bit就是單實體Bank;如果是128bit就是雙實體Bank。

在實際工作中,邏輯Bank位址與相應的行位址是同時發出的,此時這個指令稱之為“行激活”(Row Active)。在此之後,将發送列位址尋址指令與具體的操作指令(是讀還是寫),這兩個指令也是同時發出的,是以一般都會以“讀/寫指令”來表示列尋址。根據相關的标準,從行有效到讀/寫指令發出之間的間隔被定義為tRCD,即RAS to CAS Delay(RAS至CAS延遲,RAS就是行位址選通脈沖,CAS就是列位址選通脈沖),我們可以了解為行選通周期。tRCD是DDR的一個重要時序參數,廣義的tRCD以核心時鐘周期(tCK,Clock Time)數為機關,比如tRCD=3,就代表延遲周期為兩個時鐘周期,具體到确切的時間,則要根據時鐘頻率而定。以DDR3-800為例,DDR3-800的資料傳輸頻率(等效頻率)為800MHz,由于DDR3的預取(Prefetch)位寬為8位,是以核心頻率為100MHz (800MHz/8),核心時鐘的周期為10ns,如果tRCD=3,則表示延時為30ns。

DDR3總結筆記

圖3:tRCD時序

上圖是tRCD=3的時序圖,NOP=Not Operation,表示無操作,灰色區域表示Don’t Care。

接下來,相關的列位址被選中以後,将會觸發資料傳輸,但從存儲單元中輸出到真正出現在記憶體晶片的I/O接口之間還需要一定的時間(資料觸發本身就有延時,而且還需要進行信号放大),這段時間就是列位址脈沖選通潛伏期(CAS Latency,CL),CL的數值與tRCD一樣,以時鐘周期數表示。比如DDR3-800的有效頻率(傳輸資料頻率)為800MHz,由于DDR3的預取數為8,是以核心頻率為100MHz,核心周期為10ns,如果CL=2,那麼就意味着列位址脈沖選通潛伏期為20ns。CL隻針對讀取操作有效。

由于晶片體積的原因,存儲單元中的電容容量很小,是以信号要經過放大來保證其有效的識别性,這個放大/驅動工作由Sense Amplifier負責,一個存儲體對應一個Sense Amplifier通道。但它要有一個準備時間才能保證信号的發送強度(事前還要進行電壓比較以進行邏輯電平的判斷),是以從資料I/O總線上有資料到資料輸出之前的一個時鐘上升沿開始,資料即已傳向Sense Amplifier,也就是說此時資料已經被觸發,經過一定的驅動時間最終傳向資料I/O總線進行輸出,這段時間我們稱之為tAC(Access Time from CLK,時鐘觸發後的通路時間)。

Sense Amplifier在DDR結構中扮演的角色如下所示:

DDR3總結筆記

圖4:DDR結構中的Sense Amplifier

tAC和CAS的示意圖如下圖所示

DDR3總結筆記

圖5:CAS與tAC

目前記憶體的讀寫基本都是連續的,因為與CPU交換的資料量以一個Cache Line(即CPU内Cache的存儲機關)的容量為準,一般為64位元組。而現有的Rank位寬為8位元組(64bit),那麼就要一次連續傳輸8次,這就涉及到我們也經常能遇到的突發傳輸的概念。突發(Burst)是指在同一行中相鄰的存儲單元連續進行資料傳輸的方式,連續傳輸的周期數就是突發長度(Burst Lengths,簡稱BL)。

在進行突發傳輸時,隻要指定起始列位址與突發長度,記憶體就會依次地自動對後面相應數量的存儲單元進行讀/寫操作而不再需要控制器連續地提供列位址。這樣,除了第一組資料的傳輸需要若幹個周期(主要是之前的延遲,一般的是tRCD+CL)外,其後每個資料隻需一個周期的即可獲得。下圖是CAS=2,BL=4時的時序圖

DDR3總結筆記

圖6:DDR突發傳輸

突發連續讀取模式:隻要指定起始列位址與突發長度,後續的尋址與資料的讀取自動進行,而隻要控制好兩段突發讀取指令的間隔周期(與BL相同)即可做到連續的突發傳輸。

談到了突發長度時。如果BL=4,那麼也就是說一次就傳送4×64bit的資料。但是,如果其中的第二組資料是不需要的,怎麼辦?還都傳輸嗎?為了屏蔽不需要的資料,人們采用了資料掩碼(Data I/O Mask,簡稱DQM)技術。通過DQM,記憶體可以控制I/O端口取消哪些輸出或輸入的資料。這裡需要強調的是,在讀取時,被屏蔽的資料仍然會從存儲體傳出,隻是在“掩碼邏輯單元”處被屏蔽。DQM由FPGA控制,為了精确屏蔽一個P-Bank位寬中的每個位元組,每個DIMM有8個DQM 信号線,每個信号針對一個位元組。這樣,對于4bit位寬晶片,兩個晶片共用一個DQM信号線,對于8bit位寬晶片,一個晶片占用一個DQM信号,而對于 16bit位寬晶片,則需要兩個DQM引腳。

在資料讀取完之後,為了騰出讀出放大器以供同一Bank内其他行的尋址并傳輸資料,記憶體晶片将進行預充電的操作來關閉目前工作行。還是以上面那個Bank示意圖為例。目前尋址的存儲單元是B1、R2、C6。如果接下來的尋址指令是B1、R2、C4,則不用預充電,因為讀出放大器正在為這一行服務。但如果位址指令是B1、R4、C4,由于是同一Bank的不同行,那麼就必須要先把R2關閉,才能對R4尋址。從開始關閉現有的工作行,到可以打開新的工作行之間的間隔就是tRP(Row Precharge command Period,行預充電有效周期),機關也是時鐘周期數。

整個充電的步驟如下圖所示:

DDR3總結筆記

圖7:DDR3結構

在不同Bank間讀寫也是這樣,先把原來資料寫回,再激活新的Bank/Row。

下面介紹資料選取脈沖(DQS):

DQS 是DDR中的重要功能,它的功能主要用來在一個時鐘周期内準确的區分出每個傳輸周期,并便于接收方準确接收資料。每一顆晶片都有一個DQS信号線,它是雙向的,在寫入時它用來傳送由FPGA發來的DQS信号,讀取時,則由晶片生成DQS向FPGA發送。完全可以說,它就是資料的同步信号。

在讀取時,DQS與資料信号同時生成(也是在CK與CK#的交叉點)。而DDR記憶體中的CL也就是從CAS發出到DQS生成的間隔,DQS生成時,晶片内部的預取已經完畢了,由于預取的原因,實際的資料傳出可能會提前于DQS發生(資料提前于DQS傳出)。由于是并行傳輸,DDR記憶體對tAC也有一定的要求,對于DDR266,tAC的允許範圍是±0.75ns,對于DDR333,則是±0.7ns,有關它們的時序圖示見前文,其中CL裡包含了一段DQS 的導入期。

DQS 在讀取時與資料同步傳輸,那麼接收時也是以DQS的上下沿為準嗎?不,如果以DQS的上下沿區分資料周期的危險很大。由于晶片有預取的操作,是以輸出時的同步很難控制,隻能限制在一定的時間範圍内,資料在各I/O端口的出現時間可能有快有慢,會與DQS有一定的間隔,這也就是為什麼要有一個tAC規定的原因。而在接收方,一切必須保證同步接收,不能有tAC之類的偏差。這樣在寫入時,晶片不再自己生成DQS,而以發送方傳來的DQS為基準,并相應延後一定的時間,在DQS的中部為資料周期的選取分割點(在讀取時分割點就是上下沿),從這裡分隔開兩個傳輸周期。這樣做的好處是,由于各資料信号都會有一個邏輯電平保持周期,即使發送時不同步,在DQS上下沿時都處于保持周期中,此時資料接收觸發的準确性無疑是最高的。

DDR3的寫時序的時序圖如下圖所示:

DDR3總結筆記

圖8:DDR3寫時序

DDR3的讀時序的時序圖如下圖所示:

DDR3總結筆記

圖9:DDR3讀時序

由上面的時序圖可知,在寫時序中,有效資料DQ的正中間正好對應DQS的跳邊沿,而在讀時序中,有效資料的正中間對應着DQS信号的正中間。

最後在簡單說一說DDR中采用的ODT(On-Die Termination)技術:

ODT(On-DieTermination),是從DDR2 SDRAM時代開始新增的功能。其允許使用者通過讀寫DDR2/3内部的MR1寄存器,來控制DDR3 SDRAM中各個信号内部終端電阻的連接配接或者斷開。在DDR3 SDRAM中,ODT功能主要應用于:

1、DQ, DQS, DQS# andDM for X4 configuration

2、DQ, DQS, DQS#, DM,TDQS and TDQS# for X8 configuration

3、DQU, DQL, DQSU,DQSU#, DQSL, DQSL#, DMU and DML for X16 configuration

ODT(On-DieTermination)技術的目的是通過使DDR SDRAM控制器能夠獨立的打開或者關斷DDR内部的終端電阻來提高存儲器通道的信号完整性,在DLL關閉模式,ODT功能被禁用。

一個DDR通道,通常會挂接多個Rank,這些Rank的資料線、位址線等等都是共用;資料信号也就依次傳遞到每個Rank,到達線路末端的時候,波形會有反射,進而影響到原始信号;是以需要加上終端電阻,吸收餘波。之前的DDR,終端電阻做在闆子上,但是因為種種原因,效果不是太好,到了DDR2,把終端電阻做到了DDR顆粒内部,也就稱為On Die Termination,Die上的終端電阻,Die是矽片的意思,這裡也就是DDR顆粒。

ODT技術具體的内部結構圖如下:

DDR3總結筆記

圖10:DDR3内部的ODT結構

等效結構如下圖所示:

DDR3總結筆記

圖11:DDR3内部的ODT結構的戴維南等效模型

ODT終端電阻的電阻值RTT可通過模式寄存器MR1的A9,A6,A2來進行設定,具體設定可參考DDR3 SDRAM晶片資料手冊 。

總的來說,ODT技術有以下三個優點:

1、去掉了主機闆上的終結電阻器等電器元件,這樣會大大降低主機闆的制造成本,并且也使主機闆的設計更加簡潔。

2、由于ODT技術可以迅速的開啟和關閉空閑的記憶體晶片,在很大程度上減少了記憶體閑置時的功率消耗。

3、晶片内部終結電阻也要比主機闆的終端電阻具有更好的信号完整性。這也使得進一步提高DDR2記憶體的工作頻率成為可能。

第二部分:DDR3晶片

本調試筆記以美光(micron)的DDR3晶片為例介紹,晶片具體型号為:MT41J256M16HA-125,其基本性能介紹如下圖所示:

DDR3總結筆記

圖12:DDR3晶片主要特性

DDR3總結筆記

圖13:DDR3的容量及位址

該晶片行位址線為row[14:0],即215=32K;列位址線為column[9:0],即210=1K;bank位址為bank[2:0],即23=8個bank;每個存儲單元的資料為data[15:0],即24=16bit位寬,是以可以計算得到該晶片為存儲容量為:32K×1K×8×16=232=4Gb。

該晶片的管腳信号描述如下:

管腳名稱 類型 功能

A[14:13],  A12/BC#,

A11,  A10/AP, A[9:0]

Input 為位址輸入,為 ACTIVATE指令提供行位址,同時為READ/WRTE指令提供列位址和自動預充電位(A10),以便從某個Bank的記憶體陣列裡選出一個位置。LOAD MODE指令期間,位址輸入提供一個操作碼。位址輸入的參考值是 VREFCA。A12/BC#:在模式寄存器(MR)使能時,A12在READ和 WRITE指令期間被采樣,以決定burst chop(on-the-fly)是否會被執行(HIGH=BL8執行 burst chop),或者LoW-BC4不執行 burst chop
BA[2:0] Input 是Bank位址輸入,定義 ACTIVATE、READ、WRITE或 PRECHARGE指令是對哪個Bank操作的。BA[2:0]定義在 LOAD MODE指令期間哪個模式(MR0、MR1、MR2)被裝載,BA[2:0]的參考值是ⅤREFCA
CK,  CK# Input 差分時上鐘輸入,所有控制和位址輸入信号在CK上升沿和CK#的下降沿交叉處被采樣,輸出資料選通(DQS,DQS#)參考CK和CK#的交叉點。
CKE Input 時鐘使能。使能(高)和禁止(低)内電路和DRAM上的時鐘。由DDR3 SDRAM配置和操作模式決定特定電路被使能和禁止。CKE為低,提供 PRECHARGE POWER-DOWN和 SELF REFRESH操作(所有Bank都處于空閑),或者有效掉電(在任何Bank裡的行有效)。CKE與掉電狀态的進入、退出以及自重新整理的進入同步。CKE與自重新整理的退出異步,輸入Buffer(除了CKE、CK#、 RESET#和ODT)在POWER-DOWN期間被禁止。輸入Buffer(除了CKE和 RESET#)在SELF REFRESH期間被禁止。CKE的參考值是ⅤREFCA。
CS# Input 片選信号。使能(低)和禁止(高)指令譯碼,當CS#為高時,所有指令被屏蔽、CS#提供了多Bank系統的Bank選擇功能,CS#是指令代碼的一部分,CS#的參考值是 VREFCA
LDM Input 低8位資料輸入屏蔽。LDM是低8位寫資料的輸入屏蔽信号,在寫期間,當伴随低8位輸入資料的LDM信号被采樣為高時,輸入資料的低8位被屏蔽。雖然LDM僅作為輸入腳,但是LDM負載被設計成與DQ和DQS腳負載相比對。DM的參考值是 VREFCA。
ODT Input 片上終端使能。ODT使能(高)和禁止(低)片内終端電阻,在正常操作使能時,ODT僅對下面的引腳有效:DQ[15:0]、LDQS、LDQS#、UDQS、UDQS#、 UDM 以及LDM。如果通過LOADMODE指令禁止,ODT輸入被忽略。ODT的參考值是 VREFCA。
RAS#,  CAS#, WE# Input 指令輸入,這3個信号,連同CS#,定義一個指令,其參考值是ⅤREFCA。
RESET# Input 複位信号,低位有效,參考值是VSS,複位信号是異步于時鐘的。
UDM Input 高8位資料輸入屏蔽。
DQ[7:0] I/O 低8位資料輸入/輸出。參考值是 VREFDQ。
DQ[15:8] I/O 高8位資料輸入/輸出。參考值是 VREFDQ。
LDQS,  LDQS# I/O 低8位資料選通。讀時是輸出,邊緣與讀出的資料對齊。寫時是輸入,中心與寫資料對齊。
UDQS,  UDQS# I/O 高8位資料選通。讀時是輸出,邊緣與讀出的資料對齊。寫時是輸入,中心與寫資料對齊。
VDD Supply 電源電壓,1.5V±0,075V。
VDDQ Supply DQ電源,1.5V±0.075V。為了降低噪聲,在晶片上進行了隔離。
VREFCA Supply 控制、指令、位址的參考電壓。VREFCA在所有時刻(包括自重新整理)都必須保持規定的電壓。
VREFDQ Supply 資料的參考電壓。VREFDQ在所有時刻(除了自重新整理)都必須保持規定的電壓。
VSS Supply 地。
VSSQ Supply DQ地,為了降低噪聲,在晶片上進行了隔離。
ZQ Reference 輸出驅動校準的外部參考,這個引腳應該連接配接240歐姆電阻到VSSQ。
NC 管腳懸空。

第三部分:DDR3-FPGA硬體設計

本次硬體設計參考黑金的成熟設計方案來進行說明。

下面介紹原理圖設計:

1) 電源設計

DDR3需要3種電源:1.5V的主電源VDD、0.75V的參考電源VREF以及0.75V的比對電阻上拉參考電源VTT。根據上節晶片手冊的電源管腳介紹可知,電源分為4種,分别是電源電壓VDD、資料電壓VDDQ、控制/指令/位址參考VREFCA、資料參考VREFDQ。一般晶片的VDD和VDDQ共用1.5V的主電源VDD,參考電壓VREFCA和VREFDQ共用0.75V的參考電源VREF,而0.75V的比對電阻上拉參考電源VTT的使用在下面将介紹。是以我們選擇TI公司的TPS51200來給DDR3供電。如下圖所示:

DDR3總結筆記

圖14:專用于DDR的晶片

通過外部提供3.3V和1.5V電源,TPS51200輸出VREF和VTT,原理圖如下圖所示:

DDR3總結筆記

圖15:專用于DDR的晶片原理圖

DDR3總結筆記

圖16:DDR3電源晶片實際使用的原理圖

由于FPGA也需要用到1.5V和3.3V的bank電壓,是以在系統電源中肯定包含這兩種電壓,是以1.5V和3.3V可以作為TPS51200的輸入,進而産生VREF和VTT,同時1.5V電源還可以作為DDR3的VDD和VDDQ。DDR3晶片的電源管腳連接配接圖如下所示:

DDR3總結筆記

圖17:DDR3電源供電連接配接

另外,适當數量的濾波電容耦合在電源與地之間也是十分必要的,如下圖所示:

DDR3總結筆記

圖18:DDR3電源濾波電容

2)      DDR3晶片端的信号設計

DDR3的資料、控制、位址、複位等信号直接接入FPGA的專用bank管腳,具體細節後文介紹。這裡需要注意的是,DDR3的内部對資料DQ、LDM、UDM、LDQ以及UDQ信号設計了端接(ODT功能),是以不需要外接比對電阻,但位址、指令和控制線則最好外接比對電阻以保證信号完整性,這時就需要VTT了(不是必須的,但推薦加上電阻上拉比對以保證更穩定,高端FPGA有數控阻抗DCI功能,這時就可以不加外部電阻)。另外DDR3差分時鐘來自于FPGA,輸入到DDR3時,需要外部100Ω終端比對、ZQ端口下拉240Ω電阻、RESET#下拉4.7K電阻。如下圖所示:

DDR3總結筆記

圖19:DDR3原路圖的位址、控制、時鐘等細節

由于本設計采用2片DDR3的設計,是以需要共用時鐘、位址、控制、指令等信号,而資料線則并行結合成32bit。如下圖所示為兩片DDR3的設計:

DDR3總結筆記

圖20:兩片DDR3原路圖

3)      FPGA端的DDR3信号設計

由于DDR3的讀寫比較複雜,xilinx提供專門的IP來幫助使用者快速完成設計。是以DDR3信号接入FPGA時,為了能夠調用IP核,硬體連接配接有許多需要注意的地方,使用者可以參考UG586文檔中的Design Guidelines(192頁)來指導硬體設計。下面具體介紹相關内容:

XilinxFPGA為了支援更高速度的DDR 讀寫速度,對bank進行了專門的設計。在七系列的FPGA中,每個bank有50個管腳,除去bank頂部和底部的單端管腳外,剩餘的48個管腳分成4個位元組組,每個位元組組裡面包含DDR3的一個DQS選通差分信号管腳以及10個信号管腳,共占用12個管腳。在DDR3中,一個DQS選通信号對于8bit資料,是以bank一個位元組組裡的10個信号管腳中的8個管腳用做8bit資料,還有1個管腳作為DDR3的DM信号,剩下的一個管腳作為設計備援,如下圖所示為FPGA的bank圖:

DDR3總結筆記

圖21:FPGA的bank用作DDR3時的組間分類

Xilinx公司強烈建議使用者按照以下方式來進行硬體設計:

  • FPGA的系統時鐘(system clk)必須與DDR3信号所在bank在同一列中,如果有可能的話,最好與DDR3的控制、位址、指令信号在同一bank,且時鐘頻率最好為200MHz,否則後續很麻煩。
  • DDR3晶片的時鐘CK, CK#管腳必須連接配接在控制信号所在的bank位元組組(不是連接配接資料信号所在的bank),包括SRCC, MRCC和DQS在内的任何差分管腳都是可以的。
  • DDR3中的DQS選通信号、DM信号必須與相對應的高或低8bit資料一起接入bank的同一個位元組組裡面,且DQS信号必須接入位元組組中帶DQS辨別的差分管腳,DM則随意。
  • 對于支援DCI功能的bank,VRP/VRN可以使用,避免用于位址、指令、控制等信号的外部比對電阻占用PCB面積。
  • DDR3所有的信号連接配接不能超過FPGA一列中相鄰3個bank。
  • 如果DDR3的信号占用了3個bank,那麼位址、指令、控制等信号隻能接入中間的bank。如果少于3個bank,那麼位址、指令、控制等信号隻能接入同一個bank。
  • 控制信号(RAS_N, CAS_N, WE_N, CS_N, CKE, ODT)和位址信号不能接入包含資料信号的bank位元組組當中。
  • 隻要FPGA的bank電平标準滿足,RESET#信号可以接入FPGA的任何bank的任何管腳。
  • 位元組組與位元組組之間信号(資料、位址/控制)可以整體任意交換,且位元組組内部的信号之間除了DQS外,也可以任意交換。
  • 位址/控制信号可以在位元組組之内或之間任意交換。
  • 為了獲得更高讀寫速度,資料所在bank的兩個VREF管腳需要接入VTT電源。隻有當DDR3讀寫速度不大于800Mb/s時,才可以使用内部VREF,此時兩個VREF管腳可以當成普通管腳使用。

    查閱7系列FPGA資料手冊,可以發現對于xc7a100t-fgg484晶片來說,bank34和bank35屬于同一列。是以bank34可以用作時鐘、位址、控制、複位等信号接入,bank35則用來接入DQ、DQS以及DM信号。

DDR3總結筆記

圖22:FPGA的DQ、DQS、DM所在bank

DDR3總結筆記

圖23:FPGA的位址、控制、時鐘所在bank

第四部分:DDR3-FPGA的PCB設計注意事項

在DDR的PCB設計中,一般需要考慮等長和拓撲結構。等長比較好處理,給出一定的等長精度通常是PCB設計師能夠完成的。但是對于不同速率的DDR,選擇合适的拓撲結構非常關鍵,在DDR布線中經常使用的有T形拓撲結構、菊花鍊拓撲結構以及Fly-by拓撲結構。當然,如果隻有單片的DDR晶片,那就不需要所謂的拓撲結構了,DDR晶片的信号隻需要點對點的和 FPGA管腳連接配接,保證等長即可。拓撲結構針對的是兩片及以上的DDR設計。另外需要說明的是:DDR的DQ、DQS以及DM信号都和FPGA是點對點連接配接,沒有拓撲結構。拓撲結構針對的是時鐘、位址、控制這三類信号。

  • T型拓撲結構

也稱為星型拓撲結構,其結構如下圖所示。星型拓撲結構每個分支的接收端負載和走線長度盡量保持一緻,這就保證了每個分支接收端負載同時收到信号,原則上每條分支上一般都需要終端電阻上拉到VTT,終端電阻的阻值應和連線的特征阻抗相比對(實際操作時上隻在最大T點上拉電阻RT到VTT)。星形拓撲結構可以有效地避免時鐘、位址和控制信号的不同步問題。

DDR3總結筆記

圖24:DDR的時鐘、控制以及位址信号T型拓撲

  • 菊花鍊拓撲結構

和星型拓撲結構不同,菊花鍊拓撲結構沒有保持驅動端到各個負載走線長度盡量一緻,而是確定各個驅動端到信号主幹道的長度盡量短。菊花鍊拓撲結構走線的特點,犧牲了時鐘、位址、控制信号的同步,但最大的特點是盡可能降低各負載分支走線長度,避免分支信号對主幹信号的反射幹擾。

DDR3總結筆記

圖25:DDR的時鐘、控制以及位址信号菊花鍊型拓撲

  • Fly-by拓撲結構

在信号頻率低于800MHz的情況下,上面兩種拓撲結構均能滿足系統性能需要。但是當信号速率到達1000MHz甚至更高,T型拓撲結構就不能滿足性能需要。原因就在于T型拓撲結構過長的支路走線長度,在不添加終端電阻的情況下很難和主幹道實作阻抗比對,而為了實作各個支路的阻抗比對添加終端電阻,又加大了電路設計的工作量和成本,是我們不願意看到的。是以高速信号使用T型拓撲結構,特别是Stub>4的時候,支路信号對主幹信号的反射幹擾是很嚴重的。通常DDR2使用和速率要求不高的DDR3使用T型拓撲結構。菊花鍊拓撲結構主要在DDR3中使用,菊花鍊拓撲結構的主要優勢是支路走線短,一般認為菊花鍊支路走線長度小于信号上升沿傳播長度的1/10,可以有效削弱支路信号反射對主幹信号的幹擾,不同的書本上說法也不一樣,大體上走線長度小于上升沿傳播長度的1/6-1/10都是可以的,實際設計中我們肯定希望這個長度越短越好。菊花鍊拓撲結構可以有效抑制支路的反射信号,但相對于T型拓撲結構,菊花鍊拓撲結構的時鐘、位址和控制信号并不能同時到達不同的DDR晶片。為了解決菊花鍊拓撲結構信号不同步的問題,DDR3的新标準中加入了時間補償技術,通過DDR3内部調整實作信号同步。當信号頻率高達1600MHz的時候,T型拓撲結構已經無能為力,隻有菊花鍊或其衍生的拓撲結構能滿足這樣的性能需求。一般的DDR3都會建議采用菊花鍊拓撲結構的改進型拓撲結構,Fly-by拓撲結構,如下圖所示。Fly-by拓撲結構要求支路布線長度Stub=0,Fly-by具有更好的信号完整性。

DDR3總結筆記

圖26:DDR的時鐘、控制以及位址信号Fly-by型拓撲

在菊花鍊拓撲的實際應用中,為了抑制Stub過長和分支太多對主幹信号的反射幹擾,以及加強主幹信号驅動能力,一般在末端預留端接電阻電路。末端下拉電阻會增大IO口驅動功耗,是以采用末端上拉電阻的方式進行端接。計算信号驅動部分的戴維南等效電壓作為上拉電壓Vtt,Rt為驅動部分的等效電阻,通常上拉電壓取值為IO驅動電壓的一般,即Vtt=Vddr/2。

如下圖所示為資料、時鐘、控制以及位址的T型拓撲結構圖:

DDR3總結筆記

圖27:T型拓撲整體結構

如下圖所示為資料、時鐘、控制以及位址的Fly-by型拓撲結構圖:

DDR3總結筆記

圖28:Fly-by型拓撲整體結構

一般來說,對于2~4片的DDR3設計來說,T型和Fly-by拓撲結構布線都可以,但是當超過4片DDR3後,T型結構已經不能滿足要求。是以筆者建議隻要不是單片的DDR3設計,拓撲結構都用Fly-by就好。對于Fly-by拓撲結構的布線設計具體來說:

  • DQ和DM為單端線,其與FPGA之間屬于點對點的連接配接方式,如下圖所示:
DDR3總結筆記

圖29:Fly-by拓撲結構中的DQ、DM連接配接方式

  • 對于差分信号DQS,其與FPGA之間屬于差分點對點的連接配接方式,如下圖所示:
DDR3總結筆記

圖30:Fly-by拓撲結構中的DQS連接配接方式

  • 對于差分時鐘線,其與FPGA之間屬于差分Fly-by的連接配接方式,如下圖所示:
DDR3總結筆記

圖31:Fly-by拓撲結構中的時鐘連接配接方式

  • 對于單端位址、控制線,其與FPGA之間屬于單端Fly-by的連接配接方式,如下圖所示:
DDR3總結筆記

圖32:Fly-by拓撲結構中的位址、控制信号連接配接方式

網友提供的幾張T型和Fly-by的PCB走線,僅供參考:

DDR3總結筆記

圖33:T型拓撲

DDR3總結筆記

圖34:T型拓撲

DDR3總結筆記

圖35:Fly-by拓撲

DDR3總結筆記

圖36:Fly-by拓撲

DDR3總結筆記

圖37:Fly-by拓撲

第五部分:DDR3-FPGA讀寫設計

本篇在進行讀寫設計時,利用黑金的AX7102開發闆,FPGA型号為xc7a100t-fgg484,闆載兩片DDR3,共8Gb存儲空間,具體型号是micron公司的MT41J256M16HA-125。下面記錄讀寫設計的過程:

1.在vivao中建立一個工程,選擇對應的FPGA:

DDR3總結筆記

2.添加MIG(memoryinterface generator)的IP核

DDR3總結筆記

3.輕按兩下該IP核後,會出現配置界面,首頁顯示的是使用者選擇的FPGA型号。确認無誤後,點選next:

DDR3總結筆記

4.該界面的配置如下圖所示:

DDR3總結筆記

5.該界面配置如圖所示:

DDR3總結筆記

6.硬體晶片是DDR3,是以該界面的配置選擇DDR3 SDRAM即可,如下圖所示:

DDR3總結筆記

7.接下來是配置的重頭戲:

DDR3總結筆記

8.設定系統輸入時鐘,來自于200MHz差分晶振:

DDR3總結筆記

9.如下圖所示:

DDR3總結筆記

10.如下圖所示:

DDR3總結筆記

11.接下來根據FPGA硬體的管腳定義來配置IP核的信号,我們選擇“FixedPin Out”

DDR3總結筆記

12.開始一個個的輸入DDR3信号對應的管腳,如果事先寫好了管腳限制檔案,也可以直接載入。填寫完成後,點選“Validate”檢查,看寫的是否有誤。                 

DDR3總結筆記

13.下圖是本人填好管腳定義後的界面,檢查過後顯示無誤後,進入下一步:

DDR3總結筆記

14.定義系統時鐘輸入、參考時鐘輸入以及系統複位管腳位置:

DDR3總結筆記

15.到這裡就配置完成了,該界面顯示配置的IP核的資訊,使用者可以檢視:

DDR3總結筆記

16.該界面毫無意義,直接點“accept”即可:

DDR3總結筆記

17.接下來就沒啥了,一直“next”,最後點選“genereate”生成IP核。

DDR3總結筆記

18.在工程界面建立一個頂層限制檔案“DDR3_TOP.xdc”,然後在工程界面選擇“IP source”,點開DDR3IP核的下拉清單,在“synthesis”裡打開“DDR3.xdc”,複制其中全部的限制内容到頂層限制檔案中,并在頂層限制檔案中添加系統複位和任意一個狀态顯示的管腳(随意選擇一個管腳,這不重要,隻是為了確定後面提到的邏輯不被綜合掉,便于chipscope檢視)即可。

DDR3總結筆記

19.建立工程的頂層檔案“DDR_TOP.V”和用于測試DDR3 讀寫性能的子子產品“mem_burst.v”,如下圖所示:

DDR3總結筆記

20.工程檔案之間的具體關系如下圖所示,利用mem_burst.v實作對兩片16bit位寬的DDR3同時讀寫,也就是對32bit位寬的一片DDR3讀寫,讀寫容量為8Gb。

DDR3總結筆記

21.下面給出頂層檔案“DDR_TOP.V”的完整代碼:

moduleDDR3_TOP(

//

   inout [31:0]    ddr3_dq,//32bit的DDR3并行資料輸入/輸出端口

   inout[3:0]      ddr3_dqs_n,//由于DDR3每8bit資料會對應一個資料選通信//号,是以這裡是4bit資料選通信号,且選通信号是差分輸入/輸出端口

   inout [3:0]              ddr3_dqs_p,//資料選通信号p端

//

   output [14:0]  ddr3_addr,//FPGA控制DDR3的15bit位址線

   output [2:0]   ddr3_ba,// FPGA控制DDR3的3bit bank位址線

   output      ddr3_ras_n,// FPGA控制DDR3的行選通控制信号

   output      ddr3_cas_n, // FPGA控制DDR3的列選通控制信号

   output      ddr3_we_n, // FPGA控制DDR3的讀/寫使能控制信号

   output      ddr3_reset_n, // FPGA控制DDR3的複位信号

   output        ddr3_ck_p, // FPGA控制DDR3的讀/寫差分時鐘

   output        ddr3_ck_n, //  

   output        ddr3_cke, // FPGA控制DDR3的差分時鐘使能

   output      ddr3_cs_n, // FPGA控制DDR3的片選信号

           output [3:0]   ddr3_dm, // FPGA控制DDR3的mask信号,每8bit資料會//對應一個資料mask信号

   output      ddr3_odt, // FPGA控制DDR3的片上比對電阻 

 //

               input    sys_clk_p,//FPGA系統工作時鐘,必須為200MHz差分晶振輸入

   input    sys_clk_n,   

   output   error,//随意指定的一個FPGA管腳,隻是為了内部chipscope觀//察的信号不被綜合優化掉

   input    sys_rst// FPGA系統複位輸入,按照DDR3的IP設定,必須低電//平有效

   );

localparam nCK_PER_CLK = 4;//DDR3管腳時鐘和内部時鐘的比值,為固定值4,如果是//DDR2,則為2,如果是DDR則為1.

localparam DQ_WIDTH = 32;//DDR3資料位寬,在本設計為兩片16bit的DDR3組合成//32bit的資料位寬

localparam ADDR_WIDTH= 29;//讀寫DDR3的位址,根據IP核的定義,這裡的位址為//1bit rank+3bit bank+15bit row address + 10bit row address =29bit

localparam DATA_WIDTH= 32;//FPGA操作時的資料位寬為32bit

localparamAPP_DATA_WIDTH = 2 * nCK_PER_CLK * DATA_WIDTH;//DDR3 IP核的資料//位寬為256 BIT,因為8倍預取資料的原因,是以IP核一次讀寫的資料為8*32bit

localparamAPP_MASK_WIDTH = APP_DATA_WIDTH / 8;//每8bit資料對應1bit mask信号,是以這裡共32BIT mask信号

wire  init_calib_complete;//闆卡上電後,DDR3 IP核會對DDR初始化校正,完成之後IP核拉高此信号,是以使用者隻有監測到該信号為高電平後才能對DDR進行讀寫操作,PHY asserts init_calib_complete when calibration is finished.

wire[ADDR_WIDTH-1:0]  app_addr;//IP核讀寫位址輸入:29bit=1bit rank+3bit bank+15bit row address + 10bit row address,對于本設計來說,rank值為0.

wire[2:0] app_cmd;//3bit的IP核操作碼輸入,000為寫指令,001為讀指令

wire app_en;//IP核的指令使能輸入:Thisis the active-High strobe for the app_addr[], app_cmd[2:0] inputs.

wire app_rdy;// //IP核輸出的指令ready信号:This output indicates that the UI is ready to accept commands. Ifthe signal is deasserted when app_en is enabled, the current app_cmd andapp_addr must be retried until app_rdy is asserted.

wire[APP_DATA_WIDTH-1:0]  app_rd_data;//IP核的256bit資料輸入或輸出

wire  app_rd_data_end;// This active-High outputindicates that the current clock cycle is

thelast cycle of output data on app_rd_data[]. This is valid only when app_rd_data_validis active-High.

wire  app_rd_data_valid;// This active-High outputindicates that app_rd_data[] is valid.

wire[APP_DATA_WIDTH-1:0] app_wdf_data;// This provides the data for write commands.

wire app_wdf_end;//This active-High input indicates that the current clock cycle is the last cycleof input data on app_wdf_data[].

wire[APP_MASK_WIDTH-1:0] app_wdf_mask;// This provides the mask for app_wdf_data[].

wire app_wdf_rdy;//This output indicates that the write data FIFO is ready to receive data. Writedata is accepted when app_wdf_rdy = 1’b1 and app_wdf_wren = 1’b1.

wire app_sr_active;//This output is reserved.

wireapp_ref_ack;// This active-High input requests that a refresh command be issuedto the DRAM.

wireapp_zq_ack;// This active-High output indicates that the Memory Controller hassent the requested ZQ calibration command to the PHY interface.

wireapp_wdf_wren;// This is the active-High strobe for app_wdf_data[].

wire clk;// This UI clock must be a quarter of the DRAM clock. DDR3 IP核輸出的使用者時鐘,這裡為100MHz

wire rst;// This is the active-High UI reset. IP核提供給使用者的複位信号

DDR3  u_ddr3(

// Memory interface ports

.ddr3_addr (ddr3_addr),

.ddr3_ba (ddr3_ba),

.ddr3_cas_n (ddr3_cas_n),

.ddr3_ck_n (ddr3_ck_n),

.ddr3_ck_p (ddr3_ck_p),

.ddr3_cke (ddr3_cke),

.ddr3_ras_n (ddr3_ras_n),

.ddr3_we_n (ddr3_we_n),

.ddr3_dq (ddr3_dq),

.ddr3_dqs_n (ddr3_dqs_n),

.ddr3_dqs_p (ddr3_dqs_p),

.ddr3_reset_n (ddr3_reset_n),

.init_calib_complete(init_calib_complete),     

.ddr3_cs_n (ddr3_cs_n),

.ddr3_dm (ddr3_dm),

.ddr3_odt (ddr3_odt),

// Application interface ports

.app_addr (app_addr),

.app_cmd (app_cmd),

.app_en (app_en),

.app_wdf_data (app_wdf_data),

.app_wdf_end (app_wdf_end),

.app_wdf_wren (app_wdf_wren),

.app_rd_data (app_rd_data),

.app_rd_data_end (app_rd_data_end),

.app_rd_data_valid (app_rd_data_valid),

.app_wdf_rdy (app_wdf_rdy),

.app_sr_req (1'b0),//以下三個信号輸入都設定為0,讓IP自己控制,我們不用插手

.app_ref_req  (1'b0),

.app_zq_req (1'b0),

.app_sr_active (app_sr_active),

.app_ref_ack (app_ref_ack),

.app_zq_ack (app_zq_ack),

.ui_clk (clk),

.ui_clk_sync_rst (rst),    

.app_wdf_mask(app_wdf_mask),

// System Clock Ports

.sys_clk_p (sys_clk_p),

.sys_clk_n (sys_clk_n),

.sys_rst (sys_rst)

);

mem_burst

#(

.MEM_DATA_BITS (APP_DATA_WIDTH),

.ADDR_BITS(ADDR_WIDTH)

)

mem_burst_m0

 (

.rst (rst),

.mem_clk      (clk),

///

.app_addr (app_addr),//DDR3的讀寫其實就是對以下這幾個信号的操作,具體如何操作在子檔案“mem_burst.v”檔案中給出

.app_cmd       (app_cmd),

.app_en (app_en),

.app_wdf_data      (app_wdf_data      ),

.app_wdf_end(app_wdf_end       ),

.app_wdf_mask(app_wdf_mask),

.app_wdf_wren(app_wdf_wren),

.app_rd_data(app_rd_data),

.app_rd_data_end (app_rd_data_end),

.app_rd_data_valid       (app_rd_data_valid       ),

.app_rdy(app_rdy),

.app_wdf_rdy(app_wdf_rdy),

.init_calib_complete(init_calib_complete),

.error(error)

);

Endmodule

22.下面給出DDR3的例化接口檔案:(沒啥可說的,操作它就行了)

DDR3總結筆記

23.下面給出子檔案“mem_burst.v”的具體内容,該檔案就是對DDR3的IP核進行讀寫操作,間接控制兩片DDR3的讀寫,首先看看該檔案的接口:

DDR3總結筆記

24.接下來對一些内部定義的信号以及該代碼的思路介紹一下:

DDR3總結筆記

25.接下來我們需要如何讀寫,這裡插入UG586介紹的讀寫時序,首先介紹寫時序:

DDR3總結筆記

按照UG586的說明,當app_rdy為高時,将app_cmd,app_addr以及app_en拉高,此時,寫指令發出。在寫指令發出之前周期、目前周期或者之後3個周期之内,使用者可以進行寫操作。寫操作執行過程同樣是:當app_wdf_rdy為高時,将app_wdf_data,,app_wdf_wren以及app_wdf_end拉高,此時寫操作成功。

關鍵:寫資料和寫指令是獨立運作的,控制器内部有一個資料FIFO緩存使用者寫入的資料,是以隻要資料FIFO的“app_wdf_rdy”為高,就表明FIFO可以寫入資料。是以寫資料可以提前于寫指令操作,大家可以認為使用者每發一個寫指令,控制器就讀FIFO裡的一個數發送到DDR3。是以寫資料和寫指令時序不相關,隻要保證寫指令執行的時候,資料FIFO中有資料供控制器操作就行!

DDR3總結筆記

如下圖所示為讀操作的具體時序,同樣的先進行寫指令操作,時序同寫指令操作一樣。寫指令完成後的若幹個周期,app_rd_data、app_rd_data_valid以及app_rd_data_end出現。當app_rd_data_valid為高時,使用者取數即可。

另外在讀寫操作時,我們必須記住非常重要的一點:我們寫入了多少個寫資料,就必須發出相同數量的寫指令,對讀操作也是一樣。

26.接下裡具體分析讀寫代碼:

DDR3總結筆記
DDR3總結筆記
DDR3總結筆記
DDR3總結筆記
DDR3總結筆記

27.接下來我們實際測試一下上述代碼的功能是否正常,首先是從位址0開始寫入:

DDR3總結筆記

然後我們再看寫入的尾位址(即29’h0FFF_FFF8~29’h0FFF_FFFF)資料,寫完之後就開始了讀操作:         

DDR3總結筆記

接下來我們看看讀出來的資料:

DDR3總結筆記
DDR3總結筆記
DDR3總結筆記

自此,說明DDR3讀寫都ok了,在應用到相應的項目時隻需要在DDR3子產品外部添加自定義的讀寫FIFO就可以了。

參考内容:

1,DDR3布局布線規則與執行個體,https://wenku.baidu.com/view/045ade1b590216fc700abb68a98271fe910eafac.html

2,DDR布線規則與過程,https://wenku.baidu.com/view/6661c8eea21614791611285e.html?sxts=1587461512922

3,DDR3布線那些事兒,https://www.cnblogs.com/tureno/articles/7856858.html

4,DDR3基本概念6 -Write leveling(寫入均衡),https://blog.csdn.net/tbzj_2000/article/details/88304245

5,LPDDR4的訓練(training)和校準(calibration)--Write Leveling(寫入均衡),https://blog.csdn.net/wonder_coole/article/details/102788136?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-4&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-4

6,【接口時序】8、DDR3驅動原理與FPGA實作(一、DDR的基本原理),https://www.cnblogs.com/liujinggang/p/9782796.html

7,DDR3基本知識,https://www.cnblogs.com/liujinggang/p/9782796.html

8,DDR3布局注意事項,https://blog.csdn.net/hanxuexiaoma/article/details/78977726