Outline — click to expand大綱 — 點擊展開アウトライン — クリックで展開
1. Synthesis in the Flow1. 合成在設計流程中的位置1. 設計フローの中の合成
2. Supported Constructs2. 支援的語法2. サポートされる構文
3. Logic Minimization3. 邏輯最小化3. 論理最小化
4. Synthesizable Descriptions4. 可合成的描述方式4. 合成可能な記述
5. Multiplexed Datapaths5. 多工資料路徑5. マルチプレクス・データパス
6. Unwanted Latches6. 非預期的閂鎖6. 意図しないラッチ
7. Combinational Loops7. 組合邏輯迴路7. 組合せループ
8. Priority Structures8. 優先權結構8. 優先順位構造
9. Buses and Tri-States9. 匯流排與三態9. バスとトライステート
10. Resource Sharing10. 資源共享10. リソース共有
11. Summary11. 總結11. まとめ
← DCIC Study Guides← DCIC 自學指南← DCIC 学習ガイド
EE5733 Digital Communication IC Design · Lecture 4 (Part 2)EE5733 數位通訊積體電路設計 · 第 4 講(下)EE5733 デジタル通信 IC 設計 · 第4回(後編)

Synthesis of Combinational Logic組合邏輯的合成組合せ論理の合成

Synthesizable constructs, logic minimization, latch-free case / if, combinational loops, priority structures, tri-state buses and resource sharing — a self-study guide可合成語法、邏輯最小化、不產生閂鎖的 case / if、組合邏輯迴路、優先權結構、三態匯流排與資源共享 — 組合邏輯合成自學指南合成可能な構文、論理最小化、ラッチを生まない case / if、組合せループ、優先順位構造、トライステート・バス、リソース共有 — 組合せ論理合成の自学ガイド

Contents目錄目次

  1. Logic Synthesis in the Design Flow設計流程中的邏輯合成設計フローにおける論理合成
  2. Synthesizable and Un-synthesizable Constructs可合成與不可合成的語法合成可能な構文と合成不可能な構文
  3. Logic Minimization邏輯最小化論理最小化
  4. Synthesizable Descriptions of Combinational Logic組合邏輯的可合成描述方式組合せ論理の合成可能な記述
  5. Control Logic for Multiplexed Datapaths多工資料路徑的控制邏輯マルチプレクス・データパスの制御論理
  6. Unwanted Latches非預期的閂鎖意図しないラッチ
  7. Combinational Loops (Mux with Feedback)組合邏輯迴路(含回授的多工器)組合せループ(帰還つきマルチプレクサ)
  8. Priority Structures, Encoders and Decoders優先權結構、編碼器與解碼器優先順位構造、エンコーダとデコーダ
  9. Buses and Tri-State Buffers匯流排與三態緩衝器バスとトライステート・バッファ
  10. Resource Sharing資源共享リソース共有
  11. Summary and Exam Checklist總結與考前檢查表まとめと試験前チェックリスト

1. Logic Synthesis in the Design Flow1. 設計流程中的邏輯合成1. 設計フローにおける論理合成

1.1 HDL-based design flow1.1 以 HDL 為主的設計流程1.1 HDL ベースの設計フロー

The designer writes an HDL behavioral model (design entry) and checks it with functional simulation. Physical optimization and implementation then map it to a target technology, after which timing simulation verifies the implemented design against the original intent.設計者先寫出 HDL 行為模型(design entry),再以功能模擬檢查。接著由實體最佳化與實作把它映射到目標製程,最後以時序模擬驗證實作結果是否仍符合原始設計意圖。設計者はまず HDL の動作モデル(design entry)を書き、機能シミュレーションで確認する。続いて物理最適化と実装がそれをターゲット・テクノロジへマッピングし、最後にタイミング・シミュレーションで実装結果が当初の意図どおりかを検証する。

Target目標製程ターゲットImplementation steps實作步驟実装の手順
PLDPartition, map, interconnect分割、映射、連接分割・マッピング・配線
FPGA / masked gate arrayFPGA / 光罩式閘陣列FPGA / マスク・ゲートアレイMap, place, route映射、佈局、繞線マッピング・配置・配線
Standard cells標準單元スタンダードセルPlace, route佈局、繞線配置・配線

1.2 Simulation-based verification1.2 以模擬為基礎的驗證1.2 シミュレーションによる検証

One test bench drives both the Verilog behavioral description and the gate-level description produced by synthesis. A stimulus generator feeds both, a response comparator compares their outputs, and a check signal flags mismatches. This is the post-synthesis check that the netlist behaves like the RTL.同一個測試平台(test bench)同時驅動 Verilog 行為描述與合成產生的閘層描述。激勵產生器把相同輸入餵給兩者,響應比較器比對兩邊的輸出,check 訊號則標示出不一致之處。這就是合成後用來確認 netlist 行為與 RTL 相同的檢查。一つのテストベンチが、Verilog の動作記述と合成で生成されたゲートレベル記述の両方を駆動する。刺激生成器が同じ入力を両者に与え、応答比較器が出力を突き合わせ、check 信号が不一致を知らせる。これが、ネットリストが RTL と同じ振る舞いをするかを確かめる合成後のチェックである。

Verilog behavioralVerilog 行為Verilog 動作description描述記述 Logic synthesis邏輯合成論理合成 Gate-level閘層ゲートレベルdescription描述記述 Stimulus generator激勵產生器刺激生成器 Test bench (response comparator)測試平台(響應比較器)テストベンチ(応答比較器) Check signalcheck 訊號check 信号
Test bench for post-synthesis design verification.用於合成後設計驗證的測試平台。合成後の設計検証に用いるテストベンチ。

1.3 What logic synthesis does1.3 邏輯合成做了什麼1.3 論理合成は何をするか

Logic synthesis operates on Boolean equations and produces optimized combinational logic, in three stages:邏輯合成以布林方程式為操作對象,分三個階段產生最佳化後的組合邏輯:論理合成はブール式を対象に動作し、三つの段階を経て最適化された組合せ論理を生成する。

Engine引擎エンジンInput輸入入力Output輸出出力
Translation轉譯変換Behavioral description行為描述動作記述Two-level logic functions兩層邏輯函數2 段の論理関数
Optimization最佳化最適化Two-level functions兩層函數2 段の関数Optimized multi-level logic (technology independent)最佳化的多層邏輯(與製程無關)最適化された多段論理(テクノロジ非依存)
Mapping映射マッピングOptimized logic + technology library最佳化後的邏輯 + 製程元件庫最適化された論理 + テクノロジ・ライブラリTechnology implementation (cells)製程實作(cell)テクノロジ実装(セル)
Key points (click to expand)重點整理(點擊展開)要点(クリックで展開)
  • Synthesis = translation (HDL → Boolean equations) → optimization (technology independent) → mapping (apply the cell library).合成 = 轉譯(HDL → 布林方程式)→ 最佳化(與製程無關)→ 映射(套用 cell library)。合成=変換(HDL → ブール式)→ 最適化(テクノロジ非依存)→ マッピング(セルライブラリの適用)。
  • After synthesis, run the RTL and the gate-level netlist under the same test bench and compare the outputs to confirm the behavior matches.合成後要用同一個 test bench 同時跑 RTL 與 gate-level netlist,比對輸出,確認行為一致。合成後は同じテストベンチで RTL とゲートレベル・ネットリストを走らせ、出力を比較して振る舞いが一致することを確認する。
  • The final result depends on the synthesis tool and the constraints (area, delay, power), so the same source code can give different circuits.最終結果取決於合成工具與限制條件(面積、延遲、功耗),同一份程式碼可能得到不同電路。最終結果は合成ツールと制約条件(面積・遅延・電力)に左右され、同じソースでも異なる回路になりうる。

2. Synthesizable and Un-synthesizable Constructs2. 可合成與不可合成的語法2. 合成可能な構文と合成不可能な構文

2.1 Commonly supported (synthesizable)2.1 一般都支援(可合成)2.1 一般にサポートされる(合成可能)

Structure結構構造
  • Module declaration; ports input, output, inout模組宣告;埠 input、output、inoutモジュール宣言、ポート input・output・inout
  • Port binding by name or by position依名稱或依位置做埠連接名前による接続と位置による接続
  • Parameter declaration參數宣告パラメータ宣言
  • Module, macromodule and primitive instantiationmodule、macromodule 與基本元件的實例化module・macromodule・プリミティブのインスタンス化
Data types資料型別データ型
  • Nets: wire, tri, wand, wor, supply0, supply1連線型別:wire, tri, wand, wor, supply0, supply1ネット型:wire, tri, wand, wor, supply0, supply1
  • Registers: reg, integer暫存型別:reg、integerレジスタ型:reg・integer
  • Binary, decimal, octal, hex literals二進位、十進位、八進位與十六進位常數2 進・10 進・8 進・16 進のリテラル
  • Scalar and vector nets; subranges on the RHS純量與向量連線;右側可取部分位元範圍スカラ/ベクタのネット、右辺での部分ビット指定
