ハードウェアの動作を実装するには、条件文やロジックのフローを制御する他の方法が不可欠です。Verilogには、これを実現するための制御フローブロックとメカニズムが用意されています。 if-else-if この条件文は、特定の文を実行するかどうかを決定するために使用されます。これはC言語のif-else-if文と非常に似ています。式が真と評価された場合、最初の文が実行されます。式が偽と評価され、else部分が存在する場合、else部分が実行されます。 構文 // else部分なしのif文 if (expression) [statement] // else部分ありのif文 if (exp
ブロッキング代入 ブロッキング代入文は=を使用し、手続きブロック内で順次実行されます。ただし、並行ブロックで実行される文の実行を妨げることはありません。 module tb; reg [7:0] a, b, c, d, e; initial begin a = 8hDA; $display ([%0t] a=0x%0h b=0x%0h c=0x%0h, $time, a, b, c); b = 8hF1; $display ([%0t] a=0x%0h b=0x%0h c=0x%0h, $time, a, b, c); c = 8h30;
ネットや変数に値を代入することを「代入」と呼びます。基本的には以下の3種類があります。 手続き的代入 連続代入 手続き的連続代入 LHS(左辺)に指定可能な値 代入文は、右辺(RHS)と左辺(LHS)の2部分で構成され、間に等号(=)または非ブロッキング代入演算子(<=)が入ります。 代入の種類 左辺(LHS) 手続き的代入 変数(ベクタ/スカラ) ベクタreg、integer、time変数のビット選択または部分選択 メモリワード 上記の連結 連続代入 ネット(ベクタ/スカラ) ベクタネットのビット選択または部分選択 ビット選択と部分選択の連結 手続き的
一連の文をグループ化し、構文的に単一の文と等価にする方法があり、これらは ブロック文 と呼ばれます。ブロック文には2種類あります:順次と並列。 順次ブロック begin と end キーワードで文を囲み、与えられた順序で順次実行されます。遅延値は前の文の実行時間からの相対時間として扱われます。ブロック内のすべての文が実行されると、制御は他に移ります。 module design0; bit [31:0] data; initial begin // 10時間単位後、data = 0xfe #10 data = 8hfe; $display ([Time=%0t] d
前回の例ではシンプルなシーケンス検出器を扱いました。ここでは、もう少し長いパターンを検出するパターン検出器の例を示します。 設計:110101パターン検出器 module det_110101 ( input clk, input rstn, input in, output out ); parameter IDLE = 0, S1 = 1, S11 = 2, S110 = 3, S1101 = 4, S11010 = 5, S110101 = 6; reg [2:0] cur_state, next_state; assign out = (cur_state == S110
FSMの非常に一般的な例は、シーケンス検出器です。ハードウェア設計が、入力されるバイナリビットストリームで固定パターンが検出されたときにそれを検知することが期待されます。 例:1011シーケンス検出器 module det_1011 ( input clk, input rstn, input in, output out ); parameter IDLE = 0, S1 = 1, S10 = 2, S101 = 3, S1011 = 4; reg [2:0] cur_state, next_state; assign out = (cur_state == S1011) ?
generate ブロックを使用すると、モジュールインスタンスを複数生成したり、任意のモジュールを条件付きでインスタンス化したりできます。設計をVerilogパラメータに基づいて構築する機能を提供します。同じ操作やモジュールインスタンスを複数回繰り返す必要がある場合や、与えられたVerilogパラメータに基づいて特定のコードを条件付きで含める場合に特に便利です。 generate ブロックには、ポート、パラメータ、specparam 宣言や specify ブロックを含められません。しかし、他のモジュールアイテムや他のgenerateブロックは許可されます。すべての生成インスタンス化は、mo
すべての振る舞いコードは module と endmodule の内側に書きます。作成したいデジタル設計が何であれ、module ブロックの中に入ります。ポートを定義しても、しなくてもよく、信号をブロックに入れる input や、ブロックから出す output を許可します。 モジュール 以下の空のモジュールは testbench と呼ばれます。英数字と _ を含むなら何でも命名可能です。 module testbench; endmodule 別のモジュールを見てみましょう。いくつかの信号(d, clk, rstb)が入力として、q が出力として宣言されています。 module d
一連のVerilog文は通常、シミュレーションで順次実行されます。これらの文は 手続き ブロック内に配置されます。Verilogには主に2種類の 手続き ブロックがあります:initial と always 構文 initial [single statement] initial begin [multiple statements] end initialブロックの用途 initial ブロックは合成可能ではないため、デジタル要素を持つハードウェア回路図に変換できません。したがって、initialブロックはシミュレーションでの使用以外に大きな目的はありません。これらのブロックは主に
前回の記事では always ブロックで組み合わせ論理を実装する例を示しました。always ブロックは、フリップフロップのような値を保持するメモリ要素を持つ 順序 論理の実装にも主に使用されます。 JKフリップフロップ JKフリップフロップは値を格納するフロップの一種で、データ入力 j と k、リセット rstn、クロック clk を持ちます。真理値表は以下の通りで、通常NANDゲートで実装されます。 rstnjkqコメント 0000リセットアサート時、出力は常に0 100保持j=k=0で出力は前回値を保持 1011k=1で出力は1 1100k=0で出力は0 111トグルj=k=1で出
Verilogの always ブロックは順序論理と組み合わせ論理の両方に使用できます。前回の記事で assign 文を使った設計例をいくつか示しました。同じ設計群を今度は always ブロックで探ります。 例 #1:シンプルな組み合わせ論理 以下のコードは、センシティビティリスト内の信号のいずれかが値を変化させると更新される reg 型の出力信号 z を持つシンプルなデジタル組み合わせ論理を実装します。センシティビティリストは @ 演算子の後、括弧内で宣言されます。 module combo (input a, b, c, d, e, output reg z); always @ (
always ブロックはVerilogの 手続き ブロックの1つです。alwaysブロック内の文は順次実行されます。 構文 always @ (event) [statement] always @ (event) begin [multiple statements] end always ブロックは特定のイベントで実行されます。イベントはセンシティビティリストで定義されます。 センシティビティリストとは? センシティビティ リストは、alwaysブロックがいつ実行されるかを定義する式で、@ 演算子の後、括弧 ( ) 内で指定します。このリストには、値の変化でalwaysブロックを
複数ビットのVerilogワイヤや変数を、連結演算子 { と } でカンマ区切りで結合し、より大きなマルチネットワイヤや変数を形成できます。連結にはワイヤや変数に加え、式とサイズ指定付き定数もオペランドとして使用可能です。 連結の全サイズを計算するため、各オペランドのサイズは既知でなければなりません。 Verilog連結の例 wire a, b; // 1ビットワイヤ wire [1:0] res; // aとbを格納する2ビットワイヤ // res[1]はaを、res[0]はbを追従 assign res = {a, b}; wire [2:0] c;
処理できないデータは無意味です。デジタル回路とコンピュータシステムには常に何らかの計算が必要です。合成ツールが適切なハードウェア要素を実現するためのVerilog演算子を見ていきましょう。 Verilog算術演算子 除算または剰余演算子の第2オペランドが0の場合、結果はXになります。累乗演算子のいずれかのオペランドが実数なら、結果も実数になります。累乗演算子の第2オペランドが0なら結果は1(a0)です。 演算子説明 a + baプラスb a - baマイナスb a * ba乗算b a / ba除算b a % baモジュロb a ** baのb乗 module des; reg [7:
Verilogの assign 文は通常、wire データ型の信号を継続的に駆動するために使用され、組み合わせ論理として合成されます。ここでは assign 文を使ったさらなる設計例を紹介します。 例 #1:シンプルな組み合わせ論理 以下のコードは、出力ワイヤ z が assign 文で継続的に駆動され、デジタル方程式を実現するシンプルなデジタル組み合わせ論理を実装します。 module combo ( input a, b, c, d, e, output z ); assign z = ((a & b) | (c ^ d) & ~e); endmodule モジュー
wire タイプや類似のワイヤライクなデータ型の信号には、値の連続代入が必要です。例えば、ブレッドボード上でピースを接続する電気ワイヤを考えてみてください。片側に +5V の電池を接続し続ける限り、もう片側に接続されたコンポーネントは必要な電圧を得られます。 Verilogでは、この概念は assign 文によって実現されます。ここで、あらゆる wire や類似のワイヤライクなデータ型を、値で継続的に駆動できます。値は定数でも、複数の信号で構成される式でも構いません。 assign構文 代入構文はキーワード assign で始まり、その後に信号名(単一信号または異なる信号ネットの連結)が続
前回の記事で見たように、より大規模で複雑な設計は、複数のモジュールを階層的に統合することで構築されます。モジュールは他のモジュール内で インスタンス化 でき、これらの インスタンス のポートを親モジュール内の他の信号と接続できます。 これらのポート接続は、順序付きリストまたは名前による方法で行えます。 順序付きリストによるポート接続 モジュールインスタンス化時のポート式リストと、親モジュール内の信号を接続する方法の1つは 順序付きリスト です。 mydesign は module で、別のモジュール tb_top 内で d0 という名前でインスタンス化されます。ポートは、モジュール宣言の
ポートは、特定のモジュールへの入力および出力として機能する一連の信号であり、モジュールと通信する主要な手段です。モジュールをPCB上に実装された製造済みチップと見なせば、チップと通信する唯一の手段がそのピンであることは明らかです。ポートはピンのようなもので、設計が外部と信号を送受信するために使われます。 ポートの種類 ポート説明 Input設計モジュールは input ポートを通じてのみ外部から値を受信可能 Output設計モジュールは output ポートを通じてのみ外部へ値を送信可能 Inout設計モジュールは inout ポートで値を送受信両方可能 ポートはデフォルトで wire
module は特定の機能を実装するVerilogコードのブロックです。モジュールは他のモジュール内に埋め込むことができ、上位モジュールは下位モジュールの入出力ポートを通じて通信します。 構文 module は module と endmodule キーワードで囲む必要があります。モジュール名は module キーワードの直後に指定し、オプションでポートリストを宣言できます。ポートリストで宣言されたポートは、モジュール本体内で再宣言できません。 module ([port_list]); // モジュールの内容 endmodule // ポートリストが空のモジュールも可能 module
ネットまたは変数の 配列 宣言はスカラでもベクトルでも可能です。識別子名の後にアドレス範囲を指定することで任意の次元を作成でき、これを多次元配列と呼びます。配列は reg、wire、integer、real データ型で使用可能です。 reg y1 [11:0]; // スカラreg配列、深さ12、各1ビット幅 wire [0:7] y2 [3:0]; // 8ビットベクトルネット、深さ4 reg [7:0] y3 [0:1][0:3]; // 2次元配列、行2、列4、各8ビット幅 配列の特定要素にアクセスするには、各次元のインデックスを指定する必要があり、他の変数の式でも
Verilog