論理回路2

第11章 ハードウェア記述言語(その2)

   −回路の表記法−

井澤 裕司  


1 はじめに
本章では、LSIの設計・開発に広く使用されている 「ハードウェア記述言語(HDL)」
表記法について解説します。

前章で述べたように、「ハードウェア記述言語」として様々な種類が利用されていますが、
ここでは国際的に広く使用されている VHDL (VHSIC Hardware Description Language) について紹介します。

この VHDL は極めて高い記述能力をもち、大規模なLSIの開発を効率的に進めることが可能です。

しかしながら、この限られたスペースでは、その全容を紹介することはできません。
ここでは、 簡単な回路 をいくつか例に挙げ、それらの 表記法 について 紹介 することに留めます。

説明が不足する部分が多々あると思いますが、それらについては、インターネット上の解説サイトや、
参考文献に示す成書等を参照してください。

それでは、組み合せ回路から具体的な表記法について説明しましょう。

2 組み合せ回路の記述例
最も簡単な組み合せ回路を、 ハードウェア記述言語(HDL) を用いて記述してみましょう。
論理回路1で学習したように、2進数の和を求める加算回路は、
 半加算器
   と
 全加算器
を用いて構成することができます。

これらを、階層構造状に組み上げ、任意のビット数の加算回路を実現する手法を示します。
はじめに、最も低い階層に位置する 半加算器 の記述からはじめましょう。

(1) 半加算器 (Half Adder) の記述例
このソースコードについて、簡単に補足します。

ソースコードの前半が 入出力の インタフェース 関係を表す entity 部、後半がそれらの 論理関係
記述する architecture 部です。

VHDLでは 大文字と小文字は区別されません が、 読みやすさを最優先 に記述する必要があります。
本章では、原則として 信号 大文字 、それ以外の VHDLの予約語 等を 小文字 で表すことにします。
- - から始まる最初の1行は コメント文 です。

次の2行、すなわち
library IEEE;
use IEEE.std_logic_1164.all;
は、この回路で使用する VHDLのライブラリ を表しています。
IEEE は、米国の電子技術者で構成される有名な組織 (Institute of Electrical and Electronics Engineers)であり、
そこで制定した規格に1164という番号が付いています。
ここでは、C言語における代表的なヘッダーファイル stdio.h と、その include文 のようなものだと、
解釈しておいて下さい。

entity 部では、 入出力のインタフェース を表します。
この場合、 A、B という2つの信号が入力、 S、CO が出力を表しています。

in はこの回路への入力、 out はこの回路から取り出す出力を表しています。
これ以外に、双方向を表す inout 、回路内部で参照できる出力 buffer があります。

buffer は、上位の階層で使用する場合にも buffer としなければならないなどの制約があります。

ここでは、 buffer は使用せず、 out を用いることにします。

std_logic は、1bitの入出力を表すデータタイプです。
bit というデータタイプも1bitの型を表しますが、通常の1と0以外にハイインピーダンス等の
状態をとりうる点が異なります。

次の architecture 部で、入出力信号の具体的な 論理関係 を記述します。

ここで、 DATAFLOW は、アーキテクチャの名称です。
名前の付け方は基本的に自由ですが、
DATAFLOW (組み合せ回路記述)
BEHAVIOR (動作仕様記述)
STRUCTURE (構造記述)
RTL (レジスタレベル記述)
などが用いられることが多いようです。
ここでは、基本的にこの名称を用いることにします。

begin 以下の2文で、 xor 排他的論理和 and 論理積 を表しています。
これ以外には、
or (論理和)
not (否定)
nand (否定論理積)
nor (否定論理和)
のような 論理演算子 が定義されています。
記号の" <= "は、 左辺 の出力信号に 右辺 の入力信号の演算結果を接続することを表しています。

次に、この 半加算器 部品 として使用することにより、下位からの桁上げ入力のある 全加算器
設計してみましょう。

(2) 半加算器を部品として組み込んだ
    全加算器 (Full Adder) の記述例

上で紹介した 半加算器 を2個用いて、 全加算器 を設計しましょう。

一度設計した回路(半加算器)を、 部品(component) として再利用する場合の記述例を以下に示します。

以下、簡単に補足します。

