複数の信号から 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;
Kenz Yamada(山田研二)。1984年生。大阪。ちょっとずつ好きなプログラム作ってます。
好きなものはカメラと旅行。ガジェットや身の回り、ちょっとこだわります。
詳しくは Web mixi で。