自由設計の回路を今回のレポート課題とします。
library ieee;
use ieee.std_logic_1164.all;
entity dec is
port (
a: in std_logic_vector(2 downto 0);
x: out std_logic_vector(7 downto 0)
);
end dec;
architecture arch of dec is
begin
process (a) begin
case a is
when "000" => x <= "00000001";
when "001" => x <= "00000010";
when "010" => x <= "00000100";
when "011" => x <= "00001000";
when "100" => x <= "00010000";
when "101" => x <= "00100000";
when "110" => x <= "01000000";
when "111" => x <= "10000000";
when others => x <= "XXXXXXXX";
end case;
end process;
end arch;
この中では、architecture記述の中で、プロセス文(process)[p.36]というものを
使っています。
このプロセス文は、非常によく使うものですので、ぜひ覚えておきましょう。
プロセス文は、カッコ内に書いた変数(センシティビティ・リスト、と呼ぶ)の
値が変化したときに、その中が実行されます。
このデコーダの場合は、出力xが変化するのは、変数aが変化したとき、ですから、
aをセンシティビティ・リストに入れてあります。
この場合に実行される内容は、aの値に応じて出力xの値を変える、 ということですので、それをcase文[p.43]を用いて記述しています。 VHDLのcase文はC言語などのcase文と似ていて、aの値がwhenで指定した値に 応じて、「=>」の右側の処理(値の代入)が行われます。 例えばa="001"の場合は、x(1)のみが1の、x="00000010"としています。 ちなみに、入力が"000"〜"111"の場合以外は、不定値である"X"を 代入しています。
このようにして入力が3ビットのデコーダは記述できるわけですが、 この調子でいけば、何ビットのデコーダでも、同じように記述できそうです。 これが、HDLを用いた論理回路設計の特徴といえます。 従来の論理回路の設計手法では、入力が3ビットのデコーダの論理回路図[p.63]を 設計したとしても、入力が4ビットのデコーダが必要になったら、 またゼロから作り直しになってしまいます。
library ieee;
use ieee.std_logic_1164.all;
entity enc is
port (
a: in std_logic_vector(7 downto 0);
x: out std_logic_vector(3 downto 0)
);
end enc;
architecture arch of enc is
begin
process (a) begin
if (a(0) = '1') then x <= "1000";
elsif (a(1) = '1') then x <= "1001";
elsif (a(2) = '1') then x <= "1010";
elsif (a(3) = '1') then x <= "1011";
elsif (a(4) = '1') then x <= "1100";
elsif (a(5) = '1') then x <= "1101";
elsif (a(6) = '1') then x <= "1110";
elsif (a(7) = '1') then x <= "1111";
else x <= "0000";
end if;
end process;
end arch;
この例では、プロセス文の中で、if文[p.42]を使って、出力の値を
決定しています。
具体的には、a(0)から順番に1があるかを探していき、
あったところでxを決定しています。
このエンコーダの論理回路図は[p.65]の図のようになりますが、 ビット数を変える場合でも、VHDL記述であれば楽チンですね。
library ieee;
use ieee.std_logic_1164.all;
entity sel is
port (
a, b, c, d: in std_logic;
s: in std_logic_vector(1 downto 0);
x: out std_logic
);
end sel;
architecture arch of sel is
begin
process (a, b, c, d, s) begin
case s is
when "00" => x <= a;
when "01" => x <= b;
when "10" => x <= c;
when "11" => x <= d;
when others => x <= 'X';
end case;
end process;
end arch;
case文が使われていますね。
ここでプロセス文のセンシティビティ・リストに、a, b, c, dに加えて
sも入っていることに注意しておきましょう。
(その理由を考えておきましょう)
library ieee;
use ieee.std_logic_1164.all;
entity cmp is
port (
a, b: in std_logic_vector(7 downto 0);
gt, lt, eq: out std_logic;
);
end cmp;
architecture arch of cmp is
begin
process (a, b) begin
gt <= '0';
lt <= '0';
eq <= '0';
if (a > b) then
gt <= '1';
elsif (a < b) then
lt <= '1';
else
eq <= '1';
end if
end proess;
end arch;
この例では、まずgt, lt, eqを最初に0にしておき、
その後、該当するもののみを1にする、という処理を書いてあります。
この場合、プログラミング言語の場合は、gtなどの変数がまず0になり、
その後1になるわけですが、VHDLで記述しているのは回路ですので、
実際に、まずgtが0になったあとで1になる、ということは起こらず、
結果として(この場合はプロセス文が終わった時点で)gtの値が
どうなっているか、だけが意味を持つことに注意しておきましょう。