フラット表示 | 前のトピック | 次のトピック |
投稿者 | スレッド |
---|---|
webadm | 投稿日時: 2006-3-20 1:00 |
Webmaster 登録日: 2004-11-7 居住地: 投稿: 3089 |
デザインのウォーミングアップ仕上げ 先の簡単なジャンケン判定装置は論理回路設計では序の口でまだ本格的なものではない。ウォーミングアップはまだ始まったばかりである。
今度は本格的なディジタル回路であるステートマシンのデザインを練習することにする。 題材はいくらでも転がっているが、いきなりコンピューターシステムの一部に目を向けても興味が失せるので、現実世界と親和性のある題材を探してみた。 そこで思いついたのが万年カレンダー時計である。 仕様をざっと書いてみる。 1MHzのクロック信号と時計あわせのためのプリセット信号を入力でき現在の年月日時分秒を出力する。 年月日時分秒値のプリセット値入力はロータリースイッチ等を接続することを前提にBCD値入力とする。 出力はそれぞれBCD値出力とする。閏年をサポートする。西暦1万年問題は考慮しなくてよい。 ブロック図は以下の通り。 入力信号数16ピン、出力信号数45ピン。合計信号61ピン。 代表的なタイミングチャートは以下の通り。 仕様策定段階でEPF8282LC84の最大user i/oピン数64ピンの制約に収まるようにプリセット入力を2桁ずつ選択してセットするようにしてピン数を節約。 直接7セグメントLEDを駆動させようとすると出力1桁あたり7本ピンが必要になるのでピン数は収まらないため7セグメントデコーダーを内蔵することは断念。 カレンダークロックはステートマシンの中では状態数が非常に多いのですべての状態についてタイミングチャートなり真理値表を書くことは現実的ではない。 従って代表的なプリセットと年替わりのケースを示すにとどめた。 ステートマシンでは仕様策定段階で既にそれを実現するために必要な構成回路要素をあらかじめ知っている必要がある。当然ながらその設計者も同水準の知識を有する必要がある。 仕様的には簡単に見えるが、実際に実現することを考え始めると様々な選択枝があり簡単では無いことがすぐわかる。 ステートマシンをデザイン入力するに先だってまず全体を複数の小ブロックから構成するように機能分割する必要がある。 仕様設計者は時計合わせのために必要な入力ピン数を節約するために設定項目をローターリースイッチでバイナリ値として入力するようにしている。 実際には該当する内部変数(ラッチ)をプリセットするために内部でバイナリ値をデコードすることを前提としている。 バイナリデコーダーがどんなものかをあらかじめお互いに知っていることが前提になる。 また内部変数(ラッチ)はプリセット時以外は毎秒次の秒までの間表示すべき値を保持すべく更新される。 このためプリセットには外部入力信号をそれ以外は内部信号を入力するように切り替えるデータセレクタが内部に必要になる。 バイナリデコーダーもデータセレクタも基本的な組み合わせ論理であるため真理値表や論理式で記述することができる。 あとは内部変数(ラッチ)を毎秒更新するための組み合わせ論理を考える必要がある。それと1MHzのクロックから秒クロックに分周する回路が必要である。 これらをブロック図に描くと以下の通り。 DECODERはnPRESET信号がアサートされている間だけSELECTバイナリ値をデコードし該当するデコード信号のみアサートする。 各デコード信号はそれぞれ該当するラッチの入力をCOMBINATION LOGICかVALUE入力かを切り替えるデータセレクタの入力となる。 DIVはCLOCK1Mを分周してCOMBINATION LOGICが次の時刻を更新するのに使用する1秒周期のクロックを生成する。 COMBINATION LOGICは1秒クロックとラッチの前回値を入力として更新時刻を出力する。 更に詳細に各ブロックの仕様を設計する。 DECODERは組み合わせ論理で以下の真理値表で表すことができる。 DIVは単純な分周カウンタ。 COMBINATION LOGICは複数の組み合わせ論理から構成されるもっとも複雑な部分。 分替わり、時替わり、日替わり、月替わり、年替わりには様々な条件が加わるため簡単ではない。 秒の更新は一番簡単で0〜59までは1秒毎に1ずつ増加し59から60に増加するタイミングで0に戻す。 秒が0に戻った際に分替わりのため分の値を1増加させる。59から60に増加するタイミングで0に戻す。 分が0に戻った際に時替わりのため時の値を1増加させる。23から24に増加するタイミングで0に戻す。 時が0に戻った際に日替わりのため日の値を1増加させる。この場合、現在の月の最終日から増加するタイミングで1に戻す。 日が1に戻った際に月替わりのため月の値を1増加させる。最終月から増加するタイミングで1に戻す。 月が1に戻った際に年替わりのため年の値を1増加させる。 月の最終日は2月を除いて各月によって31か30のいずれか。2月の場合は、現在の年が閏年か否かによって28か29となる。 年が400で割り切れる場合は閏年。その他の年で100で割り切れる場合は閏年でない例外がある以外は4で割り切れる年が閏年。 閏年の2月は29日が最終日となりそうでなければ28日が最終日。 一番難しいのが閏年の判定に割り算が必要なことである。割り算は組み合わせ論理では実現できない。 良く考えると4で割り切れるかどうかは、年のBCD4桁の一桁目の下位2ビットが共に0かどうかで判断できる。 100で割り切れるかどうかは、下2桁が共に0かどうかで判断できる。 400で割り切れるかどうかは、下2桁が共に0でかつ上位2桁が 00,04,08,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96 の場合だけに限られる。これなら力ずくで条件判定すればできなくもない。きっとデザインツールがいまいこと論理圧縮してくれるに違いない。 これでおおよその設計情報は出そろったので次はHDLを書いてみることにする。回路図入力はできないことはないが体力が無いのでご容赦を。 |
フラット表示 | 前のトピック | 次のトピック |
投稿するにはまず登録を | |