Expressions運算式式
  • Continuous assignments連續指定連続代入
  • Shift, conditional (nested), concatenation位移、條件運算(可巢狀)、串接シフト、条件演算(入れ子可)、連接
  • Arithmetic, bitwise, reduction, logical, relational算術、位元、歸約、邏輯與關係運算算術・ビット単位・リダクション・論理・関係の各演算
Procedural程序性敘述手続き記述
  • begin ... end, if / else, case, casex, casez, defaultbegin ... end、if / else、case, casex, casez, defaultbegin ... end・if / else・case, casex, casez, default
  • for loops, disable of a procedural blockfor 迴圈、對程序區塊使用 disablefor ループ、手続きブロックの disable
  • assign ... deassign (PCA)assign ... deassign(程序性連續指定 PCA)assign ... deassign(手続き連続代入 PCA)
  • task* and functiontask* 與 functiontask* と function

* No timing or event control allowed inside a synthesizable task.* 可合成的 task 內不得出現時序控制或事件控制。* 合成可能な task の中では時間制御・イベント制御は使えない。

2.2 Not generally supported (un-synthesizable)2.2 一般不支援(不可合成)2.2 一般にサポートされない(合成不可)

Group類別分類Constructs語法構文
Simulation control模擬控制シミュレーション制御initial, event, fork ... join, forever, while, wait, repeat, force ... release
Timing時序タイミングIntra-assignment timing control, delay specifications, specify ... endspecify, $time指定式內部的時序控制、延遲設定、specify ... endspecify、$time代入内の時間制御、遅延指定、specify ... endspecify、$time
Switch level / strength開關層級/驅動強度スイッチレベル/駆動強度cmos, rcmos, nmos, pmos, rnmos, rpmos, tran, tranif0, tranif1, rtran, rtranif0, rtranif1, pullup, pulldown, weak0, weak1, strong0, strong1, pull0, pull1, small, medium, large, scalared, vectored
Other其他その他Case equality === / !==, defparam, global variables, a variable used as a bit select on the LHS, sequential UDP (primitive ... table with state), system tasks $keywordcase 等號 === / !==、defparam、全域變數、左側以變數做位元選取、含狀態的序向 UDP(primitive ... table)、系統任務 $keywordケース等価 === / !==、defparam、グローバル変数、左辺で変数によるビット選択、状態をもつ順序 UDP(primitive ... table)、システムタスク $keyword
Tool dependence工具相依性ツール依存

These lists are the lecture's "generally supported" view. Modern tools accept some items (e.g. while or repeat with a constant bound, variable bit select on the LHS), but for this course and its exam treat them as listed.這些清單是課堂上「一般支援」的觀點。現代工具其實接受其中一部分(例如界限為常數的 while 或 repeat、左側以變數做位元選取),但在本課程與考試中請依清單認定。これらの一覧は講義でいう「一般にサポートされる」範囲である。最近のツールは一部を受け付ける(上限が定数の while や repeat、左辺の変数ビット選択など)が、本講義と試験ではこの一覧どおりに扱うこと。

Practice 1 — Synthesizable or not?練習 1 — 可不可合成?演習 1 — 合成できるか?

Problem: Classify each: (a) assign y = s ? a : b; (b) always @(a) #5 y = a; (c) if (a === 1'bx) (d) a function with a complete case (e) initial q = 0; (f) for (k = 0; k < 4; k = k + 1) (g) a task containing @(posedge clk).題目:判斷下列各項:(a) assign y = s ? a : b; (b) always @(a) #5 y = a; (c) if (a === 1'bx) (d) 具有完整 case 的 function (e) initial q = 0; (f) for (k = 0; k < 4; k = k + 1) (g) 內含 @(posedge clk) 的 task。問題:次のそれぞれを分類せよ。(a) assign y = s ? a : b; (b) always @(a) #5 y = a; (c) if (a === 1'bx) (d) 完全な case をもつ function (e) initial q = 0; (f) for (k = 0; k < 4; k = k + 1) (g) @(posedge clk) を含む task。

Click to reveal solution點擊展開解答クリックで解答を表示

Synthesizable: (a), (d), (f). Not synthesizable: (b) delay control, (c) case equality === (x has no hardware meaning), (e) initial, (g) task with event control. For (b) most tools ignore the #5 with a warning, which creates a simulation/synthesis mismatch — still avoid it.可合成:(a)、(d)、(f)。不可合成:(b) 延遲控制、(c) case 等號 ===(x 在硬體上沒有對應意義)、(e) initial、(g) 含事件控制的 task。至於 (b),多數工具會忽略 #5 並發出警告,這會造成模擬與合成不一致 — 還是別寫。合成可能:(a)、(d)、(f)。合成不可:(b) 遅延制御、(c) ケース等価 ===(x にはハードウェア上の意味がない)、(e) initial、(g) イベント制御を含む task。(b) については多くのツールが警告つきで #5 を無視するが、それはシミュレーションと合成の不一致を生むので、やはり書かないこと。

3. Logic Minimization3. 邏輯最小化3. 論理最小化

3.1 Two-level vs multi-level3.1 兩層 vs 多層3.1 2 段 vs 多段

Synthesis target: minimize area, delay or power.合成的目標:最小化面積、延遲或功耗。合成の目標は面積・遅延・電力の最小化である。

3.2 The five multi-level operations3.2 五種多層最小化運算3.2 多段最小化の 5 つの操作

Operation運算操作Before之前変形前After之後変形後
Decomposition
one function → new sub-functions
分解 Decomposition
一個函數 → 新的子函數
分解 Decomposition
一つの関数 → 新しい部分関数
$F = abc + abd + a'c'd' + b'c'd'$$X = ab,\ Y = c + d$
$F = XY + X'Y'$
Extraction
common sub-expressions of several functions
抽取 Extraction
多個函數的共同子運算式
抽出 Extraction
複数の関数に共通する部分式
$F = (a+b)cd + e$
$G = (a+b)e'$
$H = cde$
$X = a+b,\ Y = cd$
$F = XY + e,\ G = Xe',\ H = Ye$
Factoring
SOP → product of sums form
因式分解 Factoring
積之和 → 和之積的形式
因数分解 Factoring
積和形 → 和積形
$F = ac + ad + bc + bd + e$$F = (a+b)(c+d) + e$
Substitution
reuse an existing function
代換 Substitution
重用既有的函數
置換 Substitution
既存の関数を再利用する
$F = a + b + c,\ G = a + b$$F = G + c$
Elimination
flatten (inverse of substitution)
消去 Elimination
攤平(代換的反向操作)
消去 Elimination
平坦化(置換の逆操作)
$F = Ga + G'b,\ G = c + d$$F = ac + ad + bc'd'$
Check the decomposition驗算:分解確認:分解
$abc + abd = ab(c+d) = XY$.
$a'c'd' + b'c'd' = (a' + b')\,c'd' = (ab)'\,(c+d)' = X'Y'$ by De Morgan.(De Morgan 定律)。(ド・モルガンの法則による)。
So 所以 したがって $F = XY + X'Y' = X \odot Y$ (XNOR of $X$ and $Y$) — 4 product terms with 12 literals become 2 small sub-functions and one XNOR.(即 $X$ 與 $Y$ 的 XNOR)— 原本 4 個乘積項、12 個 literal,變成 2 個小子函數加一個 XNOR。($X$ と $Y$ の XNOR)— 12 リテラルの積項 4 個が、小さな部分関数 2 個と XNOR 1 個になる。
Check the elimination驗算:消去確認:消去
$Ga = (c+d)a = ac + ad$.
$G'b = (c+d)'b = c'd'b$.
$F = ac + ad + bc'd'$ — one level fewer, more literals. — 少一層邏輯,但 literal 變多。 — 段数は 1 つ減るが、リテラルは増える。
Practice 2 — Factor, then eliminate練習 2 — 先因式分解,再消去演習 2 — 因数分解してから消去する

Problem: (a) Factor $F = ace + ade + bce + bde + f$. (b) Eliminate $G$ from $F = Gx + G'y$ with $G = ab$. (c) Count literals before and after each.題目:(a) 對 $F = ace + ade + bce + bde + f$ 做因式分解。(b) 在 $G = ab$ 的條件下,把 $F = Gx + G'y$ 中的 $G$ 消去。(c) 分別數出兩題前後的 literal 數。問題:(a) $F = ace + ade + bce + bde + f$ を因数分解せよ。(b) $G = ab$ として $F = Gx + G'y$ から $G$ を消去せよ。(c) それぞれについて前後のリテラル数を数えよ。

Click to reveal solution點擊展開解答クリックで解答を表示

(a) $F = (a+b)(c+d)e + f$. Literals: 13 → 6.(a) $F = (a+b)(c+d)e + f$。literal 數:13 → 6。(a) $F = (a+b)(c+d)e + f$。リテラル数は 13 → 6。

(b) $F = abx + (ab)'y = abx + a'y + b'y$. Literals in $F$: 4 (plus 2 in $G$) → 7.(b) $F = abx + (ab)'y = abx + a'y + b'y$。$F$ 中的 literal:4(再加上 $G$ 的 2 個)→ 7。(b) $F = abx + (ab)'y = abx + a'y + b'y$。$F$ のリテラル数は 4($G$ の 2 個を加える)→ 7。

