邏輯設計與 HCL (Logic Design & HCL)

Overview Table

小節 主題 核心重點
4.2 前言 (p.408) 數位系統三要素 combinational logic 計算、memory elements 儲存、clock 控制更新時機
4.2.1 (p.409) 邏輯閘 (logic gates) AND/OR/NOT;HCL 用 &&||!(單一位元運算,非 C 的 &|~)
4.2.2 (p.410) 組合電路 + HCL bool 三大建構限制(輸入來源唯一、輸出不可對接、無環);bit equal、bit MUX
4.2.3 (p.412) 字組級電路 + HCL int 字組宣告為 int(不指定位寬);== 相等測試;case expression 描述 MUX;ALU
4.2.4 (p.416) 集合成員測試 iexpr in { iexpr1, ..., iexprk },簡化多重相等比較
4.2.5 (p.417) 記憶與時脈 clocked register(rising edge 載入)、register file(2 讀 1 寫)、data memory
Important

本節是 SEQ 與 PIPE 處理器設計的硬體語彙基礎:之後所有控制邏輯(見 04-Processor-Architecture/03-Sequential-SEQ-Implementation)都以 HCL 描述。HCL 只表達硬體設計的控制部分,運算集有限、無模組化;完整參考在 Web Aside arch:hcl(位於書頁 508)。

數位系統三要素與 HCL 定位 (p.408)

現代電路以電壓表示位元:邏輯 1 約 1.0 V(高電壓),邏輯 0 約 0.0 V(低電壓)。實作數位系統需要三種元件:

Aside:現代邏輯設計(p.409)

現今硬體多以 HDL(hardware description language) 文字描述(Verilog 語法似 C;VHDL 語法似 Ada),再由 logic synthesis(邏輯合成) 程式自動產生電路——類比於「手寫組合語言 → 高階語言 + 編譯器」的轉變。書中的 HCL 可經工具轉譯為 Verilog,搭配基本硬體單元的 Verilog 程式碼即可合成出真正可運作的 Y86-64 微處理器(Web Aside arch:vlog)。

4.2.1 邏輯閘 (Logic Gates) (p.409)

邏輯閘是數位電路的基本計算元件,輸出等於輸入位元值的某個 Boolean 函數(Figure 4.9)。

   AND                 OR                  NOT
a ──┐                a ──┐
    ├D──── out           ├)>─── out      a ──▷o── out
b ──┘                b ──┘
out = a && b         out = a || b        out = !a

4.2.2 組合電路與 HCL Boolean 運算式 (p.410-411)

把多個邏輯閘接成網路即得組合電路 (combinational circuit)。建構網路有三條限制:

  1. 每個邏輯閘輸入必須恰好接到下列之一:primary input(系統輸入)、某記憶元件的輸出、或某邏輯閘的輸出
  2. 兩個以上邏輯閘的輸出不可相接——否則可能把導線驅動到不同電壓,造成無效電壓或電路故障
  3. 網路必須無環 (acyclic)——迴圈會使電路計算的函數產生歧義

Bit equal(位元相等測試)(Figure 4.10):兩輸入同為 1(上方 AND)或同為 0(下方 AND)時輸出 1:

a ──┬───────────┤AND├──┐
    │     ┌─────┤   │  │
b ──┼─────┤            ├──[OR]── eq
    │     └─!───┤   │  │
    └────!──────┤AND├──┘

eq = (a && b) || (!a && !b)
bool eq = (a && b) || (!a && !b);

HCL 的 = 只是幫運算式取名字——不像 C 那樣「執行計算並把結果存入某記憶體位置」。

Bit MUX(單一位元多工器)(Figure 4.11):multiplexor 依控制訊號值,從一組資料訊號中選出一個。此處 s=1 輸出 a;s=0 輸出 b。上方 AND 閘在 s=0 時放行 b(其另一輸入為 !s),下方 AND 閘在 s=1 時放行 a:

s ──┬──!───┤AND├──┐
b ──┼──────┤   │  │
    │             ├──[OR]── out
    │   ┌──┤AND├──┘
a ──┴───┴──┘

out = (s && a) || (!s && b)
bool out = (s && a) || (!s && b);

組合電路 vs. C 邏輯運算式的三大差異(p.411):

面向 組合電路 C 邏輯運算式
求值時機 輸出持續回應輸入變化(輸入變 → 延遲後輸出變) 只在程式執行遇到該運算式時才求值
運算元 只操作位元值 0 與 1 引數可為任意整數(0 為 false,非 0 為 true)
部分求值 無短路求值,閘只是回應輸入變化 有短路求值:如 (a && !a) && func(b,c)func 不會被呼叫

