卒 業 研 究 報 告

題目VHDL による順序回路の設計

指 導 教 員
矢野

政顕

教授

報 告 者
学籍番号： 1030220
氏名：
松田 圭弘

平成

15 年

2月

10 日

高知工科大学 電子・光システム工学科

目次
第1章

はじめに --------------------------------------------------------------------------------------------- 1

第2章

VHDL について ----------------------------------------------------------------------------------- 2
2.1

ハードウェア記述言語 ------------------------------------------------------------------------ 2

2.2

VHDL の歴史 ------------------------------------------------------------------------------------ 3

2.3

VHDL の仕組み --------------------------------------------------------------------------------- 3
2.3.1

第3章

VHDL による設計方法 -------------------------------------------------------------- 4

順序回路の設計 ------------------------------------------------------------------------------------- 7
3.1

時計の設計 --------------------------------------------------------------------------------------- 7

3.2

時計のシミュレーション結果と考察 ----------------------------------------------------- 10

VHDL による順序回路の設計 ---------------------------------------------------------------- 13

第4章

4.1

VHDL による時計の設計 ------------------------------------------------------------------- 13

4.2

アラームタイマーの設計 -------------------------------------------------------------------- 14
4.2.1

4.3

第5章

VHDL にアラームタイマーの設計 --------------------------------------------- 14

カレンダーの設計 ----------------------------------------------------------------------------- 15
4.3.1

カレンダーのアルゴリズム ------------------------------------------------------- 15

4.3.2

VHDL によるカレンダーの設計 ------------------------------------------------ 16

シミュレーション結果と考察 ----------------------------------------------------------------- 18
5.1

シミュレーション結果 --------------------------------------------------------------- 18

5.2

考察と感想 ------------------------------------------------------------------------------ 31

謝辞 -------------------------------------------------------------------------------------------------------------- 32
参考文献 -------------------------------------------------------------------------------------------------------- 33
VHDL のソース ---------------------------------------------------------------------------------------------- 34

第1章

はじめに

現在の私たちの生活の発展は電子機器なしでは考えられない所まできている。少し周囲を見回しただけでもパソコン、携帯電話、PDA など様々なものに囲まれている。例えばパソコンを例に取ってみると、CPU、グラフィックスチップ、サウンドチップなどがあり、その中にも複数の回路がある。こうした機器の進化とともにその回路も多様化、複雑化し、設計はますます難しくなっており、膨大な時間と経費がかかる作業になってきている。そうした中で集積回路を比較的簡単になおかつ短期間で設計する手段としてハードウェア記
述言語(Hardware Description Language : HDL)が生み出された。ここではその数あるハードウェア記述言語の中の一つである VHDL(VHSIC HDL)を使って小規模な回路を設計、シミュレーションすることにより回路設計に対する知識を深める。

本論文は 5 章から構成されている。第 1 章ではここまでの研究の経緯を述べる。第 2 章
では VHDL の開発までの歴史や、その文法などを述べる。第 3 章では、VHDL で設計する回路の元となるものを汎用 IC で設計する。第 4 章では、第 3 章で設計した回路に他の複数の機能を付与して VHDL で再設計するとともに、シミュレーションを行いその結果について報告する。第 5 章では、本論文の集大成として第 4 章で行ったシミュレーション結果の考察などをまとめる。

1

第2章

2.1

VHDL について

ハードウェア記述言語

今までの回路図入力による設計手法に置き換わるものとしてハードウェア記述言語を使用した設計がさかんに行われるようになってきた。それには回路図入力に比べ HDL 入力に
表 2.1 のような利点があるためである。[1]表 2.1 回路図入力と HDL 入力による設計の違い

HDL 入力回路図入力
1 回路図入力に時間がかかる。

テキストで簡単に入力できる。

2 論理式(ブール代数)を考える必要がある。 論理式を考える必要がない。
3 回路変更が難しい。

回路変更が容易。

4 設計者以外では、内容を理解しずらい。

誰にでも内容を理解しやすい。

5 特定の半導体メーカーのライブラリを使 半導体メーカーのライブラリを使用しな用して回路図入力をする。

い。どのメーカーでも作成可能。

主なハードウェア記述言語には、
VHDL, Verilog-HDL, UDL/I, SFL があり(表 2.2 参照)、
それぞれ一長一短があるが、その中でも業界標準として最も広く普及しているのが VHDLである。
表 2.2 各種 HDL の比較

言語名

開発元

特徴

VHDL

米国国防総省が中心

幅広い分野の記述が可能、高い記述能力。

Verilog-HDL

シミュレータ Verilog の言語

幅広い分野の記述が可能だが VHDL ほど
記述能力は高くない。

UDL/I

RTL での記述のみ可能。同期式の回路記

日本電子工業振興協会

述は単純化されている。
SFL

PARTHENON システムの言語

RTL での記述のみ可能。完全同期式の回路に限定。単純で分かりやすい記述。

RTL : ロジック回路生成可能なレベル

2

2.2

VHDL の歴史

VHDL は、米国国防総省の VHSIC(Very High Speed Integrated Circuit)委員会で 1981年に提唱された。VHDL が生まれた理由は、当時、大規模 IC の開発には、より上位のレベルでの検証が求められていたことと、国防省向けの ASIC(特定用途向けの集積回路)の開発
が長いもので 3 年から 4 年もかかっていたからである。開発当初での最速の ASIC を使っていても開発が終了する頃には時代遅れになってしまうという問題が生じていた。そこで直接ロジックゲートを回路図入力するのではなく、ハードウェア記述言語で設計することによって、開発終了時点で最速の ASIC が選択できるようにする必要性があった。
こうして、1983 年から VHDL の仕様作成が始まり、1985 年に作業が完了した。1986
年にはマニュアルにまとめられ、バージョン 7.2 として公開された。
その後、1986 年には IEEE(米国電気電子技術者協会)での標準化作業が VASG(VHDL
Analysis & Standardization Group)委員会で始まり、1987 年 5 月には言語仕様書が作成され、12 月には IEEE Std 1076-1987 として承認された。1989 年には VHDL シミュレータ
や論理合成ツールが販売されるようになった。さらに 1993 年には機能拡張が行われ、現在ではアナログ回路への拡張も行われている。

2.3

VHDL の仕組み

VHDL では、図 2.1 に示すように外部とのインターフェース部分(エンティティ)と内部の動作(アーキテクチャ)を別々に記述するようになっている。
エンティティ宣言では回路の基本的な構造を記述し、アーキテクチャ宣言ではその回路の中身を記述する。また、一つのエンティティ宣言の中に RTL、ゲートレベルといった複数のアーキテクチャ宣言を持つことが可能である。
エンティティ
A
OUT
B

アーキテクチャA
OUT
B

図 2.1 エンティティとアーキテクチャ

32.3.1VHDL による設計方法

VHDL の基本的な記述例として、図 2.2 に示すハーフアダーについての記述例を示す。
・ ハーフアダーの記述例

