フリップフロップを使う回路

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

これまで取り扱ってきた組み合わせ回路は、その出力が現在の入力によって一意に定まる回路、すなわち記憶機能をもたない回路であった。しかしながら、実際のコンピュータやそれを構成するディジタル回路では、レジスタやメモリなどの記憶装置が必要であることは周知の通りである。
５．１→　回路をループ（フィードバック）接続すると記憶回路が作れる

- 大規模デジタルシステムの設計では、記憶回路を設計者がゲートのループで作成は禁止されているので、この講義でもループは禁止にする。
したがって、記憶素子を使用したい場合は、これから説明するフリップフロップを部品として使用する。
- ５．２章に多数のラッチ、フリップフロップの説明があるが、これらは教養として知っておくべきであるが、大規模デジタルシステムではこのようなエッジトリガ（５．３．３）でないものは使用しない。また、クロック信号のないものは大規模デジタルシステムで使用されないので、
- 本講義では（会社やスタンフォード大学での慣習にしたがって、）クロック付エッジトリガ（５．３．３）型のものをフリップフロップとし、クロック付エッジトリガでないものをラッチと呼ぶ。非クロックのものは一切使用しない。

## ラッチとフリップフロップ（FF)

教科書ではラッチ、フリップフロップは混同して用いられているが、ここでは以下の意味に統一する。

## ラッチの定義（例：Dラッチ）

クロック入力がアクテイブ（たとえばHIGH）の時、入力から出力へデータが転送され、
クロック入力が非アクテイブ（たとえばLOW）の時、データは前の状態を保持する。
下記はDラッチの例である。

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

## Dフリップフロップ（FF)の定義（例：Dフリップフロップ）

クロック入力が非アクテイブからアクテイブへ（たとえばLow->High）の変化時に、入力Dからデータが取りこまれ、出力Qへデータが転送される。
出力はクロックのLow->High変化時のみ変化する。
下記はDラッチ２つで構成された、ポジティブトリガのDFFの例である。

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

クロック（CLK）入力の立ち上がり変化時にのみデータ入力（D）を取りこみ、内部状態を更新する。この内部状態はデータ出力（Q）に出力される。

シンボル 名称 意味
tC サイクルタイム 動作する周期、スペックでは最小値が規定される。
tS セットアップタイム クロックエッジに対するデータを用意する時間、スペックでは最小値が規定される。
tH ホールドタイム クロックエッジに対してデータを保持する時間、スペックでは最小値が規定される。
tKQ アクセスタイム クロックエッジからデータ出力までの時間、スペックでは最大値が規定される。

## フリップフロップを使った回路（同期回路）の意味

- 以下のように３つ（もしくは3人）の計算機があったとする。
- 3人はそれぞれ計算の仕事を同時に行う。例えば、計算１は加算、計算２は掛算、計算３は割算である。
- この3人が計算結果をグルグル回すことで、１つの大きな仕事ができるとする。
- この場合以下のようなことがおきる
- １）　計算１は5nsごとに計算結果を計算２に渡そうとするが、計算２は10nsごとにしか仕事もらえない。
２）　計算１は計算２が空いたことを教えてもらってから、計算２へ仕事を渡す。
３）　同様に計算２も計算３が空いたことを知らされて、計算３へ結果を渡し、その後計算１へ自分が空いたことを伝える。
４）　要するに、隣接ユニット間で知らせ合い（ユニット間の通信）を行う必要がある。
- 同期回路では、このユニットごとの通信を不要にするために、ユニット間にフリップフロップを入れて、同一のクロック信号で同期させる。
- １）　クロックの立ち上がりエッジで、セイノで、（同時に）各ユニットへ入力データが入力される。
２）　その後、計算１は7ns
(CLK立ち上がりエッジからFFの出力までの遅延を2nsとする)で計算が終わるが
３）　次の入力を得るまで、20nsぐらいの間そのまま待たされる。
４）　一番遅い計算３も22ns
後には計算を終える。
５）　そして、25ns
後のクロックの立ち上がりエッジで各FFは前のユニットの結果を次のユニットへ伝える。
- FFの働きは、各ユニットばらばらの計算時間をクロックにより遅らせて、計算時間をそろえている。
- 理想的には、最も低速な計算３の計算時間20nsのサイクル時間が使えそうであるが、実際にはFFのセットアップタイムとアクセスタイムの分だけサイクル時間を延ばす必要がある。
- 一見、同期回路は効率が悪そうであるが、最大のメリットは非同期回路のユニット間の通信が不要になることにある。
- 非同期の場合でも、計算のスループットは結局最も遅い計算３で決まり、それに、ユニット間通信の遅延が加算される。ユニット間通信の遅延がFFのセットアップ＋アクセス時間以上なら、同期の方が性能はよくなる。

#### クイズ１

１）3人の学生A，B，Cさんはそれぞれ以下の仕事をするとする

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

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

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

最初、Aさん、Bさん、Cさんにそれぞれ、「１」、「２」、「３」と書かれた紙を渡す。

そして、A，B，Cさんはすぐに自分の仕事をする。

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

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

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

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

## リスト５．８　D-FFのVHDL記述

ライブラリ宣言 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; １）　記述は出力信号Qの動作を記述すればよい

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

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

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

- process文の中で、wait文やif文でエッジを検出する記述を行えば、FFが生成される。
- エッジ検出記述　教科書のP111　コラム８参照のこと

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の記述方法１

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;

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