入出力のインタフェース関係を表す entity 部の port 文には、 3番目の入力として
下位からの桁上げ(CIN) が追加されています。

architecture 部のはじめに、半加算器 halfadder を部品として使用することを宣言する
component 文を記述します。
entity 部や 部で用いた ' is 'は 不要 なので注意して下さい。
なお、半加算器のVHDL (halfadder.vhd) は、このソースコードと同じディレクトリに置く必要があります。

次に、 内部配線 に相当する signal を定義します。
ここでは、HA0_CO、HA0_S、HA1_CO の3本の信号を使用します。

VHDLでは、 entity 部で定義した out 型の信号を、内部回路の入力として直接利用することができません。
このため、 signal で定義した信号を用いて内部の接続関係を表し、最後にこの信号を出力するような
記述方法を用います。

begin に続く3行で、 component で定義した半加算器(2個)と、or 回路、入出力信号の接続関係を記述します。
HA0 と HA1 は、2つの 半加算器の名称 (ラベル)です。

半加算器のVHDL (halfadder.vhd) entity で定義した順番に、 portmap 文以下に信号名を記述します。
入力間、あるいは出力間で 順番 が入れ替わっても、コンパイラの エラーメッセージ は表示されません。
順番が入れ替わった場合、 想定した動作にはならないので注意して下さい。

なお、このような信号名の受け渡し順のミスを避けるため、
 HA1 : halfadder port map ( A =  HA0_S, B =  CIN, S =  S, CO =  HA1_CO ); 
という指定方法を用いることをお勧めします。

このような階層化の手法は、ボトムアップの設計に欠かせない手法となっています。

(3) 4ビット加算器 (adder) の記述例
次に、半加算器と全加算器を用いて、 4bitの加算回路 を設計しましょう。

ソースコードの例を、以下に示します。

ここで、4bitの入力A、Bをそれぞれ A(3)、A(2)、A(1)、A(0)、 そして、 B(3)、B(2)、B(1)、B(0)
のように表しています。
また、それらの和に対応する 5bit の出力を S(4)、S(3)、S(2)、S(1)、S(0) としています。

それらを定義する port 文では、 std_logic_vector(3 downto 0) 、あるいは std_logic_vector(4 downto 0)
のような ベクトル型 データタイプ を使用します。
これらは、4bitあるいは、5bitのまとまった信号であり、C言語における 配列 に対応します。

この例では ( 3 downto 0 ) のように、 上位 から定義していますが、 下位 から定義するときは、
0 to 3 ) のように記述します。
先に述べた全加算器の例と同様、今回は半加算器と全加算器を、 部品(component) として使用します。

4つの signal すなわち、HA_CO、FA0_CO、FA1_CO、FA2_CO を用いて、 component の入力に接続します。
begin 以下の5行で、それらの 接続関係 = 構造(STRUCTURE) を記述しています。

このようにして、単純な部品を component として準備し、これらを階層的に組み上げて再利用するのが、
いわゆる ボトムアップの設計方法 です。

(4) 4ビット加算器 (adder) の記述例(2)

上の例では、半加算器と全加算器を組み合わせて、4bitの加算回路を設計しました。

一方、 VHDL には、 算術演算 やICの74シリーズに相当する機能を実現するマクロ、メモリ関連など、
豊富な ライブラリ を登録した様々な パッケージ が用意されています。
これまで使用した、 std_logic_1164 というパッケージも、その一つです。

この他、 算術演算 をサポートした
std_logic_arith
std_logic_signed
std_logic_unsigned
などが、VHDLコンパイラのメーカ等から提供されています。
このような算術演算のパッケージを用いて、より抽象度が高く、ある意味では直感的でわかりやすい
トップダウン設計 を紹介しましょう。

ボトムアップ設計 が、いわゆるアセンブリ言語により記述された関数群を組み合せて、
高度な処理を実現する手法に例えるならば、 トップダウン設計 は、高級言語に近い感覚で
抽象度の高い機能を、直接記述する手法といえるでしょう。

このような トップダウンの手法 により、先に説明した4bitの加算器を設計してみましょう。
ソースコードの例は、以下のようになります。

以下、簡単に補足します。

