複数の信号から 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 で。