8.2.1 リテラル / 非公式訳

pp.159-161

8.2.1 リテラル

リテラル」とはコードに直接記述された値のことです。(略)

(略)

数値リテラルは、デフォルトでは10が基数であるとして解釈されますが、基数つきの数値リテラルを使えば別の基数で値が記述できます。たとえば10進数の51は、16#33#のように16進数で書けますし、2#0011_0011#のように2進数でも書けます。指定できる基数の範囲は2~16です。数値リテラルは2進数で書こうが16進数で書こうが整数値であることに変わりはなく、整数型ではないオブジェクトに代入するとエラーが出ますので注意してください。

VHDLにおけるストリングリテラルは一般に、テキストを表現するかビット列を表現するかいずれかの目的に使われます。しかしコンパイラーは、ストリングの中身を見てその型を判断することはできず、判断材料は、そのストリングの現れるコンテキストしかありません。このことは、文字列リテラルとビット列リテラルとの違いを理解するうえで重要なことです。VHDLでストリングを記述する方法はこの2つだけであり、コードを見ただけで分かる唯一の違いは、ビット列リテラルには左引用符の前に基数指定子のあることです。ソースコードの処理されるとき、ビット列リテラルは、基数指定子を考慮した一定のルールに従って通常のストリングに自動的に拡張されます。最も単純な形だと、基数指定子はbdohのいずれか1文字です。それぞれ2進数、10進数、8進数、16進数を表します。下の例は、3種類のビット列リテラルが、同じストリング値に拡張されることを示しています。

d"123"      -- "1111011"に拡張される
b"111_1011" -- "1111011"に拡張される
7x"7b"      -- "1111011"に拡張される

拡張されたストリングにおけるデフォルトのビット数は基数指定子によって異なります。2進数の場合、拡張後のビット数はビット列リテラルと同じです。8進数の場合、拡張後のビット数は、8進数の桁数の3倍です。16進数の場合、拡張後のビット数は、16進数の桁数の4倍です。基数指定子の前にビット数を書けば、拡張後のストリングのビット数を明示的に指定することも可能です。その場合に生成されるストリングは、指定したビット数に応じてパディングもしくは切り詰めの処理が施されますが、符号つき基数指定子(sxsosb)を使用した場合は符号拡張の処理もなされます。符号なし基数指定子(uxuoub)は、シンプルな基数指定子(xob)と同じです。下に、符号つき、符号なしの各基数指定子、および固定長ビット列リテラルの使用例を示します。

8d"123"       -- "01111011"に拡張(訳註: 符号なしなのでゼロがパディングされて8ビットになる)
8b"111_1011"  -- "01111011"に拡張(訳註: 符号なしなのでゼロがパディングされて8ビットになる)
8ub"111_1011" -- "01111011"に拡張(符号なしなので符号拡張はなされない(訳註: 符号なしなのでゼロがパディングされて8ビットになる))
8sb"111_1011" -- "11111011"に拡張(符号つきなので符号拡張がなされる(訳註: 負数のままビット数8に拡張される))
x"7b"         -- "01111011"に拡張(訳註: 16進数の固定長なのでビット数は4の倍数に拡張される)
ux"7b"        -- "01111011"に拡張(符号なしなので符号拡張はなされない(訳註: 16進数の固定長なのでビット数は4の倍数に拡張される))
8sx"b"        -- "11111011"に拡張(符号ありなので符号拡張がなされる(訳註: 負数のままビット数8に拡張される))

下線も利用できます。下線は、文字列が拡張される前に自動的に取り除かれます。

x"07ff_ffff"   -- "00000111111111111111111111111111"に拡張(訳註: 最上位の0も省略されずに拡張)
b"1100_0011"   -- "11000011"に拡張
d"150_000_000" -- "1000111100001101000110000000"に拡張

下線で気をつけるべきことは、ビットベクタ型のオブジェクトに代入される通常のストリングには使用できないということです。なぜなら、エニュマレーション型のbitおよびstd_ulogicには下線文字がないからです。下線を使いたい場合は、下のようにビット列を使わなければなりません。

variable slv: std_logic_vector(7 downto 0);
...
slv := "1100_0011"; -- これはエラー。エニュマレーション型のbitに下線文字はないため。
slv := b"1100_0011" -- これはOk。"11000011"に拡張されたあとslvへ代入される。;

読みやすさを保ったまま何らかの値をビットベクタへ代入したい場合は、下のように10進数の基数指定子をつけて記述したビット列リテラルを使うのがよいでしょう。

constant HORIZONTAL_RESULUTION: coord_type := d"800"; -- "1100100000"より読みやすい。
constant PLAYER_X_POS: coord_type := d"640";          -- "1010000000"より読みやすい。

――――――――――――――――――――――――

訳註: 要するに

  • 整数を表現するときは16#ab#のようにすれば10進数ではなく16進数で表記できる。
  • ビット列を表現するときはx"ab"のようにすれば2進数ではなく16進数で表記できる。
  • 20x"ab"のようにすればビット数も指定できる(パディングまたは切り詰めがなされる)。
  • 20sx"ab"のようにすれば符号拡張もできる(パディングまたは切り詰めがなされる)。