順序回路の設計(5章フリップフロップとそのVHDL記述)



ラッチとフリップフロップ(FF)

ラッチの定義(例:Dラッチ)

CLKHighの時に、入力Dは出力Qへインバータ2段で接続され、
CLK
Lowの時に、インバータ2段がリング接続になり、値を保持する。


Dフリップフロップ(FF)の定義(例:Dフリップフロップ)


フリップフロップ(FF)の動作波形

シンボル

名称

意味

tC

サイクルタイム

動作する周期、スペックでは最小値が規定される。

tS

セットアップタイム

クロックエッジに対するデータを用意する時間、スペックでは最小値が規定される。

tH

ホールドタイム

クロックエッジに対してデータを保持する時間、スペックでは最小値が規定される。

tKQ

アクセスタイム

クロックエッジからデータ出力までの時間、スペックでは最大値が規定される。


フリップフロップを使った回路(同期回路)の意味

·         以下のように3つ(もしくは3人)の計算機があったとする。

·         3人はそれぞれ計算の仕事を同時に行う。例えば、計算1は加算、計算2は掛算、計算3は割算である。

·         この3人が計算結果をグルグル回すことで、1つの大きな仕事ができるとする。

この場合以下のようなことがおきる

1) 計算1は5nsごとに計算結果を計算2に渡そうとするが、計算2は10nsごとにしか仕事もらえない。
2) 計算1は計算2が空いたことを教えてもらってから、計算2へ仕事を渡す。
3) 同様に計算2も計算3が空いたことを知らされて、計算3へ結果を渡し、その後計算1へ自分が空いたことを伝える。
4) 要するに、隣接ユニット間で知らせ合い(ユニット間の通信)を行う必要がある。

·         同期回路では、このユニットごとの通信を不要にするために、ユニット間にフリップフロップを入れて、同一のクロック信号で同期させる。

1) クロックの立ち上がりエッジで、セイノで、(同時に)各ユニットへ入力データが入力される。
2) その後、計算1は7ns (CLK立ち上がりエッジからFFの出力までの遅延を2nsとする)で計算が終わるが
3) 次の入力を得るまで、20nsぐらいの間そのまま待たされる。
4) 一番遅い計算3も22ns 後には計算を終える。
5) そして、25ns 後のクロックの立ち上がりエッジで各FFは前のユニットの結果を次のユニットへ伝える。

·         FFの働きは、各ユニットばらばらの計算時間をクロックにより遅らせて、計算時間をそろえている。

·         理想的には、最も低速な計算3の計算時間20nsのサイクル時間が使えそうであるが、実際にはFFのセットアップタイムとアクセスタイムの分だけサイクル時間を延ばす必要がある。

·         一見、同期回路は効率が悪そうであるが、最大のメリットは非同期回路のユニット間の通信が不要になることにある。

·         非同期の場合でも、計算のスループットは結局最も遅い計算3で決まり、それに、ユニット間通信の遅延が加算される。ユニット間通信の遅延がFFのセットアップ+アクセス時間以上なら、同期の方が性能はよくなる。


クイズ1

1)3人の学生ABCさんはそれぞれ以下の仕事をするとする

A: 紙に書かれた数字を見て、その数字に1を加えたもの計算し、紙に答えを書く

B: 紙に書かれた数字を見て、その数字を2倍したもの計算し、紙に答えを書く

C: 紙に書かれた数字を見て、その数字を5倍し、それから3を引き算したもの計算し、紙に答えを書く

最初、Aさん、Bさん、Cさんにそれぞれ、「1」、「2」、「3」と書かれた紙を渡す。

そして、ABCさんはすぐに自分の仕事をする。

先生の「ハイ!」という合図で、AさんはBさんに紙を渡し、BさんはCさんに紙を渡し、CさんはAさんに紙を渡すとする。

先生が「ハイ!」と5回言った後に、Aさん、Bさん、Cさんの紙の数字はそれぞれ幾らか?

 

2) 以下の波形をそれぞれ、DラッチとDフリップフロップに入力した時の波形を描け


VHDLにおけるフリップフロップ(FF)の生成方法

 

リスト5.8 D-FFVHDL記述

ライブラリ宣言

