トップ > Tech > VHDL > std_logic_vectorのアドレスをstd_logic_vectorで指定する

std_logic_vectorのアドレスをstd_logic_vectorで指定する

複数の信号から 1 つを選択するようなマルチプレクサあるいはセレクタを VHDL で記述するとする。Web 上で発見できるソースは下記のようなものが多い。

ただし、信号は 4bit、アドレス指定は 2bit 、出力はアドレスで指定された 1 ビットを出力するものとする。

library IEEE;
use IEEE.std_logic_1164.all;

entity Selector is
  port ( 
    A, B, C, D : in  std_logic;
    Y          : out std_logic;
    ADR        : in  std_logic_vector(1 downto 0)
  );
end Selector;

architecture RTL of Selector is
begin
  process(ADR) begin
  case ADR is
   when "00"   => Y <= A;
   when "01"   => Y <= B;
   when "10"   => Y <= C;
   when others => Y <= D;
  end case;
  end process;
end RTL;

まぁ、当然これで動くのだが、when をいっぱい書いているあたりがどうも冗長であり、ADR が 4 ビット以上ともなると全部を記述する気にもなれない。こういった処理ではソフトウェア的に考えれば、入力(A, B, C, D)を配列として扱い、インデックスとなる ADR を数値で指定して選択したい。

VHDL の std_logic_vector は std_logic の配列のようなものであるから、まず入力は std_logic_vector に変えればよいが、問題は ADR をどうやってインデックスとして指定するかである。

単純に下記のようにするとエラーになる。

Y <= A(ADR);

std_logic_vector のインデックスは整数値でなければならないが、ADR は std_logic_vector であるためである。

この場合、型変換をしてやるとうまくいく。std_logic_vector から integer に変換するためにconv_integer 関数が用意されている。

Y <= A(conv_integer(ADR));

なお、この関数を使用するには

use IEEE.std_logic_unsigned.all;

でパッケージを読み込んでおかなければならない。

全体のソースはこんな感じ。ずいぶんすっきりした。

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity Selector is
  port ( 
    A    : in  std_logic_vector(3 downto 0);
    Y    : out std_logic;
    ADR  : in  std_logic_vector(1 downto 0)
  );
end Selector;

architecture RTL of Selector is
begin
  Y <= A(conv_integer(ADR));
end RTL;
(2010/03/25 17:26:31)
関連ページ
  • VHDL?
13126
プロフィール

Kenz Yamada(山田研二)。1984年生。大阪。ちょっとずつ好きなプログラム作ってます。 好きなものはカメラと旅行。ガジェットや身の回り、ちょっとこだわります。 詳しくは Web mixi で。

Bookmark and Share