はじめに、使用する算術演算のパッケージ を呼び出します。
use IEEE.std_logic_unsigned.all;
の一文です。

architecture 部では、符号のない正の5bitの入力A、Bの加算を、単純な +(プラス) で実現しています。
単純な論理和(OR)ではなく、 2進数の加算演算 を表している点に注意して下さい。

なお、加算の機能としては、先に示した半加算器、全加算器を組み合せた回路と変わりません。
ボトムアップ手法と比較すると、極めて単純かつ明快なソースコードとなっていることがわかります。
しかし、その回路規模や動作速度等を厳密に評価すると、当然のことながら性能の差が現れます。

一般に、 ボトムアップ手法 は論理ゲートやフリップフロップのレベルで設計できるので、
設計者の意図を細かく反映させることが可能です。
一方、 演算ライブラリ 等を用いて設計した回路の場合、その性能は VHDLコンパイラ の性能や
ライブラリ の品質に依存します。

回路の専門家が、独創的なアイデアや詳細な検討に基づいて、注意深く設計すれば、
(3)の手法に勝るものはありません。
しかし、VHDLのコンパイラやライブラリも、日々改良が積み重ねられており、その品質も向上しています。

動作速度に余裕のある場合、記述の容易さや、設計した回路の保守などを含めて総合的に判断すると、
より抽象度の高い演算ライブラリ等を用いた方が現実的な選択と言えるでしょう。

(5) 7セグメントデコーダ回路 (1)
次に、電卓等で使用される 7セグメントのデコーダ回路 の一例を示します。
入力 DIN は4bitの 正の2進数 で、出力 SEG7 は7つのLEDを ON/OFF させる 制御信号 です。
入力の値は、10進数の(0〜9)のいずれかであるとします。

LEDの制御信号は、7bitの vector 型で表しており、下位(LSB)がセグメントのa、
上位(MSB)がセグメントの g に対応します。
なお、LEDの制御信号は 負論理 であり、0のとき点燈し、1のとき消える点に注意して下さい。

with DIN select の構文を用いることにより、入力 DIN の値 (0〜9) に応じ、7セグメントLEDの点燈すべき
セグメントの位置を、直感的に記述することができます。

なお、DIN のすべての状態を記述しない場合は、
when others;
の一行が必要になります。

std_logic_vector のデータタイプは、1 と 0 以外の値(例えば Highインピーダンス等)をとりうるため、
必然的に when others; が必要になります。

(6) 7セグメントデコーダ回路 (2)

最後に、 7セグメントのデコーダ回路 のもう1つの記述例を示します。
入力の CNT には、 integer という 整数型のデータタイプ を用いています。
この CNT の値として、0〜9までの整数が入力されますが、回路的には 4bitの入力信号となります。

入力 ERR はキー操作のミス等があったときに、LED上にエラーに相当する " E " を表現するための信号です。

なお、 architecture 部の最初に、 process 文が宣言されています。

この process 文の中では、一般のソフトウェアと同じ感覚で、 if case などを用い、
シーケンシャルな手順 を記述することができます。
これにより、複雑な処理であっても、直感的にその動作を表現することが可能になります。

process のカッコ()内は、 センシティビティ・リスト と呼ばれ、そこで記述された信号(この例では CNT ERR )が
変化した時に、 begin から始まる処理が実行されます。
この例では、 ERR が 1 のとき ” E ” と表示され、 ERR が 0 で CNT という4bitの整数が (0〜9) のとき、
対応する"0"〜"9"の数字が表示されます。

3 順序回路の記述例
次に順序回路の記述例について紹介します。

(1) Dフリップフロップの記述例
10章で示した Dフリップフロップ の記述例を、もう1度示します。
ソースコードの前半は入出力関連を表し、後半はクロック CLK の立ち上りにおける入力 D の値が
出力 Q に出力される D-FF の動作を表しています。
このような 順序回路 の場合、 architecture 部は、 RTL(Register Transfer Level) で記述します。

process 文の中では、一般のソフトウェアと同じ感覚で、 if 文や case 文などを用い、
シーケンシャルな手順 (コンカレントではない)を記述することができます。
これにより、複雑な処理であっても、直感的で分かりやすくその動作を表現することが可能になります。

