ALUのVHDL記述

琉球大学情報工学科 和田 知久


4:1マルチプレクサの設計

以下に5種類のVHDLの記述方法を説明する。

library IEEE;
use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD;

entity MUX4_1 is
  port (Sel :     in unsigned (1 downt 0);
     A, B, C, D : in std_logic;
     Y :      out std_logic);
end entity MUX4_1;

architecture COND_DATA_FLOW of MUX4_1 is
begin

ここに内容を記述する。

end architecture COND_DATA_FLOW;


内容1:if文による記述

process (Sel, A, B, C, D)
begin
  if (Sel = "00") then
    Y <= A;
  elsif (Sel = "01" then
    Y <= B;
  elsif (Sel = "10") then
    Y <= C;
  else
    Y <= D;
  end if;
end process;


内容2:条件付代入文
(同時処理文であり、processの中に入らない。)

Y <= A when Sel = "00" else
   B when Sel = "01" else
   C when Sel = "10" else
   D ;   -- when Sel="11"


内容3:階層if文

process (Sel, A, B, C, D)
begin
  if (Sel(1) = '0' ) then
    if (Sel(0) = '1') then
      Y <= A;
    else
      Y <= B;
    end if;
  else
    if (Sel(0) = '0') then
      Y <= C;
    else
      Y <= D;
    end if;
  end if;
end process;


内容4:case文

process (Sel, A, B, C, D)
begin
  case Sel is
    when "00" => Y <= A;
    when "01" => Y <= B;
    when "10" => Y <= C;
    when others => Y <= D;
  end case;
end process;


内容5:選択代入文

with Sel select
  Y <= A when "00",
     B when "01",
     C when "10",
     D when others;


8:3プライオリティエンコーダの設計

INPUTS OUTPUTS
A7 A6 A5 A4 A3 A2 A1 A0 Y2 Y1 Y0 Valid
0 0 0 0 0 0 0 0 X X X 0
0 0 0 0 0 0 0 1 0 0 0 1
0 0 0 0 0 0 1 X 0 0 1 1
0 0 0 0 0 1 X X 0 1 0 1
0 0 0 0 1 X X X 0 1 1 1
0 0 0 1 X X X X 1 0 0 1
0 0 1 X X X X X 1 0 1 1
0 1 X X X X X X 1 1 0 1
1 X X X X X X X 1 1 1 1

以下に3種類のVHDLの記述方法を説明する。

library IEEE;
use IEEE.STD_LOGIC_1164.all; IEEE.NUMERIC_STD.all;

entity PRI_EN8_3 is
  port (A : in unsigned (7 downto 0);
     Valid : out std_logic;
     Y : out unsigned (2 downto 0));
end entity PRI_EN8_3;

architecture COND_DATA_FLOW of PRI_EN8_3 is
begin

ここに内容を記述する。

end architecture COND_DATA_FLOW of PRI_EN8_3;


内容1:if文

process (A)
begin
  Valid <='1';
  if   (A(7) = '1') then Y <= "111";
  elsif (A(6) = '1') then Y <= "110"
  elsif (A(5) = '1') then Y <= "101"
  elsif (A(4) = '1') then Y <= "100"
  elsif (A(3) = '1') then Y <= "011"
  elsif (A(2) = '1') then Y <= "010"
  elsif (A(1) = '1') then Y <= "001"
  elsif (A(0) = '1') then Y <= "000"
  else
    Valid <='0';
    Y <= "XXXX";
  end if;
end process;


内容2:case文

process (A)
  Variable A_int : integer range 0 to 255;
begin
  A_int := to_integer (A);
  Valid <='1';
  case (A) is
    when 128 to 255 => Y <= "111";
    when 64 to 128 => Y <= "110";
    when 32 to 63 => Y <= "101";
    when 16 to 31 => Y <= "100";
    when 8 to 15 => Y <= "011";
    when 4 to 7 => Y <= "010";
    when 2 to 3 => Y <= "001";
    when 1 => Y <= "000";
    when others => Valid <= '0' ; Y <= "XXX";
  end case;
end process;


内容3:for-loop文

process (A)
begin
  Valid <='0';
  Y <= "XXX";

  for N in 0 to 7 loop
    if (A(N) = '1') then
      Y <= To_Unsigned (N, 3);
      Valid <= '1' ;
    end if;
  end loop;

end process;


あるarithmetic logic unit (ALU)の設計

S4 S3 S2 S1 S0 Cin 動作 説明 実行ブロック
0 0 0 0 0 0 Y <= A Aを転送 Arithmetic Unit
0 0 0 0 0 1 Y <= A+1 Aをインクリメント Arithmetic Unit
0 0 0 0 1 0 Y <= A + B 加算 Arithmetic Unit
0 0 0 0 1 1 Y <= A + B + 1 キャリー付加算 Arithmetic Unit
0 0 0 1 0 0 Y <= A + Bbar AとBの1の補数をたす Arithmetic Unit
0 0 0 1 0 1 Y <= A + Bbar + 1 減算 Arithmetic Unit
0 0 0 1 1 0 Y <= A - 1 デクリメント Arithmetic Unit
0 0 0 1 1 1 Y <= A Aを転送 Arithmetic Unit
                 
0 0 1 0 0 0 Y <= A and B 論理積 Logic Unit
0 0 1 0 1 0 Y <= A or B 論理和 Logic Unit
0 0 1 1 0 0 Y <= A xor B 排他的論理和 Logic Unit
0 0 1 1 1 0 Y <= Abar 1の補数 Logic Unit
                 
0 0 0 0 0 0 Y <= A Aを転送 Shifter Unit
0 1 0 0 0 0 Y <= shl A Aを左シフト Shifter Unit
1 0 0 0 0 0 Y <= shr A Aを右シフト Shifter Unit
1 1 0 0 0 0 Y <= 0 0を転送 Shifter Unit

library IEEE;
use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all;

entity ALU is
  port ( Sel   : in unsigned(4 downto 0);
      CarryIn: in std_logic;
      A, B  : in unsigned(7 downto 0);
      Y    : out unsigned(7 downto 0));
end entity ALU;

architecture COND_DATA_FLOW of ALU is
begin
  ALU_AND_SHIFT:
  process (Sel, A, B, CarryIn)
   variable Sel0_1_CarryIn : unsigned(2 downto 0);
   variable LogicUnit, ArithUnit, ALU_NoShift : unsigned(7 downto 0);
  begin

    ---------------
    -- Logic Unit
    ---------------
    LOGIC_UNIT: case Sel(1 downto 0) is
      when "00"  => LogicUnit := A and B;
      when "01"  => LogicUnit := A or B;
      when "10"  => LogicUnit := A xor B;
      when "11"  => LogicUnit := not A;
      when others => LogicUnit := (others => 'X');
    end case LOGIC_UNIT;

    ---------------
    -- Arithmetic Unit
    ---------------
    Sel0_1_CarryIn := Sel(1 downto 0) & CarryIn; -- VHDLではcaseに連接を使えない
    ARITH_UNIT: case Sel0_1_CarryIn is
      when "000"  => ArithUnit := A;
      when "001"  => ArithUnit := A + 1;
      when "010"  => ArithUnit := A + B;
      when "011"  => ArithUnit := A + B + 1;
      when "100"  => ArithUnit := A + not B;
      when "101"  => ArithUnit := A - B;
      when "110"  => ArithUnit := A - 1;
      when "111"  => ArithUnit := A;
      when others  => ArithUnit := (others => 'X');  -- "XXXXXXXX"の意味
    end case ARITH_UNIT;

    ---------------
    -- Multiplex
    ---------------
    LA_MUX: if (Sel(2) = '1' ) then
      ALU_NoShift := LogicUnit;
    else
      ALU_NoShift := ArithUnit;
    end if LA_MUX;

    ---------------
    -- Shift operation
    ---------------
    SHIFT: case Sel(4 downto 3 ) is
      when "00"  => Y <= ALU_NoShift;
      when "01"  => Y <= Shift_left(ALU_NoShift, 1);  -- NUMERIC_STD関数
      when "01"  => Y <= Shift_right(ALU_NoShift, 1);  -- NUMERIC_STD関数
      when "10"  => Y <= (others => '0');
      when others => Y <= (others => 'X');
    end case SHIFT;

  end process ALU_AND_SHIFT;
end architecture COND_DATA_FLOW;


Variable と Signal (代入が時間的に異なり、トラブリやすい)

architecture RTL of REI is
signal X, Y, Z, C : unsigned (3 downto 0);
signal A, B    : unsigned(3 downto 0);
begin

process (X, Y, Z, C) begin

 C <= Z;
 A <= X + C ;
 C <= Y;
 B <= X + C;

end process;
end RTL;

A <= X + Y

B <= X + Y

architecture RTL of REI is
signal X, Y, Z : unsigned (3 downto 0);
signal A, B  : unsigned(3 downto 0);
begin

process (X, Y, Z)
variable C : unsigned ( 3 downto 0);
begin

 C := Z;
 A <= X + C ;
 C := Y;
 B <= X + C;

end process;
end RTL;

A <= X + Z

B <= X + Y