第8回: ALU・組み合わせ論理回路のVHDL記述のまとめ

ALU

[p.76] 加算だけでなく、減算や論理和・論理積などのいろいろな演算を 切り替えて行う回路を算術論理演算ユニット (Arithmetic and Logic Unit; ALU)と呼びます。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity alu is
  port (
    a, b: in std_logic_vector(7 downto 0);
    opcode: in std_logic_vector(2 downto 0);
    x: out std_logic_vector(7 downto 0)
  );
end alu;

architecture arch of alu is
begin
  process (a, b, opcode)
    case opcode is
      when I_AND => x <= a and b;
      when I_OR  => x <= a or b;
      when I_NOT => x <= not a;
      when I_XOR => x <= a xor b;
      when I_ADD => x <= a + b;
      when I_SUB => x <= a - b;
      when I_ACC => x <= a;
      when I_DAT => x <= b;
      when others => x <= "XXXXXXXX";
    end case;
  end process;
end arch;

package alu_pack is
constant I_AND: std_logic_vector(2 downto 0) := "000";
...
end alu_pack;
このALUのVHDL記述そのものは、意外と単純で、行う演算を指定する opcodeの値に応じて、出力xを、入力a, bから求める式を case文で切り替えているだけ、です。 (ちにみに後半のpackage以下で、演算の指定に使っている I_ANDなどの定数の値を定義しています。C言語での#defineのようなものと 理解しておいてください)

ここでちょっと面白いのは、その論理合成結果[p.77「論理回路図」]です。 1ビット分のALUは、入力であるa[n], b[n]からいろいろな演算回路を通し、、 そのうちの1つをopcaodeによって、セレクタを使って選ぶ、という 構成になっています。(※セレクタは[p.67]参照) 上から4つの論理演算は、そのまんま、なのですが、 真ん中の加算・減算のところが、ちょっと一工夫があります。 opcode=100のときは、xはa+b(加算)なので、加算器を通した 結果がxに出てきますが、この加算器のcin(下の桁からの桁上げ)は、 下半分の図からわかるように、最下位ビットのALUでは、opcode[0]に なっています。 opcode=100(加算)のときは、opcode[0]=0ですので、 まさに桁上げ伝播加算器(RCA)の構成となります。

ところがoppcode=101(減算)のときは、加算器のb側には b[n]をNOTゲートを通したもの(/b)が与えられています。 またこのときopcode[0]=1ですので、全体としては、 「a + /b + 1」が求められることになります。 ところが、/b + 1 とは、bの「2の補数」ですので、 2進数の数としては、bの符号を反転したもの(-b)と同じ意味となります。 (2の補数については、ここなどを参照) つまり出力xは、「a - b」と同じ意味となり、減算が行われていることに なります。


組み合わせ論理回路のVHDL記述のまとめ

演習で行ったデコーダ等演算器等の組み合わせ論理回路のVHDL記述を、 改めておさらいしておくことにしましょう。
配布資料
戻る