# SDRAM Controller and SDRAM in Caravel User Project ## 目的 ### 將LAB4-1內的wishbone-BRAM替換成Wishbond SDRAM+SDRAM-Controller #### 1. firmware 描述 "matmul" 而後執行在SDRAM ## SDRAM 背景知識 https://hackmd.io/AimapH7MQqaiewDWPtS43Q?both ## 下載安裝執行包與解說 https://github.com/bol-edu/caravel-soc_fpga-lab/tree/main/lab-sdram 確認更改程式後,最後輸出結果與以下結果相同表示更改路徑都是正確的 ``` Reading counter_la.hex counter_la.hex loaded into memory Memory 5 bytes = 0x6f 0x00 0x00 0x0b 0x13 VCD info: dumpfile counter_la.vcd opened for output. LA Test 1 started Call function adder() in User Project BRAM (mprjram, 0x38000000) return value passed, 0x2233 (這一段會根據firmware的不同而有所更動) LA Test 2 passed ``` 解說 https://www.youtube.com/watch?v=VfGQYhy2aak&list=PLTA_T2FLzYNAvdvpEQvTjXaPARtmV-0GM&index=31 ## SDRAM 結構  #### 1. SDRAM controller(紅框) 檔案位置 LABD/rtl/user/sdram_controller.v 此lab主要更改此code user_project 收到的位址訊號進而決定"read & write address" 1. controller 與 wishbond interface之間需要有一個converter作為訊號轉換 #### 2. SDRAM device 檔案位置 LABD/rtl/user/sdr.v 基本不動它 使用Bram儲存資料 #### 3. Controller-Wishbone Singnal Converter 檔案位置 LABD/rtl/user/user_proj_example.counter.v controller 和 wishbone之間的轉換code  controller 包含 2個訊號 1. busy:(1) 表示controller正在執行指令,執行完成後busy 自動->0 2. out_valid:(0) 執行完成read cmd後,需要將自資料送回wishbond時將out_valid(主動) ->1 ``` 但是 wishbond 只有 "1"個output signal "wbs_ack_o"因此我們需要 > convert busy & out_valid into "one signal" 如此將SDRAM放入user_project ``` ## SDRAM Controller design ### Flower Chart  ### 架構圖   ## SDRAM bus protocol ### SDRAM DEVICE  [1] Input /output pin: 1. CKE : clk enable 2. CS_N : disable other input, except "CLK" "CKE" "DQM" 3. CAS_N: A[8:0] 列address 4. RAS_N: A[12:0] 行address 5. WE_N : write_enable 6. BA[1:0]: 總共4個BLANK 7. A[12:0]: address(不同命令定義不同) 8. DQ[15:0]:data register input/output [2] decode:  經過decode會把各項需要執行的描述都在sdram.v裡面進行 prech_enable : 若要切換bank,必須要先將目前正在使用的bank關閉後才可以切換新的bank ### Wishbone 和 Sdram controller 因為Wishbond 只有一個響應訊號 wbs_ack_o 而 Sdram會由ctrl_busy&valid共同決定,因此需要轉換 [1]. 轉換 Wishbone 和 SDRAM controller 的訊號 ``` assign valid = wbs_stb_i && wbs_cyc_i; assign ctrl_in_valid = wbs_we_i ? valid : ~ctrl_in_valid_q && valid; assign wbs_ack_o = (wbs_we_i) ? ~ctrl_busy && valid : ctrl_out_valid; assign bram_mask = wbs_sel_i & {4{wbs_we_i}}; assign ctrl_addr = wbs_adr_i[22:0]; ``` [2] Wishbone address 的末 23 bits 會直接映射到 SDRAM address ``` always @(posedge clk) begin if (rst) begin ctrl_in_valid_q <= 1'b0; end else begin if (~wbs_we_i && valid && ~ctrl_busy && ctrl_in_valid_q == 1'b0) ctrl_in_valid_q <= 1'b1; else if (ctrl_out_valid) ctrl_in_valid_q <= 1'b0; end end ``` ### Introduce the prefectch schme 觀察這三筆訊號之波形,可以看出將「讀取記憶體」任務增加 pipeline 功能,將能使讀取效率提升,可透過前一比地址資訊預測將會使用到的連續記憶體區域,提前讀取至 Cache 中  ### Data Prefetch 並存入 Cache [1]. 在原先的 Controller 沒有 Burst mode ,每次讀取資料都需要一定的訪問延遲外加發送address的時間 ( 1T ),若該資料的地址已經被激活 ( activate ) 則需要 6T ,否則需要 9T 才能得到資料  改善: (結果如下圖連續輸出) 1. 若預先將資料抓取,存在 1T 記憶體中,則訪問只會有 2T 延遲。 sent address ( 1T ) → sent data back & ack ( 1T ) 2. Wishbone 輸入 address、rw、in_valid 等資訊後,controller 只會經歷 1T Busy,因此可以連續處理多筆訪問 3. 另外也新增了cache and burst(會在後面做補充)  ### 分別成difference bank 將Code and data兩種資料分開至不同的 Bank ,即可方便 prefetch 的設計,可以清楚知道哪些 address 存放的是將要 load 到 PE 做運算的資料。 ### Bank 判斷: 1. WB address 的末 22 bits 會直接斷應到 SDRAM address 2. 本實驗沒有調整 mapping 方式,各 bits 代表資訊如下表所示  #### sections.lds #### 分離前:  Data Fetch:( In Bank 2)  Code Execution(In Bank 0 ~ 3)  --- #### 分離後:  Data Fetch (In Bank 0)  Code Execution(In Bank 1~3)  ### Ohter SDRAM access conflicts with SDRAM refresh (refresh period) 我們新增了Prefetch的新功能,收到地址後會預先判斷該地址之資料是否為 Code 或是 Data ,若為 Code 資訊,則會用 Burst Mode 連續讀取 8 個連續記憶體資料 ( 已經為本實驗任務特化,省略 program burst length 步驟 ,但是Prefetch 會衍生出 Refresh issue : * Refresh cycle:750T * CAS:3T * Prefetch data num:8 addresses 若要連續 prefetch 多筆資料,且不想要被中斷,可能讓 Refresh 時間超出 750 T,並且不是只超出一點點。 > Ex : Time=749 T 時 Prefetch ,則實際 Refresh 時間為 749+24 = 773 T solution:將 Refresh cycle 縮短至 750- 3*8 T = 726 T ## other - FSM: > 將原先的 read mode 調整成 Burst read mode ,需要等待 SDRAM Device 處理,所以會經歷 Wait ,但是 burst 模式就能省略這些時間。 ### read mode 訪問地址是已經激活的 Row `IDLE >ACTIVATE>WAIT>READ>WAIT>ReadRes>IDLE ` 訪問地址是尚未經激活的 Row `IDLE >READ>WAIT>ReadRes>IDLE ` ### Burst read mode `IDLE >(ACTIVAT)>READ>ReadAndOutput>ReadRes>IDLE ` READ:只進行資料讀取,不輸出資料。 ReadAndOutput:進行資料讀取與輸出資料。 ReadRes:不進行資料讀取,只輸出資料。 ## other - SDRAM address 與cache 地址之映射 SDRAM address 與 Cache 地址之映射 ``` origin (column) DC:Dont care DC user_addr [ 09 | 08 | 07 | 06 | 05 ] 0x3800_0100 --> 100 --> 0001_0000_0000 --> 0 1 0 0 0 --> 0 0x3800_0120 --> 120 --> 0001_0010_0000 --> 0 1 0 0 1 --> 1 0x3800_0140 --> 140 --> 0001_0100_0000 --> 0 1 0 1 0 --> 2 0x3800_0160 --> 160 --> 0001_0110_0000 --> 0 1 0 1 1 --> 3 0x3800_0180 --> 180 --> 0001_1000_0000 --> 0 1 1 0 0 --> 4 0x3800_01A0 --> 1A0 --> 0001_1010_0000 --> 0 1 1 0 1 --> 5 0x3800_01C0 --> 1C0 --> 0001_1100_0000 --> 0 1 1 1 0 --> 6 0x3800_01E0 --> 1E0 --> 0001_1110_0000 --> 0 1 1 1 1 --> 7 0x3800_0200 --> 200 --> 0010_0000_0000 --> 1 0 0 0 0 --> 8 offset (row) [ 4 | 3 | 2 ] 0x00 --> 0 0 0 0x04 --> 0 0 1 0x08 --> 0 1 0 0x0C --> 0 1 1 0x10 --> 1 0 0 0x14 --> 1 0 1 0x18 --> 1 1 0 0x1C --> 1 1 1 ``` 因為先前已訪問過 0x3800_0120,並將該地址資料存在 Cache中,因此僅需要 2T 就能回傳資料  資料參考- from 厲害的組員 https://irradiated-hellebore-357.notion.site/LAB-D-SDRAM-4128635388f44d099ccf5abd650cbda2?pvs=25#439c1e3d7d404ddf93b9e37921b017fd
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up