課程project複習 CPU hazard

2021-07-10 17:37:26 字數 2604 閱讀 1490

一、什麼是hazards

hazards是cpu在當前週期無法獲取所要取的暫存器的值的問題。出現情況主要分為以下三種:

1、一般計算

第乙個add將和賦給gr3,第二個add則是要用到gr3的值。如果第二個add想要gr3的值,必須等到第乙個add執行到wb階段,才能得到gr3被更新之後的值。所以還要等3個週期。因此,中間的三個add其實都應該換成nop,否則gr3就是更新之前的值,導致最後的結果不是我們實際想要的。

軟體的解決方法就是新增nop了,但現在要用硬體的解決辦法:data_forwarding:其實不用等到第乙個add執行到wb才能得到更新之後的gr3的值,因為這個值是在id和ex之間(alu)計算出來的,然後存入了aluo,進而賦給reg_c、reg_c1,最後才到gr3。所以可以通過data forwarding,利用這些提前得到計算結果的中間變數給reg_a/b賦值,如下圖所示:

2、load指令

通過data forwarding解決了兩個計算指令之間的衝突,但是它不能解決所有的賦值問題。load的問題就不能:

因為load指令是從記憶體中取值,所以alu計算出來的aluo和賦給的reg_c都只是從記憶體中取值的位址,而不是從記憶體中得到的值。這個值是在mem階段才得到的。所以中間必須等待乙個週期,才能用data forwarding的方式,獲取d_datain的值。這種方法就是stall

實現方式:在下個週期內,維持pc的值。然後id_ir賦為nop指令,也就是什麼都不做。(所以其實和軟體實現的思路一樣……)

3、跳轉指令

如果當前指令已經是跳轉指令了,那麼,肯定不能讓在指令記憶體中緊接著的指令執行了,否則可能會導致意想之外的情況發生。

怎麼解決呢?方法依然是stall,因為要保持pc不變。

二、**實現

通過前面對hazards的兩種情況的解釋,應該對實現有乙個大致的框架了:用組合邏輯實現,每次判斷id_ir和ex_ir、mem_ir、wb_ir之間的關係,然後將判斷結果寫入變數中,供下乙個週期到來時,cpu判斷是否需要data forwarding或者stall。

1、data forwarding

① change_ex、change_mem、change_wb:判斷前1~3條指令是否會修改r1的值(必要性:如果都不會修改暫存器的值,就不需要data forwarding了)

② spe_idir:大部分計算指令的reg_a對應的暫存器的位址都是id_ir的6~4位,但是addi、subi和ldih這三個比較特殊,reg_a是10~8位,由於這個位置是接下來判斷是否需要data forwarding的關鍵,所以要特別區分這種狀態。

③ needforwardrega、needforwardregb:判斷當前指令是否會修改r1的值

④ forwardrega、forwardregb:是否需要進行data forwarding,如果需要,又要判斷和哪個指令發生了hazards,以確定reg_a/b應該取什麼值

⑤ forwardsmdr:這個是後來才發現的問題,別忘了id階段還對smdr賦值了,這個變數儲存了執行store的時候儲存進記憶體的值,它的值也是從暫存器中取的,所以也要進行data forwarding:

⑥ id階段,對reg_a、reg_b、smdr的賦值:

① needrega、needregb:判斷i_datain是不是需要從暫存器中取值

② stallpc、stallinstr:在needrega和needregb的基礎上,判斷id_ir是不是load指令、暫存器位址是否對應、是不是跳轉指令,進而判斷是否需要stall

③ 在if階段對pc和id_ir的賦值

GeekOS課程設計 project1

熟悉elf檔案格式,了解geekos系統如何將elf格式的可執行程式裝入到記憶體,建立核心程序並執行的實現技術。1 修改 geekos elf.c檔案 在函式parse elf executable 中新增 分析elf格式的可執行檔案 包括分析得出elf檔案頭 程式頭,獲取可執行檔案長度,段 資料段...

HCIA課程回顧複習

第一 什麼是網路?提供了資訊的傳遞,資源共享 核心就是通訊 技術上做控制 osi 將網路分成了七層 tcp ip將網路分成了四層 為什麼要進行分層?是為了便於管理 所以分層管理 世界業界各大廠商使用的是tcp ip 的標準 osi七層模型分別是 應用層1.用來實現具體的應用詳細業務 表示層1.產生資...

演算法課程期末複習總結

八大排序演算法複雜度比較 求解遞迴式的複雜度 max sum 最大子段和 int len arr.length int dp newint len 1 dp 0 0 for int i 1 i len i int res integer.min value for int i 1 i dp.leng...