(c) Factoring shrinks area; elimination usually grows literal count but removes a logic level, which helps delay. Synthesis applies them iteratively against the area/delay cost.(c) 因式分解縮小面積;消去通常會讓 literal 變多,但少一層邏輯,對延遲有利。合成工具會依面積/延遲的成本函數反覆交替使用這兩種操作。(c) 因数分解は面積を縮め、消去はリテラルを増やす代わりに論理段数を 1 つ減らすので遅延に効く。合成ツールは面積/遅延のコストを見ながら、これらを繰り返し適用する。

4. Synthesizable Descriptions of Combinational Logic4. 組合邏輯的可合成描述方式4. 組合せ論理の合成可能な記述

The following map successfully to circuits: a netlist of Verilog primitives, combinational UDPs, continuous assignments, behavioral always blocks, functions, tasks without delay or event control, and interconnected modules of these. All of §4.1 – §4.6 describe the same function and synthesize to the same two cells.以下幾種寫法都能順利映射成電路:Verilog 基本元件組成的 netlist、組合邏輯 UDP、連續指定、行為式 always 區塊、function、不含延遲或事件控制的 task,以及由這些互連而成的模組。§4.1 – §4.6 描述的其實是同一個函數,也合成出同樣的兩顆 cell。次のものはいずれも回路へ問題なくマッピングされる。Verilog プリミティブのネットリスト、組合せ UDP、連続代入、動作レベルの always ブロック、function、遅延やイベント制御を含まない task、そしてそれらを相互接続したモジュールである。§4.1 – §4.6 はすべて同じ関数を記述しており、合成結果も同じ 2 つのセルになる。

Running example貫穿全節的範例全体を通す例題 $$y = \overline{\text{enable}\cdot(x_1 + x_2)\cdot(x_3 + x_4)}$$

4.1 Netlist of primitives4.1 基本元件組成的 netlist4.1 プリミティブのネットリスト

module or_nand_1 (enable, x1, x2, x3, x4, y);
  input  enable, x1, x2, x3, x4;
  output y;
  wire   w1, w2, w3;
  or   (w1, x1, x2);
  or   (w2, x3, x4);
  or   (w3, x3, x4);              // redundant
  nand (y, w1, w2, w3, enable);
endmodule

Synthesis removes the redundant w3 gate and maps the rest to one oai22 (OR-AND-invert) cell followed by a nand2 with enable.合成會移除多餘的 w3 閘,其餘映射成一顆 oai22(OR-AND-invert)cell,後面再接一個吃 enable 的 nand2。合成は冗長な w3 のゲートを取り除き、残りを oai22(OR-AND-invert)セル 1 個と、enable を受ける nand2 にマッピングする。

x1x2x3x4 enabley oai22_a nand2i_a
Synthesized circuit: oai22 = NOT((x1+x2)(x3+x4)), then nand2 with an inverted input gives y = NOT(enable · (x1+x2)(x3+x4)).合成後的電路:oai22 = NOT((x1+x2)(x3+x4)),再經一個輸入反相的 nand2,得到 y = NOT(enable · (x1+x2)(x3+x4))。合成後の回路:oai22 = NOT((x1+x2)(x3+x4))、続く入力反転つき nand2 により y = NOT(enable · (x1+x2)(x3+x4)) が得られる。
Note注意注意

Final synthesis results depend on the synthesis tool and its cell library.最終的合成結果會隨合成工具及其 cell library 而不同。最終的な合成結果は、合成ツールとそのセルライブラリに依存する。

4.2 Combinational UDP4.2 組合邏輯 UDP4.2 組合せ UDP

primitive boolean_eqs (y, a, b, c);
  output y;
  input  a, b, c;
  table
  //  a b c : y
      0 1 ? : 1;
      0 0 ? : 0;
      1 ? 1 : 1;
      1 ? 0 : 0;
  endtable
endprimitive

Reading the table: $a = 0 \Rightarrow y = b$, $a = 1 \Rightarrow y = c$, i.e. $y = a'b + ac$ — a 2:1 mux, synthesized as two ANDs and an OR.讀這張表:$a = 0 \Rightarrow y = b$、$a = 1 \Rightarrow y = c$,也就是 $y = a'b + ac$ — 一個 2:1 多工器,合成成兩個 AND 加一個 OR。表を読むと $a = 0 \Rightarrow y = b$、$a = 1 \Rightarrow y = c$、すなわち $y = a'b + ac$ である — 2:1 マルチプレクサであり、AND 2 個と OR 1 個に合成される。

4.3 Continuous assignment4.3 連續指定4.3 連続代入

module or_nand_2 (enable, x1, x2, x3, x4, y);
  input  enable, x1, x2, x3, x4;
  output y;
  assign y = ~(enable & (x1 | x2) & (x3 | x4));
endmodule

4.4 Rules for a combinational always block4.4 組合邏輯 always 區塊的規則4.4 組合せ always ブロックの規則

Three rules三條規則三つの規則
  1. Every input must be in the event control expression, explicitly or implicitly. Inputs = operands on the RHS of assignments + control signals whose transitions affect the target registers.所有輸入都必須出現在事件控制運算式裡,明寫或隱含皆可。這裡的輸入 = 指定式右側的運算元 + 其轉態會影響目標暫存器的控制訊號。すべての入力が、明示的にせよ暗黙にせよイベント制御式に含まれていなければならない。ここでいう入力とは、代入の右辺に現れるオペランドと、その遷移が対象レジスタに影響する制御信号である。
  2. Failing rule 1 produces unwanted latches (lecture wording) — or at least a simulation/synthesis mismatch.違反規則 1 會產生非預期的閂鎖(投影片的說法)— 至少也會造成模擬與合成不一致。規則 1 を満たさないと意図しないラッチが生じる(講義の言い方)— 少なくともシミュレーションと合成の不一致になる。
  3. The target of an assignment must not be an operand on the RHS of any assignment in the block → otherwise an infinite (combinational) loop.指定式的目標不可以同時出現在該區塊內任何指定式的右側 → 否則就形成無窮的(組合邏輯)迴路。代入の対象が、同じブロック内のどの代入の右辺にも現れてはならない → さもないと無限の(組合せ)ループになる。
Aside: what does an incomplete sensitivity list really do? (click to expand)補充:敏感列表不完整到底會怎樣?(點擊展開)補足:感度リストが不完全だと実際どうなるか(クリックで展開)

Most modern synthesis tools actually ignore the sensitivity list: they build the combinational logic from the body of the block and issue a warning. What really creates a latch is a path with no assignment on it (see §6). An incomplete sensitivity list does still make the RTL simulation hold the old value like a latch, so it no longer matches the synthesized netlist. Since Verilog-2001 the advice is simply to write always @* and be done with it.大多數現代合成工具其實會忽略敏感列表,直接依程式內容產生組合邏輯並發出警告;真正產生 latch 的原因是「某些路徑沒有賦值」(見第 6 節)。但敏感列表不完整會讓 RTL 模擬像 latch 一樣保持舊值,與合成後的 netlist 不一致。Verilog-2001 起建議直接寫 always @*,一次解決。最近の合成ツールの多くは感度リストを無視し、ブロック本体の記述からそのまま組合せ論理を作って警告を出す。本当にラッチを生むのは「代入されない経路がある」ことである(第 6 節)。ただし感度リストが不完全だと、RTL シミュレーションはラッチのように古い値を保持し、合成後のネットリストと一致しなくなる。Verilog-2001 以降は always @* と書けば一度で片がつく。

4.5 always block examples4.5 always 區塊範例4.5 always ブロックの例

Example 1 — or_nand_3範例 1 — or_nand_3例 1 — or_nand_3

module or_nand_3 (enable, x1, x2, x3, x4, y);
  input  enable, x1, x2, x3, x4;
  output y;
  reg    y;

  always @ (enable or x1 or x2 or x3 or x4)
    begin
      y = ~(enable & (x1 | x2) & (x3 | x4));
    end
endmodule

Same oai22 + nand2 circuit as §4.1.與 §4.1 相同的 oai22 + nand2 電路。§4.1 と同じ oai22 + nand2 の回路になる。

Example 2 — 4-input AND with a loop and disable範例 2 — 用迴圈與 disable 寫的 4 輸入 AND例 2 — ループと disable による 4 入力 AND

module and4_behav (y, x_in);
  parameter word_length = 4;
  input  [word_length - 1:0] x_in;
  output y;
  reg    y;
  integer k;

  always @ x_in
    begin: check_for_0
      y = 1;
      for (k = 0; k <= word_length - 1; k = k + 1)
        if (x_in[k] == 0)
          begin
            y = 0;
            disable check_for_0;      // early exit
          end
    end
endmodule

The loop has a constant bound so it unrolls; the disable only shortens simulation. Result: a single 4-input AND gate.迴圈的界限是常數,所以會被展開;disable 只是縮短模擬時間。結果就是一個 4 輸入的 AND 閘。ループの上限は定数なので展開される。disable はシミュレーションを短くするだけである。結果は 4 入力 AND ゲート 1 個になる。

Example 3 — comparator (alternative algorithm)範例 3 — 比較器(另一種演算法)例 3 — 比較器(別のアルゴリズム)