library IEEE;
use IEEE.std̲logic̲1164.all;entity HALF̲ADDER is
port (
A : in std̲logic;
B : in std̲logic;
S : out std̲logic;
CO : out std̲logic);end HALF̲ADDER;

architecture DATAFLOW of HALF̲ADDER is
signal C, D : std̲logic;
begin
C <= A or B;
D <= A nand B;
CO <= not D;
S <= C and D;
end DATAFLOW;

図 2.2 ハーフアダー

4一番初めの 2 行ではライブラリの宣言とパッケージの呼び出しを行っている。また、IEEEのライブラリの使用を宣言している。
エンティティ部では使用するポートの宣言などを行う。
entity エンティティ名 isport(
ポート名 : 方向 データタイプ);
end エンティティ名;
ポートには方向とタイプを宣言する必要がある。代表的なものを表 2.3 と表 2.4 に示す。
表 2.3 ポートの方向

方向

意味

in

入力

out

複数の信号を代入できる出力(内部で再利用できない)

inout

双方向

buffer

一つの信号しか代入できない出力(内部で再利用できる)

linkage

方向指定なし表 2.4 主なデータタイプ

データタイプbit
integerreal

内容0, 1 のロジック値
整数
浮動小数点

boolean

論理値(TRUE or FALSE)

std̲logic

0, 1, 不定, ハイインピーダンス状態などおおよそ論理設計で必要なデータタイプがすべてあるbit̲vector

bit の配列タイプ

std̲logic̲vector std̲logic の配列タイプ
VHDL ではデータタイプの区別に関しては非常に厳しい制約を設けている。基本的には異なるデータタイプ同士の論理演算や四則演算を行うことはできない。どうしても必要な場
合は演算用のパッケージを使うか、同じデータタイプに変換する必要がある。

5

アーキテクチャ部は以下のような構成になっている。
architecture アーキテクチャ名 of エンティティ名 is
begin
同時処理文
end アーキテクチャ名;
同時処理文とは字のごとく同時に処理されるもので begin, end 間の文の順番に関係なく
すべて同時に処理される。回路の動作を記述する場所である。プロセス文を使うことで、条件文を用いたもっと複雑な記述をすることもできる。
architecture XXX of YYY is
begin
process (A, B, C)
begin
条件文など
end process;end XXX;
process()の()内は、センシティビティリストと言ってこの中のどれかの値が変化するとプ
ロセス文内の begin‑end 間の再計算が行われる。
architecture と begin の間は信号、関数を定義する場所で、記述例では内部信号の定義を行っている。
signal 内部信号名 : データタイプ;

6

第3章

順序回路の設計

順序回路の具体例として図 3.1 に示す時計回路を設計した。VHDL で設計する前に元となる順序回路(時計)の動作を回路シミュレータで確認した。この時計は時、分、秒をカウントするだけのシンプルなものである。時刻設定のためのスイッチも備えている。

3.1

時計の設計

1Hz

Selector

4bit BCD Counter

BCD to 7SEG Decoder

Segment

4bit BCD Counter

BCD to 7SEG Decoder

Segment

4bit BCD Counter

BCD to 7SEG Decoder

Segment

2Hz

Selector
2Hz

・・・

・・・
図 3.1 時計のブロック図

時間、分、秒、それぞれの桁ごとに 4bit の BCD カウンタを用意しておき、それを 10 進
カウンタや 6 進カウンタとすることにより 60 進、24 進を表現する。BCD カウンタから出た信号はデコーダに入り 7 セグメント用の信号に変換される。桁上げは BCD カウンタからの出力をそれぞれ 10 進用

1010, 6 進用行う。時部分だけは 240010 0100

0110

を見て桁上げとカウンタのリセットをでもリセットをかける。時刻設定時はセレクタ(2 入

力のマルチプレクサ)で、1Hz と 2Hz を切り替える。時、分、秒ごとにスイッチがありそれ7

ぞれで早送りできる。
図 3.2 に BCD コードから 7 セグメントコードへの変換規則と、図 3.3 に 2 入力のマルチ
プレクサの回路図をのせる。 [2] [3]ag

BCD Code

f

b

e

c
d

7SEG CodeDisplay0000

111111000001

0110000

1

0010

1101101

2

0011

11110013

0100

01100114

0101

10110115

0110

10111116

0111

11100107

1000

11111118

1001

11110119

図 3.2 BCD コードから 7 セグメント用コードへの変換規則

図 3.3 2 入力のマルチプレクサを使ったセレクタ

セレクト信号が 0 または 1 に変わることで、A の信号が入るか B の信号が入るかを決めることができる。

8図 3.4 時計の回路図

9

3.2

時計のシミュレーション結果と考察

シミュレーション速度が遅いため桁上げが起こるのを確認してから、時、分、秒の 2 つのカウンタごとにクロックを入れて調べている。

図 3.5 時計の秒のシミュレーション結果

図 3.5 は時計の秒のシミュレーション結果である。一番上から 1Hz のクロック、秒の下位桁のカウンタ出力 A、B、C、D、上位桁のカウンタ出力 A、B、C、D、分のカウンタ出
力 A となっている。1 秒ごとに 0000 から順番にカウントしていって下位桁が 1010(10 秒)になったとき上位桁へ桁上げを行って、上位桁が 0110(60 秒)になったとき、分のカウンタへの桁上げが行われているので 60 進カウンタとしての正しい動作が確認できた。

図 3.6 時計の分のシミュレーション結果

図 3.6 は時計の分のシミュレーション結果である。図 3.5 の場合と同様に 60 進カウンタである。一番上から 1Hz のクロック、分の下位桁のカウンタ出力 A、B、C、D、上位桁の10

カウンタ出力 A、B、C、D、時のカウンタ出力 A となっている。図 3.5 と同じ検証方法か
ら正しい動作であることが分かった。

図 3.7 時計の時のシミュレーション結果

図 3.8 時計のスイッチのシミュレーション結果

図 3.7 は時計の時のシミュレーション結果である。一番上から 1Hz のクロック、時の下位桁のカウンタ出力 A、B、C、D、上位桁のカウンタ出力 A、B、C、D となっている。下位桁では 10 進カウンタとして 1010 になった場合と 24 時になった場合にもカウントが0000 になっており、上位桁も 24 時で 0000 となっているので正しい動作であることが分かる。
図 3.8 の時計のスイッチのシミュレーション結果では上から順に 1Hz クロック、2Hz クロ
ック、時刻設定用のスイッチ、秒、分、時のスイッチ、秒、分、時の下位桁のカウンタ出
力 A となっている。最初に時刻設定スイッチをオフにしたとき普通の時計として 1Hz のク
ロック信号が秒のカウンタ出力 A に入っている。そして時刻設定スイッチがオンになってそれぞれの秒、分、時の早送りスイッチを押した時、それぞれのカウンタには 2Hz が入っている。そして時刻設定スイッチがオフになったとき、早送りスイッチを押しても出力には変化は起きていない。これは予定通りの動作である。

11

図 3.9 汎用ロジック IC で設計された時計