4.2.3 字組級組合電路與 HCL 整數運算式 (p.412-416)

實務電路多操作資料字組 (data words)——代表整數或某種控制樣式的一組位元訊號。處理器設計中字組寬度介於 4 到 64 位元(整數、位址、指令碼、暫存器識別碼)。

字組相等測試(Figure 4.12):以 64 個 bit-equal 電路逐位比較,輸出再以 AND 閘合併——若且唯若 A 的每一位元等於 B 的對應位元時輸出 1:

b63,a63 ─[Bit equal]─ eq63 ─┐
b62,a62 ─[Bit equal]─ eq62 ─┤             B ══╗
   ...        ...           ├─[AND]── Eq      ║[ = ]---→ Eq(單位元,虛線)
b1, a1  ─[Bit equal]─ eq1  ─┤             A ══╝
b0, a0  ─[Bit equal]─ eq0  ─┘
(a) 位元級實作                 (b) 字組級抽象
bool Eq = (A == B);

語法沿用 C 慣例:= 為賦值(命名),== 為相等運算子;引數 A、B 型別為 int

字組級 MUX(Figure 4.13):由 64 個結構類似 bit MUX 的子電路組成;實作上 !s 只產生一次、在每個位元位置重複使用,以減少反相器 (inverter) 數量。

Case expression(HCL 的多工器描述)(p.414)

多工功能在 HCL 以 case expression 描述,一般形式:

[
    select_1 : expr_1;
    select_2 : expr_2;
       ...
    select_k : expr_k;
]

字組級 MUX 的 HCL:

word Out = [
    s: A;
    1: B;
];
HCL case 與真實硬體的落差

真實硬體 MUX 的控制訊號必須互斥(如 Figure 4.13 的 s!s)。HCL 允許非互斥條件只是為了可讀性;logic synthesis 程式轉成硬體時必須分析選擇運算式、解決可能的衝突,確保只有第一個符合的 case 生效。

4-way MUX(Figure 4.14):以 s1 s0 兩控制位元(視為 2 位元二進位數)從 A、B、C、D 選一:

s1 ─┐
s0 ─┤
D ──┤
C ──┤ MUX4 ──→ Out4
B ──┤
A ──┘
word Out4 = [
    !s1 && !s0 : A; # 00
    !s1        : B; # 01
    !s0        : C; # 10
    1          : D; # 11
];

MIN3(三字組取最小值)(p.415):

word Min3 = [
    A <= B && A <= C : A;
    B <= A && B <= C : B;
    1                : C;
];

利用循序求值特性,第二條可化簡為 B <= C : B;(全式只需 3 次比較)——第一條沒中就代表 A 不是最小值(Practice Problem 4.11)。

ALU(arithmetic/logic unit)(Figure 4.15,p.416):重要的組合電路,三個輸入——兩個資料輸入 A、B 與一個控制輸入;控制值決定執行哪種算術/邏輯運算:

      0             1             2             3
Y ──┤A     │   Y ──┤A     │   Y ──┤A     │   Y ──┤A     │
    │ ALU  ├X+Y    │ ALU  ├X-Y    │ ALU  ├X&Y    │ ALU  ├X^Y
X ──┤B     │   X ──┤B     │   X ──┤B     │   X ──┤B     │

4.2.4 集合成員測試 (Set Membership) (p.416-417)

處理器設計常需把一個訊號與多個可能匹配值比較(典型:判斷 icode 是否屬於某類指令碼)。例:由 2 位元訊號 code 產生 4-way MUX 的控制位元 s1、s0:

code ──►[Control]──► s1
                 └─► s0  ──► 控制 MUX4 選 A/B/C/D

用相等測試表達:

bool s1 = code == 2 || code == 3;
bool s0 = code == 1 || code == 3;

集合成員測試改寫更精簡(s1 = 1 當 code ∈ {2,3};s0 = 1 當 code ∈ {1,3}):

bool s1 = code in { 2, 3 };
bool s0 = code in { 1, 3 };

一般形式:iexpr in { iexpr_1, iexpr_2, ..., iexpr_k }——被測值與候選匹配值皆為整數運算式

4.2.5 記憶與時脈 (Memory and Clocking) (p.417-420)

組合電路不儲存任何資訊,只是對輸入訊號產生對應的函數輸出。要建立循序電路 (sequential circuit)——有狀態、並對狀態進行運算的系統——必須引入儲存位元的裝置。所有儲存裝置由單一 clock(週期訊號)控制新值的載入時機。兩類記憶裝置:

