VHDL速習講座 No.2

はじめに

第二回目では、VHDLの文法のデータの型と演算子について解説します。VHDLは、多様なデータの型をサポートしますが、使用上の制約が複雑です。そこで、実回路を合成することを念頭に置いて、データの型と演算子の関係について整理して解説します。このように理解すると、VHDL文法系が非常に分かりやすくなります。

VHDLのデータ型問題

VHDLを複雑かつ難解にしているものに、多種多様なデータの型の存在があります。というのは、VHDL自体がLSIやシステムの仕様を記述するための言語として発祥したところにあります。ですから、この言語で記述した回路のシミュレーションはおろか、この記述からの回路の自動設計や合成に関しての考慮はなされていません。このことは、アルゴリズムの記述性のよさとこれと相反し、回路の合成をむずかしくします。

VHDLでは、基本となるデータの型だけで、13種があります。そしてこれらの異なるデータの型の信号や変数間で、演算を行ったり、相互接続したりするとエラーとなることがあります。図では、Module Aからのinteger型の信号変数 a とModule Bからのboolean型の信号 b、そして real型の信号 c を接続したり、演算したりしようとするとエラーが発生する場合を示しています。ここで、"場合がある"という意味は、この型とその型はやっていい、でもその型とあの型はダメだというふうにいりくんでいるということです。

また、演算子群は、論理演算、関係演算、算術演算等の大別されますが、データの型によって使用できる演算子と使用できない演算子があります。そして、これらの問題を軽減するために、データ型変換関数や演算子オーバーロードという拡張が行われますが、これらは処理系によってサポートされていないことがあったり、各メーカーの方言的な関数があったりして、結局、標準言語?であるはずのVHDLにソースの互換性問題が発生することになります。かくして、データの型問題は、習得を目指す者の前にデジタル砂漠の蜃気楼として立ちふさがります。

データの型と実際の論理回路

そこで、思い切って、使用するデータの型を必要最小限に絞り込んでしまいます。ここではstd_logic,std_logic_vectorとintegerの三つの型だけを取り上げます。どうしてこの三つなのかといいますと、まずは最初のstd_logicですが、これは論理回路で1ビットのデータを扱うために必要だからです。さらに複数の信号をまとめて扱う場合にはstd_logicをベクトル化したstd_logic_vectorを使用します。これでバス化された複数信号等がまとめて扱えるようになります。std_logicとvectorを基本のデータ型にする理由は、この二つの型だけが図に示す、( U, -, Z, 0, L, 1, H, X, W) という9つの値をとることができるからです。論理関数は、booleanのtrue(真)、fause(偽)の二値で表現できますが、実際の電気信号で論理を扱うディジタル回路の場合には、true(真)、fause(偽)の二値以外に、より詳細な値が必要になります。

ついでにお話ししますと、三つ目の型である、integer(整数)型では、論理に関係する値としては、ゼロとイチしか扱えませんから、たとえば、ハイ・インピーダンス状態や不定やドント・ケアという信号状態を処理できません。
実は、このstd_logicとstd_logic_vectorはIEEE1164という後の規格拡張で登場しました。それ以前のIEEE1076では、boolean や bit, bit_vector しかなく、これらの型では、0と1の二値しか扱えませんでしたから、論理回路上で存在するハイ・インピーダンス状態などは扱えず、実際に回路を設計するハード屋さんは大変に困ったわけです。言語を制定したほうは、そこまで考慮していませんので、彼らにとってはDon't care だったわけです。

演算子との対応関係

さてVHDLでは、機能を記述する場合の演算子には、大きく分けて、論理演算子、関係演算子、算術演算子の三つがあり、それらと使用可能なデータの型には、対応関係があります。std_logicとstd_logic_vectorですべての演算が可能ならば問題がないのですが、じつはstd_logic_vectorは算術演算には使用できないのです。
よく考えてみると、掛け算と足し算の回路で、ハイ・インピーダンスに、8を掛け算して、不定を足してもどうにもなりません。(不定にしちゃいますか?)でもやっぱり、算術演算子は使いたいですよネ。というわけで、整数型のデータ型としてのintegerを追加します。
これで三つの型が出揃いましたので、これらと型の対応関係を図にしてみましょう。
std_logicとstd_logic_vectorでは算術演算子が使用できませんが、integerだとできることがわかりますし、関係演算では、三つの型がすべて使用可能ということになります。また、integerというデータの型は、後述する process 内での variable 文を使用する場合に好都合になります。そんな訳で、三つの型が選択されました。

データ型変換とオーバーロード

通常のディジタル信号の表記としては、std_logic と std_logic_vector を使用すればよいことがわかりました。
しかし、この二つのデータ型では、算術演算をすることができません。それでは、これらの信号間で算術演算をしたい場合にはどうしたらいいでしょうか?

これには二つの方法があり、その第一が、型変換を行う方法で、その第二はオーバーロードを使用する方法です。
オーバーロードを使用する場合には、std_logic_vector型のままの変数に対してビシバシと算術演算記述ができますから、図の左下のバツ印がマルに変わったようになります。

 

これに対し、型変換関数を使用する方法では、process 記述文のなかで、variable 文を使用して任意のローカル変数を宣言し、std_logic_vector型の変数を integer 型のローカル変数に代入し、このローカル変数に対して算術演算をおこない、処理結果の値(integer型)を再び、型変換関数を用いて元のstd_logic_vector型に戻してやります。一見手間がかかる手法ですが、process 文を使用した カウンタ記述等に便利ですから、双方を覚えておいて損はありません。
これらの実際の記述例は後述することとして、次項では全体の見通しを良くするために演算子の話を先に済ませておきましょう。ここでは、std_logic_vector型で算術演算をする場合にふたつの方法があること記憶にとどめておいてください。

メッセージ:第二回目は、いかがでしたでしょうか?私は1979年からずっと半導体、ソフトウェア業界で仕事をしてきました。幸運なことに業界の発展とともに、皆さんに支えられながら今日を迎えております。今、日本のエレクトロニクス、エンジニアリングをめぐる状況は楽観できる状況にはないと思いますが、このようなセミナーを通してささやかでも皆様のお役に立てれれば幸いです。がんばれ!日本のエンジニア!

バックナンバー

>> VHDL速習講座 No.1

 

1950年代の水瓶座生まれ。米国ソフトウェアおよび半導体の先端企業に25年勤務、2004年1月ザイリンクス社を最後に独立、技術系コンサルティングを起業。オーディオ、バイク、写真が趣味。2004年から、体造りからとばかりに、エアロビクス、筋トレなどのエクササイズも始めたところ。
ホームページ http://homepage3.nifty.com/western/
メイルアドレス Renji_Mikami@nifty.com
余談少々:連載のいきさつについて
実は、この講座はE.I.Sさんが立ち上がりのころに連載を開始したのですが、本人が日本の代表を務めていた米国の会社が資産買収?の憂き目にあい、そのあおりで中断していました。今回リニューアルで再開の運びとなりました。どうかよろしくお願いします。

三上廉司 (みかみれんじ)