# 建立一個processor ## Step 1: Analyze Instruction Set(分析指令集) ![image](https://hackmd.io/_uploads/ByCio1p96.png) 指令長度: * 所有 MIPS 指令都是 32 位元。 指令格式: 有三種 MIPS 指令格式: * R 格式: 用於擁有三個Registers操作數的指令。 * I 格式: 用於具有即時值的指令。 * J 格式: 用於跳躍指令。 指令中的欄位: * op(操作):指定指令的操作碼(opcode)。 * rs、rt、rd(來源和目的Registers):rs(來源Registers): 通常是源操作數的來源Registers。 * rt(來源或目標Registers): 另一個來源Registers或目標Registers。 * rd(目的Registers): 存儲結果的Registers。 * shamt(位元位移數量):在位元位移指令中使用,以確定位移的數量。 * funct(功能碼):在 R 格式指令中使用,當僅僅使用 opcode 不足以確定操作時使用。 * 目標位址:跳躍指令的目標位址。 指令類型: * R 格式: 用於涉及Registers的操作。 * 例如:add、sub、and、or 等。 * I 格式: 用於即時值操作和 Memory 訪問。 * 例如:addi、lw、sw 等。 * J 格式: 用於跳躍指令。 * 例如:j、jal。 範例: * R 格式範例:add $t0, $s1, $s2 * I 格式範例:lw $t0, 4($s1) * J 格式範例:j 0x0040000C ### Logical Register Transfers ADD(加法): * R[rd] <- R[rs] + R[rt] * PC <- PC + 4 SUB(減法): * R[rd] <- R[rs] - R[rt] * PC <- PC + 4 LOAD(載入): * R[rt] <- MEM[R[rs] + sign_ext(Imm16)] * PC <- PC + 4 STORE(儲存): * MEM[R[rs] + sign_ext(Imm16)] <- R[rt] * PC <- PC + 4 ADDI(加法立即值): * R[rt] <- R[rs] + sign_ext(Imm16)] * PC <- PC + 4 BEQ(分支相等): * 如果 (R[rs] == R[rt]),則 PC <- PC + 4 + sign_ext(Imm16)],否則 PC <- PC + 4 ### Requirements of Instruction Set Memory: * 儲存指令和資料。 Registers(32 x 32): * 讀取 RS(來源Registers)。 * 讀取 RT(另一個來源Registers)。 * 將資料寫入 RT 或 RD(目的Registers)。 PC(Program counter): * 維護當前指令的地址。 Extender for zero- or sign-extension: * 對即時值進行零擴展或符號擴展。 Add and sub register or extended immediate (ALU): * ALU(算術邏輯單元)用於在Registers或擴展即時值上執行加法或減法。 將 4 或擴展即時添加到 PC: * 必須具有將 4 或擴展即時值添加到 PC(Program counter)的功能,以更新程序計數器。 ## Step 2a: Datapath Components 以下是一些基本的組合邏輯元件: Arithmetic Logic Unit (ALU): * 算術邏輯單元執行算術和邏輯操作,例如加法、減法、AND、OR等。 MUX(多路選擇器): * MUX 是一個多路選擇器,它根據控制信號選擇輸入的其中一個。 ![image](https://hackmd.io/_uploads/BkaLRy6ca.png) ## Step 2b: Datapath Components Register: * Register是一種存儲元件,類似於 D 觸發器,但具有 N 位元的輸入和輸出。 * 具有 Write Enable 輸入。 * Write Enable: * 當為否定(0)時,資料輸出不會變化。 * 當為斷言(1)時,資料輸出將變為輸入資料。 ![image](https://hackmd.io/_uploads/H17nAka5a.png) ### Storage Element: Register File 是一種存儲元素。以下是該 Register File 的主要特點: ![image](https://hackmd.io/_uploads/HyTRelp5T.png) 32 個 register : * 包含 32 個 register ,每個 register 都是 32 位元。 * 具有兩個 32 位元的輸出匯流排:busA 和 busB。 * 具有一個 32 位元的輸入匯流排:busW。 register 的選擇: * 通過不同的選擇信號,選擇特定的 register : * RA 選擇要放在 busA(資料)上的 register 。 * RB 選擇要放在 busB(資料)上的 register 。 * RW 在寫使能為 1 時,選擇要通過 busW(資料)進行寫入的 register 。 Clock input (CLK): * CLK 輸入僅在寫入操作期間起作用。 * 在讀取操作期間,行為類似於組合邏輯電路。 ### Storage Element: Memory 這裡將其理想化。以下是該 Memory 元件的主要特點: ![image](https://hackmd.io/_uploads/SyMmbl65T.png) Memory (理想化): * 包含一個輸入匯流排:Data In。 * 包含一個輸出匯流排:Data Out。 Word的選擇: * 通過不同的地址信號選擇特定的Word: * 通過地址選擇要放在 Data Out 上的Word。 * 當 Write Enable = 1 時,地址選擇要通過 Data In 匯流排進行寫入的 Memory Word。 Clock input (CLK): * CLK 輸入僅在寫入操作期間起作用。 * 在讀取操作期間,行為類似於組合邏輯模塊: * 地址有效 => 存取時間後,Data Out 有效。 * 無需讀取控制。 ## Step 3a: Datapath Assembly 資料路徑組合的步驟中,指令取得單元扮演著重要的角色。以下是指令取得單元的一些常見操作: ![image](https://hackmd.io/_uploads/rkZkzeaqa.png) 取得指令: * 從記憶體中讀取指令,通常是 mem[PC]。 更新程式計數器: * 對於順序執行的程式碼,更新程式計數器(PC)為 PC <- PC + 4。 * 對於分支(Branch)和跳躍(Jump)的情況,更新程式計數器為新的地址,例如 PC <- "Something else"。 ## Step 3b: Add and Subtract 在執行加法和減法的步驟中,以下是一個簡要的描述: ![image](https://hackmd.io/_uploads/HyUUMea9a.png) R[rd] <- R[rs] op R[rt](例如,add rd, rs, rt): * 這表示將寄存器 R[rs] 和 R[rt] 的值進行加法操作(op 可以是加法或減法),結果存儲在 R[rd] 中。 Ra, Rb, Rw 來自指令的 rs、rt 和 rd 欄位: * 指令的 rs 欄位選擇 Ra,指令的 rt 欄位選擇 Rb,指令的 rd 欄位選擇 Rw。 ALU 和 RegWrite: * 在解碼(decode)之後,由控制邏輯(control logic)確定 ALU 操作(加法或減法),以及是否寫入寄存器(RegWrite)。 ## Step 3c: Store/Load Operations 在執行存儲(Store)和載入(Load)操作的步驟中,以下是一個簡要的描述: ![image](https://hackmd.io/_uploads/ByLoGga9p.png) R[rt] <- Mem[R[rs] + SignExt[imm16]](例如,lw rt, rs, imm16): * 這表示將 R[rs] 中的值加上符號擴展的 imm16,得到的地址用於從記憶體中讀取一個值,並將該值存儲到 R[rt] 寄存器中。 ## Step 3d: Branch Operations 在執行分支(Branch)操作的步驟中,以下是一個簡要的描述: ![image](https://hackmd.io/_uploads/SyGlBl69T.png) beq rs, rt, imm16: * 這表示比較 R[rs] 和 R[rt] 的值,如果相等,則執行跳躍。否則,執行下一條指令。 Equal <- R[rs] == R[rt]: * 判斷 R[rs] 和 R[rt] 是否相等,結果存儲在 Equal 中。 Fetch inst. from memory: * 從記憶體中提取下一條指令。 * Calculate branch condition: * 計算分支條件,確定是否滿足跳躍的條件。 if (COND == 0) Calculate next inst. address: * 如果條件為假(COND == 0),則計算下一條指令的地址:PC <- PC + 4 + (SignExt(imm16) x 4)。 else PC <- PC +4: * 如果條件為真,則執行下一條指令:PC <- PC + 4。