論理回路の授業やテスト問題で、「デジタル時計を作ろう」ってのは見かけますが、「デジタルカレンダーを作ろう」って問題は見かけません。ハテなんででしょ〜
カレンダーは時計に比べて、動き方がフクザツで、ってコトは作る回路もそれだけフクザツになっちゃう。
何がどう複雑かって?
だって時計は、24時間周期で動いて、24時間は86400秒って決まってる。
これがカレンダーの場合だと、1年が365日の場合と366日の場合とあるし、それに月によって日数が違うし。
これを試験問題に出したら、早い人でも4時間くらいはかかるかねぇ。。。。
|
で、そういう難儀なロジックを見つけると、つい作ってみたくなるのが、遊びでやってる論理回路屋w
動作の要求仕様をボケ〜と考えてると、「なんだこうしたら楽じゃん」ってなアイデアが生まれ、
そうすると、そのアイデアが間違ってないかどうかを検証してみたくなるw
で、ついつい回路作ってシミュレーションかけてみたりする(^^;
(シミュレーションかけて動作確認しないと、落ち着かないんだな〜これがまたw)
というワケで、作ってみましたデジタルカレンダーw
|
まずは、どんなモノ作ろうとしてるかの整理。
ざくっと下表に記載のコトくらいは考えておく。ま、練習なんだから作っていくウチに変えてもいいしw
カウント範囲 |
2000年1月1日から、2099年12月31日まで。
2099年12月31日を超えた場合の動作は保証せず。
(たぶん2000年1月1日に戻る) |
閏年 |
カウント範囲の中で、自動計算。 |
リセット時のカウント値 |
2000年0月0日 (←ちと問題アリかも(^^; でもまー気にしないで置こう(^^;) |
日付あわせ機能 |
なし(^^;;;
だってコレつけると、むちゃ面倒いんだもんw |
曜日出力機能 |
なし(^^;
日付あわせ機能があれば、まだ付けて見ようかって気にもなるけど(^^; |
入力信号 |
clock |
適当な周波数のクロック。 |
enable |
1日に1回、clock×1周期分の長さのパルスが入力される。
普通は、デジタル時計部分からの23時59分59秒を示すパルス。 |
reset# |
回路を初期化する信号。
負論理、つまり'0'レベルで回路を初期化する。 |
出力信号 |
y1000[3:0] |
2000年〜2099年の千のケタを示す。つまり、常に4'b0010=4'd2。 |
y100[3:0] |
2000年〜2099年の百のケタを示す。つまり、常に4'b0000=4'd0。 |
y10[3:0] |
2000年〜2099年の十のケタを示す。値の範囲は0〜9。 |
y1[3:0] |
2000年〜2099年の一のケタを示す。値の範囲は0〜9。 |
m10[3:0] |
1月〜12月の十のケタを示す。値の範囲は0〜1。 |
m1[3:0] |
1月〜12月の一のケタを示す。値の範囲は0〜9。 |
d10[3:0] |
1日〜31日の十のケタを示す。値の範囲は0〜3。 |
d1[3:0] |
1日〜31日の一のケタを示す。値の範囲は0〜9。 |
回路動作 |
以上の記した仕様の範囲内で、ふつーのカレンダーになるよう出力信号を生成すること。 |
リセットすると2000年0月0日になるってのが、ちと問題かもねぇw
|
次に、どんな回路構成にして全体を組み立てるか、どんな部品が要るかを考えて見る。
年カウンター |
カウント範囲が2000年〜2099年だから、年号4桁のうち上位2桁は常に固定。
下位2桁は、10進カウンタが2ヶあれば作れるね。 |
月カウンター |
単純な12進カウンタだね。。。。と思ったら違った(^^;
出力信号仕様が、十のケタを示すm10[3:0]と一のケタを示すm1[3:0]とに分かれてるから、10進カウンタと2進カウンタの組み合わせ。しかも十のケタの値が1の時は、一のケタの10進カウンタは2までしかカウントしない。
これけっこオモシロイ(^^; |
日カウンター |
これがデジタルカレンダー最大の難点w
月カウンターと同じく、十のケタカウンターと1のケタカウンターとに分かれていて、
カウントの最大値は28の場合、29の場合、30の場合、31の場合って4通りあるw
とりあえず、カウントの最大値がいくつなのかを判定する回路を、日カウンターから分離独立させることで、ここはカウンターだけに集中しよう。 |
閏年判定 |
年カウンターの値から、その年が閏年かどうかを判定する回路。 |
日カウント制御 |
閏年制御の出力とと月カウンターの値から、その月は日カウンターが何日まで数えるべきかを判定する回路。 |
この5つの回路があれば、なんとか出来そうだね。
|
これらの部品を並べて、Top階層を組んでみる。
ホントだったら「デジタル時計を作ろう」に書いたようなブロック図にしちゃえば良いんだけど、
お絵かきソフト立ち上げるのが面倒いんで、htmlの表組みで作っちゃうw
入力信号 |
回路ブロック |
出力信号 |
出力信号の説明 |
CarryOfMonth→
CarryOfDay→
CarryOfTime→
clock→
reset#→ |
年カウンター |
→y1000[3:0] |
年の千の桁。0010固定値 |
→y100[3:0] |
年の百の桁。0000固定値 |
→y10[3:0] |
年の十の桁。 |
→y1[3:0] |
年の一の桁。 |
CarryOfDay→
CarryOfTime→
clock→
reset#→ |
月カウンター |
→CarryOfMonth |
月カウンターから年カウンターへの桁上げ |
→m10[3:0] |
月の十の桁 |
→m1[3:0] |
月の一の桁 |
CarryFromTime→
clock→
reset#→ |
日カウンター |
→CarryOfDay |
日カウンターから年月カウンターへの桁上げ |
→d10[3:0] |
日の十の桁 |
→d1[3:0] |
日の一の桁 |
y10[3:0]→
y1[3:0]→ |
閏年判定 |
→uruu |
年カウンタ値が閏年の時に'1' |
uruu→
m10[3:0]→
m1[3:0]→ |
日カウント制御 |
→c28 |
日付が28日までの月の時に'1' |
→c29 |
日付が29日までの月の時に'1' |
→c30 |
日付が30日までの月の時に'1' |
→c31 |
日付が31日までの月の時に'1' |
こんなかで、年カウンター月カウンター日カウンターは、中にFlipFlopを持って、状態を保持しながら動く順序回路だよ。だからclock信号とreset#信号が入力されている。
閏年判定と日カウント制御のブロックは、中にFlipFlopを持たないで、年月日カウンターの状態をデコードして出力を作る組み合わせ回路だよ。だからclock信号とreset#信号は入力されていない。
|
主要登場人物が定義できたら、各人物のキャラクターを作っていく。
まずは年カウンター、、と思ったけど、年カウンターって単純な10進カウンターを2個使うんだよね。
だからまず10進カウンタを1個の部品として作っちゃう。
これはごく基本的な10進カウンタだから簡単だよね。
|