Wednesday, August 12, 2015

Memory Controller

學習筆記 - Memory Controller

實驗:
從 NAND Flash 啟動 CPU 時,CPU 藉由硬體,自動複製 NAND Flash 前 4KB 數據到稱作 Steppingstone 的內部 RAM 中(起始地址為 0),然後跳到地址0開始執行,實驗先透過組語設置好 memory controller,使外接 SDRAM 可用,然後把程式從 Steppingstone 的內部 RAM 位置,複製到 SDRAM 處,最後在 SDRAM 中執行。


硬體動作流程:
當 CPU 透過匯流排訪問外圍設備,CPU發出地址訊號,由地址訊號範圍,透過 Memory Controller 來決定所選擇的外圍設備,被選中的外圍設備,nGCS6 輸出低電位,其餘 nGCSx 輸出高電位代表沒有選中。
硬體動作流程

S3C2440 Memory Controller 特性:
S3C2440對外引出了27條地址線ADDR0~ADDR26,它最多能夠定址128MB,而S3C2440的定址空間可以達到1GB,這是由於S3C24401GB的地址空間分成個8 BANKSBank0~Bank7),其中每一個BANK對應一條片選信號線nGCS0~nGCS7 S3C2440通過8條片選信號線和27條址線,就可以訪問1GB,如Figure5.1。
  • 匯流排位元寬可程式設計控制(8 / 16 / 32 bit),但是BANK0只能是16 / 32 bit
  • 總共8個BANK,BANK(0~5)可外接ROMSRAMBANK(67)可外接ROMSRAMSDRAM
  • BANK(0~6)的起始位址是固定的,BANK7起始位址可程式設計選擇。
  • 每個BANK的訪問週期可程式設計控制,可通過外部的“wait”信號延長匯流排的訪問週期。

SDRAM 硬體特性:
SDRAM的內部是一個存儲陣列。陣列就如同表格一樣,將資料進去。在資料讀寫時和表格的檢索原理一樣,先指定一個行(Row),再指定一個列 Column),我們就可以準確地找到所需要的儲存格,這就是記憶體晶片定址的基本原理。


這個儲存格(存儲陣列)就叫邏輯 BankLogical Bank,下文簡稱 L-Bank)。 由於技術、成本等原因,不可能只做一個全容量的 L-Bank,而且最重要的是,由於 SDRAM的工作原理限制,單一的 L-Ban k將會造成非常嚴重的定址衝突,大幅降低記憶體效率。所以人們在SDRAM內部分割成多個 L-Bank,目前基本都是 4個(這也是SDRAM規範中的最高L-Bank數量),由此可見,在進行定址時就要先確定是哪個 L-Bank,然後在這個選定的 L-Bank中選擇相應的行與列進行定址。因此對記憶體的訪問,一次只能是一個 L-Bank工作。



