Verilog
テンプレート:Infobox プログラミング言語 Verilog(ヴェリログ)は、デジタル回路の設計用の論理シミュレータであり、そこで使用するハードウェア記述言語でもある。両者を区別する場合、言語の方を「Verilog HDL」と呼ぶ場合もある。 言語の開発にあたっては、ソフトウェア開発者にも受け入れられるようにプログラム言語のC言語やPascalの要素を取り入れたものとなっている。IEEE 1364-2005として標準化している。後継言語はSystemVerilog。
目次
[非表示]概要
CPU 上で動くプログラミング言語との相違点として、文(ステートメント)の実行は並列実行を基本とし、逐次実行も記述できる。これは、並列動作する電子回路を記述する言語だからである。また、Verilogモデルは実際のハードウェアの構成に近いモジュールの階層を構成できる。モジュールではまず、入力/出力端子、必要に応じて双方向端子を宣言する。次に、配線を示すwire、記憶素子を示すregとサブモジュールのリストなどを定義する。さらに、続いてその動作を規定するステートメントやステートメントをグループにしたブロック群を定義する。ブロックはbeginキーワードで始まり、endキーワードで終わる範囲で定義し、ブロック内はステートメントが並列に実行される。逐次実行したい場合は、ブロッキング代入を使うか、クロックのタイミングを待つ書き方をする。各ブロックは並列に実行される。
Verilog 言語には、論理合成を適用して実際の回路に変換可能な記述(設計機能)とそうではない部分(検証機能)がある。検証機能はテストやデバッグ時にシミュレータ上で実行する際に使われる。設計中のモジュールが全て合成可能なステートメントだけで記述している場合、適切なソフトウェアを用いて半導体チップの回路、さらにレイアウトデータまで変換することができる。
「Verilog-HDL」という表記が用いられることがあるが、正しくは「Verilog」と「HDL」との間にハイフンが入らない「Verilog HDL」である。
歴史
始まり
Verilogは、ゲートウェイ・デザイン・オートメーション社が、ハードウェア・モデリング言語とそのためのシミュレータとして1984年頃開発した。その後、同社は1990年にケイデンス・デザイン・システムズが買収した。ケイデンスは、現在も大元のゲートウェイVerilogおよびVerilog-XL論理シミュレータの版権を持っている。
標準化
同種のハードウェア記述言語であるVHDLの台頭に対し、ケイデンスはVerilogの規格を公開し標準化する道をとった。すなわちケイデンスはOVI(Open Verilog International)という組織へ版権の一部を移譲した。その後VerilogをIEEEに提出しIEEE 1364-1995[1]として規格化し、Verilog-1995と呼ぶ。なおOVIはその後Accelleraという組織になっている。
標準化にともないVerilogシミュレータは、ケイデンス以外の各社やフリーのものも各種登場するようになった。
Verilog 2001
オリジナルのVerilog標準に対する不満を解消するために、Verilog-95に対する拡張をIEEEに提出した。この拡張はVerilog 2001といいIEEE 1364-2001[2]になった。VHDLにあったgenerate文に対応し、大規模設計が容易になった。
Superlog/System Verilog
やがてOpenVeraやVerisityのE言語のようなハイ・レベルの検証言語が登場する。このことはその種の機能を盛り込んだVerilog、すなわちコデザイン・オートメーション社によるSuperlogの開発を促すこととなった。コデザイン・オートメーション社は、シノプシスによってその後買収された。SuperlogとVeraの基本部分はAccelleraに寄贈され、次のIEEE標準としてSystemVerilogとVerilogとに分かれた。
Verilog-AMS
言語の最新のバージョンは、アナログ素子および回路の機能記述を行うための言語であるVerilog-Aを包含し、さらにアナログ/デジタルのミックス・シグナル・モデルへの対応もなされており、Verilog-AMSという。
Verilog 2005
IEEE 1364-2005[3] として規格化。その際、上位互換の SystemVerilog IEEE 1800-2005 も作った。
文法(抜粋)
キーワード
- module(入出力端子リスト) .. endmodule
- この範囲が一つの回路モジュールとなる。
- begin .. end
- 汎用のブロック範囲。
- initial
- モジュールの中で一回だけ実行されるブロック
- always @(イベント式)
- イベント式にあるイベントが発生するたびに実行されるブロック
- if (条件式) else ..
- 条件判断文
- for(変数定義;条件式;変移)
- 繰り返し処理
- while(条件式)
- 繰り返し処理
- input、output
- 入力端子、出力端子の定義。モジュールの最初に記述。
- reg、wire
- 内部配線がレジスタ(値を記憶)か単なる配線かの指定。
- =
- always 内ではブロッキング代入(逐次実行。詳細は後述する)
- <=
- always 内のノンブロッキング代入(詳細は後述する)
- assign
- 継続的代入。電気回路の配線接続に相当。
- function
- assign 用の関数定義
- task
- always 用の関数定義
- and、or、xor(exor)、nand、nor(exnor)、xnor、not
- 基本ゲート
- //、/* .. */
- コメント。実行には影響しない。
オペレータ(演算子)
- +、-、*、/
- 加減乗除(算術演算)
- %
- 除算の余り(剰余演算)
- ~、&、|、^、~^(^~)
- not、and、or、xor、xnor(ビット演算)
- &&、||、!
- and、or、not(論理演算)
- !=、==、!==、===
- 等号演算(前者2つが論理等号演算、後者2つがケース等号演算)
- {}
- 連節演算
?:
- 条件演算
上記のようにbegin、end、functionなどはPascalの文法を、オペレータや条件、繰り返し処理はC言語の文法を流用している。
モジュールの構成
Verilogの最小単位はモジュールである。以下に、カウンタ回路の例で説明する。
モジュールはキーワードmoduleで始まる。その後のDiv20xが名前を示し、続く括弧内は端子リストである。6個の端子があり、それぞれの端子の入出力方向はモジュール中のポート宣言(inputとoutput)で指定される。最後のendmoduleでモジュールの終了である。モジュール内には、パラメータ宣言、ポート宣言、レジスタ宣言、イベント宣言、ネット宣言、ステートメントなどを記述する。
//
// 表題 イネーブル付20段カウンター
//
module Div20x (
// ポート宣言(外部から本モジュールへの接続を定義する)
input clock, // クロック
input reset, // リセット(正論理, ハイアクティブ)
input cet, // カウンターとTC出力のイネーブル
input cep, // カウンターのみのイネーブル
output reg [size - 1:0] count, // 束線を示す。この場合5bit幅
// alwaysまたはinitialブロックでドライブする信号は
// reg型でなければならない
output tc); // regと明記していない、他の信号はwire型。
// ポート宣言したwire型信号のネット宣言は省略可能であり、省略することも多い。
// パラメータ宣言
parameter length = 20; // カウント段数
parameter count_zero = 5'b00000; // 5bit幅,2進数の0を表す
parameter count_one = 5'b00001; // 5bit幅,2進数の1を表す
parameter size = 5; // bit幅,基数の指定を省略すると32bit,10進数になる。
// always文。resetやclock信号の変化に同期し並列に実行される
always @ (posedge clock or posedge reset) begin
if (reset) begin // 非同期リセット
count <= count_zero;
end else begin
if (cet || cep) begin // イネーブル
if (count == length - 1) begin
count <= count_zero;
end else begin
count <= count + count_one;
end
end
end
end
// assign文。tcの値は実行中、継続的に値が与る
assign tc = (cet && (count == length - 1));
endmodule
ポート宣言やレジスタ宣言での[a:b]のような形式は、束線(多くはバス)を示す。例えば[3:0]であれば配線が4本あることになる。
プロセス(always とintialブロックのこと)内部からドライブする信号はreg型である必要があり、他はwire型である。キーワードregが必ずしもハードウェアであるレジスタを意味するものではない(論理合成の結果、FFを割り当てるとは限らない)。
次にその中のalways節を説明する。always節は、括弧内の信号を指定した条件に変化があったときに実行する。posedgeは信号が0から1に変化した場合を指定する。or は括弧内の信号のどれか1つでも変化した場合を指定する。上記のように reset に合わせて reg型を初期化するのが基本的なデザインパターンである。
always節中の"<="オペレータはCPU上で動く通常の手続き型言語と異なりハードウェア記述言語の特徴の一つであり、「ノン・ブロッキング代入」というものである。シミュレーション実行時に並列に評価する。下記の例の場合、cが変化すると、aとbへの代入を同時に行う(aとbの値を交換する)。これは実際のフリップフロップの動作に近いものである。
reg a, b;
wire c;
always @(c)
begin
a <= b;
b <= a;
end
もう一つの代入文である"="はブロッキング代入といい、手続き型言語のように逐次実行する。下記の例の場合、bかeが変化すると、aに代入された後、bに対する代入を行う。
reg a, b, c, d;
wire e;
always @(b or e)
begin
a = b & e;
b = a | b;
#5 c = b;
d = #6 c ^ e;
end
なお、#は時間経過を示し、シミュレーション時に使う。この場合、単位時間5経過の後、cにbを代入する。またc^eは一時変数に記録し、単位時間6経過後にdに代入する。時間は秒など実時間の指定も出来る。
主要ソフトウェア
シミュレータ
- 有償
- 無償
- Icarus Verilog [9]
- GPL Cver [10]
- Verilator [11]
- VeriWell Verilog Simulator [12]
論理合成
- Design Compiler シノプシス社
- Encounter RTL Compiler ケイデンス社
lint チェックツール
- SpyGlass アトレンタ社
関連項目
参照
- 元の位置に戻る ↑ 1364-1995 IEEE Standard Hardware Description Language Based on the Verilog(R) Hardware Description Language
- 元の位置に戻る ↑ 1364-2001 IEEE Standard Verilog Hardware Description Language
- 元の位置に戻る ↑ 1364-2005 IEEE Standard for Verilog Hardware Description Language