library IEEE; 
use IEEE.std_logic_1164.all;

いつもどおり

エンティティ宣言

entity PET_D_FF is 
 port( CK, D : in std_logic
       Q : out std_logic ); 
end PET_D_FF;

クロック入力:CK
データ入力:D

データ出力:Q

アーキテクチャ宣言

architecture BEHAVIOR of PET_D_FF is 
begin 
  process ( CK ) begin 
   if ( CK'event and CK = '1' ) then 
    Q <= D; 
   end if; 
  end process; 
end BEHAVIOR;

1) 記述は出力信号Qの動作を記述すればよい

2) FFの出力QはクロックのLow->High変化時のみ変化するので、

 2-1) センシティビティリストにCKのみを入れる。
    これで、クロック変化時のみに限定

 2-2) if文でクロックのLow->High変化に限定

·         process文の中で、wait文やif文でエッジを検出する記述を行えば、FFが生成される。

·         エッジ検出記述 教科書のP111 コラム8参照のこと

Clock'event and Clock= '1'

'eventアトリビュートを用いた立ち上りエッジの検出

 

Clock'event and Clock= '0'

'eventアトリビュートを用いた立ち下りエッジの検出

 

not Clock'stable and Clock = '1'

'stableアトリビュートを用いた立ち上りエッジの検出

 

not Clock'stable and Clock = '0'

'stableアトリビュートを用いた立ち下りエッジの検出

 

rising_edge(Clock)

ファンクションコールを用いた立ち上りエッジの検出

 

falling_edge(Clock)

ファンクションコールを用いた立ち下がりエッジの検出

関数rising_edge, falling_edge'X'から''への変化を検知しない。


DFFの記述方法1