SDRAM4個邏輯L-BANKs,每個BANK的行位址數是13位、列位址數9位元,16個資料IO口,因此這個32M byte=4 x (2^13 x 2^9 ) x 16bit=256Mbit
  • Bank Size: 外接記憶體容量大小(HY575616204Mbit*16bit*4Bank*2Chips/8=64MB
  • Bus Width: 匯流排寬度 (兩片16HY57561620,並聯成32位)
  • Base Component:單個晶片容量(bit)256Mb
  • Memory Configration:記憶體配置 (4M*16*4banks*2Chips )
SDRAM 訪問步驟:

  1. CPU 首先發出地址訊號,接著發出片選信號nGCS6,當片選信號有效(SDRAM 內部對應腳位nSCS0),意既它選中SDRAM晶片。
  2. SDRAM 4個L-BANK,需要兩條地址線做選擇,使用ADDR24、ADDR25。
  3. 設定CPU相關暫存器進行 行/列 尋址。
  4. 找到存儲單元後,將進行數據傳送。
  5. 期間SDRAM 需要不斷進行 Refresh ,才能保留住數據,那麼要隔多長時間重複一次刷新呢?目前公認的標準是,存儲體中電容的資料有效保存期上限是64ms(毫秒,1/1000秒),也就是說每一行刷新的迴圈週期是64ms,這樣刷新時間間隔就是: 64m/行數s。我們在看記憶體規格時,經常會看到4096 Refresh Cycles/64ms8192 Refresh Cycles/64ms的標識,這裡的40968192就代表這個晶片中每個L-Bank的行數。刷新命令一次對一行有效,刷新間隔也是隨總行數而變化,4096行時為 15.625μs(微秒,1/1000毫秒),8192行時就為 7.8125μs
SDRAM 電路圖

S3C2440讀寫訊號:


SDRAM 讀操作:

SDRAM 寫操作:




SDRAM 暫存器操作:
主要暫存器如下,
  1. BWSCON寄存器(BUS WIDTH & WAIT CONTROL REGISTER
  2. BANKCON0~BANKCON5 (BANK CONTROL REGISTER)
  3. BANKCON6~BANKCON7 (BANK CONTROL REGISTER)
  4. REFRESH (REFRESH CONTROL REGISTER)
  5. BANKSIZE暫存器(BANKSIZE REGISTER

簡述重點,設定數據寬度(8/16/32 bit)、wait訊號、BANK 6/7 外接設備設定、L-BANK、ROW、COLUMN、RAS、CAS、RAS delay 、CAS delay 、WE、數據掩碼信號(讀寫高低位)、refresh ,詳細細節參考 http://blog.csdn.net/mr_raptor/article/details/6555786

實驗代碼:
@*************************************************************************
@ File:head.S
@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
@*************************************************************************       

.equ        MEM_CTL_BASE,       0x48000000
.equ        SDRAM_BASE,         0x30000000

.text
.global _start
_start:
    bl  disable_watch_dog               @ 关闭WATCHDOG,否则CPU会不断重启
    bl  memsetup                        @ 设置存储控制器
    bl  copy_steppingstone_to_sdram     @ 复制代码到SDRAM中
    ldr pc, =on_sdram                   @ 跳到SDRAM中继续执行
on_sdram:
    ldr sp, =0x34000000                 @ 设置堆栈
    bl  main
halt_loop:
    b   halt_loop

disable_watch_dog:
    @ 往WATCHDOG寄存器写0即可
    mov r1,     #0x53000000
    mov r2,     #0x0
    str r2,     [r1]
    mov pc,     lr      @ 返回

copy_steppingstone_to_sdram:
    @ 将Steppingstone的4K数据全部复制到SDRAM中去
    @ Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000
    
    mov r1, #0
    ldr r2, =SDRAM_BASE
    mov r3, #4*1024
1:  
    ldr r4, [r1],#4     @ 从Steppingstone读取4字节的数据,并让源地址加4
    str r4, [r2],#4     @ 将此4字节的数据复制到SDRAM中,并让目地地址加4
    cmp r1, r3          @ 判断是否完成:源地址等于Steppingstone的未地址?
    bne 1b              @ 若没有复制完,继续
    mov pc,     lr      @ 返回

memsetup:
    @ 设置存储控制器以便使用SDRAM等外设

    mov r1,     #MEM_CTL_BASE       @ 存储控制器的13个寄存器的开始地址
    adrl    r2, mem_cfg_val         @ 这13个值的起始存储地址
    add r3,     r1, #52             @ 13*4 = 54
1:  
    ldr r4,     [r2], #4            @ 读取设置值,并让r2加4
    str r4,     [r1], #4            @ 将此值写入寄存器,并让r1加4
    cmp r1,     r3                  @ 判断是否设置完所有13个寄存器
    bne 1b                          @ 若没有写成,继续
    mov pc,     lr                  @ 返回


.align 4
mem_cfg_val:
    @ 存储控制器13个寄存器的设置值
    .long   0x22011110      @ BWSCON
    .long   0x00000700      @ BANKCON0
    .long   0x00000700      @ BANKCON1
    .long   0x00000700      @ BANKCON2
    .long   0x00000700      @ BANKCON3  
    .long   0x00000700      @ BANKCON4
    .long   0x00000700      @ BANKCON5
    .long   0x00018005      @ BANKCON6
    .long   0x00018005      @ BANKCON7
    .long   0x008C07A3     @ REFRESH
    .long   0x000000B1      @ BANKSIZE
    .long   0x00000030      @ MRSRB6
    .long   0x00000030      @ MRSRB7


參考資料
  1. 韋東山 嵌入式Linux應用開發完全手冊
  2. http://blog.csdn.net/mr_raptor/article/details/6555786
  3. http://blog.sina.com.cn/s/blog_9072b7750101j3hj.html
  4. http://www.cnblogs.com/zjzsky/p/3559697.html
  5. http://blog.sina.com.cn/s/blog_655781cd01014xb2.html






No comments:

Post a Comment