IDU-指令譯碼單元

1、 IDU簡介

IDU是玄鐵C910中負責指令譯碼、寄存器重命名、派遣和發射邏輯的單元,主要劃分為四級流水級,分別為ID、IR、IS、RF,玄鐵C910中流水線分為控制通路和數據通路。本文將從流水級從前到後的順序,介紹玄鐵C910譯碼單元邏輯設計,以及在玄鐵C910基礎上進行擴展四發射所涉及邏輯。

2、 指令譯碼(id)

(1)指令類型

玄鐵C910中支持的指令集分為RV基礎指令集(IMAFDC)以及玄鐵擴展指令集。根據指令類型,玄鐵C910的譯碼單元將指令分為4種,分別為normal、split_short、split_long、fence。在譯碼單元中,標準的RISC-V指令會被分解成微操作(uop)。

類型 Uop數量
Normal 1
Split_short 2
Split_long 1~5
fence 特殊指令

其中,Split_long和fence類型指令由於其特殊性,隻作為inst0譯碼,當周期隻能譯碼一條指令。在玄鐵C910中,split_long類型的指令隻有原子指令一種,其譯碼由狀態機控制,如果分解出瞭5條微操作,那麼在當周期無法全部pipe到下一級,會寄存一拍。

譯碼單元對應的分為normal、split_short、split_long、fence四種,玄鐵C910采用並行的數據通路的設計,以面積換取時序,共有三組譯碼單元,第一組可譯碼split_long和fence類型的指令,其他兩組為normal和short。

(2)指令回填

在玄鐵C910中,ID級負責將IB級pipe的指令進行譯碼,其遵循一次回填三條的原則。如IB級pipe瞭三條指令,而ID級隻能譯碼兩條,那麼下周期IB級不再向ID級發送指令,ID級將剩餘的指令進行移位處理,下一周期隻譯碼剩餘的指令。

指令回填的邏輯由ctrl_id_pipedown_x_inst信號控制,主要的回填邏輯如下表

ctrl_id_pipedown_1_inst 1. inst0是normal或short,inst1是fence或者long2. inst0是long或者fence且id級沒有發生stall
ctrl_id_pipedown_2_inst inst0/1都是normal或者short 且1. inst0和inst1都是short,inst2是normal2. inst0,1,2都是short類型3. inst2是long或者fence類型
ctrl_id_pipedown_3_inst Inst0,1,2中不能有fence或者long類型指令且inst 0,1,2不能有兩條及以上的short類型

(3)微操作數量判定

譯碼級譯碼出的微操作數量最大為4條,因此譯碼級pipedown的微操作取決於id級的指令類型。在玄鐵C910中,pipedown的uop的vld為

ctrl_id_pipedown_instx_vld

其主要判斷邏輯為if-else邏輯,對於每條微操作的vld,從inst0指令類型判斷到inst2指令類型。

對於uop0:

Uop0隻需考慮inst0指令類型,因為是並行的譯碼通路,vld信號經過一個選擇器

對應關系為

其中long_ vld[x] long類型的指令譯碼出的第幾條微操作是否有效。

fence_ctrl_instx_vld:取決於fence狀態機,在此簡單介紹:

fence指令需要等待之前所有的指令都退休瞭,才能進行後續的指令譯碼。

fence_ctrl_inst0_vld表示,fence狀態機到瞭issue狀態,表示後續指令可以繼續譯碼和pipe瞭。

fence_ctrl_inst1_vld 和fence_ctrl_inst2_vld為高時,fence 指令類型為FENCE.I指令以及玄鐵擴展的虛擬內存廣播指令以及狀態機為issue狀態。

ctrl_id_pipedown_x_inst信號在判定中作用很大,在考慮這個信號的基礎上判斷是否有效

Uop1需要考慮inst0和inst1

Uop2考慮inst0,1,2

(4)stall邏輯

Stall邏輯主要包括

1、 ir stall:ir級發生stall會同時stall ID級

2、 split_long stall:在開源版本中隻有一種,原子指令譯碼出5條微操作時會產生此種stall。