module comparator (a, b, a_gt_b, a_lt_b, a_eq_b);
  parameter size = 2;
  input  [size:1] a, b;
  output a_gt_b, a_lt_b, a_eq_b;
  reg    a_gt_b, a_lt_b, a_eq_b;
  integer k;

  always @ (a or b)
    begin: compare_loop
      for (k = size; k > 0; k = k - 1)     // MSB first
        begin
          if (a[k] != b[k])
            begin
              a_gt_b = a[k];
              a_lt_b = ~a[k];
              a_eq_b = 0;
              disable compare_loop;
            end  // if
        end      // for loop
      a_gt_b = 0;
      a_lt_b = 0;
      a_eq_b = 1;
    end          // compare_loop
endmodule

Scanning from the MSB, the first differing bit decides: if a[k] = 1 then $a > b$. Synthesis builds XOR/XNOR bit comparators, an equality AND, and muxes that select the decision bit by priority.由 MSB 往下掃,第一個不相同的位元就決定結果:若 a[k] = 1 則 $a > b$。合成會產生逐位元的 XOR/XNOR 比較器、一個做相等判斷的 AND,以及依優先權挑出決定位元的多工器。MSB から順に見ていき、最初に異なるビットで結果が決まる。a[k] = 1 なら $a > b$ である。合成はビットごとの XOR/XNOR 比較器、一致判定の AND、そして優先順位で決定ビットを選ぶマルチプレクサを生成する。

4.6 Function and task4.6 function 與 task4.6 function と task

Functionfunction 寫法function による記述
module or_nand_4 (enable, x1, x2, x3, x4, y);
  input  enable, x1, x2, x3, x4;
  output y;

  assign y = or_nand(enable, x1, x2, x3, x4);

  function or_nand;
    input enable, x1, x2, x3, x4;
    begin
      or_nand = ~(enable & (x1 | x2)
                         & (x3 | x4));
    end
  endfunction
endmodule
Tasktask 寫法task による記述
module or_nand_5 (enable, x1, x2, x3, x4, y);
  input  enable, x1, x2, x3, x4;
  output y;
  reg    y;

  always @ (enable or x1 or x2 or x3 or x4)
    or_nand(enable, x1, x2, x3, x4, y);

  task or_nand;
    input  enable, x1, x2, x3, x4;
    output y;
    begin
      y = !(enable & (x1 | x2) & (x3 | x4));
    end
  endtask
endmodule

Both synthesize to the oai22 + nand2 pair. The task uses logical ! instead of bitwise ~; for a 1-bit operand they are the same, for vectors they are not.兩者都合成成 oai22 + nand2 這一對。task 版用的是邏輯 ! 而不是位元 ~;對 1 位元運算元兩者相同,對向量則不同。どちらも oai22 + nand2 の組に合成される。task 版はビット単位の ~ ではなく論理否定の ! を使っている。1 ビットのオペランドなら同じだが、ベクタでは異なる。

4.7 Constructs to be avoided4.7 應避免的語法4.7 避けるべき構文

Construct語法構文Why原因理由
Multiple event controls in one procedural block一個程序區塊裡有多個事件控制一つの手続きブロック内に複数のイベント制御Implies a multi-cycle state machine with no explicit state等於寫了一台沒有明確狀態的多週期狀態機状態を明示しない複数サイクルの状態機械を意味する
Named event with edge-sensitive event control具名事件搭配邊緣敏感的事件控制名前つきイベントとエッジ検出のイベント制御No hardware equivalent硬體上沒有對應的東西対応するハードウェアが存在しない
Feedback loops回授迴路帰還ループCombinational loop (§7)組合邏輯迴路(§7)組合せループ(§7)
PCA containing event or delay control含事件或延遲控制的 PCAイベント制御や遅延を含む PCATiming not synthesizable時序部分無法合成時間的な記述は合成できない
fork ... join, waitfork ... join、waitfork ... join・waitSimulation-only只能用於模擬シミュレーション専用
External disable從外部 disable 其他區塊外部からの disableOnly disabling the enclosing block is supported只支援停用自己所在的那個區塊自分を囲むブロックの無効化しかサポートされない
Procedural loops with timing controls含時序控制的程序迴圈時間制御を含む手続きループCannot be unrolled無法展開展開できない
Data-dependent loops界限取決於資料的迴圈データに依存するループBound unknown at compile time編譯期無從得知界限上限がコンパイル時に分からない
Tasks with timing controls; sequential UDPs含時序控制的 task;序向 UDP時間制御を含む task、順序 UDPNot mapped by the tool工具不會把它映射成電路ツールがマッピングしない

5. Control Logic for Multiplexed Datapaths5. 多工資料路徑的控制邏輯5. マルチプレクス・データパスの制御論理

5.1 A 4-channel, 4-bit mux three ways5.1 四通道 4 位元多工器的三種寫法5.1 4 チャネル 4 ビット・マルチプレクサの三通りの書き方

Nested conditional operator巢狀條件運算子入れ子の条件演算子
module syn1_mux_4bits (y, sel, a, b, c, d);
  input  [3:0] a, b, c, d;
  input  [1:0] sel;
  output [3:0] y;

  assign y = (sel == 0) ? a :
             (sel == 1) ? b :
             (sel == 2) ? c :
             (sel == 3) ? d : 4'bx;
endmodule
abcd 0123 ysel
case
module syn2_mux_4bits (y, sel, a, b, c, d);
  input  [3:0] a, b, c, d;
  input  [1:0] sel;
  output [3:0] y;
  reg    [3:0] y;

  always @ (sel or a or b or c or d)
    case (sel)
      0: y = a;
      1: y = b;
      2: y = c;
      3: y = d;
      default: y = 4'bx;
    endcase
endmodule
if ... else
module syn3_mux_4bits (y, sel, a, b, c, d);
  input  [3:0] a, b, c, d;
  input  [1:0] sel;
  output [3:0] y;
  reg    [3:0] y;

  always @ (sel or a or b or c or d)
    if      (sel == 0) y = a;
    else if (sel == 1) y = b;
    else if (sel == 2) y = c;
    else if (sel == 3) y = d;
    else               y = 4'bx;
endmodule

All three are "simulation and synthesis friendly". Because the sel values are mutually exclusive, the if chain synthesizes to the same mux as the case version — no priority logic. The 4'bx default lets the tool treat the impossible branch as a don't care.三種寫法都屬於「模擬與合成都友善」。由於 sel 的各個值互斥,if 串接合成出來的多工器與 case 版完全相同,不會多出優先邏輯。4'bx 的 default 則讓工具把不可能發生的分支當成 don't care。三つとも「シミュレーションにも合成にも適した」書き方である。sel の各値は互いに排他なので、if チェーンも case 版と同じマルチプレクサに合成され、優先順位論理は生じない。4'bx の default は、起こりえない分岐をドントケアとして扱わせる。

5.2 The "simulation efficient" style5.2「模擬有效率」的寫法5.2「シミュレーション効率型」の記述

always @ (sel)            // only sel
  case (sel)
    0: assign y = a;      // procedural continuous assignment
    1: assign y = b;
    2: assign y = c;
    3: assign y = d;
    default: assign y = 4'bx;
  endcase

Using assign (PCA) inside the block lets y follow a–d continuously while the block wakes only on sel, so it simulates fast. The synthesis result is the same mux, but PCA support varies by tool, so the full-sensitivity version is preferred.在區塊內用 assign(PCA),y 會持續跟著 a–d 變動,而區塊本身只在 sel 改變時被喚醒,所以模擬很快。合成結果是同一個多工器,但各家工具對 PCA 的支援不一,因此還是建議用完整敏感列表的版本。ブロック内で assign(PCA)を使うと、ブロックは sel でしか起動しないのに y は a–d に追従し続けるため、シミュレーションが速い。合成結果は同じマルチプレクサだが、PCA のサポートはツールによって差があるので、感度リストを完全に書いた版のほうが望ましい。

Key points (click to expand)重點整理(點擊展開)要点(クリックで展開)
  • The ?:, case and if styles all synthesize to the same multiplexer, as long as the conditions are mutually exclusive and cover every value.?:、case、if 三種寫法,只要條件互斥且完整,都合成出相同的多工器。?:・case・if の三つの書き方は、条件が互いに排他ですべての値を網羅してさえいれば、同じマルチプレクサに合成される。
  • The "simulation efficient" style uses a PCA and is sensitive to sel only; the "simulation and synthesis friendly" style puts every input in the sensitivity list.「模擬有效率」寫法用 PCA,只對 sel 敏感;「模擬與合成都友善」寫法則把所有輸入放進敏感列表。「シミュレーション効率型」は PCA を使い sel にだけ感度をもつ。「シミュレーションにも合成にも適した」書き方は、すべての入力を感度リストに入れる。

6. Unwanted Latches6. 非預期的閂鎖6. 意図しないラッチ

6.1 Incompletely specified case / if6.1 未完整指定的 case / if6.1 不完全に指定された case / if

