教科書P31 process文を用いた組み合わせ回路

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


process文を用いた組み合わせ回路の記述方法

  1. 入力信号をもちいて、出力信号の動作のみを記述すればよい。
  2. process( )の( )内にすべての入力信号を書く。忘れると、かってにフリップフロップが生成される。
  3. process文内部は順次処理なので、if文、case文、for-loopを用いることができる。
  4. process文内部の記述で中間変数が必要であれば、process文内部で variable を宣言して用いる。
  5. variableは代入式 が TMP := S+D; のように異なるので、注意せよ。(即時代入)

リスト if文の例

ライブラリ宣言

library IEEE; 
use IEEE.std_logic_1164.all;

いつもどおり

ENTITY宣言
回路の名前と
入出力信号

entity MULTIPLEXER4 is

エンティティ宣言

port ( D : in std_logic_vector(3 downto 0);
    S : in std_logic_vector(1 downto 0);
    Y : out std_logic );

ポート宣言

end MULTIPLEXER4;

エンティティ終了。";"忘れるな!

回路の中味の記述

architecture DATAFLOW of MULTIPLEXER4 is

アーキテクチャ宣言

begin 
  -- process(順次処理文の記述
  process ( D, S ) 
  begin 
  -- if文による出力の場合分け
    if ( S = "00" ) then 
       Y <= D(0); 
    elsif ( S = "01" ) then 
       Y <= D(1);
    elsif ( S = "10" ) then
       Y <= D(2); 
    else
       Y <= D(3);
    end if; 
  end process; 
end DATAFLOW;

  • D,Sを用いて、Yを記述
  • elsifのスペルに注意

 

リスト case文の例

ライブラリ宣言

library IEEE;
use IEEE.std_logic_1164.all;

いつもどおり

ENTITY宣言
回路の名前と
入出力信号

entity DECODER_2_4 is

エンティティ宣言

port ( D : in std_logic_vector(1 downto 0);
    Y : out std_logic_vector(3 downto 0));

ポート宣言

end DECODER_2_4;

エンティティ終了。";"忘れるな!

回路の中味の記述

architecture DATAFLOW of DECODER_2_4 is

アーキテクチャ宣言

begin
  process ( D )
  begin
    -- case文による出力の場合分け
    case D is
      when "00" => Y <= "0001";
      when "01" => Y <= "0010";
      when "10" => Y <= "0100";
      when "11" => Y <= "1000";
      when others => Y <= "XXXX";
      end case;
  end process;
end DATAFLOW;

  • Dを用いて、Yを記述
  • caseの最後にその他すべてのothersが必要

 

リストfor-loop文の例

ライブラリ宣言

library IEEE;
use IEEE.std_logic_1164.all;

いつもどおり

ENTITY宣言
回路の名前と
入出力信号

entity PARITY_CHECKER is

エンティティ宣言

port ( A : in std_logic_vector(7 downto 0);
    Y : out std_logic );

ポート宣言

end PARITY_CHECKER;

エンティティ終了。";"忘れるな!

回路の中味の記述

architecture DATAFLOW of PARITY_CHECKER is

アーキテクチャ宣言

begin
  process ( A )
  variable TMP : std_logic;
    begin
      TMP := '0';
      -- for-loop文による繰り返し処理
      for I in 0 to 7 loop
        TMP := TMP xor A(I);
      end loop;
      Y <= TMP;
    end process;
end DATAFLOW;

  • process文内で variableを宣言
  • 順次処理で、すぐに代入した値を使う場合はvariableを用いて即時代入( := )を使用する。
  •  
  • Ysignalであるので、遅延代入(<=)しかできないので、TMPの代わりに使用はできない。
  • したがって、最後に TMPYに遅延代入している。

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;

この例ではCY,Zが代入されるが、それらは
process
から出る時の一度なので、Cは前回の
Y
の値を保持しているので、

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;

この例ではCvariableであり、その行で
値が代入されるので、

A <= X + Z

B <= X + Y


ある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

ABの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

 

リスト alu.vhd

テストベンチ test_alu.vhd

ライブラリ宣言

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 
use IEEE.STD_LOGIC_UNSIGNED.all;

IEEE.std_logic_unsignedは、std_logic_vector型で
符号ビットなしの演算を行うためのパッケージである。

エンティティ

entity ALU is
  port(Sel : in std_logic_vector(4 downto 0);
    CarryIn : in std_logic
    A, B : in std_logic_vector(7 downto 0);
    Y : out std_logic_vector(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 : std_logic_vector(2 downto 0);
    variable LogicUnit, ArithUnit
            ALU_NoShift : std_logic_vector(7 downto 0);  
    begin

内部で直ぐに後段の回路で用いる信号はVariableで宣言する。

      ---------------------------
      -- 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; 

LogicUnitは後段で用いるので、Variableとし、即値代入(:=)を使用する。

      --------------------------- 
      -- Arithmetic Unit 
      --------------------------- 
        Sel0_1_CarryIN := Sel(1 downto 0) & CarryIN
        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');
        end case ARITH_UNIT; 

ArithUnitは後段で用いるので、Variableとし、即値代入(:=)を使用する。

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

ALU_NoShiftは後段で用いるので、Variableとし、即値代入(:=)を使用する。

      ---------------------------
      -- Shift operation 
      --------------------------- 
        SHIFT: case Sel(4 downto 3) is 
          when "00" => Y <= ALU_NoSHift
          when "01" => Y <= (ALU_NoShift(6 downto 0) & '0');
          when "10" => Y <= ('0' & ALU_NoShift(7 downto 1));
          when "11" => Y <= (others => '0'); 
          when others => Y <= (others => 'X'); 
        end case SHIFT; 

出力YSignalなので、遅延代入(<=)を用いる。

    end process ALU_AND_SHIFT; 
end architecture COND_DATA_FLOW;

 


実習 ALUの動作シミュレーション(1)

リスト alu.vhd

テストベンチ test_alu.vhd

0) 作業ディレクトリに、上記2つのファイルをコピーする。

1)正常動作を確認せよ!


実習

2) 回路合成を行う。


HOMEWORK2

上記ALU回路にて、入力信号A,B、出力信号Yを16ビット化し、

@   動作シミュレーション波形

A   回路合成FINALレポート

B   回路合成後の、テクノロジースケマティック

を含む、設計レポートを提出せよ。

以上