? ? 關注、星標公眾號,直達精彩內容
內存是我們平常嵌入式系統中接觸的比較頻繁的硬件之一,但是我們對這個器件的了解卻知之甚少。主要的原因是作為嵌入式工程師的我們,這部分主要是配置參數,而這些參數都是由芯片廠商已經提供好了,硬件工程師都會基于廠商認證的DDR選型,減少開發周期。其實對于內存,有很多的細節和知識點可以深挖,本章的內容包括如下內容:
?-通過由淺入深的學習內存的基本原理
?-通過由淺入深的學習內存的軟硬件特性
?-從軟件的角度來學習下,我們該如何嘗試去配置一塊處理器上的DDR
1
情景
小張有一定的計算機背景知識,最近他在京東上買了兩條DDR3的內存,打算把筆記本升級成8G。可是一拆開包裝到就傻眼了:
4GB看起來很好,兩根剛好8GB。2Rx8是啥,PC3又是啥,10600似乎和他想買的1333的差好遠,后面那串數字又代表什么呢?于是乎對于這些細節,我們越看越傻眼。后面將會詳細的介紹這些細節。
2
DDR的前世今生
2.1 ROM和RAM的概念
在回歸DDR的發展過程之前,我們先來了解下儲存器的主要功能,其主要是儲存程序和各種數據,并能在計算機運行過程中高速、自動完成程序或數據的出存取。
首先,要了解下儲存的基本部分,ROM和RAM。
從上面的可以看出,其主要的區別有兩點:
?-ROM是可讀可寫,并且速度很快,而ROM只能事先寫,然后就只能讀取,所以程序在運行過程中必須讀寫,就必須要有RAM存在
?-ROM只作為儲存用途,斷電不會丟失數據;而RAM在斷電的時候會丟失數據
而對于RAM,可分為SRAM(靜態隨機存儲器)和DRAM(動態隨機存儲器)
2.2 發展歷程
但回顧內存容量的發展,從最初KB到GB的躍進,從單條1GB到如今單條16GB或者32GB的進化,經歷了漫長的過程。
從最初的時候,個人電腦和嵌入式系統對于功能的實現都比較簡單,內存的容量和儲存容量都比較小,只有64K到256KB,對于嵌入式系統上甚至更小。
?-對于個人電腦,個人電腦上是沒有內存條的,內存是直接以DIP芯片的形式安裝在主板的DRAM插座上面,需要安裝8到9顆這樣的芯片,容量只有64KB到256KB,要擴展相當困難,但這對于當時的處理器以及程序來說這已經足夠了,直到80286的出現硬件與軟件都在渴求更大的內存,只靠主板上的內存已經不能滿足需求了,于是內存條就誕生了。
?-對于嵌入式設備,例如我最早開始接觸的51單片機,內部就集成了ROM和RAM,空間很小。后來又接觸到了MTK的芯片,像山寨時期比較流程的53系列的芯片,就使用到了nor flash,可以片上執行,隨著時代的發展,35系列就引入了SDRAM,慢慢隨著CPU的主頻越來越高和對于RAM的容量要求越來越大,就慢慢的開始使用DDR。
那我們以PC的過程來講解發展過程,由于第一代DIP的芯片難以擴展,而隨著CPU的數據總線的寬度達到64bit,一根DDR就難以滿足處理需要,所以就需要兩根、4根,內存容量也有所增加,它的出現很快就替代了30pin SIMM內存,386、486以及后來的奔騰、奔騰Pro、早期的奔騰II處理器多數會用這種內存。
EDO DRAM【擴展數據輸出內存】
它擁有更大的容量和更先進的尋址方式,這內存簡化了數據訪問的流暢,讀取速度DRAM快不少,主要用在486、奔騰,奔騰Pro、早期的奔騰II處理器的電腦上面。
在1991到1995年EDO內存盛行的時候,憑借著制造工藝的飛速發展,EDO內存在成本和容量上都有了很大的突破,單條EDO內存容量從4MB到16MB不等,數據總線依然是32位,所以搭配擁有64位數據總線的奔騰CPU時基本都成對的使用。
SDR SDRAM【同步型動態存儲器】
然而隨著CPU的升級EDO內存已經不能滿足系統的需求了,內存技術也發生了大革命,插座從原來的SIMM升級為DIMM(Dual In-line Memory Module),兩邊的金手指傳輸不同的數據,SDR SDRAM內存插座的接口是168Pin,單邊針腳數是84,進入到了經典的SDR SDRAM(Single Data Rate SDRAM)時代。
SDRAM其實就是同步DRAM的意思,“同步”是指內存工作需要同步時鐘,內部命令的發送與數據的傳輸都以它為基準。內存頻率與CPU外頻同步,這大幅提升了數據傳輸效率,再加上64bit的數據位寬與當時CPU的總線一致,只需要一根內存就能讓電腦正常工作了,這降低了采購內存的成本。
?DDR
SDRAM從發展到現在已經經歷了四代,分別是:第一代SDR SDRAM,第二代DDR SDRAM,第三代DDR2 SDRAM,第四代DDR3 SDRAM,現在已經發展到DDR5 SDRAM。
?·DDR SDRAM是Double Data Rate Synchronous Dynamic Random Access Memory(雙數據率同步動態隨機存儲器)的簡稱,是由VIA等公司為了與RDRAM相抗衡而提出的內存標準,為第二代SDRAM標準。其常見標準有DDR 266、DDR 333和DDR 400。其對于SDRAM,主要它允許在時鐘脈沖的上升沿和下降沿傳輸數據,這樣不需要提高時鐘的頻率就能實現雙倍的SDRAM速度,例如DDR266內存與PC133 SDRAM內存相比,工作頻率同樣是133MHz,但在內存帶寬上前者比后者高一倍。這種做法相當于把單車道更換為雙車道,內存的數據傳輸性能自然可以翻倍。
?·DDR2(Double Data Rate 2)SDRAM是由JEDEC(電子設備工程聯合委員會)開發的第三代SDRAM內存技術標準,1.8v工作電壓,240線接口,提供了相較于DDR SDRAM更高的運行效能與更低的電壓,同樣采用在時鐘的上升/下降延同時進行數據傳輸的基本方式,但擁有兩倍于上一代DDR內存預讀取能力(即4bit數據讀預取能力),其常見的頻率規范有DDR2 400\533\667\800\1066\1333等,總線頻率553MHz的DDR2內存只需133MHz的工作頻率。
?·DDR3 SDRAM相比起DDR2具備更低的工作電壓(1.5v),240線接口,支持8bit預讀,只需133MHz的工作頻率便可實現1066MHz的總線頻率。其頻率從800MHz起跳,常見頻率有DDR3 800\1066\1333\1600\1866\2133等。DDR3是當前流行的內存標準,Intel酷睿i系列(如LGA1156處理器平臺)、AMD AM3主板及處理器的平臺都是其“支持者”。
?·DDR4相比DDR3最大的區別有三點:16bit預取機制(DDR3為8bit),同樣內核頻率下理論速度是DDR3的兩倍;更可靠的傳輸規范,數據可靠性進一步提升;工作電壓降為1.2V,更節能。
在80286時代,內存顆粒(Chip)是直接插在主板上的,叫做DIP(Dual In-line Package)。到了80386時代,換成1片焊有內存顆粒的電路板,叫做SIMM(Single-Inline Memory Module)。那么這樣又帶來哪些好處呢?
由陣腳形態變化成電路板帶來了很多好處:模塊化,安裝便利等等,造就了我們現在的DIY市場的產生,我們就可以針對我們現在的PC進行內存的升級工作。
當時SIMM的位寬是32bit,即一個周期讀取4個字節,到了奔騰時,位寬變為64bit,即8個字節,于是SIMM就順勢變為DIMM(Double-Inline Memory Module)。這種形態一直延續至今,也是內存條的基本形態。現在的DIMM分為很多種:
?·RDIMM: 全稱(Registered DIMM),寄存型模組,主要用在服務器上,為了增加內存的容量和穩定性分有ECC和無ECC兩種,但市場上幾乎都是ECC的。
?·UDIMM:全稱(Unbuffered DIMM),無緩沖型模組,這是我們平時所用到的標準臺式電腦DIMM,分有ECC和無ECC兩種,一般是無ECC的。
?·SO-DIMM:全稱(Small Outline DIMM),小外型DIMM,筆記本電腦中所使用的DIMM,分ECC和無ECC兩種。
?·Mini-DIMM:DDR2時代新出現的模組類型,它是Registered DIMM的縮小版本,用于刀片式服務器等對體積要求苛刻的高端領域。
從DDR到DDR4主要的區別是在于傳輸速率的不同,隨著時鐘周期的不斷降低,傳輸率也不斷提高。還有電壓也越來越低。有趣的是命名規則,大部分臺式機DIMM廠商都會標注DDRx-yyy,x代表第幾代,yyy代表數據傳輸率。而大部分的SO-DIMM和RDIMM等則標注PCx-zzzz,x還代表第幾代,zzzz則代表最大帶寬。因為DDR位寬為64位,8個字節,所以zzzz=yyy * 8,而yyy又是時鐘的兩倍。
所以小張的內存條上的PC3-10600S代表DDR3,1333MHz的SO-DIMM。小張又問,那2R*8啥意思呢?
2.3 DDR區別
DDR到DDR5的主要變化,我們可以看到,為了配合整體行業對于性能,容量和省電的不斷追求,規范的工作電壓越來越低,芯片容量越來越大, IO的速率也越來越高。
除了電壓,容量和IO的速率變化之外,還列出了Bank, Bank Group,Prefetch和Burst Length的演進,bank數越來越多,到DDR4出現bank group,prefetch也從2n增加到4n,8n。雖然我們說現在DDR4的最大速率是3200MT/s, 但是這是指的DDR4的IO頻率,即DDR4和memroy controller之間的接口數據傳輸速率。那么DRAM是怎么實現用比較低的核心傳輸頻率來滿足日益高漲的高速IO傳輸速率的需求呢?這就是靠prefetch來實現的。
從DDR開始到DDR3很好理解,Prefetch相當于DRAM core同時修了多條高速公路連到外面的IO口,來解決IO速率比內部核心速率快的問題,IO數據速率跟核心頻率的倍數關系就是prefetch。
burst length的長度跟CPU的cache line大小有關。Burst length的長度有可能大于或者等于prefetch。但是如果prefetch的長度大于burst length的長度,就有可能造成數據浪費,因為CPU一次用不了那么多。所以從DDR3到DDR4,如果在保持DDR4內存data lane還是64的前提下,繼續采用增加prefetch的方式來提高IO速率的話,一次prefetch取到的數據就會大于一個cache line的大小 (512bits),對于目前的CPU系統,反而會帶來性能問題。
DDR4出現了Bank Group,這就是DDR4在不改變prefetch的情況下,能繼續提升IO速率的秘密武器。DDR4利用Bank group的interleave,實現IO速率在DDR3基礎上進一步提升。
3
內存原理
其實從外觀上就可以看出來小張的內存條由很多海力士的內存顆粒組成。從內存控制器到內存顆粒內部邏輯,籠統上講從大到小為:channel>DIMM>rank>chip>bank>row/column,如下圖:
一個現實的例子是:
在這個例子中,一個i7 CPU支持兩個Channel(雙通道),每個Channel上可以插倆個DIMM,而每個DIMM由兩個rank構成,8個chip組成一個rank。由于現在多數內存顆粒的位寬是8bit,而CPU帶寬是64bit,所以經常是8個顆粒可以組成一個rank。所以小張的內存條2R X 8的意思是由2個rank組成,每個rank八個內存顆粒(為啥我們以后講)。由于整個內存是4GB,我們可以算出單個內存顆粒是256MB。
這次我們來看看rank和Chip里面有什么,如下圖:
這是個DDR3一個Rank的示意圖。我們把左邊128MB Chip拆開來看,它是由8個Bank組成,每個Bank核心是個一個存儲矩陣,就像一個大方格子陣。這個格子陣有很多列(Column)和很多行(Row),這樣我們想存取某個格子,只需要告知是哪一行哪一列就行了,這也是為什么內存可以隨機存取而硬盤等則是按塊存取的原因。
實際上每個格子的存儲寬度是內存顆粒(Chip)的位寬,在這里由8個Chip組成一個Rank,而CPU尋址寬度是64bit,所以64/8=8bit,即每個格子是1個字節。選擇每個格子也不是簡單的兩組信號,是由一系列信號組成,以這個2GB DDR3為例:
其引腳按照功能可以分為7類:前3類為電源、地、配置
后4類為:控制信號、時鐘信號、地址信號、數據信號
電源、地、配置信號的功能很簡單,在此不贅述。控制信號主要是用來完成DDR4與DDR4 Controller之間的狀態切換。DDR4中最重要的信號就是地址信號和數據信號。
如上DDR4芯片有20根地址線(17根Address、2根BA、1根BG),16根數據線。在搞清楚這些信號線的作用以及地址信號為何還有復用功能之前,我們先拋出1個問題。假如我們用20根地址線,16根數據線,設計一款DDR,我們能設計出的DDR尋址容量有多大?
Size(max)=(2^20) * 16=1048576 *16=16777216bit=2097152B=2048KB=2MB。
但是事實上,該DDR最大容量可以做到1GB,比傳統的單線編碼尋址容量大了整整512倍,它是如何做到的呢?答案很簡單,分時復用。我們把DDR存儲空間可以設計成如下樣式:
首先將存儲空間分成兩個大塊,分別為BANK GROUP0和BANK GROUP1,再用1根地址線(還剩19根),命名為BG,進行編碼。若BG拉高選擇BANK GROUP0,拉低選擇BANK GROUP1。(當然你也可以劃分成4個大塊,用2根線進行編碼)
再將1個BANK GROUP區域分成4個BANK小區域,分別命名為BANK0、BANK1、BANK2、BANK3。然后我們挑出2根地址線(還剩余17根)命名為BA0和BA1,為4個小BANK進行地址編碼。
此時,我們將DDR內存顆粒劃分成了2個BANK GROUP,每個BANK GROUP又分成了4個BANK,共8個BANK區域,分配了3根地址線,分別命名為BG0,BA0,BA1。然后我們還剩余17根信號線,每個BANK又該怎么設計呢?這時候,就要用到分時復用的設計理念了。
剩下的17根線,第一次用來表示行地址,第二次用來表示列地址。現在修改為傳輸2次地址,在傳輸1次數據,尋址范圍最多被擴展為2GB。雖然數據傳輸速度降低了一半,但是存儲空間被擴展了很多倍。這就是改善空間。
所以,剩下的17根地址線,留1根用來表示傳輸地址是否為行地址。
·在第1次傳輸時,行地址選擇使能,剩下16根地址線,可以表示行地址范圍,可以輕松算出行地址范圍為2^16=65536個=64K個。
·在第2次傳輸時,行地址選擇禁用,剩下16根地址線,留10根列地址線表示列地址范圍,可以輕松表示的列地址范圍為2^10=1024個=1K個,剩下6根用來表示讀寫狀態/刷新狀態/行使能、等等復用功能。
·這樣,我們可以把1個BANK劃分成67108864個=64M個地址編號。如下所示
·所以1個BANK可以分成65536行,每行1024列,每個存儲單元16bit。
所以1個BANK可以分成65536行,每行1024列,每個存儲單元16bit。
?-每行可以存儲1024*16bit=2048bit=2KB。每行的存儲的容量,稱為Page Size。
?-單個BANK共65536行,所以每個BANK存儲容量為65536*2KB=128MB。
?-單個BANK GROUP共4個BANK,每個BANK GROUP存儲容量為512MB。
?-單個DDR4芯片有2個BANK GROUP,故單個DDR4芯片的存儲容量為1024MB=1GB。
至此,20根地址線和16根數據線全部分配完成,我們用正向設計的思維方式,為大家講解了DDR4的存儲原理以及接口定義和尋址方式。
但是細心的同學發現一個問題,對于每一個bank,按照正常的10位數據,那么col應該是1024,而現在是128,是什么原因呢?
那么問題又來了,為什么Column Address的尋址能力只有128呢?請繼續看下圖:
在上圖中,可以清晰地發現,10bits的Column Address只有7bits用于列地址譯碼!列地址0,1,2并沒有用!!!列地址0,1,2,這3bits被用于什么功能了?或者是DDR的設計者腦殘,故意浪費了這三個bits?在JESD79-3規范中有如下的這個表格:
可以發現,Column Address的A2,A1,A0三位被用于Burst Order功能,并且A3也被用于Burst Type功能。由于一般情況,我們采用的都是順序讀寫模式(即{A2,A1,A0}={0,0,0}),所以此時的A3的取值并無直接影響,這個后面章節中重點介紹。
CA[2:0]的值決定了一次Burst sequence的讀寫地址順序。
比如一次Burst Read的時候如果CA[2:0]=3’b001表示低三位從地址1開始讀取,CA3=0的時候按順序讀取1,2,3,0,5,6,7,4,CA3=1的時候交錯讀取1,0,3,2,5,4,7,6。
?·對于Prefetch而言,正好是8N Prefetch,對于Burst而言對應BL8。
?·BC4其實也是一次BL8的操作,只是丟棄了后一半的數據。
更形象地理解就是對于一個Bank里面的Memory Array,每個Memory Cell可以看作是一個Byte的集合體。CA[9:3]選中一行中的一個特定Byte,再由CA[2:0]選擇從這個Byte的哪個位置開始操作。CA3既參與了列地址譯碼,也決定Burst是連續讀取還是交錯讀取。Prefetch也決定了I/O Frequency和SDRAM Core Frequency之間的關系。
4
總結
本章主要是針對DDR的發展和原理進行了學習,主要集中在硬件的組成原理,其中涉及到Channel > DIMM > Rank > Chip > Bank > Row/Column,其組成如下圖所示:
?·Channel:一個主板上可能有多個插槽,用來插多根內存。這些槽位分成兩組或多組,組內共享物理信號線。這樣的一組數據信號線、對應幾個槽位(內存條)稱為一個channel(通道)。簡單理解就是DDRC(DDR控制器),一個通道對應一個DDRC。CPU外核或北橋有兩個內存控制器,每個控制器控制一個內存通道。內存帶寬增加一倍。(理論上)
?·DIMM(dual inline memory module)是主板上的一個內存插槽。一個Channel可以包括多個DIMM。
?·Rank是一組內存芯片的集合,當芯片位寬x芯片數=64bits(內存總位寬)時,這些芯片就組成一個Rank。一般是一個芯片位寬8bit,然后內存每面8個芯片,那么這一面就構成一個Rank(為了提高容量,有些雙面內存條就有兩個rank。在DDR總線上可以用一根地址線來區分當前要訪問的是哪一組)。同一個Rank中的所有芯片協作來共同讀取同一個Address(一個Rank8個芯片 * 8bit = 64bit),這個Address的數據分散在這個Rank的不同芯片上。設計Rank的原因是這樣可以使每個芯片的位寬小一些,降低復雜度。
?·Chip是內存條上的一個芯片。由圖中是由8個bank組成了一個memory device。
?·Bank:Bank是一個邏輯上的概念。一個Bank可以分散到多個Chip上,一個Chip也可以包含多個Bank。Bank和Chip的關系可以參考下面的圖,每次讀數據時,選定一個Rank,然后同時讀取每個chip上的同一bank。
?·Row/Column組成的Memeory Array:Bank可以理解為一個二維數組bool Array[Row][Column]。而Row/Column就是指示這個二維數組內的坐標。注意讀取時每個Bank都讀取相同的坐標。
5
參考文檔
1.《內存的故事》外一篇–Rambus之戰:https://zhuanlan.zhihu.com/p/69420038
2.從誕生到三足鼎立格局,DRAM到底經歷了什么?:https://www.sohu.com/a/331550672_100246125
3.內存系列二:深入理解硬件原理:https://zhuanlan.zhihu.com/p/26327347
4.LPDDR4協議規范:https://blog.csdn.net/YJFeiii/article/details/105469366
本文轉自:https://blog.csdn.net/u012489236
版權聲明:本文來源網絡,免費傳達知識,版權歸原作者所有。如涉及作品版權問題,請聯系我進行刪除。
???????????????? ?END ????????????????
關注我的微信公眾號,回復“星球”加入知識星球,有問必答。
點擊“閱讀原文”查看知識星球詳情,歡迎點分享、收藏、點贊、在看。