當高速 AndesCore™ 遇上低速Embedded Flash 的晶片效能提升方法

Facebook
Twitter
LinkedIn

陳群旻,技術副理,晶心科技股份有限公司

  AndesCore™除提供 AHP,APB ,HSMP 介面外,亦可透過 EILM 介面與記憶體整合,使 AndesCore™可以不透過 AMBA BUS 直接透過 EILM 介面擷取指令。然而嵌入式 Flash 的執行速度目前,並不能趕及 AndesCore™的工作頻率, AndesCore™的執行效能將受限於嵌入式 Flash 的執行速度。此時可透過在AndesCore™與 Flash 間的 EILM 介面之間加入一個預取模組,減少 AndesCore™ 因為 Flash throughput 跟不上 AndesCore™ 效能,使執行效能下降的影響。文章中所提供的參考預取模組,以 data width 32 bits 的 Flash 為操作對象,預取 buffer size 為兩道 Instructions (32bits*2)提供一預取機制的設計參考。
  本文之目的在提供與介紹一個預取模組的參考設計作為使用者設計預取模組的參考。期望能對使用者有所助益,也希望讀者不吝指教提供您寶貴的意見。

1. Prefetch design 介面介紹
  AndesCore™透過 EILM 介面可與外部 external local memory 整合,為了透過Prefetch 模組根據前一道指令擷取時的位址,以 AndesCore™將循序擷取指令為預測邏輯來預取下道指令,並儲存該指令內容於 Prefetch 模組,供 AndesCore™ 循序擷取指令時使用,我們將原本 AndesCore™與 EILM 的整合方式(如圖一所示),改為在 AndesCore™與 EILM 之間加入 Prefetch 模組的整合方式(如圖一所示)。
  AndesCore™透過 EILM 介面跟 Prefetch 模組提交 request,Prefetch 模組透過eilm_wait 告知 AndesCore™該 request 執行是否需要 wait,並在對應的時序提供AndesCore™欲擷取的指令內容。
  Prefetch 模組另有介面與 memory (Flash or ROM)整合,透過該介面進行對memory 的讀取。由於坊間 Flash or ROM 有各種 protocol,Andes 提供的 Prefetch reference design 主要專注於提供 prefetch 機制的參考設計,memory 介面以一pseudo Flash 介面為設計對象,使用者後續可根據所使用的 memory 的 protocol 進行調整設計。

1.1 Block Diagram  

1.2 Signal Descriptions
Prefetch 模組的 clock 與 reset,與 AndesCore™使用相同的 clock,reset 訊號源作設計,此外有一 input 訊號“ratio”用以設定 AndesCore™與 memory 工作頻率倍率關係。其餘訊號,我們分作兩個群組”EILM”與”MEM”分別說明。

  1.2.1. Global signals

  1.2.2. EILM
  Prefetch 模組透過 EILM 介面與 AndesCore™整合,依循 AndeStar 所定義的 protocol 與 AndesCore™溝通。

以下時序圖說明 EILM 介面 Read/Write 時的訊號

  1.2.3. 本次模擬使用的 Flash 介面的訊號
  Prefetch 模組的 memory 介面以一 pseudo Flash 介面為設計對象。並以此memory 的 behavior module 與 Prefetch 模組整合後模擬。以下圖表介紹此pseudo Flash 之訊號與工作之時序。

2. Prefetch 模組的主要功能介紹
  透過 Prefetch 模組來提升 AndesCore EILM 擷取指令時的效率,減少AndesCore 提出指令 request 後,等待 read data 自 Flash 回覆有效值的等待時間, 來增加 AndesCore 的執行效能。
  實現方式是以前次 AndesCore 提出指令 request 時,所發出的 address 來預測後續 AndesCore 提出指令 request 的 address 為遞增方式,在 AndesCore 提出指令 request 前,Prefetch 模組先將該遞增 address 的指令內容由 Flash 取回並儲存於 Prefetch 模組中,當 AndesCore 提出指令 request 的 address 確為遞增方式,且指令內容已在 Prefetch 模組中,AndesCore 將不需 wait,可在下一時序即可自Prefetch 模組擷取指令內容。
  若 AndesCore 提出指令 request 的 address 為非遞增方式,或是 AndesCore 提出指令 request 的頻率高過 Prefetch 模組預取資料的頻率,Prefetch 模組中已無事先預取的指令內容時,則依然透過 wait 訊號來延遲 AndesCore 擷取指令內容。

2.1 預取功能說明
  圖表 10 所示為 Prefetch 模組自 Flash 擷取指令內容的 function 示意圖

Reset 後, Prefetch 模組內並無預取的指令內容,於是執行 general prefetch function,後續當 AndesCore 提出指令 request 為遞增方式,若指令已預取完成, 則將指令內容傳給 AndesCore,若指令預取未完成則拉 wait 訊號來延遲AndesCore 擷取指令內容。再以目前 request 的 address 遞增來預取指令。當AndesCore 提出指令 request 不為遞增方式(本文後續稱為 branch),則拉 wait 訊號來延遲 AndesCore 擷取指令內容,同時 Prefetch 模組自 Flash 擷取該指令,當Prefetch 模組得到有效資料時,撤回 wait 訊號,並將有效資料傳給 AndesCore。再以目前 request 的 address 遞增來預取指令。