裝置 儲存內容 定址方式 Y86-64 中的例子
Clocked register(register) 單一位元或字組 無(直接接線) PC、CC(condition codes)、Stat
Random access memory(memory) 多個字組 以位址選字組 register file(15 個程式暫存器 %rax–%r14)、data memory;虛擬記憶體系統亦屬之
「register」的兩種意義(p.417)

  • Hardware register(硬體暫存器):以輸入/輸出導線直接接到電路其餘部分的儲存元件
  • Program register(程式暫存器):CPU 中一小組可定址字組,位址為 register ID,一般存放於 register file

例外:硬體有時會把字組直接從一個指令傳遞給另一個指令,略過「先寫再讀 register file」的延遲(即 forwarding,見 04-Processor-Architecture/05-Pipelined-PIPE-Implementation-and-Hazards)。

Clocked register 的運作(Figure 4.16)

        State = x                  rising          State = y
Input=y ──►[ x ]──► Output=x      ─clock─►  ──►[ y ]──► Output=y
(clock 低電位期間:輸出鎖定為 x)            (上升緣:輸入 y 載入成新狀態)

Register file(暫存器檔案)(p.418-419)

         valA ◄──┐
srcA ───────► A  │
                 │  Register    W ◄─── dstW(寫入位址)
         valB ◄──┤    file        ◄─── valW(寫入資料)
srcB ───────► B  │
                 └────┬────
                    clock
  讀取埠 A、B(位址 srcA/srcB,輸出 valA/valB);寫入埠 W
同時讀寫同一暫存器

若同一 register ID 同時用於讀取埠與寫入埠,則 clock 上升時讀取埠的資料輸出會從舊值轉變 (transition) 為新值。把 register file 納入處理器設計時必須把這個性質考慮進去(p.419)。

Data memory(資料記憶體)(p.419-420)

             ┌──────────┐──► data out
 error ◄─────┤          │
 read  ─────►│   Data   │
 write ─────►│  memory  │◄── clock
             └──────────┘
         address ▲   ▲ data in
Aside:真實記憶體設計(p.420)

真實微處理器的記憶體系統遠比此複雜——多種 RAM、非揮發性記憶體或磁碟,以及各種軟硬體管理機制(詳見 06-Memory-Hierarchy/02-Locality-and-Memory-Hierarchy)。本節的簡化模型仍適用於小型系統,並提供「處理器—記憶體介面」的有效抽象。

Exam/Test Patterns

情境/關鍵字 答案
HCL 為何用 &&/||/! 而非 &/|/~? 邏輯閘操作單一位元,不是整個字組
寫出 XOR 的 HCL(對照 Problem 4.9) bool xor = (!a && b) || (a && !b);且 xor 與 eq 互為補數(一個為 1 時另一個必為 0)
用 64 個 XOR 電路做字組相等(對照 Problem 4.10) XOR 輸出是 bit-equal 的補數;用 DeMorgan 定律以 OR+NOT 取代 AND:所有 !eq_i 進 OR 再整體取 NOT
組合電路網路的三條限制 每個閘輸入恰接一個來源;閘輸出不可相接;必須無環 (acyclic)
HCL case expression 與 C switch 的差異 選擇條件不需互斥;依序求值、取第一個為 1 的 case;default 寫 1 :
MIN3 只用 3 次比較(對照 Problem 4.11) 第二條化簡為 B <= C : B;——第一條未命中即表示 A 非最小
求三數中位數(對照 Problem 4.12) MIN3 的變形:每條 case 檢測「該值介於另兩值之間」
ALU 減法時運算元順序? A 輸入被 B 輸入減(輸出 X − Y,A 接 Y、B 接 X),配合 subq rA, rB 的引數順序;控制值 = Y86-64 function code
register file 的 dstW = 0xF? 不寫入任何程式暫存器
clock 低電位期間輸入改變,暫存器輸出? 維持不變;只有 clock 上升緣才把輸入載入為新狀態
同時讀寫同一 register ID clock 上升時讀取埠輸出從舊值轉變為新值
register file 是組合電路嗎? 不是(有內部儲存),但讀取行為像組合邏輯
data memory 的 error 訊號如何產生? 組合邏輯產生——邊界檢查只是位址輸入的函數,不需儲存狀態
C 運算式 (a && !a) && func(b,c) 對比電路 C 有短路求值(func 不被呼叫);組合邏輯無部分求值,閘只回應輸入
Y86-64 用 clocked register 存哪些狀態? PC、CC、Stat