3、 id bypass stall:發生瞭ir stall 或者當周期不能pipe3條指令時發生此stall。

Fence、long以及ir stall 三種會產生ID級pipedown stall。

(5)四發射修改

對四發射主要邏輯修改與上述所列類似,主要包括指令回填以及指令pipe

1、指令回填主要邏輯表格如下:

ctrl_id_pipedown_1_inst 3. inst0是normal或short,inst1是fence或者long4. inst0是long或者fence且id級沒有發生stall
ctrl_id_pipedown_2_inst 4. inst0/1都是normal或者short 且inst2是long或者fence5. inst0/1都是short,inst2是short/long/fence
ctrl_id_pipedown_3_inst 1. inst 0,1,2 兩個short一個normal2. inst 0,1,2 一個short兩個normal且inst3 fence或long3. inst 0,1,2 三個normal且inst3是fence或者long
ctrl_id_pipedown_4_inst 1. inst0,1,2,3中最多有一個short,其他都是normal且不能有fence也不能有long

2、微操作pipe主要邏輯如下:

3、 指令重命名和預派遣(IR)

(1) 指令隊列

在IS級派遣指令前,需要根據指令信息決定要派遣到的隊列,在指令譯碼後,根據指令類型將指令分別送往7條隊列,每個隊列有兩個寫入端口分別為c0和c1,c0從隊列左側寫入,c1從隊列右側寫入。對於可以派遣到兩條隊列的指令,如某些AIQ0和AIQ1都能派遣的指令,優先級為A0c0>A1c0>A0c1>A1c1。

指令隊列 表項數 指令發射的執行級
AIQ0 8 ALU、DIV、SPECIAL
AIQ1 8 ALU和MUL
BIQ 12 BIU
LSIQ 12 LSU
SDIQ 12 LSU
VIQ0 8 FALU、FMUL和FDIV
VIQ1 8 FALU和FMUL指令

(2) Stall和反饋機制

由於每個隊列隻有兩個寫入端口和一個寫出端口,因此當同周期出現三條及以上某隊列類型的指令時,當周期無法將全部的指令寫入到指令隊列中,如果直接stall流水線會造成性能損失。因此玄鐵C910中加入瞭反饋機制,在ir和is兩級流水之間增加反饋判斷邏輯。

1、 typestall處理

stall分為 ir_stage_stall 和type_stall

其中type_stall可以通過反饋機制優化

當ir和is 的指令數量<4條時,可以反饋來避免stall

反饋信號主要是

ctrl_xx_is_inst0_sel[0] 表示is級pipe瞭2條(說明is級有3條同類型指令)

ctrl_xx_is_inst0_sel[1] 表示is 級不是pipe瞭兩條

當is級pipe瞭兩條時,以下兩種情況會發生stall

如果is inst3 vld(說明is級pipe瞭兩條,剩瞭2條 (inst2 inst3)指令)且 ir級inst2 vld(說明ir有3條及以上(0,1,2)的指令),此時超過瞭最大微操作數量4條,因此需要stall流水線。