2.2 主要程式說明
  以下我們剪輯 Prefetch 模組 RTL 程式中幾個重要部分來做說明

  2.2.1 branch 判斷:
  當一個 AndesCore™ request (instruction fetch)被 Prefetch 模組接受時,若此時的 address 不等於預設的遞增 address,表示一個 branch 發生,Prefetch 模組將跟據 branch 時應有的動作來對 Flash 讀取指令,使用 wait 訊號來延遲 AndesCore, 選擇 read data 等。

相關程式片斷:
assign    branch= eilm_read_req_valid&((lastest_eilm_ifetch_addr_inc1!=eilm_addr)|eilm_ifetch_n);

  2.2.2 prefetch 判斷:
  當 Prefetch 模組處於 idle 狀態時,若需要被預取的指令內容,未儲存於Prefetch 模組,則進行 prefetch 的動作,對 Flash 讀取指令,並存放至 Prefetch 模組。 Prefetch 模組預取深度我們設計為 2,故我們會預取下一道(lastest_eilm_ifetch_addr_inc1)及下下一道(lastest_eilm_ifetch_addr_inc2)指令。

相關程式片斷:
assign     prefetch_next1= (state_cnt==4’h0)& (~wait_for_write)&
                                                              (~((lastest_eilm_ifetch_addr_inc1==addr0)&addr0_valid )&
                                                                 ~((lastest_eilm_ifetch_addr_inc1==addr1)&addr1_valid ));
  assign      prefetch_next2= (state_cnt==4’h0)& (~wait_for_write)&
                                                                  (~((lastest_eilm_ifetch_addr_inc2==addr0)&addr0_valid )&
                                                                      ~((lastest_eilm_ifetch_addr_inc2==addr1)&addr1_valid ));

  2.2.3 選擇執行 branch, prefetch 或 idle
  當 Branch 發生時,不論需要被預取的指令內容是否已儲存於 Prefetch 模組, 執行 branch 時應有的動作,若有 prefetch 的動作執行中則放棄。
當Branch 未發生時,需要被預取的指令內容未儲存於 Prefetch 模組,執行 prefetch 時應有的動作,若需要被預取的指令內容已儲存於 Prefetch 模組,Prefetch 模組處於 idle。

相關程式片斷:
 

 

 

 

 

 

 

 

 

 

 2.2.4 選擇 read data:
  若 Prefetch 模組處在執行 branch 時應有 function 的動作,自 Flash 於資料有效時撤回wait 訊號,選擇 DO (Flash read data)作為回應給AndesCore 的read data。若 AndesCore 提出指令 request 為遞增方式,則以預取的指令內容,作為回應給AndesCore 的 read data。

相關程式片斷:

 

 

 

2.2.5 儲存預取的指令內容:
  當進行 prefetch 的動作完成時,更新預取的指令內容。
A_latch 為進行 prefetch 的動作發 request 給 Flash 時所發出的 address,我們以A_latch 最後一個位元選擇要儲存於兩個 buffer 中的哪一個。

 

 

 

 

 

 

 

 

 

 

 

 

2.3 波形圖說明
 
  以下小節,為 After Reset, Branch, Sequential 三種狀況下的波形圖以及說明。

   2.3.1. After Reset

圖表 11 After reset 波形圖


2.3.2. Branch fetch
 

圖表 12 branch fetch  波形圖

2.3.3. Sequential fetch

圖表 13 sequential fetch 波形圖

3. Instruction fetch效能改善
 
  由於參考模組,以 32 bits Flash 為設計對象,預設 AndesCore™ frequency 與Flash frequency 為 n:1 (n≧2),Instruction fetch performance 受限 Flash 輸出頻率, 故未能有明顯提升,當 Flash 擴充頻寬為 64 bits,使 Flash 輸出及上 AndesCore™ 指令消耗速度後,Instruction fetch performance 將會有明顯提升。
  Andes 已有客戶參考此設計,並加以修改,使之支援頻寬為 64 bits之 Flash。以 AndesCore™ frequency 與 Flash frequency 為 2:1 下,由原本 fetch 一道指令平均需要兩 cycle 增進為 fetch 一道指令平均需要 1.1cycle。Instruction fetch 效能改善 80%左右。
  Instruction fetch 效能改善可透過下列公式計算。
Instruction fetch performance improvement = ( 2/(1+ branch instruction ratio)
-1)*100%
(當branch 發生時,由於欲 fetch 的指令不在prefetch 內,此時仍需花費 2cycle fetch 該指令。)

4. 結語
 
  AndesCore™所提供的 EILM 介面相當方便客戶與 Flash 或 ROM 整合,然而Flash 或 ROM 目前最高速 access time 目前不能與AndesCore™所能實現的最高工作頻率相同。AndesCore™的執行效能將受限於 Flash 或 ROM 目前最高速 access time。Prefetch 模組提供一預取的機制來增加 AndesCore™與 Flash 或 ROM 整合時的執行效能。文章中所提供的參考預取模組,以 data width 32 bits 的 Flash 為操作對象,提供一預取機制的設計參考。使用者可參考此設計概念,將 data width 32 bits 的 Flash 為操作對象改為 data width 64 bits 的 Flash,在增加此設計後, Instruction fetch performance 將可得到符合使用者期待的效果。