A case or if that does not cover all possible values is incompletely specified. On the uncovered paths the register must keep its old value, so synthesis inserts a latch. Avoid it.沒有涵蓋所有可能值的 case 或 if 就是未完整指定。在沒涵蓋到的路徑上,變數必須保持舊值,於是合成工具會插入一個閂鎖。請避免。取りうる値をすべて網羅していない case や if は不完全指定である。網羅されていない経路では変数が古い値を保持しなければならないので、合成はそこにラッチを挿入する。避けること。

module mux_latch (y_out, sel_a, sel_b, data_a, data_b);
  input  sel_a, sel_b, data_a, data_b;
  output y_out;
  reg    y_out;

  always @ (sel_a or sel_b or data_a or data_b)
    case ({sel_a, sel_b})
      2'b10: y_out = data_a;
      2'b01: y_out = data_b;     // incomplete case list!!
    endcase
endmodule
data_adata_bsel_asel_b data mux資料多工器データ・マルチプレクサ(sel_a ? data_a : data_b) enable logic致能邏輯イネーブル論理sel_a ^ sel_b Latch閂鎖ラッチ DEn y_out
Generic synthesis result: when (sel_a, sel_b) = 00 or 11 the latch is closed and y_out keeps its old value.一般的合成結果:當 (sel_a, sel_b) = 00 或 11 時閂鎖關閉,y_out 保持舊值。一般的な合成結果:(sel_a, sel_b) = 00 または 11 のときラッチは閉じ、y_out は古い値を保持する。

6.2 Bad and good ALU examples6.2 ALU 的壞例與好例6.2 ALU の悪い例と良い例

Bad 1a — incomplete case and sensitivity壞例 1a — case 與敏感列表都不完整悪い例 1a — case も感度リストも不完全
module alu_incomplete1a (alu_out, data_a,
                    data_b, enable, opcode);
  input  [2:0] opcode;
  input  [3:0] data_a, data_b;
  input        enable;
  output       alu_out;      // scalar
  reg    [3:0] alu_reg;

  assign alu_out = (enable == 1) ? alu_reg : 4'b0;

  always @ (opcode)
    case (opcode)
      3'b001: alu_reg = data_a | data_b;
      3'b010: alu_reg = data_a ^ data_b;
      3'b110: alu_reg = ~data_b;
    endcase
endmodule
Bad 2a — sensitivity fixed, case still incomplete壞例 2a — 敏感列表修好了,case 仍不完整悪い例 2a — 感度リストは直したが case はまだ不完全
module alu_incomplete2a (alu_out, data_a,
                    data_b, enable, opcode);
  ...
  assign alu_out = (enable == 1) ? alu_reg : 4'b0;

  always @ (opcode or data_a or data_b)
    case (opcode)
      3'b001: alu_reg = data_a | data_b;
      3'b010: alu_reg = data_a ^ data_b;
      3'b110: alu_reg = ~data_b;
    endcase
endmodule

Both synthesize a latch (latrnb) between the opcode-selected datapath and alu_out: for the five opcodes not listed, alu_reg must hold its value. Fixing the sensitivity list alone does not remove it.兩者都會在由 opcode 選出的資料路徑與 alu_out 之間合成出一個閂鎖(latrnb):對於沒列出的那五個 opcode,alu_reg 必須保持原值。只修敏感列表並不能把它消掉。どちらも、opcode で選ばれたデータパスと alu_out の間にラッチ(latrnb)を合成してしまう。列挙されていない 5 つの opcode では alu_reg が値を保持しなければならないからである。感度リストだけを直してもラッチは消えない。

module alu_complete (alu_out, data_a, data_b, enable, opcode);
  ...
  always @ (opcode or data_a or data_b)
    case (opcode)
      3'b001:  alu_reg = data_a | data_b;
      3'b010:  alu_reg = data_a ^ data_b;
      3'b110:  alu_reg = ~data_b;
      default: alu_reg = 4'b0;      // makes the case list complete
    endcase
endmodule

With default the result is pure gates plus a mux — no latch.加上 default 之後,結果只剩純邏輯閘加一個多工器 — 沒有閂鎖。default を加えれば、結果は純粋なゲートとマルチプレクサだけになり、ラッチは生じない。

Scalar output detail關於純量輸出的細節スカラ出力についての補足

alu_out is a 1-bit port ("scalar for illustration"), so alu_reg is truncated to alu_reg[0] on assignment. That is why the synthesized schematic shows only one bit of datapath.alu_out 是 1 位元的埠(投影片寫「為了示意而用純量」),所以指定時 alu_reg 會被截成 alu_reg[0]。這就是合成出來的電路圖只看得到一個位元資料路徑的原因。alu_out は 1 ビットのポート(講義では「説明のためのスカラ」)なので、代入時に alu_reg は alu_reg[0] に切り詰められる。合成後の回路図にデータパスが 1 ビットしか現れないのはこのためである。

6.3 Bad example using if6.3 用 if 寫出的壞例6.3 if を使った悪い例

