Verilog数学関数は定数式の代わりに使用でき、整数と実数の両方の数学をサポートしています。 整数数学関数 関数$clog2は、与えられた引数のlog2の天井(切り上げ)を返します。これは通常、与えられたサイズのメモリをアドレッシングするために必要な最小ビット幅を計算するために使用されます。 例えば、設計に7つの並列アダーがある場合、すべての7つのアダーを表現するために必要な最小ビット数は、7の$clog2であり、3になります。 module des #(parameter NUM_UNITS = 7) // このシステム関数の使用により、このモジュールへの // 入力ワイヤ数
表示システムタスクは、主にシミュレーションログからシミュレーションの流れを追跡するための情報およびデバッグメッセージを表示するために使用され、デバッグを高速化するのにも役立ちます。表示タスクにはさまざまなグループがあり、値を出力するフォーマットも複数あります。 Display/Writeタスク 構文 $displayと$writeの両方は、引数リストに出現する順序で引数を表示します。 $display(<引数リスト>); $write(<引数リスト>); $writeは文字列の末尾に改行文字\nを追加しませんが、$displayは追加します。これは以下の例からわ
クロックは、異なるブロックを互いに同期させることを可能にするため、デジタル回路の構築に不可欠です。 クロックの特性 デジタルクロックの主要な特性は、クロック周期を決定する周波数、デューティサイクル、および他のクロックとの関係でのクロック位相です。 クロック周期 周波数は、一定期間内に何サイクル存在するかを示します。したがって、クロック周期は1サイクルを完了するのにかかる時間です。 クロックデューティサイクル クロックがハイレベルである時間の、周期に対する割合がデューティサイクルを定義します。 クロック位相 1サイクルのクロックを360度の完全な円と見なせる場合、別のクロックは円
Verilogの設計とテストベンチには通常、alwaysまたはinitialブロック、連続代入、その他の手続き文など、多くのコード行が含まれ、これらはシミュレーションの過程で異なる時間にアクティブになります。 Verilogモデル内の信号値のすべての変化は更新イベントと見なされます。そして、これらの更新イベントにセンシティブなalwaysやassignブロックなどのプロセスは、任意の順序で評価され、これは評価イベントと呼ばれます。これらのイベントは異なる時間に発生する可能性があるため、シミュレーション時間で並べられたイベントキューにスケジューリングすることで、より適切に管理し、正しい実行順序
Verilogシミュレーションは、時間がどのように定義されるかに依存します。なぜなら、シミュレータは#1が時間の面から何を意味するかを知る必要があるからです。`timescaleコンパイラディレクティブは、それに続くモジュールの時間単位と精度を指定します。 構文 `timescale <time_unit>/<time_precision> // 例 `timescale 1ns/1ps `timescale 10us/100ns `timescale 10ns/1ns time_unitは遅延とシミュレーション時間の測定単位であり、time_precisionは遅
Verilogはハードウェア記述言語であり、設計者がRTL設計をシミュレートしてロジックゲートに変換できるようにする要件はありません。では、なぜシミュレートする必要があるのでしょうか? シミュレーションは、設計に異なる入力刺激を異なるタイミングで適用し、RTLコードが意図した通りに振る舞うかどうかをチェックする技法です。本質的に、シミュレーションは設計の堅牢性を検証するためのよく実践される技法です。これは、製造されたチップが現実世界でどのように使用され、さまざまな入力にどう反応するかにも似ています。 例えば、上記の設計は、クロックと信号の入力を持つポジティブエッジ検出器を表し、これらが
標準的なVerilogプリミティブ(nand、notなど)では、複雑なロジックを表現するのが常に簡単または十分とは限りません。UDPまたはユーザー定義プリミティブと呼ばれる新しいプリミティブ要素を定義して、組み合わせロジックや順序ロジックをモデル化できます。 すべてのUDPは正確に1つの出力を持ち、0、1、またはXのいずれかになり、Zにはなりません(サポートされていません)。値Zを持つ入力はXとして扱われます。 Verilog UDP記号 Verilogユーザー定義プリミティブは、module定義と同じレベルで記述できますが、moduleとendmoduleの間には決して記述できません。多
Verilogはトランジスタレベルのモデリングもサポートしていますが、回路の複雑さが増したため、設計者はスイッチレベルモデリングを使用するのではなく、より高い抽象化レベルに移行することが求められており、現在ではめったに使用されません。 NMOS/PMOS module des ( input d, ctrl, output outn, outp ); nmos (outn, d, ctrl); pmos (outp, d, ctrl); endmodule module tb; reg d, ctrl; wire outn, outp; des u0 (.
デジタル要素はバイナリエンティティであり、0と1の2値のみを保持できます。しかし、0から1、1から0への遷移には過渡遅延があり、各ゲート要素も入力から出力への値の伝播に遅延があります。 例えば、2入力ANDゲートは、両入力が1になれば出力を1に切り替え、いずれかの入力が0になれば出力を0に戻す必要があります。これらのゲート遅延とピン間遅延は、ロジックプリミティブをインスタンス化する際にVerilogで指定できます。 立ち上がり、立ち下がり、ターンオフ遅延 ゲートの出力がある値から1に変化するのにかかる時間を立ち上がり遅延と呼びます。ゲートの出力がある値から0に変化するのにかかる時間を立ち下
前回の記事で主要な組み込みプリミティブについて説明しましたが、シンプルなand、nor、notゲートを使用した実践例を見てみると良いでしょう。 プリミティブの出力ポートと接続するため、モジュールの出力はwire型でなければならないことに注意してください。 例 #1: 2×1マルチプレクサ module mux_2x1 ( input a, b, sel, output out ); wire sel_n; wire out_0; wire out_1; // 追加: 不足していた宣言 not (sel_n, sel); and (out_0, a, se
ほとんどのデジタル設計はRTLのようなより高い抽象化レベルで行われますが、andやorのような組み合わせ要素を使用して、より低いレベルで小さな決定論的回路を構築する方が直感的な場合もあります。このレベルでのモデリングは通常、ゲートレベルモデリングと呼ばれ、ゲートを扱い、ハードウェア回路図とVerilogコードの間に一対一の関係があります。 Verilogは、プリミティブと呼ばれるいくつかの基本論理ゲートをサポートしています。これらはモジュールのようにインスタンス化できるため、プリミティブと呼ばれます(事前に定義済みだからです)。 AND/OR/XORゲート これらのプリミティブは、複数のス
ほとんどのプログラミング言語には、コードの特定セクションが変数やメソッドにどの程度見えるかを定義するスコープという特徴的な機能があります。スコープは、同じ名前空間内の異なるオブジェクト名間の衝突を避けるための名前空間を定義します。 Verilogは、モジュール、関数、タスク、名前付きブロック、generateブロックに新しいスコープを定義します。 module tb; reg signal; // 同じスコープ内で既存の名前で // 別の変数を宣言することはできない reg signal; // エラー // しかし、signalという名前は // 異なるスコ
Verilog遅延文では、代入演算子の左辺または右辺のいずれかに遅延を指定できます。 インターバル遅延(Inter-assignment Delays) // 遅延は左辺に指定 #<delay> <LHS> = <RHS> インターバル遅延文では、代入演算子のLHSに遅延値があります。これは、遅延が期限切れになった後に文自体が実行されることを示し、最も一般的に使用される遅延制御の形式です。 module tb; reg a, b, c, q; initial begin $monitor([%0t] a=%0b b=%0b c=%0b
Verilogには遅延とイベント式の2種類のタイミング制御があります。遅延制御は、シミュレータが文に遭遇した時点と実際に実行する時点の間に遅延を追加する方法です。イベント式は、ネットや変数の値の変化(暗黙的イベント)や、別の手続きでトリガーされる明示的に名前付けられたイベントなど、何らかのシミュレーションイベントの発生まで文を遅延させます。 シミュレーション時間は以下の方法のいずれかで進められます。 内部遅延を持つようにモデル化されたゲートとネットもシミュレーション時間を進めます。 遅延制御 遅延式が未知値またはハイインピーダンス値と評価される場合、ゼロ遅延として解釈されます。負の値と評
Verilogはいくつかのコンパイラディレクティブをサポートしており、これらは本質的にコンパイラにコードを特定の方法で扱うよう指示します。例えば、コードの一部がある機能の実装を表しており、その機能が使用されない場合はコードを設計に含めない方法が必要です。 これは条件付きコンパイルで解決できます。設計者はコードをコンパイラディレクティブでラップし、与えられた名前付きフラグが設定されているときにコードをコンパイルに含めるか除外するかをコンパイラに指示できます。 構文 条件付きコンパイルは、Verilogの`ifdefと`ifndefキーワードで実現できます。これらのキーワードは設計のどこにでも
パラメータは、モジュールを異なる仕様で再利用できるようにするVerilogの構成要素です。例えば、4ビットアダーをパラメータ化してビット数の値を受け取れるようにし、モジュールインスタンス化時に新しいパラメータ値を渡せるようにします。これにより、Nビットアダーが4ビット、8ビット、16ビットアダーになれます。これらは関数呼び出し時に渡される関数の引数のようなものです。 parameter MSB = 7; // MSBは定数値7を持つパラメータ parameter REAL = 4.5; // REALは実数を保持 parameter FIFO_DEPTH = 256,
functionは入力に対して何らかの処理を行い単一の値を返すことを目的としますが、taskはより汎用的で、複数の結果値を計算し、outputおよびinoutタイプの引数でそれらを返すことができます。タスクには@、posedgeなどのシミュレーション時間を消費する要素を含めることができます。 構文 タスクはポートリストの引数セットを持つ必要はなく、その場合は空にできます。 // スタイル1 task [name]; input [port_list]; inout [port_list]; output [port_list]; begin [statements]
RTL内で特定のコード片が繰り返し呼び出されることがよくあります。これらは主にシミュレーション時間を消費せず、異なるデータ値で実行する必要がある複雑な計算を含む場合があります。このような場合、functionを宣言し、繰り返しコードを関数内に配置して結果を返すようにできます。これにより、計算を実行するデータを渡して関数呼び出しを行うだけでよくなるため、RTLの行数を大幅に削減できます。これはC言語の関数と非常に似ています。 関数の目的は、式で使用される値を返すことです。関数定義は常にキーワードfunctionで始まり、続いて戻り値の型、名前、括弧で囲まれたポートリストが続きます。Verilo
case文は、与えられた式がリスト内の他の式のいずれかと一致するかどうかをチェックし、それに応じて分岐します。通常、マルチプレクサの実装に使用されます。条件が多い場合、if-else構造は適さず、マルチプレクサではなくプライオリティエンコーダに合成されてしまいます。 構文 Verilogのcase文はcaseキーワードで始まり、endcaseキーワードで終わります。括弧内の式は正確に1回評価され、記述順に代替案のリストと比較され、与えられた式と一致する代替案の文が実行されます。複数の文のブロックはbeginとendでグループ化する必要があります。 // expressionは項目(item
forループはソフトウェアで最も広く使用されるループですが、Verilogでは主にハードウェアロジックを複製するために使用されます。forループの考え方は、与えられた条件が真である限り、ループ内に与えられた文のセットを反復実行することです。これはwhileループと非常に似ていますが、イテレータが利用可能で、条件がこのイテレータの値に依存する文脈でより多く使用されます。 構文 for (<初期条件>; <条件>; <ステップ代入>) begin // 文 end キーワードforはこのタイプのループを指定するために使用され、3つの部分からなります:
Verilog