4.194304MHz(2^22)の水晶発信器から 20 個と 21 個の D フリップフロップを通して 1Hz と2Hz を取り出している。中心部にはそれぞれの桁ごとに 4bit の BCD アップカウンタと 7 セ
グメントデコーダが用意されている。スイッチは画像には載ってないが別の小さな基盤上にある。マルチプレクサは NAND4 個を用いてある。
図 3.5〜図 3.8 までのシミュレーション結果と図 3.9 の汎用ロジック IC で製作した回路
で正しい動作が確認できたので第 4 章にて VHDL による設計に入る。

12

第4章

VHDL による順序回路の設計

第 3 章での回路の動作を元に VHDL で再設計する。この時計にはアラームタイマーとカレンダーの機能を新たに付与する。

4.1

VHDL による時計の設計

まず、普段の動作では CLK または前のカウンタからの桁上りを時刻設定時には CLK2 に切り替えるようなセレクタを 3 つ分作る。
process ( TIMER̲SET, SEC̲SET, CLK, CLK2 ) begin
if ( TIMER̲SET = "01" ) thenif ( SEC̲SET = '0' ) then
SEL1̲OUT <= '0';
elsif ( SEC̲SET <= '1' ) then
SEL1̲OUT <= CLK2;
end if;elsif ( TIMER̲SET = "00" ) then
SEL1̲OUT <= CLK;
end if;end process;次に BCD カウンタを設計する。リセット機能を持たせてからそれぞれのカウンタごとに桁上げを行う値を決め、桁上げ信号も作る。そしてカウンタ自体の動作を記述する。
process ( RST, SEL1̲OUT, COUNTER1̲OUT, COUNTER2̲CLK ) begin
if ( RST = '1' ) then
COUNTER1̲OUT <= "0000";
COUNTER2̲CLK <= '0';
elsif ( COUNTER1̲OUT = "1010" ) then
COUNTER1̲OUT <= "0000";
COUNTER2̲CLK <= '1';
else
COUNTER2̲CLK <= '0';end if;if ( SEL1̲OUT'event and SEL1̲OUT = '1' ) then
COUNTER1̲OUT <= COUNTER1̲OUT + '1';
end if;end process;
時の一桁目だけは 24 時になった瞬間でもカウンタの値のリセットを行う。
elsif ( COUNTER5̲OUT = "1010" or (COUNTER5̲OUT="0100" and COUNTER6̲OUT="0010") ) then13

COUNTER5̲OUT <= "0000";
COUNTER6̲CLK <= '1';
最後に BCD コードを７セグメント用のコードに変えるために case 文を使って BCD カウン
タからの出力信号をすべての場合において記述する。時刻カウント用の BCD カウンタは 6個あるので７セグメント用のデコーダも 6 個分記述する。
process () begin
case COUNTER1̲OUT is
when "0000" => 7SEG̲DEC1 <= "1111110";when "0001" => 7SEG̲DEC1 <= "0110000";
when "0010" => 7SEG̲DEC1 <= "1101101";
when "0011" => 7SEG̲DEC1 <= "1111001";
when "0100" => 7SEG̲DEC1 <= "0110011";
when "0101" => 7SEG̲DEC1 <= "1011011";
when "0110" => 7SEG̲DEC1 <= "1011111";
when "0111" => 7SEG̲DEC1 <= "1110010";
when "1000" => 7SEG̲DEC1 <= "1111111";
when "1001" => 7SEG̲DEC1 <= "1111011";
when "1010" => 7SEG̲DEC1 <= "1111110";when others => 7SEG̲DEC1 <= "1111110";end case;end process;

4.2

アラームタイマーの設計

このアラームタイマーは設定されたある時刻に合わせてアラーム用の信号を出力するというものである。
アラーム用の時刻設定にはモードを切り替えることにより本体の時計部分のスイッチを兼用する。本体の時計の時間、分の所を比較しながら設定された時刻になるとアラームがオンになる。強制停止用のスイッチを押すとアラームはオフとなる。

4.2.1

VHDL によるアラームタイマーの設計

まず信号宣言でアラームに必要な信号を定義する。
signal ALARM̲MIN : std̲logic̲vector(0 to 3);
signal ALARM̲MIN2 : std̲logic̲vector(0 to 3);
signal ALARM̲HOUR : std̲logic̲vector(0 to 3);
signal ALARM̲HOUR2 : std̲logic̲vector(0 to 3);
signal ALARM̲MIN̲AGARI : std̲logic;
signal ALARM̲HOUR̲AGARI : std̲logic;

14

signal ALARM̲SEL : std̲logic;
signal ALM̲OUT : std̲logic;
次にアラーム用のタイマーの部分を記述する。TIMER_SET(時計の状態を切り替えるための信号)が 10 のときにアラームがセットできるようして、その他の部分は時計用のカウン
タと同じような動作にする。
process ( RST, CLK2, TIMER̲SET, MIN̲SET, ALARM̲MIN) begin
if ( RST = '1' ) then
ALARM̲MIN <= "0000";
elsif ( TIMER̲SET = "10" and MIN̲SET = '1' and … ) then
ALARM̲MIN <= ALARM̲MIN + '1';
end if;if ( ALARM̲MIN = "1010" ) then
ALARM̲MIN <= "0000";
ALARM̲MIN̲AGARI <= '1';else
ALARM̲MIN̲AGARI <= '0';end if;end process;内部の信号の状態が分からないとアラームタイマーをセットできないので視認できるよ
うに TIMER_SET の状態に合わせてセグメントの表示を切り替えるための記述を追加する。
if ( TIMER̲SET="10" ) then
SEG̲SEL3 <= ALARM̲MIN;
else
SEG̲SEL3 <= COUNTER3̲OUT;
end if;

4.3

カレンダーの設計

このカレンダーは 2000 年から 3999 年までの日付、曜日を表示するもので、うるう年にも対応している。曜日は年数、日付が確定すれば自動で計算する。4000 年になった場合は2000 年に戻る。

4.3.1

カレンダーのアルゴリズム

まず年にはうるう年というものが設定されている。平年かうるう年かで 2 月の日数が変わってくるので区別することが必要である。現在の暦でのその定義は「年数が 4 の倍数の15

年をうるう年とする。ただし、100 の倍数の年で 400 の倍数でない年は、平年とする。」となっている。そのため、400 年や 800 年はうるう年だが、500 年、900 年は平年となる。
次に曜日について考える。ツェラー(Zeller)の公式によれば、 [4]
西暦 y 年 m 月 d 日の曜日は、(y + [y/4] - [y/100] + [y/400] + [2.6m+1.6] + d) mod 7
この値が 0 なら日曜日、1 なら月曜日、・・・6 なら土曜日である。
ただし、1、2 月は前年の 13、14 月とする。
(有効範囲は 1583 年から 3999 年までとする。)[ ]はガウス記号 ([ ]の中の値を超えない最大の整数)となる。これらを踏まえた上でカレンダーを設計する。

4.3.2

VHDL によるカレンダーの設計

始めにカレンダー用の信号を定義する。YEAR などの信号で integer を使っているのは曜
日の計算に乗算や除算を使用するためである。(std̲logic̲vector では除算などを直接、行うことができないため)
signal YEAR : integer range 0 to 11;
signal MONTH : integer range 0 to 3;
signal MAX̲DAYS : integer range 0 to 4;
signal DAY : integer range 0 to 4;
signal MONTH̲KETA̲AGARI : std̲logic;
signal DAY̲KETA̲AGARI : std̲logic;
signal TMP̲YEAR : integer range 0 to 11 := 0;signal TMP̲MONTH : integer range 0 to 3 := 0;signal TMP̲YOUBI : integer range 0 to 2 := 0;
次にその月の日数を決める。平年かうるう年かで 2 月の日数を変え、その他の月はそれ
ぞれ 30 日か 31 日かで分ける。うるう年の計算に必要な YEAR が 4、100、400 の倍数かの判
断は除算の余りで決定する。
if ( MONTH = 2 and ( ( YEAR mod 4 = 0 and YEAR mod 100 /= 0 ) or ( YEAR mod 400= 0 ) ) ) thenMAX̲DAYS <= 29;
elsif ( MONTH = 2 and not ( ( YEAR mod 4 = 0 and YEAR mod 100 /= 0 ) or ( YEAR
mod 400 = 0 ) ) ) thenMAX̲DAYS <= 28;16

elsif ( MONTH = 1 or MONTH = 3 or MONTH = 5 or MONTH = 7 or MONTH = 8 or MONTH= 10 or MONTH = 12 ) thenMAX̲DAYS <= 31;
elsif ( MONTH = 4 or MONTH = 6 or MONTH = 9 or MONTH = 11 ) thenMAX̲DAYS <= 30;
end if;
最後に重要な曜日の計算であるが、ツェラーの公式から 1 月と 2 月は前年の 13 月、14 月で計算するため、その場合分けを行っている。曜日の計算には時間がかかるため曜日用に別のクロックを用意している。計算した後、TMP̲YOUBI の値によって日曜日から土曜日を
000 から 110 で出力している。
TMP̲YOUBI <= ( TMP̲YEAR + TMP̲YEAR / 4 ‑ TMP̲YEAR / 100 + TMP̲YEAR / 400 +( 13 * TMP̲MONTH + 8 ) / 5 + DAY ) mod 7;
if ( MONTH = 1 or MONTH = 2 ) then
TMP̲YEAR <= YEAR ‑ 1;
TMP̲MONTH <= MONTH + 12;
else
TMP̲YEAR <= YEAR;
TMP̲MONTH <= MONTH;
end if;end process;process ( TMP̲YOUBI ) begin
if ( TMP̲YOUBI = 0 ) then
YOUBI <= "000";
elsif ( TMP̲YOUBI = 1 ) then
YOUBI <= "001";
elsif ( TMP̲YOUBI = 2 ) then
YOUBI <= "010";
elsif ( TMP̲YOUBI = 3 ) then
YOUBI <= "011";
elsif ( TMP̲YOUBI = 4 ) then
YOUBI <= "100";
elsif ( TMP̲YOUBI = 5 ) then
YOUBI <= "101";
elsif ( TMP̲YOUBI = 6 ) then
YOUBI <= "110";
end if;
第 5 章でシミュレーション結果の考察を行う。

17

第５章

5.1

シミュレーション結果と考察

シミュレーション結果

次のページ以降にまとめてシミュレーション結果の図を示す。時計とカレンダー本体に関してはシミュレーション結果が膨大なため、桁上げなどの重要な部位だけをのせている。
図 5.1〜図 5.3 は時計本体の動作のシミュレーション結果である。TIMER̲SET は時刻設定
用の信号、HOUR̲SET、MIN̲SET、SEC̲SET は時、分、秒のそれぞれの早送り信号になっている。SEG̲DEC は 7 セグメント用の信号、COUNTER̲OUT は上から順に秒、分、時の BCD カウン
タの出力である。BCD カウンタの出力は 0, １, ・・・ 9 または 0, 1, ・・・ 5 で次段への桁上げと正常な動作になっているのが確認できる。時に関しても 24 時になった瞬間 00に戻っており時計の動作となっている。次に 7 セグメント用の信号の出力であるが、図 5.1〜図 5.3 の BCD カウンタの出力と表 5.1 の結果を照らし合わせると正しいことが確認できる。
表 5.1 7 セグメント用信号の出力結果の確認
シミュレーション結果の表記(16 進)

2 進数での表記

Display

7E(0)1111110

030(0)011000016D(0)1101101

279(0)1111001

333(0)0110011

45B(0)1011011

55F(0)1011111

672(0)1110010

77F(0)1111111

87B(0)1111011

9

図 5.4、
図 5.5 は時刻設定のシミュレーション結果である。
時刻設定用の信号の TIMER̲SET
はあらかじめ 1(01)(時刻設定用)に設定されている。TIMER̲SET が 1(01)のときの時計用のカウンタは現在の値を保ったまま停止する。HOUR̲SET、MIN̲SET、SEC̲SET を 1 にすること
で時、分、秒ごとのカウンタだけを早送りしている。このとき、60 または 24(時の場合)になったとしても上位の桁への桁上がりは起こらないようになっている。

18

図 5.6、図 5.7 はアラームタイマーのシミュレーション結果である。TIMER̲SET を 10 にすることによりアラームの設定ができるようになっている。その間、時計は通常通りの動作をしている。アラーム設定時のみ HOUR̲SET、MIN̲SET でアラームタイマーの時、分を設定できる。TIMER̲SET を 11 にした場合は時計の時、分とアラームタイマーの時、分が同じ値のとき ALARM̲OUT が 1 になりアラームがオンとなる。ALARM̲STOP が 1 になることにより
ALARM̲OUT は 0 になりアラームはオフとなる。
図 5.8、図 5.9 はカレンダーのシミュレーション結果である。2000 年は 100 の倍数であるが、400 の倍数でもあるため、うるう年となるから 2 月は 29 日まである。その他の月は
1 月、3 月〜12 月まではそれぞれ 31 日(1 月)、31 日(3 月)、30 日(4 月)、31 日(5 月)、30日(6 月)、31 日(7 月)、31 日(8 月)、30 日(9 月)、31 日(10 月)、30 日(11 月)、31 日(12 月)となっていて実際の日数と一致する。曜日についても 2000 年 1 月 1 日は 6(011)で土曜日、
2004 年 2 月 1 日は 0(000)で日曜日となっており、これも実際のものと一致する。
図 5.10 はカレンダー設定のシミュレーション結果である。YMD̲MODE(カレンダーの設定用)の信号が 0(00)、1(01)、2(10)、3(11)で普段のカレンダー動作、日設定、月設定、年設
定用の状態に対応している。YMD̲MODE が設定用の信号になっているとき YMD̲SWITCH を 1 にするとそれぞれの信号に応じた日、月、年を早送りできる。
図 5.11 は時計とカレンダーの全体動作のシミュレーション結果である。日付が変わるときの曜日の変化、その他のカウント値のリセット動作も全体として正常にできている。

19

図 5.1 時計のシミュレーション結果 120図 5.2 時計のシミュレーション結果 221図 5.3 時計のシミュレーション結果 322図 5.4 時刻設定のシミュレーション結果 123図 5.5 時刻設定のシミュレーション結果 224図 5.6 アラームタイマーのシミュレーション結果 125図 5.7 アラームタイマーのシミュレーション結果 226図 5.8 カレンダーのシミュレーション結果の一部 127図 5.9 カレンダーのシミュレーション結果の一部 228図 5.10 カレンダー設定のシミュレーション結果

29

図 5.11 時計とカレンダーの全体動作のシミュレーション結果

30

5.2

考察と感想

時計本体の動作やその早送りの動作は時計として問題のないシミュレーション結果が得られた。アラームやカレンダーについても正常な動作が確認できた。しかし、問題もある。
それはシミュレーション上では遅延が 0 であるため、この回路の場合、非同期式特有の遅延が上位に蓄積する現象が確認しづらいことである。もし、遅延があまりにも大きいようなら同期式に改良する必要性がある。
今回、取り組むことができなかったが、電波時計を設計するというアイデアもあった。
電波で時刻を設定すれば手動で設定する必要もないし、ズレも最小限で抑えることができる。また機会があれば、この問題点の修正と新しい機能の追加に挑戦してみたい。

31

謝辞
本研究の全過程を通じて懇切丁寧な指導を賜りました高知工科大学工学部電子・光シス
テム工学科矢野 政顕教授、原央教授、橘昌良助教授に感謝します。御助言を頂きました電子・光システム工学コース修士課程の木村知史氏、松村 暢也氏、石川 純平氏および原研究室、橘研究室の皆様に厚く御礼申し上げます。

32

参考文献
[1] 「VHDL によるハードウェア設計入門」

長谷川 裕恭 著[2] 「2002 最新 汎用ロジック・デバイス規格表」[3] 「論理回路入門」

浜辺 隆二 著

CQ 出版社

CQ 出版社

森北出版株式会社[4] 「日付に関するアルゴリズム」
http://www.ht‑net21.ne.jp/ tomokazu/pclab/days/days.html

33

VHDL のソース
回路全体の VHDL のソースを以下に示す。
library IEEE;
use IEEE.std̲logic̲1164.all;use IEEE.std̲logic̲unsigned.all;entity PTIMER is
port (
CLK : in std̲logic;
CLK2 : in std̲logic;
RST : in std̲logic;
TIMER̲SET : in std̲logic̲vector(0 to 1);
HOUR̲SET : in std̲logic;
MIN̲SET : in std̲logic;
SEC̲SET : in std̲logic;
SEG̲DEC1 : out std̲logic̲vector(0 to 6);
SEG̲DEC2 : out std̲logic̲vector(0 to 6);
SEG̲DEC3 : out std̲logic̲vector(0 to 6);
SEG̲DEC4 : out std̲logic̲vector(0 to 6);
SEG̲DEC5 : out std̲logic̲vector(0 to 6);
SEG̲DEC6 : out std̲logic̲vector(0 to 6);
ALARM̲STOP : in std̲logic;
ALARM̲OUT : out std̲logic;
YMD̲MODE : in std̲logic̲vector(0 to 1);‑‑ normal=00 day=01 month=10 year=11
YMD̲SWITCH : in std̲logic;
YEAR̲OUT : out integer range 0 to 11;
MONTH̲OUT : out integer range 0 to 3;
DAY̲OUT : out integer range 0 to 4;
YOUBI : out std̲logic̲vector(0 to 2));
end PTIMER;
architecture RTL of PTIMER is
signal SEL1̲OUT : std̲logic;
signal SEL2̲OUT : std̲logic;
signal SEL3̲OUT : std̲logic;

34

signal COUNTER2̲CLK : std̲logic;
signal COUNTER3̲CLK : std̲logic;
signal COUNTER4̲CLK : std̲logic;
signal COUNTER5̲CLK : std̲logic;
signal COUNTER6̲CLK : std̲logic;
signal COUNTER1̲OUT : std̲logic̲vector(0 to 3);
signal COUNTER2̲OUT : std̲logic̲vector(0 to 3);
signal COUNTER3̲OUT : std̲logic̲vector(0 to 3);
signal COUNTER4̲OUT : std̲logic̲vector(0 to 3);
signal COUNTER5̲OUT : std̲logic̲vector(0 to 3);
signal COUNTER6̲OUT : std̲logic̲vector(0 to 3);
signal COUNTER6̲AGARI : std̲logic;
signal SEG̲SEL1 : std̲logic̲vector(0 to 3);
signal SEG̲SEL2 : std̲logic̲vector(0 to 3);
signal SEG̲SEL3 : std̲logic̲vector(0 to 3);
signal SEG̲SEL4 : std̲logic̲vector(0 to 3);
signal SEG̲SEL5 : std̲logic̲vector(0 to 3);
signal SEG̲SEL6 : std̲logic̲vector(0 to 3);
signal ALARM̲MIN : std̲logic̲vector(0 to 3);
signal ALARM̲MIN2 : std̲logic̲vector(0 to 3);
signal ALARM̲HOUR : std̲logic̲vector(0 to 3);
signal ALARM̲HOUR2 : std̲logic̲vector(0 to 3);
signal ALARM̲MIN̲AGARI : std̲logic;
signal ALARM̲HOUR̲AGARI : std̲logic;
signal ALARM̲SEL : std̲logic;
signal ALM̲OUT : std̲logic;
signal YEAR : integer range 0 to 11;
signal MONTH : integer range 0 to 3;
signal MAX̲DAYS : integer range 0 to 4;
signal DAY : integer range 0 to 4;
signal MONTH̲KETA̲AGARI : std̲logic;
signal DAY̲KETA̲AGARI : std̲logic;
signal TMP̲YEAR : integer range 0 to 11 := 0;signal TMP̲MONTH : integer range 0 to 3 := 0;signal TMP̲YOUBI : integer range 0 to 2 := 0;signal YOUBI̲CLK : std̲logic;
begin‑‑ SELECTER1(SEC)‑‑ NORMAL=00 TIMERSET=01 ALARMSET=10 NONE=11
process ( TIMER̲SET, SEC̲SET, CLK, CLK2 ) begin
if ( TIMER̲SET = "01" ) then35

if ( SEC̲SET = '0' ) then
SEL1̲OUT <= '0';
elsif ( SEC̲SET <= '1' ) then
SEL1̲OUT <= CLK2;
end if;elsif ( TIMER̲SET = "00" ) then
SEL1̲OUT <= CLK;
end if;end process;‑‑ SELECTER2(MIN)
process ( TIMER̲SET, MIN̲SET, COUNTER3̲CLK, CLK2 ) begin
if ( TIMER̲SET = "01" ) thenif ( MIN̲SET = '0' ) then
SEL2̲OUT <= '0';
elsif ( MIN̲SET = '1' ) then
SEL2̲OUT <= CLK2;
end if;elsif ( TIMER̲SET = "00" ) then
SEL2̲OUT <= COUNTER3̲CLK;
end if;end process;‑‑ SELECTER3(HOUR)
process ( TIMER̲SET, HOUR̲SET, COUNTER5̲CLK, CLK2 ) begin
if ( TIMER̲SET = "01" ) thenif ( HOUR̲SET = '0') then
SEL3̲OUT <= '0';
elsif ( HOUR̲SET = '1' ) then
SEL3̲OUT <= CLK2;
end if;elsif ( TIMER̲SET = "00" ) then
SEL3̲OUT <= COUNTER5̲CLK;
end if;end process;‑‑ BCD COUNTER1
process ( RST, SEL1̲OUT, COUNTER1̲OUT ) begin
if ( RST = '1' ) then
COUNTER1̲OUT <= "0000";
COUNTER2̲CLK <= '0';
elsif ( COUNTER1̲OUT = "1010" ) then
COUNTER1̲OUT <= "0000";
COUNTER2̲CLK <= '1';
else
COUNTER2̲CLK <= '0';end if;if ( SEL1̲OUT'event and SEL1̲OUT = '1' ) then36

COUNTER1̲OUT <= COUNTER1̲OUT + '1';
end if;end process;‑‑ BCD COUNTER2
process ( RST, COUNTER2̲CLK, COUNTER2̲OUT ) begin
if ( RST = '1' ) then
COUNTER2̲OUT <= "0000";
COUNTER3̲CLK <= '0';
elsif ( COUNTER2̲OUT = "0110") then
COUNTER2̲OUT <= "0000";
COUNTER3̲CLK <= '1';
else
COUNTER3̲CLK <= '0';end if;if ( COUNTER2̲CLK'event and COUNTER2̲CLK = '1' ) then
COUNTER2̲OUT <= COUNTER2̲OUT + '1';
end if;end process;‑‑ BCD COUNTER3process ( RST, SEL2̲OUT, COUNTER3̲OUT ) begin
if ( RST = '1' ) then
COUNTER3̲OUT <= "0000";
COUNTER4̲CLK <= '0';
elsif ( COUNTER3̲OUT = "1010" ) then
COUNTER3̲OUT <= "0000";
COUNTER4̲CLK <= '1';
else
COUNTER4̲CLK <= '0';end if;if ( SEL2̲OUT'event and SEL2̲OUT = '1' ) then
COUNTER3̲OUT <= COUNTER3̲OUT + '1';
end if;end process;‑‑ BCD COUNTER4
process ( RST, COUNTER4̲CLK, COUNTER4̲OUT) begin
if ( RST = '1' ) then
COUNTER4̲OUT <= "0000";
COUNTER5̲CLK <= '0';
elsif ( COUNTER4̲OUT = "0110" ) then
COUNTER4̲OUT <= "0000";
COUNTER5̲CLK <= '1';
else
COUNTER5̲CLK <= '0';end if;if ( COUNTER4̲CLK'event and COUNTER4̲CLK = '1' ) then37

COUNTER4̲OUT <= COUNTER4̲OUT + '1';
end if;end process;‑‑ BCD COUNTER5process ( RST, SEL3̲OUT, COUNTER5̲OUT, COUNTER6̲OUT ) begin
if ( RST = '1' ) then
COUNTER5̲OUT <= "0000";
COUNTER6̲CLK <= '0';
elsif ( COUNTER5̲OUT = "1010" or ( COUNTER5̲OUT = "0100" and COUNTER6̲OUT= "0010" ) ) then
COUNTER5̲OUT <= "0000";
COUNTER6̲CLK <= '1';
else
COUNTER6̲CLK <= '0';end if;if ( SEL3̲OUT'event and SEL3̲OUT = '1' ) then
COUNTER5̲OUT <= COUNTER5̲OUT + '1';
end if;end process;‑‑ BCD COUNTER6
process ( RST, COUNTER6̲OUT, COUNTER6̲CLK ) begin
if ( RST = '1' ) then
COUNTER6̲OUT <= "0000";
COUNTER6̲AGARI <= '0';
elsif ( COUNTER6̲OUT = "0011" ) then
COUNTER6̲OUT <= "0000";
COUNTER6̲AGARI <= '1';
else
COUNTER6̲AGARI <= '0';end if;if ( COUNTER6̲CLK'event and COUNTER6̲CLK = '1' ) then
COUNTER6̲OUT <= COUNTER6̲OUT + '1';
end if;end process;‑‑ ALARM
process ( RST, CLK2, TIMER̲SET, MIN̲SET, ALARM̲MIN) begin
if ( RST = '1' ) then
ALARM̲MIN <= "0000";
elsif ( TIMER̲SET = "10" and MIN̲SET = '1' and CLK2'event and CLK2 = '1' )then
ALARM̲MIN <= ALARM̲MIN + '1';
end if;if ( ALARM̲MIN = "1010" ) then
ALARM̲MIN <= "0000";
ALARM̲MIN̲AGARI <= '1';

38

else
ALARM̲MIN̲AGARI <= '0';end if;end process;process ( RST, ALARM̲MIN̲AGARI, TIMER̲SET, ALARM̲MIN2 ) begin
if ( RST = '1' ) then
ALARM̲MIN2 <= "0000";
elsif ( ALARM̲MIN̲AGARI = '1' and ALARM̲MIN̲AGARI'event ) then
ALARM̲MIN2 <= ALARM̲MIN2 + '1';
end if;if ( ALARM̲MIN2 = "0110") then
ALARM̲MIN2 <= "0000";
end if;end process;process ( RST, CLK2, TIMER̲SET, HOUR̲SET, ALARM̲HOUR, ALARM̲HOUR2 ) begin
if ( RST = '1' ) then
ALARM̲HOUR <= "0000";
elsif ( TIMER̲SET = "10" and HOUR̲SET = '1' and CLK2'event and CLK2 = '1' )then
ALARM̲HOUR <= ALARM̲HOUR + '1';
end if;if ( ALARM̲HOUR = "1010" ) then
ALARM̲HOUR <= "0000";
ALARM̲HOUR̲AGARI <= '1';
elsif ( ALARM̲HOUR = "0100" and ALARM̲HOUR2 = "0010" ) then
ALARM̲HOUR <= "0000";
ALARM̲HOUR̲AGARI <= '0';else
ALARM̲HOUR̲AGARI <= '0';end if;end process;process ( RST, ALARM̲HOUR̲AGARI, TIMER̲SET, ALARM̲HOUR, ALARM̲HOUR2 ) begin
if ( RST = '1' ) then
ALARM̲HOUR2 <= "0000";
elsif ( ALARM̲HOUR̲AGARI = '1' and ALARM̲HOUR̲AGARI'event ) then
ALARM̲HOUR2 <= ALARM̲HOUR2 + '1';
end if;if ( ALARM̲HOUR = "0100" and ALARM̲HOUR2 = "0010" ) then
ALARM̲HOUR2 <= "0000";
end if;end process;
ALARM̲OUT <= ALM̲OUT;
process ( TIMER̲SET, ALARM̲STOP, ALARM̲MIN2, ALARM̲MIN, ALARM̲HOUR2, ALARM̲HOUR,
COUNTER6̲OUT, COUNTER5̲OUT, COUNTER4̲OUT, COUNTER3̲OUT, ALM̲OUT ) begin
ALARM̲SEL <= not( (ALARM̲HOUR2(0) xor COUNTER6̲OUT(0)) and (ALARM̲HOUR2(1) xor

39

COUNTER6̲OUT(1)) and (ALARM̲HOUR2(2) xor COUNTER6̲OUT(2)) and (ALARM̲HOUR2(3) xor
COUNTER6̲OUT(3)) and (ALARM̲HOUR(0) xor COUNTER5̲OUT(0)) and (ALARM̲HOUR(1) xor
COUNTER5̲OUT(1)) and (ALARM̲HOUR(2) xor COUNTER5̲OUT(2)) and (ALARM̲HOUR(3) xor
COUNTER5̲OUT(3)) and (ALARM̲MIN2(0) xor COUNTER4̲OUT(0)) and (ALARM̲MIN2(1) xor
COUNTER4̲OUT(1)) and (ALARM̲MIN2(2) xor COUNTER4̲OUT(2)) and (ALARM̲MIN2(3) xor
COUNTER4̲OUT(3)) and (ALARM̲MIN(0) xor COUNTER3̲OUT(0)) and (ALARM̲MIN(1) xor
COUNTER3̲OUT(1)) and (ALARM̲MIN(2) xor COUNTER3̲OUT(2)) and (ALARM̲MIN(3) xor
COUNTER3̲OUT(3)) );if ( ALARM̲SEL = '1' and TIMER̲SET = "11" ) then
ALM̲OUT <= '1';else
ALM̲OUT <= '0';end if;if ( ALARM̲SEL = '0' and TIMER̲SET = "11" and ALM̲OUT = '1' ) then
ALM̲OUT <= '0';end if;if ( ALARM̲STOP = '1' ) then
ALM̲OUT <= '0';end if;end process;‑‑ FOR SEC‑‑ BCD to 7SEG DECORDER1
process ( TIMER̲SET, SEG̲SEL1, COUNTER1̲OUT ) begin
if ( TIMER̲SET="10" ) then
SEG̲SEL1 <= "0000";
else
SEG̲SEL1 <= COUNTER1̲OUT;
end if;case SEG̲SEL1 iswhen "0000" => SEG̲DEC1 <= "1111110";when "0001" => SEG̲DEC1 <= "0110000";
when "0010" => SEG̲DEC1 <= "1101101";
when "0011" => SEG̲DEC1 <= "1111001";
when "0100" => SEG̲DEC1 <= "0110011";
when "0101" => SEG̲DEC1 <= "1011011";
when "0110" => SEG̲DEC1 <= "1011111";
when "0111" => SEG̲DEC1 <= "1110010";
when "1000" => SEG̲DEC1 <= "1111111";
when "1001" => SEG̲DEC1 <= "1111011";
when "1010" => SEG̲DEC1 <= "1111110";when others => SEG̲DEC1 <= "1111110";end case;end process;‑‑ BCD to 7SEG DECORDER2process (TIMER̲SET, SEG̲SEL2, COUNTER2̲OUT, SEG̲DEC2) begin
if ( TIMER̲SET="10" ) then40

SEG̲SEL2 <= "0000";
else
SEG̲SEL2 <= COUNTER2̲OUT;
end if;case SEG̲SEL2 iswhen "0000" => SEG̲DEC2 <= "1111110";when "0001" => SEG̲DEC2 <= "0110000";
when "0010" => SEG̲DEC2 <= "1101101";
when "0011" => SEG̲DEC2 <= "1111001";
when "0100" => SEG̲DEC2 <= "0110011";
when "0101" => SEG̲DEC2 <= "1011011";
when "0110" => SEG̲DEC2 <= "1011111";
when "0111" => SEG̲DEC2 <= "1110010";
when "1000" => SEG̲DEC2 <= "1111111";
when "1001" => SEG̲DEC2 <= "1111011";
when "1010" => SEG̲DEC2 <= "1111110";when others => SEG̲DEC2 <= "1111110";end case;end process;‑‑ FOR MIN‑‑ BCD to 7SEG DECORDER3process (TIMER̲SET, SEG̲SEL3, COUNTER3̲OUT, SEG̲DEC3) begin
if ( TIMER̲SET="10" ) then
SEG̲SEL3 <= ALARM̲MIN;
else
SEG̲SEL3 <= COUNTER3̲OUT;
end if;case SEG̲SEL3 iswhen "0000" => SEG̲DEC3 <= "1111110";when "0001" => SEG̲DEC3 <= "0110000";
when "0010" => SEG̲DEC3 <= "1101101";
when "0011" => SEG̲DEC3 <= "1111001";
when "0100" => SEG̲DEC3 <= "0110011";
when "0101" => SEG̲DEC3 <= "1011011";
when "0110" => SEG̲DEC3 <= "1011111";
when "0111" => SEG̲DEC3 <= "1110010";
when "1000" => SEG̲DEC3 <= "1111111";
when "1001" => SEG̲DEC3 <= "1111011";
when "1010" => SEG̲DEC3 <= "1111110";when others => SEG̲DEC3 <= "1111110";end case;end process;‑‑ BCD to 7SEG DECORDER4process (TIMER̲SET, SEG̲SEL4, COUNTER4̲OUT, SEG̲DEC4) begin
if ( TIMER̲SET="10" ) then41

SEG̲SEL4 <= ALARM̲MIN2;
else
SEG̲SEL4 <= COUNTER4̲OUT;
end if;case SEG̲SEL4 iswhen "0000" => SEG̲DEC4 <= "1111110";when "0001" => SEG̲DEC4 <= "0110000";
when "0010" => SEG̲DEC4 <= "1101101";
when "0011" => SEG̲DEC4 <= "1111001";
when "0100" => SEG̲DEC4 <= "0110011";
when "0101" => SEG̲DEC4 <= "1011011";
when "0110" => SEG̲DEC4 <= "1011111";
when "0111" => SEG̲DEC4 <= "1110010";
when "1000" => SEG̲DEC4 <= "1111111";
when "1001" => SEG̲DEC4 <= "1111011";
when "1010" => SEG̲DEC4 <= "1111110";when others => SEG̲DEC4 <= "1111110";end case;end process;‑‑ FOR HOUR‑‑ BCD to 7SEG DECORDER5process (TIMER̲SET, SEG̲SEL5, COUNTER5̲OUT, SEG̲DEC5) begin
if ( TIMER̲SET="10" ) then
SEG̲SEL5 <= ALARM̲HOUR;
else
SEG̲SEL5 <= COUNTER5̲OUT;
end if;case SEG̲SEL5 iswhen "0000" => SEG̲DEC5 <= "1111110";when "0001" => SEG̲DEC5 <= "0110000";
when "0010" => SEG̲DEC5 <= "1101101";
when "0011" => SEG̲DEC5 <= "1111001";
when "0100" => SEG̲DEC5 <= "0110011";
when "0101" => SEG̲DEC5 <= "1011011";
when "0110" => SEG̲DEC5 <= "1011111";
when "0111" => SEG̲DEC5 <= "1110010";
when "1000" => SEG̲DEC5 <= "1111111";
when "1001" => SEG̲DEC5 <= "1111011";
when "1010" => SEG̲DEC5 <= "1111110";when others => SEG̲DEC5 <= "1111110";end case;end process;‑‑ BCD to 7SEG DECORDER6
process (TIMER̲SET, SEG̲SEL6, COUNTER6̲OUT, SEG̲DEC6) begin
if ( TIMER̲SET="10" ) then
SEG̲SEL6 <= ALARM̲MIN2;

42

else
SEG̲SEL6 <= COUNTER6̲OUT;
end if;case SEG̲SEL6 iswhen "0000" => SEG̲DEC6 <= "1111110";when "0001" => SEG̲DEC6 <= "0110000";
when "0010" => SEG̲DEC6 <= "1101101";
when "0011" => SEG̲DEC6 <= "1111001";
when "0100" => SEG̲DEC6 <= "0110011";
when "0101" => SEG̲DEC6 <= "1011011";
when "0110" => SEG̲DEC6 <= "1011111";
when "0111" => SEG̲DEC6 <= "1110010";
when "1000" => SEG̲DEC6 <= "1111111";
when "1001" => SEG̲DEC6 <= "1111011";
when "1010" => SEG̲DEC6 <= "1111110";when others => SEG̲DEC6 <= "1111110";end case;end process;‑‑ CALENDAR
process ( CLK, CLK2, YMD̲MODE ) begin
if ( YMD̲MODE = "01" or YMD̲MODE = "10" or YMD̲MODE = "11" ) then
YOUBI̲CLK <= CLK2;
else
YOUBI̲CLK <= CLK;
end if;end process;‑‑ days of MONTH
process ( MONTH, YEAR ) begin
if ( MONTH = 2 and ( ( YEAR mod 4 = 0 and YEAR mod 100 /= 0 ) or ( YEAR mod
400 = 0 ) ) ) thenMAX̲DAYS <= 29;
elsif ( MONTH = 2 and not ( ( YEAR mod 4 = 0 and YEAR mod 100 /= 0 ) or ( YEAR
mod 400 = 0 ) ) ) thenMAX̲DAYS <= 28;
elsif ( MONTH = 1 or MONTH = 3 or MONTH = 5 or MONTH = 7 or MONTH = 8 or MONTH= 10 or MONTH = 12 ) thenMAX̲DAYS <= 31;
elsif ( MONTH = 4 or MONTH = 6 or MONTH = 9 or MONTH = 11 ) thenMAX̲DAYS <= 30;
end if;end process;‑‑ DAYprocess ( CLK2, DAY, RST, YMD̲MODE, MAX̲DAYS, DAY̲KETA̲AGARI, COUNTER6̲AGARI,YMD̲SWITCH ) begin
if ( RST = '1' or ( YMD̲MODE = "01" and DAY = MAX̲DAYS + 1 ) ) then43DAY <= 1;
elsif ( YMD̲MODE = "00" and DAY = MAX̲DAYS + 1 ) thenDAY <= 1;
DAY̲KETA̲AGARI <= '1';
else
DAY̲KETA̲AGARI <= '0';end if;if ( ( YMD̲MODE = "00" and COUNTER6̲AGARI = '1' and COUNTER6̲AGARI'event )or ( YMD̲MODE = "01" and YMD̲SWITCH = '1' and CLK2'event and CLK2 = '1' ) ) thenDAY <= DAY + 1;
end if;DAY̲OUT <= DAY;end process;‑‑ MONTH
process ( CLK2, RST, YMD̲MODE, MONTH, DAY̲KETA̲AGARI, YMD̲SWITCH ) begin
if ( RST = '1' or ( YMD̲MODE = "10" and MONTH = 13 ) ) then
MONTH <= 1;
elsif ( YMD̲MODE = "00" and MONTH = 13 ) then
MONTH <= 1;
MONTH̲KETA̲AGARI <= '1';
else
MONTH̲KETA̲AGARI <= '0';end if;if ( ( YMD̲MODE = "00" and DAY̲KETA̲AGARI = '1' and DAY̲KETA̲AGARI'event )or ( YMD̲MODE="10" and YMD̲SWITCH='1' and CLK2'event and CLK2='1') ) then
MONTH <= MONTH + 1;
end if;MONTH̲OUT <= MONTH;
end process;‑‑ YEARprocess ( CLK2, RST, YMD̲MODE, YEAR, MONTH̲KETA̲AGARI, YMD̲SWITCH ) begin
if ( RST = '1' or YEAR = 2100 ) then
YEAR <= 2000;
elsif ( ( YMD̲MODE = "00" and MONTH̲KETA̲AGARI = '1' andMONTH̲KETA̲AGARI'event ) or ( YMD̲MODE = "11" and YMD̲SWITCH = '1' and CLK2'event
and CLK2 = '1' ) ) then
YEAR <= YEAR + 1;
end if;
YEAR̲OUT <= YEAR;
end process;‑‑ YOUBI
process ( DAY, MONTH, TMP̲MONTH, TMP̲YEAR ) begin
TMP̲YOUBI <= ( TMP̲YEAR + TMP̲YEAR / 4 ‑ TMP̲YEAR / 100 + TMP̲YEAR / 400 +( 13 * TMP̲MONTH + 8 ) / 5 + DAY ) mod 7;
if ( MONTH = 1 or MONTH = 2 ) then44

TMP̲YEAR <= YEAR ‑ 1;
TMP̲MONTH <= MONTH + 12;
else
TMP̲YEAR <= YEAR;
TMP̲MONTH <= MONTH;
end if;end process;‑‑ Sun=000 Mon=001 Tue=010 Wed=011 Thu=100 Fri=101 Sat=110
process ( TMP̲YOUBI ) begin
if ( TMP̲YOUBI = 0 ) then
YOUBI <= "000";
elsif ( TMP̲YOUBI = 1 ) then
YOUBI <= "001";
elsif ( TMP̲YOUBI = 2 ) then
YOUBI <= "010";
elsif ( TMP̲YOUBI = 3 ) then
YOUBI <= "011";
elsif ( TMP̲YOUBI = 4 ) then
YOUBI <= "100";
elsif ( TMP̲YOUBI = 5 ) then
YOUBI <= "101";
elsif ( TMP̲YOUBI = 6 ) then
YOUBI <= "110";
end if;end process;end RTL;

45