module incomplete_and (y, a1, a2);
  input  a1, a2;
  output y;
  reg    y;

  always @ (a1 or a2)
    begin
      if      ({a2, a1} == 2'b11) y = 1;
      else if ({a2, a1} == 2'b01) y = 0;
      else if ({a2, a1} == 2'b10) y = 0;   // the last statement should be "else"
    end
endmodule

The case {a2, a1} = 00 is missing, so the tool builds inverters, a NOR/NAND enable and a latch (latrnb). Ending with a plain else y = 0; gives one AND gate.少了 {a2, a1} = 00 這個情況,工具就造出反相器、一組 NOR/NAND 致能邏輯與一個閂鎖(latrnb)。只要最後改成單純的 else y = 0;,就只剩一個 AND 閘。{a2, a1} = 00 の場合が抜けているため、ツールはインバータ、NOR/NAND のイネーブル論理、そしてラッチ(latrnb)を作ってしまう。最後を単純な else y = 0; にすれば AND ゲート 1 個で済む。

Practice 3 — Spot the latch練習 3 — 找出閂鎖演習 3 — ラッチを見つける

Problem: Which blocks infer a latch?題目:下列哪些區塊會推論出閂鎖?問題:ラッチが推論されるのはどのブロックか。

// (a)
always @ (a or b or s) if (s) y = a; else y = b;
// (b)
always @ (en or d) if (en) q = d;
// (c)
always @ (s or a or b) begin y = b; if (s) y = a; end
// (d)
always @ (op or a or b)
  case (op) 2'b00: y = a; 2'b01: y = b; 2'b10: y = a & b; endcase
// (e)  op is 2 bits
always @ (op or a or b)
  case (op) 2'b00: y = a; 2'b01: y = b; 2'b10: y = a & b; 2'b11: y = a | b; endcase
Click to reveal solution點擊展開解答クリックで解答を表示

(a) No — every path assigns y.(a) 不會 — 每條路徑都有指定 y。(a) いいえ — どの経路でも y に代入される。

(b) Yes — no else; this is the standard way to write an intentional D-latch.(b) 會 — 沒有 else;這正是刻意寫出 D 型閂鎖的標準寫法。(b) はい — else がない。意図的に D ラッチを書くときの標準的な形である。

(c) No — the default assignment at the top covers the missing else.(c) 不會 — 開頭的預設指定已經補上了缺少的 else。(c) いいえ — 先頭の既定代入が、欠けている else を補っている。

(d) Yes — op = 2'b11 is not covered.(d) 會 — op = 2'b11 沒有被涵蓋。(d) はい — op = 2'b11 が網羅されていない。

(e) No — all four values of a 2-bit op are listed. (In simulation op = x would hold y, but synthesis only considers 0/1, so no latch; adding default is still good style.)(e) 不會 — 2 位元 op 的四個值都列出來了。(模擬時 op = x 會讓 y 保持舊值,但合成只考慮 0/1,所以不會有閂鎖;不過補上 default 仍是好習慣。)(e) いいえ — 2 ビットの op の 4 値がすべて列挙されている。(シミュレーションでは op = x のとき y が保持されるが、合成は 0/1 しか考えないのでラッチは生じない。とはいえ default を足しておくのは良い作法である。)

7. Combinational Loops (Mux with Feedback)7. 組合邏輯迴路(含回授的多工器)7. 組合せループ(帰還つきマルチプレクサ)

7.1 Completed case / if with feedback7.1 用回授「補完」的 case / if7.1 帰還で「完全」にした case / if

A case or if that is "completed" by assigning the variable to itself in a level-sensitive behavior synthesizes to a mux whose output feeds back to its input. This combinational loop cannot be mapped to proper gates — avoid it.在位準敏感的行為區塊裡,用把變數指定給自己的方式來「補完」case 或 if,合成出來會是一個輸出回授到自己輸入的多工器。這種組合邏輯迴路無法對應成正常的邏輯閘 — 請避免。レベル検出の記述の中で、変数に自分自身を代入して case や if を「完全」にすると、出力が自分の入力へ戻るマルチプレクサに合成される。この組合せループはまともなゲートにマッピングできない — 避けること。

Completed case with feedback用回授補完的 case帰還で完全にした case
module latch_case1 (latch_out, latch_in,
                    set, clear, enable);
  input  latch_in, set, clear, enable;
  output latch_out;
  reg    latch_out;

  always @ (enable or set or clear or latch_in)
    case ({enable, set, clear})
      3'b000: latch_out = latch_in; // transparent
      3'b110: latch_out = 1'b1;     // set
      3'b010: latch_out = 1'b1;     // set
      3'b101: latch_out = 1'b0;     // clear
      3'b001: latch_out = 1'b0;     // clear
      default: latch_out = latch_out; // holds value
    endcase
endmodule
Completed if with feedback用回授補完的 if帰還で完全にした if
module latch_if1 (data_out, data_in,
                  latch_enable);
  input  [3:0] data_in;
  output [3:0] data_out;
  input        latch_enable;
  reg    [3:0] data_out;

  always @ (latch_enable or data_in)
    if (latch_enable) data_out = data_in;
    else data_out = data_out;
endmodule
data_inlatch_enable 10 data_out mux feedback回授帰還
Mux with feedback (one bit shown). The tool cannot synthesize this loop to gates; it is a latch built from a combinational loop, with races and timing analysis problems.含回授的多工器(只畫出一個位元)。工具無法把這個迴路合成成邏輯閘;它其實是用組合邏輯迴路做出來的閂鎖,會帶來競爭與時序分析上的問題。帰還つきマルチプレクサ(1 ビット分のみ図示)。ツールはこのループをゲートに合成できない。組合せループで作られたラッチであり、レースやタイミング解析上の問題を生む。
Practice 4 — Fix the loop練習 4 — 修掉迴路演習 4 — ループを直す

Problem: Rewrite latch_if1 two ways: (a) as an intentional latch the tool will map to a latch cell, (b) as pure combinational logic that outputs 0 when disabled.題目:用兩種方式改寫 latch_if1:(a) 寫成工具會映射到閂鎖 cell 的刻意閂鎖,(b) 寫成純組合邏輯,未致能時輸出 0。問題:latch_if1 を二通りに書き直せ。(a) ツールがラッチセルにマッピングする意図的なラッチとして、(b) 無効時に 0 を出力する純粋な組合せ論理として。

Click to reveal solution點擊展開解答クリックで解答を表示
// (a) intentional latch: no else, no self-assignment
always @ (latch_enable or data_in)
  if (latch_enable) data_out = data_in;

// (b) combinational: every path gets a new value
always @ (latch_enable or data_in)
  if (latch_enable) data_out = data_in;
  else              data_out = 4'b0;

(a) is recognized as a latch template and mapped to latch cells; (b) becomes four AND gates. The self-assignment x = x is what makes the tool build an explicit feedback mux instead.(a) 會被辨識成閂鎖樣板,映射到閂鎖 cell;(b) 則變成四個 AND 閘。真正讓工具去造出明確回授多工器的,就是 x = x 這種自我指定。(a) はラッチのテンプレートとして認識され、ラッチセルにマッピングされる。(b) は AND ゲート 4 個になる。ツールにわざわざ明示的な帰還マルチプレクサを作らせてしまうのは、x = x という自己代入である。

8. Priority Structures, Encoders and Decoders8. 優先權結構、編碼器與解碼器8. 優先順位構造、エンコーダとデコーダ

8.1 Mux vs priority chain8.1 多工器 vs 優先鏈8.1 マルチプレクサ vs 優先順位チェーン

module mux_4pri (y, a, b, c, d, sel_a, sel_b, sel_c);
  input  a, b, c, d, sel_a, sel_b, sel_c;
  output y;
  reg    y;

  always @ (sel_a or sel_b or sel_c or a or b or c or d)
    begin                       // not mutually exclusive
      if      (sel_a == 1) y = a;
      else if (sel_b == 0) y = b;
      else if (sel_c == 1) y = c;
      else                 y = d;
    end
endmodule
sel_asel_bsel_c dcba mux_2mux_2mux_2 y low低低high高高
Priority chain: sel_c is tested last (lowest priority, closest to the inputs), sel_a first (highest, closest to the output). Each extra condition adds one mux delay.優先鏈:sel_c 最後才判斷(優先權最低,最靠近輸入),sel_a 最先判斷(優先權最高,最靠近輸出)。每多一個條件就多一級多工器延遲。優先順位チェーン:sel_c は最後に判定され(優先度が最も低く、入力に最も近い)、sel_a は最初に判定される(優先度が最も高く、出力に最も近い)。条件が一つ増えるごとにマルチプレクサ 1 段分の遅延が加わる。

8.2 8:3 encoder (without priority)8.2 8:3 編碼器(無優先權)8.2 8:3 エンコーダ(優先順位なし)

if chainif 串接if チェーン
module encoder (Data, Code);
  input  [7:0] Data;
  output [2:0] Code;
  reg    [2:0] Code;

  always @ (Data)
    begin
      if      (Data == 8'b00000001) Code = 0;
      else if (Data == 8'b00000010) Code = 1;
      else if (Data == 8'b00000100) Code = 2;
      else if (Data == 8'b00001000) Code = 3;
      else if (Data == 8'b00010000) Code = 4;
      else if (Data == 8'b00100000) Code = 5;
      else if (Data == 8'b01000000) Code = 6;
      else if (Data == 8'b10000000) Code = 7;
      else                          Code = 3'bx;
    end
endmodule
case — equivalentcase — 等效寫法case — 等価な記述
module encoder (Data, Code);
  input  [7:0] Data;
  output [2:0] Code;
  reg    [2:0] Code;

  always @ (Data)
    case (Data)
      8'b00000001 : Code = 0;
      8'b00000010 : Code = 1;
      8'b00000100 : Code = 2;
      8'b00001000 : Code = 3;
      8'b00010000 : Code = 4;
      8'b00100000 : Code = 5;
      8'b01000000 : Code = 6;
      8'b10000000 : Code = 7;
      default     : Code = 3'bx;
    endcase
endmodule

The one-hot patterns are mutually exclusive and the default is a don't care, so the tool reduces each output bit to a 4-input OR:one-hot 的樣式彼此互斥,default 又是 don't care,所以工具把每個輸出位元化簡成一個 4 輸入 OR:ワンホットのパターンは互いに排他で、default はドントケアなので、ツールは各出力ビットを 4 入力 OR に簡単化する。

Synthesized result (three or4 cells)合成結果(三顆 or4 cell)合成結果(or4 セル 3 個) $$\text{Code}[2] = D_4 + D_5 + D_6 + D_7,\quad \text{Code}[1] = D_2 + D_3 + D_6 + D_7,\quad \text{Code}[0] = D_1 + D_3 + D_5 + D_7$$

8.3 8:3 priority encoder8.3 8:3 優先編碼器8.3 8:3 プライオリティエンコーダ

if chainif 串接if チェーン
module priority (Data, Code, valid_data);
  input  [7:0] Data;
  output [2:0] Code;
  output       valid_data;
  reg    [2:0] Code;

  assign valid_data = |Data;   // reduction or

  always @ (Data)
    begin
      if      (Data[7]) Code = 7;
      else if (Data[6]) Code = 6;
      else if (Data[5]) Code = 5;
      else if (Data[4]) Code = 4;
      else if (Data[3]) Code = 3;
      else if (Data[2]) Code = 2;
      else if (Data[1]) Code = 1;
      else if (Data[0]) Code = 0;
      else              Code = 3'bx;
    end
endmodule
casex — equivalentcasex — 等效寫法casex — 等価な記述
module priority (Data, Code, valid_data);
  ...
  assign valid_data = |Data;

  always @ (Data)
    casex (Data)
      8'b1xxxxxxx : Code = 7;
      8'b01xxxxxx : Code = 6;
      8'b001xxxxx : Code = 5;
      8'b0001xxxx : Code = 4;
      8'b00001xxx : Code = 3;
      8'b000001xx : Code = 2;
      8'b0000001x : Code = 1;
      8'b00000001 : Code = 0;
      default     : Code = 3'bx;
    endcase
endmodule

Now several bits may be 1 at once, so the conditions overlap and the highest index wins. The synthesized netlist adds inverters and AND/NOR terms that mask lower bits, e.g.現在可能同時有好幾個位元是 1,條件因此重疊,由索引最高的那個勝出。合成出的 netlist 會多出反相器與遮蔽低位元的 AND/NOR 項,例如:今度は複数のビットが同時に 1 になりうるため条件が重なり、添字の大きいほうが勝つ。合成されたネットリストには、下位ビットをマスクするインバータと AND/NOR 項が加わる。例えば次のとおり。

$$\text{Code}[2] = D_7 + D_6 + D_5 + D_4,\qquad \text{Code}[1] = D_7 + D_6 + \overline{D_5}\,\overline{D_4}\,(D_3 + D_2)$$ $$\text{Code}[0] = D_7 + \overline{D_6}\,D_5 + \overline{D_6}\,\overline{D_4}\,D_3 + \overline{D_6}\,\overline{D_4}\,\overline{D_2}\,D_1$$

8.4 3:8 decoder8.4 3:8 解碼器8.4 3:8 デコーダ

if chainif 串接if チェーン
module decoder (Code, Data);
  output [7:0] Data;
  input  [2:0] Code;
  reg    [7:0] Data;

  always @ (Code)
    begin
      if      (Code == 0) Data = 8'b00000001;
      else if (Code == 1) Data = 8'b00000010;
      else if (Code == 2) Data = 8'b00000100;
      else if (Code == 3) Data = 8'b00001000;
      else if (Code == 4) Data = 8'b00010000;
      else if (Code == 5) Data = 8'b00100000;
      else if (Code == 6) Data = 8'b01000000;
      else if (Code == 7) Data = 8'b10000000;
      else                Data = 8'bx;
    end
endmodule
case — equivalentcase — 等效寫法case — 等価な記述
  always @ (Code)
    case (Code)
      0 : Data = 8'b00000001;
      1 : Data = 8'b00000010;
      2 : Data = 8'b00000100;
      3 : Data = 8'b00001000;
      4 : Data = 8'b00010000;
      5 : Data = 8'b00100000;
      6 : Data = 8'b01000000;
      7 : Data = 8'b10000000;
      default: Data = 8'bx;
    endcase

Each Data[i] is a 3-input minterm of Code; the netlist uses inverters, nand2/and2 pre-decoding and nor/and3 cells. HW: write a mux the same way.每個 Data[i] 都是 Code 的 3 輸入最小項;netlist 會用到反相器、nand2/and2 做預解碼,以及 nor/and3 等 cell。作業:用同樣的方式寫一個多工器。各 Data[i] は Code の 3 入力最小項である。ネットリストはインバータ、nand2/and2 によるプリデコード、nor/and3 などのセルを使う。宿題:同じやり方でマルチプレクサを書くこと。

Practice 5 — Encoder outputs練習 5 — 編碼器的輸出演習 5 — エンコーダの出力

Problem: For Data = 8'b0010_0100, give Code from (a) the non-priority encoder in simulation, (b) the same encoder's synthesized OR netlist, (c) the priority encoder. (d) What does valid_data mean when Data = 0?題目:當 Data = 8'b0010_0100 時,分別給出 (a) 無優先權的 encoder 在模擬中的 Code、(b) 同一個編碼器合成後 OR netlist 的輸出、(c) 優先編碼器的輸出。(d) 當 Data = 0 時,valid_data 代表什麼?問題:Data = 8'b0010_0100 のとき、(a) 優先順位なしの encoder のシミュレーション上の Code、(b) 同じエンコーダを合成した OR ネットリストの出力、(c) プライオリティエンコーダの出力をそれぞれ示せ。(d) Data = 0 のとき valid_data は何を意味するか。

Click to reveal solution點擊展開解答クリックで解答を表示

(a) Not one-hot → default → Code = 3'bxxx.(a) 不是 one-hot → 走 default → Code = 3'bxxx。(a) ワンホットではない → default → Code = 3'bxxx。

(b) $D_5 = D_2 = 1$: Code[2] = 1 ($D_5$), Code[1] = 1 ($D_2$), Code[0] = 1 ($D_5$) → 3'b111. The x in RTL became a concrete (and wrong-looking) value: a simulation/synthesis mismatch caused by the don't care.(b) $D_5 = D_2 = 1$:Code[2] = 1(來自 $D_5$)、Code[1] = 1(來自 $D_2$)、Code[0] = 1(來自 $D_5$)→ 3'b111。RTL 裡的 x 變成了具體(而且看起來不對)的值:這正是 don't care 造成的模擬/合成不一致。(b) $D_5 = D_2 = 1$ なので Code[2] = 1($D_5$)、Code[1] = 1($D_2$)、Code[0] = 1($D_5$)→ 3'b111。RTL の x が具体的な、しかも一見おかしな値になった。ドントケアが生むシミュレーションと合成の不一致である。

(c) Highest set bit is 5 → Code = 3'b101.(c) 最高的 1 在第 5 位 → Code = 3'b101。(c) 立っている最上位ビットは 5 → Code = 3'b101。

(d) valid_data = 0 flags that Code is meaningless; downstream logic must ignore Code then.(d) valid_data = 0 表示 Code 沒有意義;此時下游邏輯必須忽略 Code。(d) valid_data = 0 は Code が無意味であることを示す。このとき後段の論理は Code を無視しなければならない。

9. Buses and Tri-State Buffers9. 匯流排與三態緩衝器9. バスとトライステート・バッファ

Buses transport multi-bit data; buffers store or drive data with or without control signals. Four implementation concerns: tri-state buffers, bidirectional buses, bus loading, and tri-state outputs with don't cares.匯流排負責搬運多位元資料;緩衝器則在有或沒有控制訊號的情況下儲存或驅動資料。實作上有四個重點:三態緩衝器、雙向匯流排、匯流排負載,以及帶 don't care 的三態輸出。バスは多ビットのデータを運び、バッファは制御信号の有無に応じてデータを保持または駆動する。実装上の論点は四つある。トライステート・バッファ、双方向バス、バスの負荷、そしてドントケアを伴うトライステート出力である。

9.1 Tri-state buffer9.1 三態緩衝器9.1 トライステート・バッファ

module stuff_to_bus1 (data_to_bus, bus_enabled, clk);
  input         bus_enabled, clk;
  output [31:0] data_to_bus;
  reg    [31:0] ckt_output_to_bus;

  assign data_to_bus = (bus_enabled) ? ckt_output_to_bus : 32'bz;
  // Description of core circuit goes here to drive ckt_output_to_bus
endmodule

A conditional operator whose other branch is z synthesizes to a 32-bit tri-state buffer controlled by bus_enabled.條件運算子的另一個分支給 z,就會合成成一個由 bus_enabled 控制的 32 位元三態緩衝器。条件演算子のもう一方の分岐を z にすると、bus_enabled で制御される 32 ビットのトライステート・バッファに合成される。

9.2 Bidirectional bus9.2 雙向匯流排9.2 双方向バス

module stuff_to_bus2 (data_to_from_bus, clk, send_data, rcv_data);
  input         clk, send_data, rcv_data;
  inout  [31:0] data_to_from_bus;
  reg    [31:0] reg_to_bus;
  wire   [31:0] data_to_from_bus, inbound_data;

  assign inbound_data     = (rcv_data)  ? data_to_from_bus : 32'bz;
  assign data_to_from_bus = (send_data) ? reg_to_bus       : 32'bz;
  // Behavior using inbound_data goes here
endmodule
Core circuit核心電路コア回路 reg_to_businbound_data data_to_from_bussend_datarcv_data inout padinout 接腳inout パッド
Two tri-state drivers share the inout port: send_data drives the bus out, rcv_data gates it in.兩個三態驅動器共用同一個 inout 埠:send_data 把資料往匯流排送出,rcv_data 則把資料閘入。二つのトライステート・ドライバが同じ inout ポートを共有する。send_data がバスへ出力し、rcv_data が取り込みをゲートする。

9.3 Bus loading9.3 匯流排負載9.3 バスの負荷

module stuff_to_bus3 (data_to_from_bus, enab_a, enab_b, clk, rcv_data);
  input         enab_a, enab_b, rcv_data, clk;
  inout  [31:0] data_to_from_bus;
  reg    [31:0] reg_a_to_bus, reg_b_to_bus;

  assign data_to_from_bus = (enab_a) ? reg_a_to_bus :
                            (enab_b) ? reg_b_to_bus : 32'bz;
endmodule // not showing other logic

Rather than two tri-state drivers on the bus, one nested conditional gives a 2:1 mux (select enab_a) followed by a single tri-state driver enabled by enab_a | enab_b. Only one driver loads the bus, and contention is impossible.與其在匯流排上掛兩個三態驅動器,用一個巢狀條件式就能得到一個 2:1 多工器(以 enab_a 選擇),後面再接單一由 enab_a | enab_b 致能的三態驅動器。匯流排上只有一個驅動器,也就不可能發生競爭。バスにトライステート・ドライバを 2 個ぶら下げる代わりに、入れ子の条件式を使えば、2:1 マルチプレクサ(選択は enab_a)の後ろに enab_a | enab_b でイネーブルされる単一のトライステート・ドライバが置かれる。バスを駆動するのは 1 個だけなので、競合は起こりえない。

9.4 Tri-state outputs with don't cares9.4 帶 don't care 的三態輸出9.4 ドントケアを伴うトライステート出力

module alu_with_z1 (alu_out, data_a, data_b, enable, opcode);
  input  [2:0] opcode;
  input  [3:0] data_a, data_b;
  input        enable;
  output       alu_out;          // scalar for illustration
  reg    [3:0] alu_reg;

  assign alu_out = (enable == 1) ? alu_reg : 4'bz;

  always @ (opcode or data_a or data_b)
    case (opcode)
      3'b001:  alu_reg = data_a | data_b;
      3'b010:  alu_reg = data_a ^ data_b;
      3'b110:  alu_reg = ~data_b;
      default: alu_reg = 4'b0;   // alu_with_z2: alu_reg = 4'bx;  (don't cares)
    endcase
endmodule
Version版本バージョンdefaultSynthesized circuit合成出的電路合成される回路
alu_with_z14'b0Must force 0 for 5 unused opcodes: two muxes, several gates, tri-state output5 個未使用的 opcode 都必須強制為 0:兩個多工器、數個邏輯閘、一個三態輸出未使用の 5 つの opcode で 0 を強制する必要がある:マルチプレクサ 2 個、ゲート数個、トライステート出力
alu_with_z24'bxUnused opcodes are free: one mux, fewer gates, tri-state output未使用的 opcode 可以隨意:一個多工器、較少的邏輯閘、一個三態輸出未使用の opcode は自由なので、マルチプレクサ 1 個、より少ないゲート、トライステート出力で済む
Key result重要結論重要な結論

Assigning x in a default both prevents a latch (the case is complete) and gives the optimizer freedom. Use it only when those input values truly never occur, because the hardware output for them is unpredictable.在 default 裡指定 x,既能避免閂鎖(case 變完整),又給了最佳化器自由。但只有在那些輸入值真的不可能出現時才可以這樣寫,因為硬體在那些情況下的輸出是無法預期的。default で x を代入すると、case が完全になるのでラッチを防げるうえに、最適化器に自由度を与えられる。ただし、その入力値が本当に起こらない場合にのみ使うこと。起きたときのハードウェア出力は予測できないからである。

Practice 6 — Bus contention練習 6 — 匯流排競爭演習 6 — バス競合

Problem: Instead of §9.3, a designer writes題目:有人沒照 §9.3 的寫法,而是寫成問題:§9.3 の代わりに、ある設計者は次のように書いた。

assign data_to_from_bus = enab_a ? reg_a_to_bus : 32'bz;
assign data_to_from_bus = enab_b ? reg_b_to_bus : 32'bz;

With reg_a_to_bus = 32'h0000_00FF, reg_b_to_bus = 32'h0000_0F0F and enab_a = enab_b = 1, what does simulation show for the low byte? What does §9.3 show?若 reg_a_to_bus = 32'h0000_00FF、reg_b_to_bus = 32'h0000_0F0F,且 enab_a = enab_b = 1,模擬中最低位元組會是什麼?改用 §9.3 的寫法又會是什麼?reg_a_to_bus = 32'h0000_00FF、reg_b_to_bus = 32'h0000_0F0F、enab_a = enab_b = 1 のとき、シミュレーションで下位バイトはどうなるか。§9.3 の書き方ならどうなるか。

Click to reveal solution點擊展開解答クリックで解答を表示

Two drivers on a wire: bits that agree keep their value, bits that differ become x. Low byte: a = 1111_1111, b = 0000_1111 → xxxx_1111. In silicon this is a short between the two drivers.同一條 wire 上有兩個驅動器:相同的位元維持原值,不同的位元變成 x。最低位元組:a = 1111_1111、b = 0000_1111 → xxxx_1111。在晶片上這就是兩個驅動器之間的短路。一本の wire を二つのドライバが駆動する。一致するビットは値を保ち、異なるビットは x になる。下位バイトは a = 1111_1111、b = 0000_1111 → xxxx_1111。シリコン上ではこれは二つのドライバ間の短絡である。

§9.3 gives enab_a priority: the bus carries 8'hFF, no contention.§9.3 的寫法讓 enab_a 有優先權:匯流排上是 8'hFF,不會發生競爭。§9.3 では enab_a が優先される。バスには 8'hFF が乗り、競合は起きない。

10. Resource Sharing10. 資源共享10. リソース共有

Do the resource sharing before RTL coding — it is what gives hardware its low-cost property.資源共享要在寫 RTL 之前就想好 — 硬體之所以能低成本,靠的就是這件事。リソース共有はRTL を書く前に済ませておく — ハードウェアが低コストでいられるのはこれによる。

module res_share (y_out, sel, data_a, data_b, accum);
  input  [3:0] data_a, data_b, accum;
  input        sel;
  output [4:0] y_out;

  // two adders + mux
  // assign y_out = sel ? (data_a + accum) : (data_a + data_b);

  // one mux + one adder
  assign y_out = data_a + (sel ? accum : data_b);
endmodule
++ data_aaccumdata_adata_b 10sely_out accumdata_bdata_a 10sel Adder加法器加算器y_out 2 adders + mux2 個加法器 + 多工器加算器 2 個 + mux 1 mux + 1 adder1 個多工器 + 1 個加法器mux 1 個 + 加算器 1 個
Sharing the common operand data_a moves the mux in front of the adder, saving one 4-bit adder.共用共同運算元 data_a,把多工器移到加法器之前,省下一個 4 位元加法器。共通のオペランド data_a を共有し、マルチプレクサを加算器の前へ移すことで、4 ビット加算器を 1 個節約できる。
Practice 7 — Share the operator練習 7 — 共用運算器演習 7 — 演算器を共有する

Problem: Rewrite each with one arithmetic unit. (a) y = sel ? a * b : a * c; (b) y = sel ? a + b : c + d; (c) Is (b) always a win?題目:把下列各式改寫成只用一個算術單元。(a) y = sel ? a * b : a * c; (b) y = sel ? a + b : c + d; (c) (b) 一定划算嗎?問題:それぞれを演算器 1 個で書き直せ。(a) y = sel ? a * b : a * c; (b) y = sel ? a + b : c + d; (c) (b) は必ず得になるか。

Click to reveal solution點擊展開解答クリックで解答を表示

(a) y = a * (sel ? b : c); — one multiplier + one mux.(a) y = a * (sel ? b : c); — 一個乘法器加一個多工器。(a) y = a * (sel ? b : c); — 乗算器 1 個とマルチプレクサ 1 個。

(b) y = (sel ? a : c) + (sel ? b : d); — one adder + two muxes.(b) y = (sel ? a : c) + (sel ? b : d); — 一個加法器加兩個多工器。(b) y = (sel ? a : c) + (sel ? b : d); — 加算器 1 個とマルチプレクサ 2 個。

(c) For narrow adders two muxes may cost as much as the saved adder, and the mux now sits in front of the adder, lengthening the critical path. Sharing pays off for large units (multipliers, wide adders) and when timing has slack.(c) 對位元數少的加法器而言,兩個多工器的成本可能和省下的那個加法器差不多;而且多工器現在擋在加法器前面,會拉長關鍵路徑。只有在運算單元很大(乘法器、寬加法器)且時序還有餘裕時,共享才划算。(c) ビット幅の小さい加算器では、マルチプレクサ 2 個のコストが節約した加算器と同程度になりうる。しかもマルチプレクサが加算器の前に入るため、クリティカルパスが延びる。共有が得になるのは、演算器が大きい場合(乗算器や幅の広い加算器)と、タイミングに余裕がある場合である。

11. Summary and Exam Checklist11. 總結與考前檢查表11. まとめと試験前チェックリスト

Synthesis basics合成基礎合成の基本
  • Translate → optimize → map.轉譯 → 最佳化 → 映射。変換 → 最適化 → マッピング。
  • Verify netlist with the same test bench.用同一個測試平台驗證 netlist。同じテストベンチでネットリストを検証する。
  • No initial, delays, ===, fork, wait.不可用 initial、延遲、===、fork、wait。initial・遅延・===・fork・wait は使わない。
Minimization最小化最小化
  • Two-level: SOP.兩層:積之和(SOP)。2 段:積和形(SOP)。
  • Multi-level: decomposition, extraction, factoring, substitution, elimination.多層:分解、抽取、因式分解、代換、消去。多段:分解・抽出・因数分解・置換・消去。
Combinational always組合邏輯 always組合せ always
  • All inputs in the event list (@*).所有輸入都要列進事件列表(@*)。すべての入力をイベントリストに入れる(@*)。
  • Assign every output on every path.每條路徑都要指定到每個輸出。すべての経路ですべての出力に代入する。
  • No target used as its own operand.目標變數不可以當成自己的運算元。代入対象を自分自身のオペランドにしない。
Latches and loops閂鎖與迴路ラッチとループ
  • Missing case item / else → latch.少了 case 項目或 else → 閂鎖。case 項目や else の欠落 → ラッチ。
  • Fix with default / final else.用 default 或最後一個 else 補起來。default か最後の else で補う。
  • x = x feedback → combinational loop.x = x 的回授 → 組合邏輯迴路。x = x の帰還 → 組合せループ。
Mux vs priority多工器 vs 優先權マルチプレクサ vs 優先順位
  • Mutually exclusive → mux.條件互斥 → 多工器。互いに排他 → マルチプレクサ。
  • Overlapping → priority chain, first test highest.條件重疊 → 優先鏈,最先判斷的優先權最高。条件が重なる → 優先順位チェーン。最初に判定するものが最優先。
  • Priority encoder: if chain or casex.優先編碼器:if 串接或 casex。プライオリティエンコーダ:if チェーンか casex。
Buses and cost匯流排與成本バスとコスト
  • cond ? v : 'bz → tri-state.cond ? v : 'bz → 三態。cond ? v : 'bz → トライステート。
  • One driver per bus via nested ?:.用巢狀 ?: 讓每條匯流排只有一個驅動器。入れ子の ?: でバスごとにドライバを 1 個にする。
  • default x = don't care; share adders.default x 就是 don't care;加法器要共用。default x はドントケア。加算器は共有する。
Latch-free template不會產生閂鎖的樣板ラッチを生まないテンプレート
always @*                 // complete sensitivity
  begin
    y = DEFAULT_VALUE;      // every path assigned
    case (sel)
      ...
      default: y = 'bx;     // complete list, don't care
    endcase
  end