如果is inst3 不vld(說明is級剩(inst2 )的指令)且 ir級inst3 vld(說明ir有4條及 (0,1,2,3)指令,超過最大微操作數量4,因此stall流水線。

ctrl_xx_is_inst_sel[0] Is pipe兩條 且is inst3 vld (說明剩瞭2,3兩條uop)
ctrl_xx_is_inst_sel[1] Is pipe兩條 且!is inst3 vld(說明剩瞭2一條uop)
ctrl_xx_is_inst_sel[2] 沒有發生typestall的情況

(3) 動態平衡

對於AIQ0和AIQ1 以及VIQ0和VIQ1,因為存在aqi01和viq01類型的指令,而寫入優先級總是A0>A1,因此aiq0和viq0中的指令數量會變多,增加stall的風險,因此玄鐵c910中加入瞭動態平衡機制來解決這個問題

動態平衡機制通過對隊列表項進行計數來實現。可以通過cp0配置信號來開啟和關閉。

有兩種情況會使能

1、 AIQ0(VIQ0)中表項數量為8且AIQ1(VIQ1)中表項數為0

2、 AIQ0(VIQ0)中表項數量和AIQ1(VIQ1)表項數量相差 2~7個之間。

這兩種情況下會把AIQ01(VIQ01)變成AIQ1(VIQ1)類型的指令,然後再進行預派遣。

(4) 指令派遣

指令派遣邏輯主要分為兩部分,隊列端口的enable信號和隊列端口要寫入哪條指令的sel信號。其中AIQ和VIQ兩條隊列是特殊的,因為存在AIQ01和VIQ01類型的指令,因此在邏輯判斷上要更復雜。

1、AIQ/VIQ隊列端口的使能邏輯

a0c0 4條uop中有一條及以上的aiq0或者aiq01類型指令
a1c0 1、1條及以上的aiq1類型指令2、1條及以上的aiq0類型指令且一條及以上的aiq01類型指令3、2條及以上的aiq01類型指令
a0c1 1、2條及以上的aiq0類型指令2、1條及以上的aiq0,1條及以上的aiq1,1條及以上aiq013、三條及以上的aiq01類型
a1c1 1、2條及以上的aiq1類型指令2、2條及以上的aiq0,且1條及以上的aiq1且1條及以上aiq013、2條及以上的aiq01且3.1、2條及以上aiq03.2、1條及以上的aiq0,一條及以上aiq14、3條及以上aiq01且1條aiq0或者1條aiq15、4條aiq01類型指令

2、 AIQ/VIQ指令隊列的派遣邏輯

Sel邏輯用於數據通路選擇對應的指令

3、 其他隊列端口的使能邏輯,以BIQ為例

按照inst0 – inst3的優先級分配端口即可。

(5) 指令折疊

指令折疊是玄鐵C910中用來節約ROB表項的優化。AIQ0、AIQ1、AIQ01和VIQ0、VIQ1、VIQ01類型的指令可以進行fold,是否可以進行fold需要進行判定

assign ctrl_ir_pre_dis_inst0_fold = ctrl_ir_pre_dis_inst0_vld

&& ctrl_ir_inst0_fold

&& !ctrl_ir_inst0_split

&& !ctrl_ir_inst0_intmask

&& !rtu_idu_srt_en

&& !cp0_idu_rob_fold_disable;

Fold具有下面幾種組合

ctrl_ir_pre_dis_inst01_fold

ctrl_ir_pre_dis_inst12_fold

ctrl_ir_pre_dis_inst23_fold

ctrl_ir_pre_dis_inst012_fold

ctrl_ir_pre_dis_inst123_fold

fold折疊必須要有連續2條以上可以fold的指令。

(6) ROB端口

在IR流水級中,會向ROB的表項中寫入指令的相關信息,完成寄存器重命名過程。

在發生瞭指令折疊時,寫入的是折疊的第一條指令的信息,同時記錄折疊的指令數量。

所以雖然寫入的都是折疊的第一條指令的信息,但是需要記錄折疊情況,所有需要sel。

所以sel對應的數字其實沒有特定意義,隻是表示不同的情況,用於數據通路選擇。

1、ROB 端口enable判斷

2、ROB sel邏輯

3、 ROB IID邏輯

IID是表示指令先後順序的標志位,也是ROB64個表項的索引。經過折疊的指令具有相同的iid。

4、 指令隊列

1、 隊列維護

隊列的維護主要分為寫入和彈出。寫入在IS級寫入,根據指令的類型送入不同的指令隊列,寫入端口為兩個,pop端口為一個。隊列會有表項數的計數,同時將信號傳遞個IR級進行DLB的控制。Create0的創建優先級為entry0-entry7,create1的創建優先級為entry7-entry1。

表項中主要維護以下內容:

① 年齡向量(agevec)

年齡向量是表示隊列中表項的先後順序的信號。隊列的發射是順序的,遵循先入先出原則,隊列pop的指令是隊列中最老的指令。

Create0和create1的年齡向量判斷略有不同,因為在同一個周期中,create·0的指令一定比create1的指令要老。

2、 隊列bypass

隊列中表項的src0,src1,src2

都可以bypass


本文章僅供學習交流使用,如引用請標註出處。

赞(0)