データ型の使い方と型変換


【データの種類】

VHDLでは、信号宣言(signal)、変数宣言(variable)、定数宣言(constant)の
全ての場合にデータタイプ(型)を指定する必要があります。
この型が異なると代入などの式はエラーとしてはじかれてしまいます。

VHDLはデータの型が沢山用意されているだけでなく、新たな型を自ら作る
ことも可能となっています。
さらには、この型の異なる間を変換する関数も用意されています。



【VHDLの標準の型】

 下表の型はあらかじめVHDLの標準で用意されているもので、これらを
使うには新たにパッケージを追加して呼ぶ必要はありません。

データ型 内容
 Integer  整数で32ビット -2147483647〜2147483646 
 Real  浮動少数点
 Bit  ロジック値 0 または 1
 Bit_Vector  Bit列  "010010" "01011010"
 Boolean  論理値  True または False
 Character  ASCII文字
 Time  時間の物理タイプ fs、ps、ns、us、ms、sec、min、hr
 Severity level  メッセージタイプ NOTE、WARNING、ERROR、FAILURE
 Natural、Positive  Integerのサブタイプ 0=< NATURAL、0<POSITIVE
 String  文字列



【ユーザ定義の型】

 ユーザは新しいデータ型を新たに定義することが出来ます。
その時使うのが type 、subtype という宣言文です。

(1) 型定義
  新しい型定義に使う type文の書式は下記のような種類となります。

 《列挙タイプの時》

  type データ型名 is (要素、要素、・・・);

  例 1週間の型 WEEK の定義
   type WEEK is (SUN,MON,TUE,WED,THU,FRI,SAT);

  例 std_logic の定義
   このstd_logicは最もよく使う型ですが、これは、std_logic_1164という
   IEEEのパッケージの中で下記のように型宣言されています。
   type std_logic is ('U','X','0','1','Z','W','L','H','-');


 《Integerタイプの時》
   integerタイプではrangeで値の範囲を指定します。これをしないと
   32ビットの型を作成してしまい大きな回路となってしまうことがあります。

   type データ型名 is integer range i to j;

   例 BCD桁の型 digit の定義
    type digit is integer range 0 to 9;


(2) サブタイプ定義
  サブタイプとは、既にあるデータ型の範囲を指定して、分かりやすい名前で
  再定義しるものです。
  これには subtype文を使い、書式は下記となります。

   subtype サブタイプ名 is データ型名 [範囲|レンジ];

  例 std_logic_vectorのサブタイプ定義
   subtype IOBUS is std_logic_vector(7 downto 0);
   subtype DIGIT is integer range 0 to 9;


【配列タイプ】

配列は新たな型定義のひとつで、同じタイプのデータを集めて新たな型として
定義するものです。その書式は下記となります。

 type データ型名 is array 範囲 of 元の型名;

この中の範囲の項にもいろいろな型が指定できます。型指定が無いときはinteger
とみなされます。

例 下記は同じ扱いとなります。
  type WORD is array(1 to 8) of std_logic;
  type WORD2 is array(integer 1 to 8) is std_logic;

例 std_logic_vector の型定義
  これはIEEEのstd_logic_1164の中で下記のように定義されています。

  type std_logic_vector is array (Natural range <>) of std_logic;


《多次元配列》
 範囲を2つ以上の組合せで指定すると多次元配列となります。

  例 2次元配列の例
   
    type memarray is array (0 to 5, 7 downto 0)  of std_logic;

  例 上記型を使ったROMの作成例
   
    constant ROMDATA : memarray :=(('0','0','0','0','0','0','0','0'),
                             ('0','1','1','1','0','0','0','1'),
                             ('0','0','0','0','0','1','0','1'),
                             ('1','1','0','0','0','1','1','0'),
                             ('1','1','1','1','1','1','1','1'));

 (注) constant文には初期値の設定が必要で、それには、”:=”という
     記号を使ってデータ型名のあとに続いて初期値を定義します。
     例  constant AAA : std_logic := "0";

 (注) 上記のような多次元配列のROM定義では、実際のロジック回路を生成
     することが出来ません。従って上記のようなROMデータはシミュレーション
     パターン用のデータ作成用として使われます。



《配列の多重定義》
 型定義をする際に、元の型が配列のものから、さらに新しい配列を定義することを
 配列の多重定義と呼びます。
 例えば下記の例では、もともと配列であるstd_logic_vectorの型をもつWAVE型を定義し
 そのWAVE型を元に、新しい配列ROMを多重定義しています。

 下記の例では、この新しいROMという型で、定数SINEを定義しています。そしてその
 実際の初期値を := 以下で定義していますが、std_logic_vector ですから、6ビット
 の長さの配列を、64個並べて定義しています。この内容は、6ビット分解能の正弦波
 の1周期分のデータとなっています。

 このように多重定義で定義されたROMはロジック回路として生成が可能ですので、
 これで多数個の定数列をロジック回路で組むことが可能になります。

   例 6ビットの正弦波を生成するsinの値のバイナリ配列
 
  





【型の変換】

VHDLは厳密に型の一致が求められます。従って異なる型同士の演算や代入は出来ま
せん。代入を行うためには代入される側の型に変換してから行う必要があります。
この型を変換する文法があり、型変換関数が用意されています。

関数名 機能内容
std_logic_1164パッケージ内
  To_stdlogicvector(A) bit_vectorからstd_logic_vectorへの変換
  To_bitvector(A) std_logic_vectorからbit_vectorへの変換
  To_stdlogic(A) bitからstd_logicへの変換
  To_bit(A) std_logicからbitへの変換
std_logic_arithパッケージ内
  CONV_std_logic_vector(A、ビット幅) integer、unsigned、signedからstd_logic_vectorへの変換
  CONV_INTEGER(A) unsigned、signedからintegerへの変換
std_logic_unsignedパッケージ内
  CONV_INTEGER(A) std_logic_vectorからintegerへの変換


実際の使用例は下記のようにします。

 tblout <= SINE(CONV_INTEGER(sumlt (21 downto 16)));
 



Topへ戻る