## DFFの記述方法２

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

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

## DFFの記述方法３

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

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

## DFFの記述方法４

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

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

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

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

## 移動平均回路の設計

以下の回路は8ビットの入力信号を移動平均する回路である。
入力からクロックサイクルごとに入力されてくる信号のうち、最新の4個の入力値をすべて加算し、４で割ることによりその平均値を出力する。

リスト　avg4.vhd

テストベンチ　SigGen.vhd

入力信号列　fm.txt

/net/home/teacher/wada/public_html/cadpub/avg4.vhd

/net/home/teacher/wada/public_html/cadpub/SigGen.vhd

/net/home/teacher/wada/public_html/cadpub/fm.txt

にもファイルがある。

## 移動平均回路のVHDL記述

ライブラリ宣言 library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all; 今回は入力信号として、２の補数表現を用いた正･負混合の信号を用いるので、P63コラム４の算術演算用パー-ケージで説明されているように、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
データ入力：FMINPUT（8ビット）

データ出力：AVGOUT（8ビット）

アーキテクチャ宣言 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 ４つの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; このような記述で４つのFFが生成される。

FF1 ：＝FMINPUT;
FF2 ：＝ FF1;
FF3 ：＝ FF2;
FF4 ：＝ FF3;

とすると、

FF４ ：＝FMINPUT;

と等価となり、FFは1個しか生成されない。

-- 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コラム４の算術演算用パー-ケージで説明されているように、signedで型変換を行っている。

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

-- 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; 教科書P85にTEXTIOパッケージの説明がある。

今回、テスト入力として他のテキストファイルに書かれた値を用いるので、ライブラリ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ごとに変化するので、クロック周期は１０nsである。

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ページのリスト４．１４を参考にしてください。

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

/net/home/teacher/wada/public_html/cadpub/avg4.vhd

/net/home/teacher/wada/public_html/cadpub/SigGen.vhd

/net/home/teacher/wada/public_html/cadpub/fm.txt

にもファイルがある。

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

１）　Sciroccoにて正常動作を確認せよ！

各値は２の補数表現にしている。
最下位の2個の信号は、アナログ波形表現にしている。
アナログ波形は右の波形画面で、右クリックで選択できる。

## 実習５（２）

２）　クロック信号とその周期を指定する。

クロックのある回路では、以下の図のようにクロック信号を選択して、クロックサイクル時間を指定する。

- クロック入力端子クリックで選択し、
- Attributes -> SpecifyClock...
- Periodの欄に数値（たとえば５０）を入力し、Rising を　0,
Falling を 25　として
- Applyする。これによりサイクル
- この数値がサイクルタイムの合成時の目標値になるので、面積重視で、サイクルタイムが長くてよい場合は大きな値を入れる。
- 逆に、サイクルタイムを小さくしたければ、小さな値をいれる。

３）　回路の合成を行う。

Design -> Compile Design

デフォルトの設定でOKである！

これで、以下のような回路が合成される。

４）　上記回路は階層的な回路構成なので、階層を破壊し、１つの階層にすべての回路を置く。

Hierarchy -> Ungroup

All cells で　Ungroup all levels

としてOKとする。

以下のような回路がになる。

５）　面積とタイミングを確認する。

面積：　Design -> Report Area でOKとする。

avg/arearep.txt

ここでNoncombinational Areaはフリップフロップの面積、Combinational
Areaは組み合わせ回路の面性を示す。

トータルのその両方の和である。

タイミング：　Timing -> Report Timing Path　でOKとする。

avg/timingrep.txt

クロックのある回路のクリティカルパスは、あるFFからべつのFFまでの遅延時間が最大の経路を示す。
なぜなら、この最大時間がシステムのクロックサイクルタイムを決めるからである。

## ｔC　＞　ｔKQ　＋　組み合わせ回路の遅延時間　＋ｔS

が正常動作する条件である。

クロックがある場合の data arrival timeは　以下のことである。

## ｔKQ　＋　組み合わせ回路の遅延時間

全体として、

## ｔC　＞　ｔKQ　＋　組み合わせ回路の遅延時間　＋ｔS

が成立する必要性を

## ｔC　ー　ｔS　＞　ｔKQ　＋　組み合わせ回路の遅延時間

で上記リストはチェックしている。

tC：サイクルタイムで　CLK　と示されている

tS：フリップフロップのセットアップタイムで　リストでは　-tSを
library setup time としている。

上記リストでは

## slack = (tC -tS) - (tKQ + 組み合わせ回路の遅延時間)

として、これが正であれば条件を満たしているので､　MET（満たした）という表示になっている。

### 最小の動作サイクル時間は　tC - slack
で求めることができる。

上記リストでは、５０－２３．１９＝２１．８１ns　となる。

## HW5

１）　クロックの周期のターゲット値を１として、再合成する。（なるべく、最小サイクル時間の小さい回路を合成せよ）

２）　この時の最小の動作サイクル時間はいくらか？

３）　クロック＝５０nsの場合と、面積および最小サイクルタイムで比較を行え！

４）　回路を改造して、１６ポイントの平均を計算する回路を設計せよ。

http://www.ieee.org/portal/cms_docs_iportals/iportals/publications/journmag/transactions/TRANS-JOUR.doc

TRANS-JOUR.pdf

このHW5より上記のフォーマットを用いてレポート作成のこと！

例は英語であるが、日本語でOKである。

提出時にはPDFフォーマットで送付すること！