3.3 記憶
3.3.1 基本構成
計数器とかシフトレジスタとか時間を追って動くものに使う論理設計には欠かせないものです。ここでいう記憶とは、図3.16 の同期式の論理設計を前提にしています。いつ記憶するのかをpに、何を記憶するのかをdに設計します。
図3.16 記憶の構成
リスト14 が図3.16 の最も簡単な例です。bitr q が記憶信号であることを示します。
リスト14 1ビットの記憶
entity main
input RESET;
input P;
input D;
output Q;
bitr q;
Q=q;
if (RESET)
q=0;
else
if (P)
q=D;
else
q=q;
endif
endif
ende
図3.17 リスト14 の実行
図3.17 がリスト14 を実行したものです。P は1CLK だけ1 になっていますが、1 点で記憶したい場合はこのような信号を使います。P が1CLK 以上の信号なら、P が1 の最後のCLK のD の値で記憶します。
3.3.2 シフトレジスタ
通信や除算などでよく使うシフトレジスタも、リスト15 のように図3.16 の構成と同じです。図3.16 のデータのd がリスト15 では入力のD と前段の記憶素子の出力になっています。
図3.18 がリスト15 を実行したものです。
リスト15 シフトレジスタ
entity main
input RESET;
input P;
input D;
output Q[8];
bitr q[8];
Q=q;
if (RESET)
q=0;
else
if (P)
q.0=D;
q.1:7=q.0:6;
else
q=q;
endif
endif
ende
リスト16 計数器
entity main
input RESET;
input P;
output Q[8];
bitr q[8];
Q=q;
if (RESET)
q=0;
else
if (P)
q=q+1;
else
q=q;
endif
endif
ende
図3.18 リスト15 の実行
データのd の部分を変えることで、下位のビットから上位のビットへの移動だけではなくて逆に上位のビットから下位のビットへ移動させたりとか、RESET のほかにも別の信号を設けてシフトレジスタに値を設定したりするとか、多機能なシフトレジスタにすることができます。
計数器もリスト16 のように図3.16 の構成と同じです。図3.16 のデータのd がリスト16 ではq+1 になっています。図3.19 がリスト16 を実行したものです。
図3.19 リスト16 の実行
データのd の部分を変えることで減計数器にしたり、RESET のほかにも別の信号を設けて計数器に値を設定したりするとか、多機能な計数器にすることができます。
3.3.4 立ち上がりで記憶
図3.16 の記憶信号のp にあたるリスト17 のp.0&!p.1 によって、記憶位置をP が0 から1 になったところにします。
リスト17 立ち上がり計数器
entity main
input RESET;
input P;
output Q[8];
bitr q[8];
bitr p[2];
Q=q;
p.0=P;
p.1=p.0;
if (RESET)
q=0;
else
if (p.0&!p.1)
q=q+1;
else
q=q;
endif
endif
ende 図3.20 は、リスト17 を実行したものです。
図3.20 リスト17 の実行
3.3.5 立ち下がりで記憶
図3.16 の記憶信号のp にあたるリスト18 の!p.0&p.1 によって、記憶位置をP が1 から0 になったところにします。
リスト18 立ち下がり計数器
entity main
input RESET;
input P;
output Q[8];
bitr q[8];
bitr p[2];
Q=q;
p.0=P;
p.1=p.0;
if (RESET)
q=0;
else
if (!p.0&p.1)
q=q+1;
else
q=q;
endif
endif
ende
図3.21は、リスト18 を実行したものです。
図3.21 リスト18 の実行
3.3.6 立ち上がりと立ち下がりで記憶
図3.16 の記憶信号のp にあたるリスト19 のp.0^ p.1 によって、記憶位置をP が1 から0 になったところと0 から1 になったところにします。
リスト19 立ち上がりと立ち下がり計数器
entity main
input RESET;
input P;
output Q[8];
bitr q[8];
bitr p[2];
Q=q;
p.0=P;
p.1=p.0;
if (RESET)
q=0;
else
if (p.0^p.1)
q=q+1;
else
q=q;
endif
endif
ende これまで作ってきたように、記憶によって動いている論理は図3.16 の記憶信号のp で決める記憶位置とd で決める記憶するデータによって様々な動きを作ることができます。
3.3.7 順序
記憶された値によって、簡単に順序のある動きを作ることができます。図3.23 のQ の値は一見してバラバラに動いているようですが、リスト20 に書いたとおりに動いています。図3.23 は図3.24 のような行程図を描くと動きがわかりやすくなります。
図3.24 ではP の値によって行程の行き先が違っていますが、このように流れ図のような動きを書くことができます。Q は現在の行程の位置を示しているだけで何もしていませんが、Q で条件付けされた論理を書いておけば、行程の順番のとおりにプログラムのような動きをします。
リスト20 順序
entity main
input RESET;
input P;
output Q[3];
bitr q[3];
Q=q;
if (RESET)
q=0;
else
switch(q)
case 0: q=7;
case 1: q=6;
case 2: q=5;
case 3: q=4;
case 4:
if (P) q=5; else q=0; endif
case 5: q=3;
case 6: q=2;
case 7: q=1;
endswitch
endif
ende
プログラムのような動きをする図3.24 の行程図も、図3.25 のような真理値表と考えられます。この真理値表は、入力と出力にQ が使われています。このQ は同じものではありません。図3.26 に示すように真理値表の入力に書かれたQ は現在値のQ で、真理値表の出力に書かれたQ は1CLK 後のQ です。
図3.26 行程と真理値表の構成このように、真理値表に同じ信号を入力と出力に使えるのは、違う時刻の値がCLK によってはっきりと分離されているからです。また、CLK は、ほかの論理の記憶素子と共有しているので、ほかのところで書かれた行程の論理とも連携して動きます。論理設計ではプログラムと違っていくつもの論理を連携して動かすと速度が遅くなるということはありません。連携は並列的に行われているからです。また、連携はCLK単位で行われているので、大規模な動きを緻密に設計することができます。
言語の表記は明瞭なものですが、順序の論理が長文になるようなとても複雑な動きをする論理を作るときは、行程図を描いたほうが全体像がはっきりして後の作業がわかりやすいと思います。
渕上賢二



コメントする