P1: process (Clock)
begin
  if ( Clock'event and Clock= '1') then
    Y1 <= A1;
  end if;

  if ( Clock'event and Clock= '1') then
    Y2 <= A2;
  end if;
end process P1;

·         立ち上りエッジのDFFif文は繰り返し書けるで複数のFFを生成できる。


DFFの記述方法2

P2: process
begin
  wait until (Clock'event and Clock= '1');
    Y3 <= A3;
end process P2;

·         wait文はそこでブロックして止まるので、複数のwait文を一つのprocess文に書けない。


DFFの記述方法3

P3: process (Clock)
begin
  if rising_edge(Clock) then
    Y4 <= A4;
  end if;
end process P3;

·         if文中でrising_edge関数を用いた場合。記述がコンパクトでGOOD!


DFFの記述方法4

P4: process
begin
  wait until rising_edge(Clock);
    Y5 <= A5;
end process P4:
 

·         wait文に関数rising_edgeを用いた記述。


P111コラム9 process文を用いたフリップフロップの記述

·         process文を用いて、組み合わせ回路を記述する場合、その組み合わせ回路の全ての入力信号をセンシティビティ・リストに記述すればよかった・一方、process文を用いてフリップフロップや順序回路を記述する場合には、センシティビティ・リストに記述する信号を選択する必要がある。


移動平均回路の設計

リスト avg4.vhd

テストベンチ SigGen.vhd

入力信号列 fm.txt

移動平均回路のVHDL記述

ライブラリ宣言

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 
use IEEE.STD_LOGIC_ARITH.all;

今回は入力信号として、2の補数表現を用いた正・負混合の信号を用いるので、P63コラム4の算術演算用パー-ケージで説明されているように、std_logic_arithを用いる。

エンティティ宣言

entity AVG4 is 
 port(CLK : in std_logic
    FMINPUT : in std_logic_vector(7 downto 0);
    AVGOUT : out std_logic_vector(7 downto 0));
end AVG4;

クロック入力:CLK
データ入力:FMINPUT8ビット)

データ出力:AVGOUT8ビット)

アーキテクチャ宣言

architecture RTL of AVG4 is 
signal FF1, FF2, FF3, FF4 : std_logic_vector(7 downto 0);
signal SUM : std_logic_vector(9 downto 0); 
begin 

4つのFF出力を定義

加算した信号を定義

-- SHIFT REGISTER 
 process(CLK) begin 
  if (CLK'event and CLK = '1') then 
   FF1 <= FMINPUT; 
   FF2 <= FF1; 
   FF3 <= FF2; 
   FF4 <= FF3; 
  end if; 
 end process; 

このような記述で4つのFFが生成される。

   FF1 :=FMINPUT; 
   FF2 := FF1; 
   FF3 := FF2; 
   FF4 := FF3; 

とすると、

   FF4 :=FMINPUT; 

と等価となり、FF1個しか生成されない。

-- SUM 
SUM <= signed(FF1(7)&FF1(7)&FF1)
    +signed(FF2(7)&FF2(7)&FF2) 
    +signed(FF3(7)&FF3(7)&FF3)
    +signed(FF4(7)&FF4(7)&FF4); 

std_logic_arithを用いているので、P63コラム4の算術演算用パー-ケージで説明されているように、signedで型変換を行っている。

8ビットを10ビットに拡張する時に、”00”を前につけると、全て正の数になってしまうので、MSB2ビットコピーしている。

-- DIVIDE BY 4 (SHIFT 2 bit), OUTPUT REGISTER
 process(CLK) begin 
  if (CLK'event and CLK='1') then 
   AVGOUT <= SUM(9 downto 2); 
  end if; 
 end process; 

end RTL;

出力のレジスタを記述している。

4の割り算を2ビット右シフトで実現している。

ここでは、四捨五入は用いず、切り捨てしている。

 


テストベンチのVHDL記述

ライブラリ宣言

library STD, IEEE; 
use STD.TEXTIO.all
use IEEE.std_logic_1164.all; 
use IEEE.std_logic_textio.all;

教科書P85TEXTIOパッケージの説明がある。

今回、テスト入力として他のテキストファイルに書かれた値を用いるので、ライブラリSTDを指定し、パッケージTEXTIOを呼び出している。

エンティティ宣言

entity TESTBENCH_FF1 is 
end TESTBENCH_FF1;

テストベンチであるので、中味は空である。

アーキテクチャ宣言

architecture SIM_DATA of TESTBENCH_FF1 is 

component AVG4 
  port(CLK : in std_logic; FMINPUT : in std_logic_vector(7 downto 0); 
  AVGOUT : out std_logic_vector(7 downto 0)); 
end component; 

signal FMINPUT : std_logic_vector(7 downto 0); 
signal AVGOUT : std_logic_vector(7 downto 0); 
signal CLK : std_logic := '0'; 

begin

今回テストされるAVG4回路(移動平均回路)をコンポーネント(部品)宣言している。

その他用いる信号を宣言している。

-- Sysetem CLK generation 
CLK <= not CLK after 5 ns;

システムクロックを発生している。

nsごとに変化するので、クロック周期は10nsである。

CLKの初期値はsignal宣言のところで、定義されている。

-- DUT 
U1: AVG4 port map (CLK, FMINPUT, AVGOUT);

テストされる回路AVG4を置いている。

-- TEST VECTOR
P1: process
 file TEST_IN : text is in "fm.txt";
 variable LINE_IN : line;
 variable V_FMINPUT : std_logic_vector(7 downto 0);
begin
 readline(TEST_IN, LINE_IN);
 read(LINE_IN, V_FMINPUT);
 FMINPUT <= V_FMINPUT;
 wait for 10 ns;
 if endfile(TEST_IN) then
  wait;
 end if;
end process;

end SIM_DATA;

詳しくは、P85ページの説明とP87ページのリスト4.14を参考にしてください。

fm.txt

の値を読み込んで、10nsすなわち、毎サイクルごとに値をFMINPUT信号に代入している。

if文は終了条件。

configuration CFG_FF1 of TESTBENCH_FF1 is
 for SIM_DATA
 end for;
end CFG_FF1;

VHDLではひとつのエンティティに複数のアーキテクチャを
持たせることができるので、その割り当ての宣言。
必ず最上位階層に記述する必要がある。

 


実習 移動平均回路の動作シミュレーション(1)

リスト avg4.vhd

テストベンチ SigGen.vhd

入力信号列 fm.txt

 

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

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

2) 回路の合成を行え 


HW4

1)    上記内容をレポートにして提出せよ!

2)    16点平均をとる回路に再設計し、動作波形を示し、上記4点平均回路との回路規模を比較せよ。

以上