4.1.2 process文を用いた組み合わせ回路 P64

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




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

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

リスト4.5 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のスペルに注意

 

リスト4.7 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が必要

 

リスト4.11 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を用いて即時代入( := )を使用する。
  •  
  • Yはsignalであるので、遅延代入(<=)しかできないので、TMPの代わりに使用はできない。
  • したがって、最後に TMPをYに遅延代入している。

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;

この例ではCにY,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;

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

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

 

リスト 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; 
出力YはSignalなので、遅延代入(<=)を用いる。
    end process ALU_AND_SHIFT; 
end architecture COND_DATA_FLOW;
 

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

リスト alu.vhd

テストベンチ test_alu.vhd

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

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


実習

2) 回路合成を行う。

制約なしの回路図、面積、クリティカルパス遅延、クリテイカルパスの入力ピンと出力ピン
速度最小での回路図、面積、クリティカルパス遅延、クリテイカルパスの入力ピンと出力ピン
を求める。
(プリントする回路図では、クリテイカルパスを以下の方法でハイライトさせること。)

3) クリティカルパスのハイライト方法

回路図を表示させ、

Analysys -> Highlight -> CriticalPath

4) 信号線の入力からの遅延時間を調べる方法

信号線をクリックして選択し、

Analysis -> ShowTiming
(マウス右ボタンのポップアップメニューでも使える)

5) 次にTOPの回路の中にあるすべてのBOX(他の回路が違うレベルにある)を展開(同一レベルに)する。

BOXをクリックして選択、

Attribute -> Optimization Directives -> Cell...

Ungroup Cell's Hierarchy をチエックし、Apply

これをすべてのBOXに対して行う。

6) 展開した回路に対して2)と同じものを求める。

制約なしでの回路図、面積、クリティカルパス遅延、クリテイカルパスの入力ピンと出力ピン
速度最小での回路図、面積、クリティカルパス遅延、クリテイカルパスの入力ピンと出力ピン
を求める。
(プリントする回路図では、クリテイカルパスを以下の方法でハイライトさせること。)


宿題3

下記の内容を含むレポートを提出する。

1)与えられたALU記述に対して以下をレポートする。

2) 記述を変更して4ビットと16ビットの同一機能のALUを設計し、

2-1) 制約なしで合成し、

4ビット、8ビット、16ビットALUのビット幅と回路面積、およびビット幅と回路速度の関係を調べよ。

2-2) 最小速度で合成し、

4ビット、8ビット、16ビットALUのビット幅と回路面積、およびビット幅と回路速度の関係を調べよ。


1)ピン間の速度を最小にする設定図

 

2)回路合成の設定図

 

3)合成語の回路図

以上