控制表(control table)
一旦你接受控制單元的工作是「運算碼進、控制訊號出」,指定它最自然的方式就是一張表:每種指令類型一列,每個控制訊號一欄,每個格子填上該訊號應有的 0 或 1。那張格子就是控制表——它是一本完整的食譜,告訴你對每一種指令,究竟該扳動哪些資料路徑開關。
讀一列,就是讀一道指令的個性。R-type 那列可能是 ALUSrc = 0、MemRead = 0、MemWrite = 0、MemToReg = 0、RegWrite = 1、Branch = 0;載入那列是 ALUSrc = 1、MemRead = 1、MemWrite = 0、MemToReg = 1、RegWrite = 1、Branch = 0;儲存那列是 ALUSrc = 1、MemRead = 0、MemWrite = 1、RegWrite = 0、Branch = 0(MemToReg 是無關項,因為不寫回任何東西);分支那列是 ALUSrc = 0、RegWrite = 0、MemRead = 0、MemWrite = 0、Branch = 1。這張表本身就是控制單元的規格。
實際的硬體就由這張表產生。因為每個輸出欄都只是運算碼位元的一個布林函數,你可以把它直接實作成邏輯閘(硬接線控制),或緊湊地實作成可程式化邏輯陣列(PLA),或一塊內容就是表中各列的小型查表記憶體(更接近微程式控制)。誠實的提醒:無關項(寫成「X」)不是偷懶——它們讓邏輯化簡器能造出更小、更快的閘,因為對那道指令而言該值真的無所謂。
儲存與載入共用 ALUSrc = 1(兩者都算基底+偏移),但在三個欄位上不同:載入是 MemRead = 1、MemToReg = 1、RegWrite = 1;儲存是 MemWrite = 1、RegWrite = 0。兩列表,資料路徑的行為就完全不同。
每種指令類型一列、每個訊號一欄——這張表完整地指定了控制單元。
無關項「X」表示對那道指令而言,該訊號的值不會影響正確結果(例如儲存中的 MemToReg,因為沒有任何東西被寫回)。它是刻意的最佳化提示,不是疏漏。