標籤:mips 處理器 開源 自己動手寫cpu 軟核
將陸續上傳本人寫的新書《自己動手寫CPU》(尚未出版),今天是第21篇,我盡量每周四篇
6.2 移動操作指令實現思路6.2.1 實現思路
這6條移動操作指令可以分為兩類:一類是不涉及特殊寄存器HI、LO的指令,包括movn、movz;另一類是涉及特殊寄存器HI、LO的指令,包括mfhi、mflo、mthi、mtlo。前一類很好實現,基本思路與第5章實現邏輯、移位操作指令時類似,只需要修改ID、EX模組即可。後一類涉及到特殊寄存器HI、LO,需要為OpenMIPS添加HI、LO寄存器,以及相應的讀寫控制。下面分別介紹各自的實現思路。
1、movn、movz指令實現思路
與第5章邏輯、移位操作指令的實現過程類似。
(1)在解碼階段給出運算類型alusel_o、運運算元類型aluop_o、要寫入的目的寄存器地址wd_o等訊號的值,同時讀取地址為rs、rt的通用寄存器的值,但是這裡需要新增一個步驟:依據讀取的地址為rt的通用寄存器的值是否為0,判斷是否要寫目的寄存器。將上述結果送到執行階段。
(2)執行階段依據傳入的訊號,確定最終要寫目的寄存器的資訊(包含:是否寫、寫入的目的寄存器地址、寫入的值),並將這些資訊傳遞到訪存階段。
(3)上述資訊會一直傳遞到回寫階段。最後,依據這些資訊修改目的寄存器,或者不作任何修改。
2、mthi、mtlo指令實現思路
這2條指令需要寫HI、LO寄存器,與之前實現的通用寄存器一樣,對HI、LO寄存器的寫操作放在回寫階段進行。
(1)在解碼階段依據指令,給出運算類型alusel_o、運運算元類型aluop_o的值,同時讀出地址為rs的通用寄存器的值。由於mthi、mtlo不寫通用寄存器,所以wreg_o為WriteDisable,wd_o為0。
(2)在執行階段確定要寫HI、LO寄存器的情況,以及要寫入的值,並將這些資訊傳遞到訪存階段。
(3)訪存階段將這些資訊再傳遞到回寫階段。
(4)回寫階段依據這些資訊修改HI、LO寄存器的值。
3、mfhi、mflo指令實現思路
這2條指令需要讀HI、LO寄存器,設計在執行階段才能讀取到。
(1)在解碼階段依據指令,給出運算類型alusel_o、運運算元類型aluop_o的值,同時因為有要寫的目的寄存器,所以wreg_o為WriteEnable,wd_o為指令中rd的值,也就是目的寄存器地址。
(2)在執行階段擷取HI或LO寄存器的值,作為要寫入目的寄存器的資料,並將這些資訊傳遞到訪存階段。
(3)訪存階段將這些資訊再傳遞到回寫階段。
(4)回寫階段依據這些資訊修改目的寄存器。
添加移動操作指令後的資料流圖6-2所示。
對比圖6-2與圖5-7可以發現有如下區別。
- 增加了HILO寄存器模組,並且該模組放在回寫階段。
- 將HI、LO寄存器的值傳遞到執行階段,在執行階段增加了一個選擇模組,用於選擇要參與運算的資料,如果是mfhi、mflo指令,那麼就會選擇傳遞過來的HI、LO寄存器的值。
6.2.2 新的資料相關情況的解決
進一步考慮mfhi、mflo指令的處理過程,這2條指令會在流水線執行階段讀取HI、LO寄存器的值,如果直接採用HILO模組給出的HI、LO寄存器的值,可能不是正確的HI、LO寄存器的值,因為此時處於訪存、回寫階段的指令有可能會修改HI、LO寄存器,以如下程式為例。
1、 lui $1,0x0000 # $1 = 0x000000002、 lui $2,0xffff # $1 = 0xffff00003、 mthi $0 # hi = 0x000000004、 mthi $1 # hi = 0x000000005、 mthi $2 # hi = 0xffff00006、 mfhi $4 # $4 = 0xffff0000
指令3、4、5均要修改HI寄存器,當指令6處於執行階段時,指令5處於訪存階段,指令4處於回寫階段,而此時HI寄存器的值是指令3剛剛寫入的0x00000000,HILO模組正是將該值傳到執行階段,如果採用這個值,那麼就會出錯,偏離程式設想,正確的值應該是當前處於訪存階段的指令5要寫的資料,6-3所示。
似曾相識,是不是?這就是上一章介紹過的資料相關問題,解決措施還是使用資料前推。將處於訪存階段、回寫階段的指令對HI、LO寄存器的操作資訊反饋到執行階段,執行階段依據這些資訊,確定HI、LO寄存器的正確值。
為此,需要修改資料流圖6-4所示,相比圖6-3,主要增加的部分就是將訪存階段、回寫階段的資訊反饋到執行階段,輸入到執行階段的選擇模組(圖中粗線所示),如果處於執行階段的是mfhi、mflo指令,那麼就會從中選擇HI、LO寄存器的正確值。
6.2.3 系統結構的修改
為了實現移動操作指令需要對OpenMIPS系統結構進行補充完善,主要修改6-5所示。
主要有三個方面。
(1)增加了HILO模組,用於實現HI、LO寄存器。
(2)執行階段的EX模組增加了whilo_o、hi_o、lo_o介面,分別表示是否要寫HILO、要寫入HI寄存器的值、要寫入LO寄存器的值。這三個介面傳遞出來的,對HI、LO寄存器的修改資訊會通過EX/MEM、MEM、MEM/WB三個模組一直傳遞到回寫階段,並最終傳遞給HILO模組。
(3)執行階段的EX模組增加了與HI、LO寄存器有關的輸入介面,包括為解決HI、LO寄存器的資料相關問題而引入的介面,在6.3.3節會有詳細介紹。
下一次會介紹移動操作指令實現,並給出代碼,敬請關注!