先に述べたように、 process 文のカッコ()内は、 センシティビティ・リスト と呼ばれ、
そこで記述された信号(上の例では CLK )が変化した時に、 begin から始まる処理が実行されます。
この例では、 CLK が 0 から 1 に遷移しない限り、入力 D が変化しても出力 Q は変化しません。
したがって、 センシティビティ・リスト に入力 D を記述する必要はありません。

次の if 文では、クロック CLK の立ち上った時点で、その後の end if 文までの処理が
実行されることを示しています。

この場合、入力 D の値が、出力 Q に表れるので、 D-FF の動作が実現されます。

(2) Dフリップフロップを使用したレジスタの記述例
複数の D-FF を並列に配置した nbit レジスタ の例を、以下に示します。
入力 EN = 1 のとき、クロック CLK の立ち上りにおける D-FF の入力 D が、出力 Q にあらわれます。
一方、 EN = 0 のとき、 D-FF の出力 Q の値は変化しません。

ここで、 entity の次に、 generic から始まる一文があります。

これは、設計するレジスタ等のビット数を具体的な数字(たとえば、4 )で示さず、
WIDTH のような 変数 を用いて一般化する手法です。
いわゆる パラメタライズ手法 とも呼ばれ、これにより 汎用性のあるVHDLソースコード
生成することが可能です。

先に述べた パッケージ群 にも導入され、登録されたライブラリの有効活用にも大きく寄与しています。

(3) 10進カウンタの記述例
10章で紹介した 10進カウンタ のソースコードを、以下に示します。
ここでは、2進数の演算パッケージ ( IEEE.std_logic_unsigned.all )を呼び出すことにより、

COUNT <= COUNT + 1;

の一行で、4bitの変数 COUNT のカウントアップ動作を表しています。

(4) 疑似ランダムパターン発生回路(M系列)の記述例
第8章で解説した 疑似ランダムパターン発生回路 を、VHDLを用いて記述してみましょう。

原始多項式に x3 + x2 + 1 を用いた場合のソースコードを以下に示します。




なお、動作を開始する時点で、入力 CLRN = 0 とし、それ以降は CLRN = 1 とします。
これにより、4個のD-FFの出力がすべて 1 にセットされ、その後は15クロック周期の
疑似ランダムパターン を発生し続けます。

(5) ステートマシンを用いた2bitアップダウンカウンタの記述例
順序回路の最後に、簡単な ステートマシン を設計してみましょう。

一般に、 ステートマシン では、 状態図 から 遷移表 を作成し、フリップフロップを用いて具体的な回路を設計します。
しかし、VHDLを用いれば、 状態図 から 直接 回路を記述することも可能です。

ステートマシンを用いた、 2ビットのアップダウンカウンタ の記述例を以下に示します。



architecture 部の 2行に、 type から始まる2行があります。

ここでは、 列挙型変数 を用いて、4つの状態に( ZERO )、( ONE )、( TWO )、( THREE )
という名称を付加しています。

process 文の中で、これらの変数名と、 case 文を組み合わせることにより、
直感的でわかりやすいソースコードとなっています。
なお、コンパイラは、これらの状態に適当なビット数の2進数を自動的に割り当てます。

5 まとめ
本章では、 ハードウェア記述言語(VHDL)を用いた回路の表記法 について解説しました。

このように、VHDLでは、下位のゲートレベルから上位の STRUCTURE まで、
幅広いレベルで記述することが可能です。
なお、VHDLにより記述できる回路設計や回路シミュレーションの範囲は極めて広く、
この限られた教材の中ではとても紹介しきれません。
不足する部分が多々あると思いますが、その場合はインターネット上の解説や、
下に示す参考文献を参考にして下さい。

次章では、簡単な電卓をVHDLを用いて設計する事例を紹介します。

6 参考文献
(1) 長谷川裕恭: 「VHDLによるハードウェア設計入門」、CQ出版社
(2) Z.Navabi著、佐藤一幸訳: 「VHDLの基礎」、日経BP出版センター
(3) 中 幸政: 「VHDLによるロジック設計入門」、 トランジスタ技術 1997年12月号
(4) MAX+PLUSU VHDL解説書、 ALTERA

論理回路2のトップページに戻る