論理シミュレーションを行う癖を付けよう:触って学ぼう FPGA開発入門(2)(1/3 ページ)
回路が大規模になればなるほど実機動作から不具合を特定することは難い。必ず論理シミュレーションを行うようにしよう
前回は、「理論より実践」をテーマに「3入力8出力のデコーダ」の開発と動作確認を行いました。第2回目は、以下の3点を中心に解説していきます。
- 前回のverilog-HDLデコーダのソースを解説
- 7セグメントLEDのデコーダの作成
- テストベンチを用いた論理シミュレーションの実行
関連リンク: | |
---|---|
⇒ | いまさら聞けない FPGA入門 |
Verilog-HDLソースの中をのぞいてみよう
まずは、第1回目のリスト2のVerilog-HDLソースの中身を詳しく見ていきましょう。
1行目
「module」を宣言し、モジュール名として「DECODER」(モジュール名は任意の名前)を命名します。「( )」の中に入出力ポートの名前を列挙(ポートリストを指定)します。ここでは「DECODER」モジュールの入出力である「A」「B」「C」「Y」の4つの入出力ポートを指定します。
2〜3行目
ポートリストで指定した信号の方向を記述しています。入力には「input」、出力には「output」を宣言します。ちなみに、入出力双方向の場合には「inout」を宣言します。
4行目
Verilog-HDLの代入には、assign文による「継続的代入文」とalways文、initial文による「手続的代入文」があります。継続的代入文で代入される、つまり左辺で使用される信号(変数)はwire宣言し、「手続的代入文」の中で左辺で使用される信号(変数)はreg宣言する必要があります。6行目からのalways文で出力の「Y」が左辺で使用されているので、ここでは「Y」をreg宣言します。
6行目
always文を使用して動作を記述します。「( )」内の記述は、入力信号である「A」「B」「C」をセンシティビティ・リストに指定しています。つまり、「A」「B」「C」のいずれかが変化したらalways文中の「begin」と「end」で囲まれている代入処理が行われます。
7〜18行目
case文を使用して「A」「B」「C」のすべての組み合わせを記述します。「A」「B」「C」を3bitの信号と見立てるため「{ }」を使用して、3bitに連接した信号を作成します。例えば、8行目のcase文「case(~{A,B,C})」で「~」の反転演算子を利用して参照していますので「3'b010」というのは、
「Aが1:Aが押されていない」
「Bが0:Bが押されている」
「Cが1:Cが押されていない」
場合を示しています。
入力信号は、3bitなので「1」「0」を使用したすべての組み合わせは8通りです。しかし、Verilog-HDLでは「1」「0」以外にも「z:ハイ・インピーダンス」「x:アンノン」の状態が存在します。
「Aがz」
「Bが0」
「Cがx」
例えば、「3'bz0x」のような場合は「default」に処理が飛ぶようにします(「z」「x」まで考慮すると組み合わせが膨大になるので、defaultで記述するのがよいでしょう)。
case文ですべての組み合わせを記述したら、最後に「endcase」を記述します。
20行目
最後にモジュールの終わりを示す「endmodule」を記述して、実際に回路となる部分の記述は終了です。
7セグメントLEDを点灯させよう(1)
今回は、ボードにある7セグメントLEDを点灯させてみましょう。
ここでは、入力スイッチ「A」「B」「C」の押され方によって、7セグメントLEDの表示部分に「0〜7」を表示させます。
「7セグメントLEDのデコーダ」のソース
リスト1に「7セグメントLEDのデコーダ」のソースを示します。
1 module DECODER7(A,B,C,LED,SA); 2 input A,B,C; 3 output [7:0] LED; 4 output [3:0] SA; 5 reg [7:0] LED; 6 7 assign SA = 4'bzzz0; 8 9 always @(A or B or C) 10 begin 11 case(~{A,B,C}) //ABCDEFG Dp 12 3'b000:LED <= 8'b0000001_1; 13 3'b001:LED <= 8'b1001111_1; 14 3'b010:LED <= 8'b0010010_1; 15 3'b011:LED <= 8'b0000110_1; 16 3'b100:LED <= 8'b1001100_1; 17 3'b101:LED <= 8'b0100100_1; 18 3'b110:LED <= 8'b0100000_1; 19 3'b111:LED <= 8'b0001101_1; 20 default:LED <= 8'b0110000_1; 21 endcase 22 end 23 endmodule
前回作成した「3入力8出力のデコーダ」と異なる主な点を以下に示します。
- 出力の信号名を「Y」から「LED」に変更した
- LEDの出力の値を変更した(ビットアサインに関しては、図1を参照)
- 「 _ 」を使用すると代入する固定値を区切ることができる。ここではDp(ドットポイント)だけを区別した
- 代入記号を「=」(ブロッキング代入)から「<=」(ノンブロッキング代入)に変更した(今回の場合は、どちらの記号を使用しても代入結果は同じ)
- このボードの7セグメントLEDは、ダイナミック点灯を使用している。使用する7セグメントLEDを選択する必要があるので、一番右側にある7セグメントLEDのけたを選択するために「0」を出力して、それ以外の選択しない7セグメントLEDのけたに対しては「z」を与える(リスト1の7行目)。ハイ・インピーダンス「z」を与えることに関しては、ボードのマニュアルを参照
このVerilog-HDLソースを使って、前回と同様にISE WebPACKで「論理合成(XST)」を実行します。
Copyright © ITmedia, Inc. All Rights Reserved.