User-defined primitives, gate / net / module-path delay, `timescale, specify blocks, BNF syntax, system tasks and compiler directives — a self-study guide使用者自訂原型、閘/net/模組路徑延遲、`timescale、specify 區塊、BNF 語法、系統任務與編譯指令 — Verilog 模型語法自學指南ユーザー定義プリミティブ、ゲート/net/モジュールパス遅延、`timescale、specify ブロック、BNF 構文、システムタスクとコンパイラ指令 — Verilog モデル構文の自学ガイド
and, or, nand, nor, buf, not, xor, xnor, ...原型(primitive):語言內建、事先定義好的邏輯模型 — and, or, nand, nor, buf, not, xor, xnor, ...プリミティブ:言語があらかじめ定義している組み込みの論理モデル — and, or, nand, nor, buf, not, xor, xnor, ...and (d, a, b, c); is a 3-input AND with output d.輸出埠只有一個,而且一定排在最前面,後面接任意數目的輸入:and (d, a, b, c); 是輸出為 d 的三輸入 AND。出力ポートは必ず一つで、常に先頭に書く。その後に任意個の入力が続く:and (d, a, b, c); は出力が d の 3 入力 AND である。primitive ... endprimitive; body is a table ... endtable.關鍵字為 primitive ... endprimitive;本體是一個 table ... endtable。キーワードは primitive ... endprimitive、本体は table ... endtable である。and, or, not, ...實體化的寫法與 and、or、not 完全相同。インスタンス化の書き方は and、or、not とまったく同じ。inout.永遠只有一個輸出;不能有 inout。出力は常に一つ。inout は使えない。x.表中未列出的任何輸入組合,輸出一律被驅動為 x。表に書かれていない入力の組合せでは、出力は x になる。Rules shared by built-in and user-defined primitives:內建原型與使用者自訂原型共通的規則:組み込みプリミティブとユーザー定義プリミティブに共通する規則:
and (z1, x1, y1); and M1 (z2, x2, y2); my_udp (c2, a2, b2); my_udp N1 (c1, a1, b1);
| Symbol符號記号 | Meaning意義意味 |
|---|---|
0 1 x | Logic values (no z: a z input is treated as x)邏輯值(沒有 z:輸入的 z 會被當成 x)論理値(z は無い:入力の z は x として扱われる) |
? | Any of {0, 1, x}{0, 1, x} 之中任一{0, 1, x} のいずれか |
b | Any of {0, 1}{0, 1} 之中任一{0, 1} のいずれか |
(vw) | Input changes from v to w (each may be any symbol above)輸入由 v 變成 w(兩者都可以是上面任一符號)入力が v から w へ変化する(いずれも上記の記号でよい) |
- | No change (sequential output only)維持不變(只用於循序邏輯的輸出欄)変化なし(順序 UDP の出力欄のみ) |
* | (??) — any transition on the input(??) — 輸入的任何轉態(??) — 入力の任意の遷移 |
r / f | (01) rising / (10) falling(01) 上升 / (10) 下降(01) 立ち上がり / (10) 立ち下がり |
n inputs, 1 output, n+1 columns: the first n are the inputs (in port order), the last is the output.n 個輸入、1 個輸出,共 n+1 欄:前 n 欄是輸入(依埠的順序),最後一欄是輸出。入力 n 個、出力 1 個で n+1 列:先頭の n 列が入力(ポート順)、最後の列が出力である。
primitive mux_prim (mux_out, select, a, b); output mux_out; input select, a, b; table // select a b : mux_out 0 0 0 : 0; 0 0 1 : 0; 0 0 x : 0; 0 1 0 : 1; 0 1 1 : 1; 0 1 x : 1; 1 0 0 : 0; 1 1 0 : 0; 1 x 0 : 0; 1 0 1 : 1; 1 1 1 : 1; 1 x 1 : 1; x 0 0 : 0; // reduces pessimism x 1 1 : 1; endtable endprimitive
table // select a b : mux_out 0 0 ? : 0; // ? = 0, 1, x 0 1 ? : 1; 1 ? 0 : 0; 1 ? 1 : 1; ? 0 0 : 0; ? 1 1 : 1; endtable
The last two rows say: when both data inputs agree, the output is known even if select is unknown. Without them, select = x would always produce x (pessimism).最後兩列的意思是:兩個資料輸入相同時,即使 select 未知,輸出仍然確定。少了這兩列,select = x 就一定得到 x,也就是過度悲觀(pessimism)。最後の 2 行は、二つのデータ入力が一致していれば select が不定でも出力は確定する、という意味である。これが無いと select = x は常に x を生み、悲観的(pessimism)になる。
out = ab + ac + bc (majority)範例 — 布林函數 out = ab + ac + bc(多數決)例 — ブール関数 out = ab + ac + bc(多数決)primitive boolean_func (out, a, b, c);
output out;
input a, b, c;
table
// a b c : out
0 0 ? : 0;
0 ? 0 : 0;
? 0 0 : 0;
1 1 ? : 1;
1 ? 1 : 1;
? 1 1 : 1;
endtable
endprimitive
? cover the whole table.多數決函數:任兩個輸入為 0 就輸出 0,任兩個為 1 就輸出 1,用 ? 六列就能涵蓋。多数決関数:どれか二つの入力が 0 なら出力は 0、二つが 1 なら 1。? を使えば 6 行で表現できる。<inputs> : <state> : <output = next state>.n 個輸入、1 個狀態、1 個輸出,共 n+2 欄:<inputs> : <state> : <output = next state>。入力 n 個、状態 1 個、出力 1 個で n+2 列:<inputs> : <state> : <output = next state>。reg; the state column is the current value of that reg.輸出宣告為 reg;狀態欄就是該 reg 目前的值。出力は reg として宣言する。状態の列はその reg の現在値である。primitive latch (q_out, enable, data); output q_out; input enable, data; reg q_out; table // en data : state : q_out/next state 1 1 : ? : 1; 1 0 : ? : 0; 0 ? : ? : -; // "-" = no change endtable endprimitive
primitive d_prim1 (q_out, clock, data); output q_out; input clock, data; reg q_out; table // clk data : state : q_out/next state (01) 0 : ? : 0; // rising clock edge (01) 1 : ? : 1; (0?) 1 : 1 : 1; (?0) ? : ? : -; // falling clock edge ? (??) : ? : -; // steady clock, ignore data endtable endprimitive
The row (0?) 1 : 1 : 1 covers 0→x when data and state are both 1 — the output stays 1 regardless of whether the edge was real. The last row is essential: without it any change on data while the clock is steady would hit no row and drive q_out to x.(0?) 1 : 1 : 1 這一列涵蓋 data 與狀態都是 1 時的 0→x:不論那個邊緣是不是真的發生,輸出都維持 1。最後一列不可省略:少了它,時脈穩定不變時只要 data 有變化就會對不到任何一列,q_out 會被驅動成 x。(0?) 1 : 1 : 1 の行は、data と状態がともに 1 のときの 0→x を覆う。エッジが実際に起きたかどうかに関係なく出力は 1 のままになる。最後の行は不可欠で、これが無いとクロックが変化しない間に data が変わるとどの行にも一致せず、q_out が x になってしまう。
Problem: Give the output of boolean_func for (a) a=1,b=1,c=x (b) a=0,b=x,c=1 (c) a=z,b=0,c=0. Then for mux_prim (shorthand table): (d) select=x,a=1,b=0.題目:求 boolean_func 在下列情況的輸出:(a) a=1,b=1,c=x (b) a=0,b=x,c=1 (c) a=z,b=0,c=0。接著對 mux_prim(簡寫表):(d) select=x,a=1,b=0。問題:boolean_func の出力を求めよ。(a) a=1,b=1,c=x (b) a=0,b=x,c=1 (c) a=z,b=0,c=0。さらに mux_prim(短縮表)について (d) select=x,a=1,b=0。
(a) 1 — matches 1 1 ?.(a) 1 — 對應到 1 1 ? 這一列。(a) 1 — 1 1 ? の行に一致する。
(b) x — no row has a 0 and a 1 with the third input x; unlisted combinations give x (correct, since the result depends on b).(b) x — 沒有任何一列同時有一個 0、一個 1 而第三個輸入是 x;未列出的組合輸出為 x(這是對的,因為結果確實取決於 b)。(b) x — 0 と 1 が一つずつで第三の入力が x という行は存在しない。表に無い組合せは x になる(結果が b に依存するので正しい)。
(c) 0 — z is treated as x, which ? 0 0 covers.(c) 0 — z 被當成 x,而 ? 0 0 這一列涵蓋了它。(c) 0 — z は x として扱われ、? 0 0 の行が一致する。
(d) x — a and b differ, so the output really depends on select; only ? 0 0 and ? 1 1 cover select = x.(d) x — a 與 b 不同,輸出確實取決於 select;只有 ? 0 0 與 ? 1 1 兩列涵蓋 select = x。(d) x — a と b が異なるため出力は本当に select に依存する。select = x を覆うのは ? 0 0 と ? 1 1 だけである。
Problem: Write a falling-edge D flip-flop UDP with an active-low asynchronous clear clr_n, port order (q, clk, d, clr_n).題目:寫一個下降緣觸發的 D 型正反器 UDP,附低準位有效的非同步清除 clr_n,埠順序為 (q, clk, d, clr_n)。問題:立ち下がりエッジの D フリップフロップ UDP を書け。負論理の非同期クリア clr_n を持ち、ポート順は (q, clk, d, clr_n) とする。
primitive dff_neg_clr (q, clk, d, clr_n); output q; input clk, d, clr_n; reg q; table // clk d clr_n : q : q+ ? ? 0 : ? : 0; // clear dominates ? ? (?1) : ? : -; // releasing clear: hold (10) 0 1 : ? : 0; // falling edge (10) 1 1 : ? : 1; (1x) ? 1 : ? : -; // uncertain edges: hold (optimistic) (x0) ? 1 : ? : -; (0?) ? 1 : ? : -; // rising edge: hold ? (??) 1 : ? : -; // data change on steady clock endtable endprimitive
At most one edge specifier is allowed per row. UDP rows have no priority, so they must not conflict: every clock and data row requires clr_n = 1, leaving the clear row as the only match while clr_n = 0.每一列最多只能有一個邊緣指定子。UDP 的列沒有優先順序,因此不能互相衝突:所有時脈與資料的列都要求 clr_n = 1,於是 clr_n = 0 時只有清除那一列會被對應到。1 行に書けるエッジ指定子は最大一つである。UDP の行には優先順位が無いため、互いに矛盾してはならない。クロックとデータの行はすべて clr_n = 1 を要求しており、clr_n = 0 のときはクリアの行だけが一致する。
| Type種類種類 | Where it is written寫在哪裡記述する場所 | Behavior行為振る舞い |
|---|---|---|
| Gate delay閘延遲ゲート遅延 | On a primitive instance: and #3 (...)寫在原型實體上:and #3 (...)プリミティブのインスタンスに書く:and #3 (...) | Inertial — pulses shorter than the delay are swallowed慣性延遲 — 比延遲短的脈衝會被吞掉慣性遅延 — 遅延より短いパルスは飲み込まれる |
| Net delaynet 延遲net 遅延 | On a net declaration: wire #2 y;寫在 net 宣告上:wire #2 y;net の宣言に書く:wire #2 y; | Transport (per the lecture) — the waveform reaching the net is shifted傳輸延遲(transport)(依講義)— 送到該 net 的波形整個平移伝送遅延(transport)(講義による)— net に届く波形がそのまま平行移動する |
| Module path delay模組路徑延遲モジュールパス遅延 | In a specify block寫在 specify 區塊內specify ブロック内に書く | Pin-to-pin delay of a whole module整個模組的腳對腳延遲モジュール全体のピン間遅延 |
| Delay延遲遅延 | Transitions轉態遷移 |
|---|---|
| Rising上升立ち上がり | to 1 from anything else: 0→1, x→1, z→1由任何其他值變成 1:0→1、x→1、z→1他の値から 1 へ:0→1、x→1、z→1 |
| Falling下降立ち下がり | to 0 from anything else: 1→0, x→0, z→0由任何其他值變成 0:1→0、x→0、z→0他の値から 0 へ:1→0、x→0、z→0 |
| Turn-off關斷(turn-off)ターンオフ | to z from anything else: 0→z, 1→z, x→z由任何其他值變成 z:0→z、1→z、x→z他の値から z へ:0→z、1→z、x→z |
and (y, x1, x2); // zero delay and #2 (y, x1, x2); // all transitions 2 and #1.45 (y, x1, x2); // real delay, rounded to precision and #(2,3) (y, x1, x2); // (rise, fall) bufif1 #(3,4,1) (out, in, ctrl); // (rise, fall, turn-off) bufif1 #(3:4:5, 6:7:8, 5:8:9) (out, in, ctrl); // each as min:typ:max
| bufif1 in \ ctrl | 0 | 1 | x | z |
|---|---|---|---|---|
| 0 | z | 0 | L | L |
| 1 | z | 1 | H | H |
| x | z | x | x | x |
| z | z | x | x | x |
L = 0 or z, H = 1 or z. A turn-off delay only makes sense for tri-state gates, which is why plain and takes at most two values.L = 0 或 z,H = 1 或 z。關斷延遲只對三態閘有意義,所以單純的 and 最多只接受兩個延遲值。L は 0 または z、H は 1 または z。ターンオフ遅延は三状態ゲートにしか意味がないため、単なる and は最大 2 個の遅延値しか取らない。
| from \ to由 \ 到遷移元 \ 遷移先 | 0 | 1 | x | z |
|---|---|---|---|---|
| 0 | — | dr | d* | dz |
| 1 | df | — | d* | dz |
| x | df | dr | — | d** |
| z | df | dr | d* | — |
Going to x uses the smallest delay — the pessimistic choice: the output becomes unknown as early as it possibly could.變成 x 時取最小的延遲 — 這是悲觀的選擇:輸出會盡可能早地變成未知。x へ遷移するときは最小の遅延を使う。これは悲観的な選択であり、出力はできるだけ早く不定になる。
#(1, 2) means 1 time unit rise, 2 units fall. The unit is set by the compiler directive#(1, 2) 表示上升 1 個時間單位、下降 2 個時間單位。單位由編譯指令設定:#(1, 2) は立ち上がり 1 時間単位、立ち下がり 2 単位を表す。単位はコンパイラ指令で設定する。
`timescale <time_unit> / <time_precision> `timescale 10ps/1ps // 1 unit = 10 ps, round to 1 ps nor #3.57 (z, x1, x2); // 3.57 x 10 ps = 35.7 ps -> 36 ps
`timescale 1 ns / 10 ps
module modA (y, x1, x2);
input x1, x2;
output y;
nand #(3.225, 4.237) (y, x1, x2);
endmodule
`timescale 10 ns / 10 ns
module modB ();
reg x1, x2;
wire y;
modA M1 (y, x1, x2);
initial begin
$monitor($time, "%f x1=%b x2=%b y=%b",
$realtime, x1, x2, y);
end
initial begin
#5 x1 = 0; x2 = 0;
#5 x2 = 1;
#5 x1 = 1;
#5 x2 = 0;
end
endmodule$time $realtime x1 x2 y 0 0.000000 x x x 5 5.000000 0 0 x 5 5.323000 0 0 1 10 10.000000 0 1 1 15 15.000000 1 1 1 15 15.424000 1 1 0 20 20.000000 1 0 0 20 20.323000 1 0 1
$time returns an integer in modB's unit (5.323 → 5); $realtime keeps the fraction.$time 以 modB 的單位回傳整數(5.323 → 5);$realtime 保留小數。$time は modB の単位で整数を返す(5.323 → 5)。$realtime は小数部を保持する。wire #2 y_tran; // net delay
and #3 (y_tran, x1, x2);
buf #1 (buf_out, y_tran);
and #3 (y_inertial, x1, x2);
module my_xor1 (y_out, a, b); input a, b; output y_out; parameter driver_delay = 5; wire #driver_delay y_out = a ^ b; endmodule
Net declaration assignment: the single delay belongs to the assignment → 5.net 宣告時直接指定:這個唯一的延遲屬於該指定 → 5。net 宣言代入:この一つの遅延は代入に属する → 5。
module my_xor2 (y_out, a, b); input a, b; output y_out; parameter wire_delay = 5; parameter driver_delay = 3; wire #wire_delay y_out; assign #driver_delay y_out = a ^ b; endmodule
Driver delay 3 plus net delay 5 → 8.驅動器延遲 3 加上 net 延遲 5 → 8。ドライバ遅延 3 と net 遅延 5 を足して 8。
`timescale unit/precision: each module reads its # delays with its own timescale and rounds them to its precision; $time returns an integer and $realtime a real, both expressed in the calling module's unit.`timescale 單位/精度:每個模組用自己的 timescale 解讀 #,再四捨五入到精度;$time 回傳整數、$realtime 回傳實數,都以呼叫者模組的單位表示。`timescale 単位/精度:各モジュールは自分の timescale で # を解釈し、精度に丸める。$time は整数、$realtime は実数を返し、いずれも呼び出し側モジュールの単位で表される。Problem: For bufif1 #(3,4,1), give the delay of each output transition: (a) 0→1 (b) 1→0 (c) 1→z (d) 0→x (e) x→z (f) z→1. For and #(2,3): (g) 1→x.題目:對 bufif1 #(3,4,1),寫出每個輸出轉態所用的延遲:(a) 0→1 (b) 1→0 (c) 1→z (d) 0→x (e) x→z (f) z→1。對 and #(2,3):(g) 1→x。問題:bufif1 #(3,4,1) について、各出力遷移で使われる遅延を答えよ。(a) 0→1 (b) 1→0 (c) 1→z (d) 0→x (e) x→z (f) z→1。and #(2,3) については (g) 1→x。
(a) 3 rise (b) 4 fall (c) 1 turn-off (d) min(3,4,1) = 1 (e) d** = dz = 1 (f) 3 rise (g) min(2,3) = 2.(a) 3,上升 (b) 4,下降 (c) 1,關斷 (d) min(3,4,1) = 1 (e) d** = dz = 1 (f) 3,上升 (g) min(2,3) = 2。(a) 3、立ち上がり (b) 4、立ち下がり (c) 1、ターンオフ (d) min(3,4,1) = 1 (e) d** = dz = 1 (f) 3、立ち上がり (g) min(2,3) = 2。
Problem: Under `timescale 1ns/100ps, what absolute delays result from (a) #2.34 (b) #0.06 (c) #(1.25, 3.449)? (d) In a module with `timescale 10ns/1ns instantiating it, what does $realtime show for an event at 52.3 ns?題目:在 `timescale 1ns/100ps 之下,(a) #2.34 (b) #0.06 (c) #(1.25, 3.449) 各自是多少絕對延遲?(d) 若由一個 `timescale 10ns/1ns 的模組實體化它,發生在 52.3 ns 的事件,$realtime 會顯示多少?問題:`timescale 1ns/100ps のもとで (a) #2.34 (b) #0.06 (c) #(1.25, 3.449) はそれぞれ何 ns の絶対遅延になるか。(d) `timescale 10ns/1ns のモジュールがそれをインスタンス化しているとき、52.3 ns の事象に対して $realtime は何を表示するか。
(a) 2.3 ns (b) 0.1 ns (c) rise 1.3 ns, fall 3.4 ns (d) $realtime reports in the caller's 10 ns unit: 52.3 / 10 = 5.23; $time shows 5.(a) 2.3 ns (b) 0.1 ns (c) 上升 1.3 ns、下降 3.4 ns (d) $realtime 以呼叫者的 10 ns 為單位回報:52.3 / 10 = 5.23;$time 顯示 5。(a) 2.3 ns (b) 0.1 ns (c) 立ち上がり 1.3 ns、立ち下がり 3.4 ns (d) $realtime は呼び出し側の 10 ns 単位で報告する:52.3 / 10 = 5.23。$time は 5 を表示する。
| Path kind路徑種類パスの種類 | Exists存在條件成立する条件 | Typical use典型用途典型的な用途 |
|---|---|---|
| Simple簡單路徑単純パス | Unconditionally, input → output無條件成立,輸入 → 輸出無条件に成立、入力 → 出力 | Combinational cells組合邏輯單元組合せセル |
| State-dependent狀態相依状態依存 | Only when a condition holds只有在某個條件成立時ある条件が成り立つときだけ | Transparent latches透通式閂鎖器透過ラッチ |
| Edge-sensitive邊緣敏感エッジ依存 | On an edge of a synchronizing signal在同步訊號的邊緣上同期信号のエッジで | Edge-triggered flip-flops邊緣觸發正反器エッジトリガ・フリップフロップ |
module norf201 (O, A1, B1); output O; input A1, B1; nor (O, A1, B1); specify // module paths (A1, B1 *> O) = (0.1:0.3:0.8, 0.1:0.2:0.5); // (rise, fall), each min:typ:max endspecify endmodule
module nand1 (O, A, B);
input A, B;
output O;
nand (O, A, B);
specify
specparam // local to the specify block
T01 = 1.13:3.09:7.75,
T10 = 0.93:2.50:7.34;
(A => O) = (T01, T10);
(B => O) = (T01, T10);
endspecify
endmodule
(A1 => OA) = ...; // bit i -> bit i
(B1 => OB) = ...;
Source and destination must have the same width.來源與目的的位元寬度必須相同。ソースとデスティネーションのビット幅は同じでなければならない。
(A1, B1 *> O) = ...; // every source bit // to every dest bit
input (or inout). (The slides say input or output; per IEEE 1364 it should be input or inout.)路徑的來源:宣告為 input(或 inout)的 net。(講義寫 input or output;依 IEEE 1364 應為 input 或 inout。)パスのソース:input(または inout)として宣言された net。(講義資料には input or output とあるが、IEEE 1364 では input または inout が正しい。)reg declared as output or inout.路徑的目的:宣告為 output 或 inout 的 net 或 reg。デスティネーション:output または inout として宣言された net あるいは reg。A path that exists only while a condition is true — useful for latches:只有在某個條件為真時才存在的路徑 — 常用來描述閂鎖器:条件が真の間だけ存在するパス。ラッチの記述に便利である:
specify
if (enable) (data *> q) = (3, 4); // rise 3, fall 4, only while enable = 1
endspecify
(siga +*> q1) = delay_to_q1; // positive: output moves in the same direction as input (sigb -*> q2) = delay_to_q2; // negative: output moves in the opposite direction (sigc *> q3) = delay_to_q3; // unknown polarity
Gates ignore pulses shorter than their delay. For module paths the rejection window is set with PATHPULSE$:閘會忽略比自身延遲更短的脈衝。對模組路徑而言,濾除的窗口是用 PATHPULSE$ 設定的:ゲートは自身の遅延より短いパルスを無視する。モジュールパスでは、その除去の範囲を PATHPULSE$ で指定する:
specify
(clk => q) = 10;
(data => q) = 7;
(clr, preset *> q) = 3;
specparam
PATHPULSE$clk$q = (3, 8); // (reject limit, error limit) for clk -> q
PATHPULSE$clr$q = (0, 5);
PATHPULSE$ = 4; // one value = both limits; all other paths
endspecify
Problem: With the specify block above, what happens on q for (a) a 2-unit pulse through clk→q (b) a 5-unit pulse through clk→q (c) a 9-unit pulse through clk→q (d) a 3-unit pulse through data→q?題目:以上面的 specify 區塊為準,q 上會發生什麼事:(a) 經由 clk→q 的 2 單位脈衝 (b) 經由 clk→q 的 5 單位脈衝 (c) 經由 clk→q 的 9 單位脈衝 (d) 經由 data→q 的 3 單位脈衝?問題:上の specify ブロックのもとで、q には何が起こるか。(a) clk→q を通る 2 単位のパルス (b) clk→q を通る 5 単位のパルス (c) clk→q を通る 9 単位のパルス (d) data→q を通る 3 単位のパルス。
(a) 2 < 3 → rejected. (b) 3 < 5 < 8 → an x pulse. (c) 9 > 8 → passed (delayed by 10). (d) data→q uses the default PATHPULSE$ = 4: 3 < 4 → rejected.(a) 2 < 3 → 被濾除。(b) 3 < 5 < 8 → 輸出一個 x 脈衝。(c) 9 > 8 → 通過(延遲 10)。(d) data→q 使用預設的 PATHPULSE$ = 4:3 < 4 → 被濾除。(a) 2 < 3 → 除去される。(b) 3 < 5 < 8 → x のパルスになる。(c) 9 > 8 → 通過する(10 遅れる)。(d) data→q は既定の PATHPULSE$ = 4 を使うので、3 < 4 → 除去される。
The source is an edge — models clock-to-output delay of a register.來源是一個邊緣 — 用來描述暫存器的時脈到輸出延遲。ソースがエッジになる — レジスタのクロックから出力までの遅延をモデル化する。
(posedge clock *> (q : data)) = (3, 4); // rise 3, fall 4
The path from data to q is established by the rising edge of clock; (q : data) says data is what flows to q (use +: / -: for non-inverting / inverting).由 clock 的上升緣建立 data 到 q 的路徑;(q : data) 表示流向 q 的資料來源是 data(非反相/反相分別用 +: 與 -:)。clock の立ち上がりエッジによって data から q へのパスが成立する。(q : data) は q に流れ込むのが data であることを示す(非反転/反転はそれぞれ +: と -:)。
| Notation記號記法 | Meaning意義意味 |
|---|---|
::= | is defined as定義為~と定義される |
| | alternative或(選項之一)選択肢 |
[ ... ] | optional (zero or one)可省略(零次或一次)省略可能(0 回または 1 回) |
{ ... } | zero or more times重複零次或多次0 回以上の繰り返し |
source_text ::= { description }
description ::= module_declaration | udp_declaration
module_declaration ::= module_keyword module_identifier [ list_of_ports ] ;
{ module_item }
endmodule
module_keyword ::= module | macromodule
list_of_ports ::= ( port { , port } )
module_item ::= module_item_declaration | parameter_override
| continuous_assign | gate_instantiation
| udp_instantiation | module_instantiation
| specify_block | initial_construct | always_construct
continuous_assign ::= assign [ drive_strength ] [ delay3 ] list_of_net_assignments ;
drive_strength ::= ( strength0 , strength1 )
delay3 ::= # delay_value
| # ( delay_value [ , delay_value [ , delay_value ] ] )
list_of_net_assignments ::= net_assignment { , net_assignment }
net_assignment ::= net_lvalue = expression
Reading delay3: one, two or three delay values — exactly the rise / fall / turn-off forms of §2.2. A port list is optional, which is why a test-bench can be module modB(); or module tb;.讀 delay3:一個、兩個或三個延遲值 — 正好就是 §2.2 的上升/下降/關斷三種形式。埠列表可以省略,所以測試平台可以寫成 module modB(); 或 module tb;。delay3 の読み方:遅延値は 1 個、2 個または 3 個 — まさに §2.2 の立ち上がり/立ち下がり/ターンオフの形式である。ポートリストは省略可能なので、テストベンチは module modB(); でも module tb; でもよい。
$; for simulation and test-benches only — not synthesizable.以 $ 開頭;只用於模擬與測試平台 — 不可合成。$ で始まる。シミュレーションとテストベンチ専用で、合成できない。| Task / function任務/函式タスク/関数 | Purpose用途用途 |
|---|---|
$time | Current simulation time as a 64-bit integer目前的模擬時間,以 64 位元整數表示現在のシミュレーション時刻を 64 ビット整数で返す |
$realtime | Current simulation time as a real number目前的模擬時間,以實數表示現在のシミュレーション時刻を実数で返す |
$monitor(...) | Prints whenever any listed argument changes (one active monitor at a time)只要列出的任一引數改變就印出(同時只能有一個 monitor 生效)列挙した引数のいずれかが変化するたびに出力する(同時に有効なのは一つだけ) |
$display(...) | Prints once, immediately, with a newline立即印出一次,並換行その場で一度だけ出力し、改行する |
$monitor ("%d %f %b %b", $time, $realtime, x, y);
$display ("x = %b y = %b\n", x, y);
module test_bench ();
reg x;
wire y;
reg [31:0] cd; // channel descriptor
assign y = ~x;
initial begin
cd = $fopen("test.dat");
#100 x = 0;
$fdisplay(cd, "%b %b", x, y);
$fclose(cd);
end
endmodule
$readmemh / $readmemb read a text file of hex / binary words into a memory (a 2-D array — Verilog-1995 supports only one memory dimension):$readmemh/$readmemb 把一個十六進位/二進位的文字檔讀進記憶體(二維陣列 — Verilog-1995 只支援一個記憶體維度):$readmemh/$readmemb は 16 進/2 進のワードを並べたテキストファイルをメモリ(2 次元配列 — Verilog-1995 はメモリの次元を一つしか扱えない)に読み込む:
parameter ram_file = "ram_data_file"; reg [15:0] RAM_1 [0:1023]; // 1024 entries x 16 bits initial $readmemb(ram_file, RAM_1); // file lines like 0110_1101_0100_1011 // $readmemh(ram_file, RAM_1); // same, but hex digits
The example file holds binary words with _ separators, so it must be loaded with $readmemb. Reading it with $readmemh would interpret each digit as hex and overflow 16 bits.範例檔案存的是以 _ 分隔的二進位字組,所以必須用 $readmemb 載入。若用 $readmemh 讀,每個數字都會被當成十六進位,結果會超出 16 位元。例のファイルは _ で区切った 2 進ワードを保持しているので、$readmemb で読み込む必要がある。$readmemh で読むと各桁が 16 進として解釈され、16 ビットを超えてしまう。
$finish — end the whole simulation.$finish — 結束整個模擬。$finish — シミュレーション全体を終了する。$stop — halt and enter interactive mode so the user can type commands; the run can be resumed.$stop — 暫停並進入互動模式讓使用者輸入指令,之後可以繼續執行。$stop — 一時停止して対話モードに入り、利用者がコマンドを入力できる。実行は再開できる。| Directive指令指令 | Example範例例 | Effect作用効果 |
|---|---|---|
`timescale | `timescale 1ns/10ps | Time unit / precision for following modules之後各模組的時間單位/精度以降のモジュールの時間単位/精度 |
`include | `include "testbench.v" | Textual file inclusion以文字方式插入檔案內容ファイルをテキストとして取り込む |
`default_nettype | `default_nettype wor | Type of implicitly declared nets (none catches typos)隱含宣告之 net 的型態(用 none 可以抓出拼錯的訊號名)暗黙に宣言される net の型(none にすると綴り間違いを検出できる) |
`define / `undef | `define wait_state 3'b010 | Text macro, used as `wait_state文字巨集,使用時寫成 `wait_stateテキストマクロ。使うときは `wait_state と書く |
The slides write `defaultnettype; the correct spelling is `default_nettype.講義寫 `defaultnettype;正確拼法是 `default_nettype。講義資料には `defaultnettype とあるが、正しい綴りは `default_nettype である。
Problem: Declare a 256 × 8 ROM, load it from the hex file "rom.hex", print entry 5 at time 10, and dump every entry to "rom_dump.txt".題目:宣告一塊 256 × 8 的 ROM,從十六進位檔 "rom.hex" 載入,在時間 10 印出第 5 筆,並把每一筆都倒到 "rom_dump.txt"。問題:256 × 8 の ROM を宣言し、16 進ファイル "rom.hex" から読み込み、時刻 10 で 5 番目の要素を表示し、全要素を "rom_dump.txt" に書き出せ。
reg [7:0] rom [0:255];
integer fd, k;
initial begin
$readmemh("rom.hex", rom);
#10 $display("rom[5] = %h", rom[5]);
fd = $fopen("rom_dump.txt");
for (k = 0; k < 256; k = k + 1)
$fdisplay(fd, "%0d %h", k, rom[k]);
$fclose(fd);
end
?=0/1/x, b=0/1, - no change.?=0/1/x、b=0/1、- 表示維持不變。?=0/1/x、b=0/1、- は変化なし。(vw), r=(01), f=(10), *=(??).#(rise, fall, turnoff), each min:typ:max.#(rise, fall, turnoff),每個都可寫成 min:typ:max。#(rise, fall, turnoff)、それぞれ min:typ:max で書ける。`timescale unit/precision.`timescale 單位/精度。`timescale 単位/精度。$time integer, $realtime real, both in caller's unit.$time 是整數、$realtime 是實數,都以呼叫者的單位表示。$time は整数、$realtime は実数。どちらも呼び出し側の単位で表す。=> parallel, *> full.=> 平行連接、*> 全連接。=> は並列、*> は全結合。if (cond) state-dependent; posedge edge-sensitive.if (cond) 為狀態相依;posedge 為邊緣敏感。if (cond) は状態依存、posedge はエッジ依存。