Digital IC design flow, levels of abstraction, Verilog basics, descriptive styles, module hierarchy and first sequential circuits — an introductory self-study guide.數位 IC 設計流程、抽象層次、Verilog 基礎、描述風格、模組階層與第一個序向電路 — 數位 IC 設計流程與 Verilog 入門自學指南。デジタル IC 設計フロー、抽象化レベル、Verilog の基礎、記述スタイル、モジュール階層、そして最初の順序回路 — 入門者向け自学ガイド。
| Stage階段段階 | Steps步驟手順 |
|---|---|
| Front-end (this course)前段(本課程)フロントエンド(本講義) | Verilog HDL → synthesis → design for testability (DFT) → automatic test pattern generation (ATPG)Verilog HDL → 合成 → 可測試性設計 (DFT) → 自動測試樣型產生 (ATPG)Verilog HDL → 合成 → テスト容易化設計 (DFT) → 自動テストパターン生成 (ATPG) |
| Back-end後段バックエンド | Automatic place and route (APR) → tape-out (TO)自動佈局與繞線 (APR) → 下線 (TO)自動配置配線 (APR) → テープアウト (TO) |
| Chip measurement晶片量測チップ測定 | Pattern generator (PG) and logic analyzer (LA)樣型產生器 (PG) 與邏輯分析儀 (LA)パターンジェネレータ (PG) とロジックアナライザ (LA) |
Research steps: study reference ICs, model the algorithm (e.g. in C or MATLAB), write Verilog, then use CAD tools (simulator, synthesis, TetraMAX for ATPG) to reach your own IC. Verilog is the hub of the whole front end.研究的步驟:先研讀參考 IC,再用 C 或 MATLAB 把演算法模型化,接著寫 Verilog,最後用 CAD 工具(模擬器、合成工具、做 ATPG 的 TetraMAX)做出自己的 IC。Verilog 是整個前段流程的樞紐。研究の手順:まず参考となる IC を調べ、C や MATLAB でアルゴリズムをモデル化し、次に Verilog を書き、最後に CAD ツール(シミュレータ、合成ツール、ATPG 用の TetraMAX)を使って自分の IC に仕上げる。Verilog はフロントエンド全体の中心にある。
| Level層次レベル | What is described描述的內容記述される内容 | Typical artifact典型產出典型的な成果物 |
|---|---|---|
| System specification系統規格システム仕様 | Function blocks and their behavior功能方塊與其行為機能ブロックとその動作 | Block diagram, spec document方塊圖、規格書ブロック図、仕様書 |
| Algorithm realization & architecture演算法實現與架構アルゴリズム実現とアーキテクチャ | Algorithm mapping onto hardware resources把演算法對應到硬體資源アルゴリズムのハードウェア資源への割り当て | C / MATLAB model, architecture diagramC / MATLAB 模型、架構圖C / MATLAB モデル、アーキテクチャ図 |
| Register transfer level (RTL)暫存器轉移層 (RTL)レジスタ転送レベル (RTL) | Data flow between registers暫存器之間的資料流レジスタ間のデータの流れ | Verilog RTLVerilog RTLVerilog RTL |
| Gate level閘級ゲートレベル | Logic gates and interconnections邏輯閘與其間的連線論理ゲートとその配線 | NetlistNetlistNetlist |
| Transistor level電晶體級トランジスタレベル | Transistors and interconnections; physical layout電晶體與其間的連線;實體佈局トランジスタとその配線、および物理レイアウト | SPICE netlist, layout (e.g. an inverter cell), APR chip layoutSPICE netlist、佈局(例如一個反相器 cell)、APR 晶片佈局SPICE netlist、レイアウト(例:インバータセル)、APR によるチップレイアウト |
Going down the list increases detail; going up increases behavioral abstraction.沿著表往下走,細節愈來愈多;往上走,行為的抽象程度愈來愈高。表を下へ行くほど詳細になり、上へ行くほど動作の抽象度が上がる。
| Abstraction抽象層次抽象化レベル | Behavioral行為動作 | Structural結構構造 | Physical實體物理 |
|---|---|---|---|
| Architecture架構アーキテクチャ | System spec系統規格システム仕様 | Processors, memories處理器、記憶體プロセッサ、メモリ | Chip floorplan晶片佈局規劃チップのフロアプラン |
| Algorithm / RTL演算法 / RTLアルゴリズム / RTL | Algorithms, register transfers演算法、暫存器轉移アルゴリズム、レジスタ転送 | Registers, ALUs, muxes暫存器、ALU、多工器レジスタ、ALU、マルチプレクサ | Macro placement巨集的擺放マクロの配置 |
| Logic邏輯論理 | Boolean equations布林方程式ブール式 | Gates, flip-flops邏輯閘、正反器ゲート、フリップフロップ | Cell placement單元的擺放セルの配置 |
| Transistor電晶體トランジスタ | Transfer functions轉移函數伝達関数 | Transistors電晶體トランジスタ | Layout佈局レイアウト |
Moving down a column is synthesis (architecture → RTL → logic → layout); checking that each lower level matches the upper one is verification.在同一欄裡往下走就是合成(架構 → RTL → 邏輯 → 佈局);確認下面一層與上面一層相符,則是驗證。同じ列を下へ進むことが合成(アーキテクチャ → RTL → 論理 → レイアウト)であり、下位の層が上位の層と一致するかを確かめることが検証である。
| Verilog (this course)Verilog(本課程)Verilog(本講義) | VHDLVHDLVHDL | |
|---|---|---|
| Origin起源起源 | Gateway, 1984; opened by Cadence 1990Gateway,1984 年;1990 年由 Cadence 公開Gateway、1984 年。1990 年に Cadence が公開 | VHSIC project, 1980sVHSIC 計畫,1980 年代VHSIC プロジェクト、1980 年代 |
| Standard標準規格 | IEEE 1364 (1995)IEEE 1364 (1995)IEEE 1364 (1995) | IEEE 1076 (1987), IEEE 1164 (1993)IEEE 1076 (1987)、IEEE 1164 (1993)IEEE 1076 (1987)、IEEE 1164 (1993) |
| Strength強項得意分野 | Slightly better at gate / transistor level在閘級/電晶體級稍佔優勢ゲート/トランジスタレベルがやや得意 | Slightly better at system level在系統層級稍佔優勢システムレベルがやや得意 |
| Style語法風格文体 | Close to C/C++接近 C/C++C/C++ に近い | Close to Ada / Pascal接近 Ada / PascalAda / Pascal に近い |
| Types型別型 | Pre-defined, easy to use預先定義好,容易使用定義済みで使いやすい | User-defined, more flexible使用者自行定義,較有彈性ユーザー定義で柔軟 |
Both are equally effective — a matter of preference.兩者同樣有效,選哪一個只是偏好問題。どちらも同じように有効であり、好みの問題にすぎない。
module ... endmodule) is the basic building block. Modules are created by declaration, cannot be nested, and all run concurrently.模組(module ... endmodule)是最基本的建構單元。模組以宣告的方式建立,不能巢狀包在另一個模組裡,而且全部並行執行。モジュール(module ... endmodule)が基本の構成単位である。モジュールは宣言によって作られ、入れ子にはできず、すべて並行に動作する。input, output, inout.埠的方向有三種:input、output、inout。ポートの方向は input、output、inout の 3 種類である。module test (a, b, c, d); input a, b; output c, d; wire c, d; assign c = a | b; assign d = a & b; endmodule
Keywords wire, wand, wor, tri, triand, trior, supply0, supply1. Driven by assign; store no value; ports default to wire; cannot be assigned inside always.關鍵字為 wire, wand, wor, tri, triand, trior, supply0, supply1。由 assign 驅動;本身不儲存值;埠預設是 wire;不能在 always 裡面被指派。キーワードは wire, wand, wor, tri, triand, trior, supply0, supply1。assign で駆動され、値を保持しない。ポートは既定で wire となり、always の中では代入できない。
module test (a, b, c, d);
input a, b;
output c, d;
reg c, d;
always @ (a or b) begin // sensitivity list
c = a | b;
d = a & b;
end
endmodule
Keywords reg, integer, time, real. Assigned in always (event-driven). A reg is not necessarily a hardware register — here it is plain gates; it becomes storage only when tied to a clock.關鍵字為 reg, integer, time, real。在 always(事件驅動)中被指派。reg 不一定是硬體暫存器 — 這裡合成出來的只是純邏輯閘,只有接上時脈之後才會變成儲存元件。キーワードは reg, integer, time, real。always(イベント駆動)の中で代入される。reg は必ずしもハードウェアのレジスタではない — ここでは単なるゲートであり、クロックにつながって初めて記憶素子になる。
Values: 0, 1, x/X (unknown), z/Z (high impedance). Operators are defined on all four:四個值:0、1、x/X(未知)、z/Z(高阻抗)。所有運算子對這四個值都有定義:値は 0、1、x/X(不定)、z/Z(ハイインピーダンス)の 4 つ。演算子はこの 4 値すべてに対して定義されている:
| AND | 0 | 1 | x | z |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 1 | x | x |
| x | 0 | x | x | x |
| z | 0 | x | x | x |
A 0 on either input forces the AND output to 0 regardless of the other input — even x or z. A z input is read as unknown, so it produces x (a gate never outputs z unless it is a tri-state).只要任一個輸入是 0,AND 的輸出就被壓成 0,另一個輸入是什麼都沒差 — 即使是 x 或 z 也一樣。輸入的 z 會被當成未知,因此結果是 x(除非是三態閘,否則邏輯閘不會輸出 z)。どちらか一方の入力が 0 なら、もう一方が何であっても AND の出力は 0 になる — x や z であっても同じ。入力の z は不定として読まれるため結果は x になる(トライステートでない限り、ゲートが z を出力することはない)。
size = number of bits (decimal, optional); base: d/D, h/H, o/O, b/B. Shorter values are zero-extended on the left — or x/z-extended if the leftmost digit is x/z.size 是位元數(以十進位書寫,可省略);基底可用 d/D、h/H、o/O、b/B。位數不足時,左邊補 0 — 若最左邊那個數字是 x 或 z,則改補 x 或 z。size はビット数(10 進で書き、省略可)。基数は d/D、h/H、o/O、b/B。桁が足りない場合は左側に 0 が拡張される — 最左の桁が x または z なら、x/z が拡張される。
| Literal常量寫法リテラル | Stored bits實際儲存的位元格納されるビット |
|---|---|
6'b010111 | 01_0111 |
8'b0110 | 0000_0110 |
4'bx01 | xx01 |
16'H3AB | 0000_0011_1010_1011 |
12'd24 | 0000_0001_1000 |
5'O36 | 11110 |
16'Hx | xxxx_xxxx_xxxx_xxxx |
8'hz | zzzz_zzzz |
3'b5 | invalid — 5 is not a binary digit不合法 — 5 不是二進位數字不正 — 5 は 2 進数の数字ではない |
Problem: Write the stored bits: (a) 10'h2F (b) 6'o57 (c) 8'bz1 (d) 4'd20 (e) 'hA.題目:寫出實際儲存的位元:(a) 10'h2F (b) 6'o57 (c) 8'bz1 (d) 4'd20 (e) 'hA。問題:格納されるビットを書きなさい:(a) 10'h2F (b) 6'o57 (c) 8'bz1 (d) 4'd20 (e) 'hA。
(a) 00_0010_1111. (b) 101_111. (c) zzzz_zzz1 (z-extended). (d) 20 = 1_0100 needs 5 bits → truncated to 0100 (most tools warn). (e) Unsized: at least 32 bits, …0000_1010.(a) 00_0010_1111。(b) 101_111。(c) zzzz_zzz1(向左補 z)。(d) 20 = 1_0100 需要 5 個位元 → 被截成 0100(多數工具會發出警告)。(e) 未指定位寬:至少 32 位元,…0000_1010。(a) 00_0010_1111。(b) 101_111。(c) zzzz_zzz1(z が拡張される)。(d) 20 = 1_0100 は 5 ビット必要 → 0100 に切り捨てられる(多くのツールは警告を出す)。(e) サイズ指定なし:最低 32 ビットで、…0000_1010。
Problem: Evaluate: (a) 1'b0 & 1'bx (b) 1'b1 & 1'bz (c) 1'b1 | 1'bx (d) 1'b0 | 1'bz (e) 4'b10xz & 4'b1111.題目:求下列各式的值:(a) 1'b0 & 1'bx (b) 1'b1 & 1'bz (c) 1'b1 | 1'bx (d) 1'b0 | 1'bz (e) 4'b10xz & 4'b1111。問題:次の式を評価しなさい:(a) 1'b0 & 1'bx (b) 1'b1 & 1'bz (c) 1'b1 | 1'bx (d) 1'b0 | 1'bz (e) 4'b10xz & 4'b1111。
(a) 0 — a controlling 0. (b) x. (c) 1 — a 1 controls OR. (d) x. (e) 10xx.(a) 0 — 0 是 AND 的控制值。(b) x。(c) 1 — 1 是 OR 的控制值。(d) x。(e) 10xx。(a) 0 — 0 が AND の支配値。(b) x。(c) 1 — 1 が OR の支配値。(d) x。(e) 10xx。
| Level層次レベル | Model describes模型描述的內容モデルが記述するもの |
|---|---|
| Architectural / algorithmic架構/演算法層アーキテクチャ/アルゴリズムレベル | A design algorithm in high-level language constructs用高階語法結構寫出的設計演算法高水準な構文で書かれた設計アルゴリズム |
| RTLRTLRTL | Data flow between registers and how the design processes the data暫存器之間的資料流,以及設計如何處理這些資料レジスタ間のデータの流れと、設計がそのデータをどう処理するか |
| Gate閘級ゲートレベル | Logic gates and their interconnections邏輯閘與其間的連線論理ゲートとその配線 |
| Transistor電晶體級トランジスタレベル | Transistors and their interconnections電晶體與其間的連線トランジスタとその配線 |
| Style描述風格スタイル | Key features主要特徵主な特徴 |
|---|---|
| 1. Behavioral1. 行為描述1. 動作記述 | Procedural, C-like: if-else, case, loops; arithmetic, logical, bitwise, reduction operators; timing control程序式、寫起來像 C:if-else、case、迴圈;算術、邏輯、位元與縮減運算子;還有時間控制手続き的で C に近い:if-else、case、ループ。算術・論理・ビット・リダクション演算子、そしてタイミング制御 |
| 2. RTL / dataflow2. RTL/資料流2. RTL/データフロー | Flow of data; split into combinational logic and sequential registers著重資料的流動;拆成組合邏輯與序向的暫存器兩部分データの流れを書く。組合せ論理と順序回路のレジスタに分けて考える |
| 3. Structural3. 結構描述3. 構造記述 | Instantiation of primitives and modules; gate delays and output strengths實例化基本閘與模組;可指定閘延遲與輸出強度プリミティブとモジュールのインスタンス化。ゲート遅延や出力強度も指定できる |
module fa_bhv (S, CO, A, B, CI); output S, CO; input A, B, CI; reg S, CO; // hold values between events always @ (A or B or CI) begin // procedural assignments S = A ^ B ^ CI; CO = A & B | A & CI | B & CI; end endmodule
module fa_rtl (S, CO, A, B, CI); output S, CO; input A, B, CI; assign S = A ^ B ^ CI; // continuous assign CO = A & B | A & CI | B & CI; // continuous endmodule
module full_add (S, CO, A, B, CI); output S, CO; input A, B, CI; wire N1, N2, N3; half_add HA1 (N1, N2, A, B), // module name, instance names HA2 (S, N3, N1, CI); or P1 (CO, N3, N2); // primitive endmodule
module half_add (S, C, X, Y); output S, C; input X, Y; xor (S, X, Y); and (C, X, Y); endmodule
All three describe the same hardware. Note that one instantiation statement can create several instances separated by commas (HA1 (...), HA2 (...)).三種寫法描述的是同一組硬體。另外注意,一條實例化敘述可以用逗號隔開,一次建立好幾個實例(HA1 (...), HA2 (...))。三つとも同じハードウェアを記述している。1 つのインスタンス化文をカンマで区切り、複数のインスタンスを一度に生成できる点にも注意(HA1 (...), HA2 (...))。
An HDL describes a design by structure, behavior or a mix. Circuits are combinational (pure logic function) or sequential (with a clock). A schematic focuses on structural detail.HDL 可以用結構、行為、或兩者混合的方式描述一個設計。電路分成組合電路(純粹的邏輯函數)與序向電路(有時脈)。電路圖著重的則是結構上的細節。HDL は設計を構造・動作、あるいはその組合せで記述する。回路は組合せ回路(純粋な論理関数)と順序回路(クロックをもつ)に分かれる。回路図が重点を置くのは構造の詳細である。
module Add_half (sum, c_out, a, b); // module name, ports input a, b; // port modes output sum, c_out; wire c_out_bar; // internal signal xor (sum, a, b); // primitive gates nand (c_out_bar, a, b); not (c_out, c_out_bar); endmodule
module Add_half (sum, c_out, a, b);
input a, b;
output sum, c_out;
reg sum, c_out;
always @ (a or b)
begin
sum = a ^ b; // exclusive or
c_out = a & b; // and
end
endmodulemodule add_half (sum, c_out, a, b);
input a, b;
output sum, c_out;
assign {c_out, sum} = a + b; // concatenation on the LHS
endmodule
The concatenation {c_out, sum} forms a 2-bit target, so the carry of a + b lands in c_out.串接 {c_out, sum} 組成一個 2 位元的指派目標,因此 a + b 的進位就落在 c_out 上。連結 {c_out, sum} は 2 ビットの代入先を作るので、a + b の桁上げが c_out に入る。
module nand2_1 (y, x1, x2); input x1, x2; output y; assign y = ~(x1 & x2); endmodule
module nand2_2 (y, x1, x2); input x1, x2; output y; wire y = ~(x1 & x2); endmodule
A continuous assignment is a static binding between LHS and RHS; there is no mechanism to remove or change it.連續指派是左式與右式之間的靜態繫結;語言裡沒有任何機制可以把它移除或改掉。連続代入は左辺と右辺の静的な結び付きであり、これを取り除いたり変更したりする手段はない。
The slide writes x1 ~& x2. In Verilog ~& exists only as a unary reduction NAND (~&bus); a two-operand NAND is written ~(x1 & x2), as above.投影片寫成 x1 ~& x2。在 Verilog 裡,~& 只以單元縮減 NAND 的形式存在(~&bus);兩個運算元的 NAND 要像上面那樣寫成 ~(x1 & x2)。スライドには x1 ~& x2 と書かれている。Verilog の ~& は単項のリダクション NAND(~&bus)としてしか存在せず、2 項の NAND は上のように ~(x1 & x2) と書く。
module and4_rtl (y_out, x_in); input [3:0] x_in; output y_out; assign y_out = & x_in; // reduction AND // alternative (bitwise AND): // assign y_out = x_in[3] & x_in[2] & x_in[1] & x_in[0]; endmodule
module and4_alg (y_out, x_in);
input [3:0] x_in;
output y_out;
reg y_out;
integer k;
always @ (x_in)
begin: and_loop
y_out = 1;
for (k = 0; k <= 3; k = k + 1)
if (x_in[k] == 0)
begin
y_out = 0;
disable and_loop;
end
end
endmoduleCompare $A = \{A_1, A_0\}$ and $B = \{B_1, B_0\}$; outputs A_lt_B, A_gt_B, A_eq_B. From the truth table (K-map):比較 $A = \{A_1, A_0\}$ 與 $B = \{B_1, B_0\}$;輸出為 A_lt_B、A_gt_B、A_eq_B。由真值表(卡諾圖)化簡可得:$A = \{A_1, A_0\}$ と $B = \{B_1, B_0\}$ を比較する。出力は A_lt_B、A_gt_B、A_eq_B。真理値表(カルノー図)より:
module compare_2_str (A_lt_B, A_gt_B, A_eq_B, A0, A1, B0, B1); input A0, A1, B0, B1; output A_lt_B, A_gt_B, A_eq_B; wire w1, w2, w3, w4, w5, w6, w7; or (A_lt_B, w1, w2, w3); nor (A_gt_B, A_lt_B, A_eq_B); // neither less nor equal and (A_eq_B, w4, w5); and (w1, w6, B1); // ~A1 B1 and (w2, w6, w7, B0); // ~A1 ~A0 B0 and (w3, w7, B0, B1); // ~A0 B1 B0 not (w6, A1); not (w7, A0); xnor (w4, A1, B1); // A1 == B1 xnor (w5, A0, B0); // A0 == B0 endmodule
module compare_2a (A_lt_B, A_gt_B, A_eq_B, A1, A0, B1, B0);
input A1, A0, B1, B0;
output A_lt_B, A_gt_B, A_eq_B;
assign A_lt_B = (~A1) & B1 | (~A1) & (~A0) & B0 | (~A0) & B1 & B0;
assign A_gt_B = A1 & (~B1) | A0 & (~B1) & (~B0) | A1 & A0 & (~B0);
assign A_eq_B = (~A1) & (~A0) & (~B1) & (~B0) | (~A1) & A0 & (~B1) & B0
| A1 & A0 & B1 & B0 | A1 & (~A0) & B1 & (~B0);
endmodule
module compare_2b (A_lt_B, A_gt_B, A_eq_B,
A1, A0, B1, B0);
input A1, A0, B1, B0;
output A_lt_B, A_gt_B, A_eq_B;
assign A_lt_B = ({A1, A0} < {B1, B0});
assign A_gt_B = ({A1, A0} > {B1, B0});
assign A_eq_B = ({A1, A0} == {B1, B0});
endmodulemodule compare_2ca (A_lt_B, A_gt_B, A_eq_B, A, B); input [1:0] A, B; output A_lt_B, A_gt_B, A_eq_B; assign A_lt_B = (A < B); assign A_gt_B = (A > B); assign A_eq_B = (A == B); endmodule
module compare_2_algo (A_lt_B, A_gt_B, A_eq_B, A, B);
input [1:0] A, B;
output A_lt_B, A_gt_B, A_eq_B;
reg A_lt_B, A_gt_B, A_eq_B;
always @ (A or B) // behavior and event expression
begin
A_lt_B = 0;
A_gt_B = 0;
A_eq_B = 0;
if (A == B) A_eq_B = 1;
else if (A > B) A_gt_B = 1;
else A_lt_B = 1;
end
endmodule
Synthesis (Synopsys Design Compiler / Design Vision, Cadence Encounter RTL Compiler) turns any of these into gates — a few inverters, NAND/NOR/OR gates and buffers. The regs here are not flip-flops: there is no clock.合成(Synopsys Design Compiler / Design Vision、Cadence Encounter RTL Compiler)會把上面任何一種寫法都變成閘 — 幾個反相器、NAND/NOR/OR 閘與緩衝器。這裡的 reg 並不是正反器:因為沒有時脈。合成(Synopsys Design Compiler / Design Vision、Cadence Encounter RTL Compiler)は、これらのどの記述もゲートに変換する — 数個のインバータ、NAND/NOR/OR ゲート、バッファである。ここの reg はフリップフロップではない。クロックがないからである。
Problem: (a) Verify A_lt_B for A = 01, B = 10 using the Type 2 equation. (b) Why can the structural version compute A_gt_B as a NOR of the other two outputs? (c) Extend compare_2ca to 8-bit operands.題目:(a) 用型式 2 的式子驗證 A = 01、B = 10 時的 A_lt_B。(b) 為什麼結構版可以把 A_gt_B 算成另外兩個輸出的 NOR?(c) 把 compare_2ca 擴充成 8 位元運算元。問題:(a) タイプ 2 の式を使い、A = 01、B = 10 のときの A_lt_B を確かめなさい。(b) 構造記述版で A_gt_B を残り 2 つの出力の NOR として求められるのはなぜか。(c) compare_2ca を 8 ビットのオペランドに拡張しなさい。
(a) A1 = 0, A0 = 1, B1 = 1, B0 = 0: first term $\bar A_1 B_1 = 1$ → A_lt_B = 1. ✔ (1 < 2)(a) A1 = 0、A0 = 1、B1 = 1、B0 = 0:第一項 $\bar A_1 B_1 = 1$ → A_lt_B = 1。✔(1 < 2)(a) A1 = 0、A0 = 1、B1 = 1、B0 = 0:第 1 項が $\bar A_1 B_1 = 1$ → A_lt_B = 1。✔(1 < 2)
(b) Exactly one of lt, gt, eq is true, so gt = NOT(lt OR eq).(b) lt、gt、eq 三者恰好只有一個為真,所以 gt = NOT(lt OR eq)。(b) lt・gt・eq のうち真になるのはちょうど 1 つなので、gt = NOT(lt OR eq) と書ける。
(c) Change input [1:0] A, B; to input [7:0] A, B; — nothing else. The multi-bit relational style scales; the gate-level style does not.(c) 只要把 input [1:0] A, B; 改成 input [7:0] A, B;,其餘完全不動。多位元的關係運算寫法可以放大規模;閘級寫法則不行。(c) input [1:0] A, B; を input [7:0] A, B; に変えるだけでよい。多ビットの関係演算による記述は規模を拡張できるが、ゲートレベルの記述はそうはいかない。
module child (a, b, c); ... endmodule
module parent; wire u, v, w; child m1 (u, v, w); // by position child m2 (.c(w), .a(u), .b(v)); // by name child m3 (u, , w); // empty port (b unconnected) endmodule
module Add_full (sum, c_out, a, b, c_in); // parent module input a, b, c_in; output c_out, sum; wire w1, w2, w3; Add_half M1 (w1, w2, a, b); // child module Add_half M2 (sum, w3, w1, c_in); // child module or (c_out, w2, w3); // primitive instantiation endmodule
| Netnetnet | Value值値 |
|---|---|
| w1 | $a \oplus b$ |
| w2 | $ab$ |
| w3 | $(a \oplus b)\,c_{in}$ |
| sum | $(a \oplus b) \oplus c_{in}$ |
| c_out | $(a \oplus b)\,c_{in} + ab$ |
Hierarchy: Add_full → M1, M2 (Add_half, each containing xor, nand, not) and an or. Nested instantiation is the mechanism for hierarchical decomposition. (The primitive instance name is optional; module instance names are required.)階層:Add_full → M1、M2(都是 Add_half,各自含 xor、nand、not),再加一個 or。層層實例化就是做階層式分解的手段。(基本閘的實例名稱可省略;模組的實例名稱則一定要寫。)階層:Add_full → M1、M2(いずれも Add_half で、それぞれ xor・nand・not を含む)と or 1 個。インスタンス化を入れ子にすることが階層的な分割の手段である。(プリミティブのインスタンス名は省略できるが、モジュールのインスタンス名は必須である。)
module Add_rca_16 (sum, c_out, a, b, c_in); output [15:0] sum; output c_out; input [15:0] a, b; input c_in; wire c_in4, c_in8, c_in12; Add_rca_4 M1 (sum[3:0], c_in4, a[3:0], b[3:0], c_in); Add_rca_4 M2 (sum[7:4], c_in8, a[7:4], b[7:4], c_in4); Add_rca_4 M3 (sum[11:8], c_in12, a[11:8], b[11:8], c_in8); Add_rca_4 M4 (sum[15:12], c_out, a[15:12], b[15:12], c_in12); endmodule
module Add_rca_4 (sum, c_out, a, b, c_in); output [3:0] sum; output c_out; input [3:0] a, b; input c_in; wire c_in2, c_in3, c_in4; Add_full G1 (sum[0], c_in2, a[0], b[0], c_in); Add_full G2 (sum[1], c_in3, a[1], b[1], c_in2); Add_full G3 (sum[2], c_in4, a[2], b[2], c_in3); Add_full G4 (sum[3], c_out, a[3], b[3], c_in4); endmodule
The slide also lists c_in and c_out in the wire declaration of Add_rca_16; redeclaring ports as wire is legal in Verilog-1995 style but redundant.投影片在 Add_rca_16 的 wire 宣告裡還列了 c_in 與 c_out;在 Verilog-1995 的寫法中把埠再宣告一次 wire 是合法的,但多此一舉。スライドでは Add_rca_16 の wire 宣言に c_in と c_out も挙げられている。Verilog-1995 形式ではポートを wire として再宣言しても文法上は正しいが、冗長である。
module array_of_nor (y, a, b);
input [0:7] a, b;
output [0:7] y;
nor array [0:7] (y, a, b); // 8 NOR gates
endmodulemodule array_of_adders (sum, c_out, a, b, c_in);
input [3:0] a, b;
input c_in;
output [3:0] sum;
output c_out;
wire [3:1] carry;
Add_full M [3:0] (sum, {c_out, carry[3:1]},
a, b, {carry[3:1], c_in});
endmoduleThe vectors are split bit by bit across the instances. Example 2 is equivalent to:向量會逐位元分配到各個實例上。範例 2 等同於:ベクタはビットごとに各インスタンスへ振り分けられる。例 2 は次と等価である:
Add_full M[0] (sum[0], carry[1], a[0], b[0], c_in); Add_full M[1] (sum[1], carry[2], a[1], b[1], carry[1]); Add_full M[2] (sum[2], carry[3], a[2], b[2], carry[2]); Add_full M[3] (sum[3], c_out, a[3], b[3], carry[3]);
Problem: For module child (a, b, c); inside parent with wires u, v, w: (a) which child ports connect to which wires in child m2 (.c(w), .a(u), .b(v));? (b) Rewrite child m3 (u, , w); by name. (c) What is wrong with child (u, v, w);?題目:parent 內有 wire u、v、w,子模組為 module child (a, b, c);:(a) 在 child m2 (.c(w), .a(u), .b(v)); 裡,哪個埠接到哪一條線?(b) 把 child m3 (u, , w); 改寫成具名接法。(c) child (u, v, w); 錯在哪裡?問題:parent の中に wire u・v・w があり、子モジュールは module child (a, b, c); とする。(a) child m2 (.c(w), .a(u), .b(v)); では、どのポートがどの線につながるか。(b) child m3 (u, , w); を名前による接続で書き直しなさい。(c) child (u, v, w); の何が誤りか。
(a) a–u, b–v, c–w (order in the list does not matter). (b) child m3 (.a(u), .c(w)); or with .b(). (c) No instance name — module instances must be named (only primitive instances may omit the name).(a) a–u、b–v、c–w(寫的順序不影響結果)。(b) child m3 (.a(u), .c(w));,或再補上 .b()。(c) 少了實例名稱 — 模組實例一定要命名(只有基本閘的實例可以省略名稱)。(a) a–u、b–v、c–w(並べる順序は関係しない)。(b) child m3 (.a(u), .c(w));、または .b() を加えた形。(c) インスタンス名がない — モジュールのインスタンスには名前が必要である(名前を省略できるのはプリミティブのインスタンスだけ)。
Problem: In the half-adder–based Add_full, assume every gate (xor, nand, not, or) has delay 1. What is the worst-case delay from c_in to c_out of one full adder, and from c_in to c_out of Add_rca_16?題目:在用半加器組成的 Add_full 中,假設每個閘(xor、nand、not、or)的延遲都是 1。單一個全加器從 c_in 到 c_out 的最壞延遲是多少?整個 Add_rca_16 從 c_in 到 c_out 又是多少?問題:半加算器で構成した Add_full において、各ゲート(xor・nand・not・or)の遅延をすべて 1 とする。全加算器 1 個の c_in から c_out までの最悪遅延はいくらか。また Add_rca_16 の c_in から c_out まではいくらか。
In one full adder, c_in → M2 (nand 1 + not 1) → or 1 = 3. The carry passes through 16 full adders: 16 × 3 = 48 gate delays. This linear growth is why carry look-ahead and pipelining (Lecture 6) exist.在單一個全加器裡,c_in → M2(nand 1 + not 1)→ or 1,合計 3。進位必須走過 16 個全加器:16 × 3 = 48 個閘延遲。正因為延遲隨位元數線性成長,才會有超前進位與管線化(第 6 講)這些手法。全加算器 1 個では、c_in → M2(nand 1 + not 1)→ or 1 で合計 3。桁上げは 16 個の全加算器を通るので、16 × 3 = 48 ゲート遅延となる。この線形な増加があるからこそ、キャリールックアヘッドやパイプライン化(第 6 講)が存在する。
module Flip_flop (q, data_in, clk, rst);
input data_in, clk, rst;
output q;
reg q;
always @ (posedge clk) // synchronous behavior
begin
if (rst == 1) q = 0;
else q = data_in;
end
endmodulemodule Flip_flop (q, data_in, clk, set, rst);
input data_in, clk, set, rst;
output q;
reg q;
always @ (posedge clk)
begin
if (rst == 0) q = 0;
else
if (set == 0) q = 1;
else q = data_in;
end
endmoduleBoth are synchronous controls — reset and set act only at the rising clock edge. Reset has priority over set because it is tested first. (Asynchronous controls appear in Lecture 4 and Lecture 6.) Clocked logic is usually written with <=; the slides use =, which is harmless here because each block assigns one variable.兩者都是同步控制 — reset 與 set 只在時脈上升緣才作用。因為 reset 先被判斷,所以優先權高於 set。(非同步控制會在第 4 講與第 6 講出現。)時脈驅動的邏輯通常用 <= 撰寫;投影片用的是 =,在這裡無害,因為每個區塊只指派一個變數。どちらも同期制御である — reset と set はクロックの立ち上がりエッジでのみ作用する。reset が先に判定されるため set より優先される。(非同期制御は第 4 講と第 6 講で扱う。)クロック同期の論理は通常 <= で書くが、スライドでは = を使っている。ここでは各ブロックが変数を 1 つしか代入しないので問題はない。
module array_of_flops (q, data_in, clk, set, rst); input [7:0] data_in; input clk, set, rst; output [7:0] q; Flip_flop M [7:0] (q, data_in, clk, set, rst); endmodule
module array_pipeline (q, data_in, clk, set, rst);
input [7:0] data_in;
input clk, set, rst;
output [7:0] q;
wire [23:0] pipe;
array_of_flops M [3:0] ({q, pipe}, {pipe, data_in},
clk, set, rst);
endmodule{q, pipe} is 32 bits and is split into four 8-bit outputs; {pipe, data_in} into four 8-bit inputs. Instance M[0] gets data_in → pipe[7:0]; M[3] gets pipe[23:16] → q. Scalars clk, set, rst are shared by every instance.{q, pipe} 共 32 位元,被切成四組 8 位元輸出;{pipe, data_in} 則切成四組 8 位元輸入。實例 M[0] 拿到 data_in → pipe[7:0];M[3] 拿到 pipe[23:16] → q。純量訊號 clk、set、rst 由每個實例共用。{q, pipe} は 32 ビットで、8 ビットずつ 4 つの出力に分けられる。{pipe, data_in} も 8 ビットずつ 4 つの入力に分けられる。インスタンス M[0] は data_in → pipe[7:0]、M[3] は pipe[23:16] → q となる。スカラ信号 clk・set・rst はすべてのインスタンスで共有される。
Problem: set = rst = 1 (inactive). All registers start at 0. data_in = 8'h11, 8'h22, 8'h33, 8'h44, 8'h55 at clock edges 1–5. Give pipe and q after edges 4 and 5. What happens if rst = 0 at edge 6?題目:set = rst = 1(皆未作用)。所有暫存器初值為 0。第 1–5 個時脈邊緣時 data_in 依序為 8'h11、8'h22、8'h33、8'h44、8'h55。寫出第 4 與第 5 個邊緣之後的 pipe 與 q。若第 6 個邊緣時 rst = 0,會發生什麼事?問題:set = rst = 1(どちらも非アクティブ)。すべてのレジスタの初期値は 0 とする。クロックエッジ 1〜5 で data_in は 8'h11、8'h22、8'h33、8'h44、8'h55 とする。エッジ 4 と 5 の後の pipe と q を示しなさい。エッジ 6 で rst = 0 になったらどうなるか。
After edge 4: pipe[7:0] = 44, pipe[15:8] = 33, pipe[23:16] = 22, q = 11.第 4 個邊緣之後:pipe[7:0] = 44、pipe[15:8] = 33、pipe[23:16] = 22、q = 11。エッジ 4 の後:pipe[7:0] = 44、pipe[15:8] = 33、pipe[23:16] = 22、q = 11。
After edge 5: 55, 44, 33, q = 22.第 5 個邊緣之後:55、44、33,q = 22。エッジ 5 の後:55、44、33、q = 22。
Edge 6 with rst = 0: every stage clears to 00 at that edge (synchronous reset).第 6 個邊緣且 rst = 0:該邊緣一到,每一級都被清成 00(同步重置)。エッジ 6 で rst = 0 のとき:そのエッジですべての段が 00 にクリアされる(同期リセット)。
$; up to 1024 characters; the first character must not be a digit or $.識別字可用字母、數字、底線與 $;長度最多 1024 個字元;第一個字元不可以是數字或 $。識別子に使えるのは英字・数字・アンダースコア・$ で、長さは最大 1024 文字。先頭の文字に数字や $ は使えない。// single line and /* block */.註解有兩種:// single line 與 /* block */。コメントは // single line と /* block */ の 2 種類である。`define state0 3'b001.編譯器指令以反引號開頭:`define state0 3'b001。コンパイラディレクティブはバッククォートで始まる:`define state0 3'b001。$ are built-in system tasks / functions, e.g. $monitor.以 $ 開頭的名稱是內建的系統任務/函數,例如 $monitor。$ で始まる名前は組み込みのシステムタスク/関数である(例:$monitor)。assign and always code.把基本觀念與語法學好,找一個好的參考對象(人或程式碼),並養成好習慣:命名規則、註解,以及把 assign 與 always 的程式碼分開寫。基本的な概念と文法を身につけ、良い手本(人でもコードでもよい)を持ち、良い習慣をつけること:命名規則、コメント、そして assign と always のコードを分けて書くこと。Problem: Which are legal identifiers? data_in, 2bit, _tmp, $count, reg, Reg, a$b, clk-1.題目:下列哪些是合法的識別字?data_in、2bit、_tmp、$count、reg、Reg、a$b、clk-1。問題:次のうち正しい識別子はどれか。data_in、2bit、_tmp、$count、reg、Reg、a$b、clk-1。
Legal: data_in, _tmp, Reg (case sensitive, so not the keyword), a$b. Illegal: 2bit (starts with a digit), $count (starts with $ — reserved for system tasks), reg (keyword), clk-1 (- not allowed; parsed as subtraction).合法:data_in、_tmp、Reg(區分大小寫,所以它不是關鍵字)、a$b。不合法:2bit(以數字開頭)、$count(以 $ 開頭,保留給系統任務)、reg(關鍵字)、clk-1(不能用 -,會被解析成減法)。正しいもの:data_in、_tmp、Reg(大文字小文字を区別するのでキーワードではない)、a$b。誤りのもの:2bit(数字で始まる)、$count($ で始まり、システムタスク用に予約されている)、reg(キーワード)、clk-1(- は使えず、減算として解釈される)。
assign.net:負責連接,用 assign 驅動。net:接続を表し、assign で駆動する。always; not always flip-flops.register:在 always 中指派;不一定是正反器。register:always で代入する。必ずしもフリップフロップではない。size'base value.格式為 size'base value。書式は size'base value。always, if/case/loops.行為描述:always、if/case/迴圈。動作記述:always、if/case/ループ。assign.RTL:assign。RTL:assign。