3. シミュレーションによるvhdl 記述の検証jte401/2017/2017_text_2.pdf73 3....

81
73 3. シミュレーションによる VHDL 記述の検証 これまでは、QuartusⅡ上で、回路図と VHDL で4ビット加算器を設計してきました。 しかし、回路図入力もしくは VHDL 記述した内容が正しいかどうかを確認せずに、直接実機用モジュールを作成し、実機で動作させて、設計した 内容が正しいかどうかを確認しましたが、通常は実機評価をする前に設計内容が正しいかどうかを、シミュレーション を使って確認します。 従って、本章では、QuartusⅡ上で設計した VHDL 記述を、シミュレーションで検証する方法を 実習します。 シミュレータは、VHDL シミュレータのスタンダードである“ModelSim”を使用します。 4ビット加算モジュール(図 1-11)を記述した VHDL のシミュレーションを実行 4ビット加算器(図 1-60)を記述した VHDL のシミュレーションを実行 31 ModelSim の起動と新規プロジェクトの作成方法 (1)ModelSim の起動 ModelSim は、以下の 2 つの方法で起動します(版数は、少し違うかもしれません)。 1.デスクトップのアイコンによる起動 デスクトップ上に「ModelSim SE-64 10.5」のアイコンが生成されていれば、このアイコンを ダブルクリックすると起動します。 2.スタートメニューからの起動 Windows のスタートメニューから 「コンピューター」-「ローカルディスク(C: )」-「Modeltech64_10.5」-「 Win64」-「modelsim.exeを選択すると起動します。 なお、「modelsim.exe」右クリックして、ポップアップメニューから「ショートカット作成」を選択して、 デスクトップ上にショートカットを作成すると、1の方法で起動できます。 正常に起動すると図 3-1 の画面が表示されますので、「Jumpstart もしくは Close」を選択します。 3-1 ModelSim の起動画面 Jumpstart もしくは Close を選択

Upload: others

Post on 06-May-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

73

3. シミュレーションによる VHDL 記述の検証

これまでは、QuartusⅡ上で、回路図と VHDL で4ビット加算器を設計してきました。 しかし、回路図入力もしくは

VHDL 記述した内容が正しいかどうかを確認せずに、直接実機用モジュールを作成し、実機で動作させて、設計した

内容が正しいかどうかを確認しましたが、通常は実機評価をする前に設計内容が正しいかどうかを、シミュレーション

を使って確認します。 従って、本章では、QuartusⅡ上で設計したVHDL記述を、シミュレーションで検証する方法を

実習します。 シミュレータは、VHDL シミュレータのスタンダードである“ModelSim”を使用します。 - 4ビット加算モジュール(図 1-11)を記述した VHDL のシミュレーションを実行 - 4ビット加算器(図 1-60)を記述した VHDL のシミュレーションを実行 3.1 ModelSim の起動と新規プロジェクトの作成方法 (1)ModelSim の起動

ModelSim は、以下の 2 つの方法で起動します(版数は、少し違うかもしれません)。 1.デスクトップのアイコンによる起動

⇒ デスクトップ上に「ModelSim SE-64 10.5」のアイコンが生成されていれば、このアイコンを ダブルクリックすると起動します。

2.スタートメニューからの起動

⇒ Windows のスタートメニューから 「コンピューター」-「ローカルディスク(C:)」-「Modeltech64_10.5」-「Win64」-「modelsim.exe」

を選択すると起動します。 なお、「modelsim.exe」右クリックして、ポップアップメニューから「ショートカット作成」を選択して、

デスクトップ上にショートカットを作成すると、1の方法で起動できます。

正常に起動すると図 3-1 の画面が表示されますので、「Jumpstart」 もしくは 「Close」を選択します。

図 3-1 ModelSim の起動画面

Jumpstart もしくは Close を選択

Page 2: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

74

① (図 3-1 の)「Jumpstart」を選択すると、以下の“Welcome to ModelSim”画面(図 3-2)が表示されます。

図 3-2 “Welcome to ModelSim”画面

-「Create a Project」を選択すると、“(2)新規プロジェクトの作成”へと続きます。 -「Open a Project」を選択すると、図 3-3 の“Open Project”画面が表示されるので、“Browse…”から既存

のプロジェクトを選択するか、直接プロジェクト名を入力して、「OK」を選択すると、既存のプロジェクトを オープンして、継続して作業を続けることができます。

-「Close」を選択すると、前回操作したプロジェクトがオープンされます。

図 3-3 “Open Project”画面

② (図 3-1 の)「Close」を選択すると、図 3-4 のように、

・前回オープンしたプロジェクトが自動的にダウンロードされ、オープンされるか、もしくは(次頁)、

図 3-4 前回使用したプロジェクトがオープンされた画面

Page 3: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

75

・(新規の場合は、初期画面が表示されますので、)「File」 → 「New」 → 「Project」の順に クリックして(図 3-5)、“(2)新規プロジェクトの作成”の操作を行います。

図 3-5 新規プロジェクトの作成

(2) 新規プロジェクトの作成

ModelSim でも QuartusⅡと同様に、設計毎にプロジェクトを作成して管理しながら設計を進めます。 ModelSim での最初の実習は、QuartusⅡで設計した“4ビット加算器の VHDL 記述”のシミュレーションを実行して、

機能を確認することなので、以下の条件でプロジェクトを作成します。

プロジェクト名: adder_4bit プロジェクトのディレクトリ: z:/modelsim/adder_4bit

手順通りに作業すると、以下の“Create Project”画面が表示されるので、上記の条件で、Project Name、 Project Location を設定します(図 3-6)。 Default library Name: work は、自動的に設定されます。

図 3-6 新規プロジェクトの設定画面

「File」 → 「New」 → 「Project」 を選択

adder_4bit と入力

z:/modelsim/adder_4bit と入力

work と自動的に設定されます(デフォルト値)

「OK」 を選択

Page 4: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

76

「OK」選択後、“Project Location”で指定したディレクトリが存在しない場合は、以下の画面(図 3-7)が表示される

ので、「はい(Y)」をクリックして作業フォルダを作成します。

図 3-7 Project Location の作業ディレクトリ作成の確認画面

上記の作業を行うと“Add items to the Project”画面(作成したプロジェクトにファイルを追加するかの画面)が表示さ

れますが、(特に何も作業しないので、)ここでは、「Close」 をクリックして閉じます(図 3-8)。

図 3-8 Add items to the Project 画面

以上で新規プロジェクトの作成が完了したので、この環境下で具体的な作業を進めていきます。 すなわち、 これから作成する VHDL 等のファイルは、z:/modelsim/adder_4bit 下に作成され、作業が進みます。

[参考] エクスプローラー等で確認すると、z:/modelsim/adder_4bit/adder_4bit.mdf という ファイルが作成されているはずです。 mdf は、modelsim definition file の略です。

3.2 VHDL ファイルの作成

ModelSim で VHDL を作成するのは、図 3-9 の手順でオープンした VHDL エディタで行います。 [VHDL エディタのオープン手順] 「File」 → 「New」 → 「Source」 → 「VHDL」の順にクリック

図 3-9 VHDL エディタをオープンする手順

「はい」 を選択

「Close」 を選択

Page 5: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

77

最初にシミュレーションする4ビット加算モジュールは、 half_adder.vhd、full_adder.vhd、adder_4.vhd の3つの

モジュールで構成されています。 これらを VHDL エディタで再度入力しても良いですが、QuartusⅡで作成した

VHDL 記述をコピー&ペースト(cut&paste)して移します。 図 3-10 は、ModelSim の VHDL エディタに QuartusⅡ

で作成した half_adder.vhd を cut&paste して移し、「Save As…」で保存するところです。 【備考】 「Save As…」は、新規の名前を付けて保存する場合にを用います。

図 3-10 VHDL ファイルの cut&paste と保存

「File」 → 「Save As…」 の順にクリックすると、“Save As…”画面が表視されるので、保存したいモジュール名を

“ファイル名(N)”に指定します(上記の場合は、“half_adder.vhd”です。 拡張子は必ず、“.vhd”として下さい。 同様に、full_adder.vhd、adder_4.vhd も copy して、それぞれの名前で保存します。 これら一連の作業を行うと、

z:/modelsim/adder_4bit の下には、図 3-11 のように、3つのファイルが保存されているので、確認してください。

図 3-11 プロジェクト・ディレクトリ下に保存されたファイル一覧

「File」→「Save As…」 を選択

VHDL エディタ

QuartusⅡで入力した VHDL 記述:

“half_adder.vhd”(←テキストファイル)を

ここに、copy する。

プロジェクト・ディレクトリになっていることを確認

half_adder.vhd、 full_adder.vhd、 adder_4.vhd のファイルが表示される

Page 6: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

78

3.3 プロジェクトメンバーの管理 ModelSimでも QuartusⅡと同様に、プロジェクト(Project)のメンバーを制御して、シミュレーションの実行モジュー

ルを作成します。 プロジェクト・ディレクトリに保存した VHDL ファイルを以下の手順でプロジェクトに追加します。

[プロジェクトへ登録/追加する手順](図 3-12) -“Project”画面の中で右クリックして、「Add to Project」 → 「Existing File」を選択 -“Add file to Project”画面がポップアップされるので、“Browse…”で登録/追加するファイルを選択して、

「OK」をクリック。 複数のファイルを登録する場合は、同じ操作を繰り返します。

図 3-12 プロジェクトへの登録/追加手順

上記の作業により、half_adder、 full_adder、 adder_4 の 3 つのファイル(モジュール)をプロジェクトメンバーに 登録すると、以下のように表示されます(図 3-13)。

図 3-13 Project へメンバー登録後の画面

3.4 VHDL ファイルのコンパイル

Project に追加された VHDL ファイルをコンパイルします。 図 3-14 のように、 「Compile」 → 「Compile All」 を選択してコンパイルを実行します。

図 3-14 コンパイルコマンドの選択

「Add to Project」 → 「Existing File」を選択

Page 7: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

79

コンパイルが成功すると、図 3-15 のように、チェックマーク: ✔ が入ります。 コンパイルでエラーが出たときは、 図 3-16 で ✔ の代わりに、バツマーク: ✖ が表示されます。

図 3-15 コンパイルが成功したときの画面

ModelSim でコンパイルしたときにエラー(Status にバツマークが入る)が出たときは、以下の方法を参考にして、 エラーを修正して下さい(図 3-16)。 修正したモジュールは再保存して、もう一度コンパイルします。 これを繰り返

して、図3-15のように、すべてのモジュールの“Status”欄が、“ ✔ ”になるようにします(この状態にならないと次に

進めないので、しっかりソースの VHDL を修正しましょう。“デバッグする”と言います)。

図 3-16 コンパイルでのエラー発生画面

“Status”欄が、“?”から“ ✔ ”に変わったことを確認

② 具体的なエラー箇所が表示されるので、そのエラーメッセージの内容に従って、

VHDL の記述を修正します(エラーメッセージは丁寧に読みましょう)

Page 8: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

80

VHDL のソースを変更した後、 “Save (Ctrl+S))” をクリックすると保存され、Project ウィンドウの“Status”欄 が、“?”に変更されます。 この後、「Compile」 → 「Compile Selected」を選択してコンパイルすると、選択された

モジュール(図 3-17 で紗が掛かっているモジュール)だけがコンパイルされます。

図 3-17 修正後のモジュールの保存と(選択)コンパイルの実行 3.5 “4ビット加算モジュール:adder_4.vhd”のシミュレーション実行 3.5.1 シミュレーションするモジュールの選択とシミュレーション・モードへの移行

以下のように、2通りの手順がありますが、共に選択したモジュールをシミュレーションする環境が起動されます。

① プルダウンメニューから起動する方法 (プルダウンメニューの)「Simulate」 → 「Start Simulation…」 と選択すると(図 3-18(左))、 ”Start Simulation“画面(図 3-18(右))がポップされるので、+work を展開すると、

- work +adder_4 +full_adder +half_adder

となるので、シミュレーションするモジュール: adder_4 をクリックして、「OK」を選択すると、シミュレーション・ モードへ移行し(図 3-20)、選択したモジュール:adder_4 のシミュレーションが実行できる環境になります。 なお、シミュレーションするモジュール(adder_4) をダブルクリックしても良いです。

図 3-18 「Start Simulation」からの起動方法(左)とシミュレーションモジュールの選択(右)

“Save (Ctrl+S))” を選択

Page 9: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

81

② “Library”シートからの起動方法 “Project”シートの左隣りにある“Library”シートを選択して(最上層にして)、+work を展開すると、

- work +adder_4 +full_adder +half_adder

となるので、シミュレーションするモジュール: “adder_4” を選択して、マウスの右ボタンをクリックすると、 選択メニューがポップアップされるので、左ボタンで「Simulate」を選択します(図 3-19)。 なお、ダブルクリック

すると、図 3-19 は表示されず、図 3-20 に直接移ります。 以降は、①と同様に、選択したモジュール:adder_4のシミュレーションが実行できる環境になります(図 3-20)。

図 3-19 “Library”シートから起動画面

図 3-20 adder_4 のシミュレーション・モードの画面

Page 10: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

82

図 3-20 はモジュール:adder_4 のシミュレーションを実行する環境になっているので、“Objects”画面の“Name”

欄には、adder_4 の VHDL で記述した入出力端子名(port 文)と内部信号名(signal 文)が表示されいます。 実際の VHDL では以下のように記述されているので、“Objects”画面の“Name”欄と一致しています。

port ( A, B : in std_logic_vector(3 downto 0); S : out std_logic_vector(3 downto 0); CO: out std_logic);

signal C1, C2, C3: std_logic; ← 別の名前にしてある場合は、その名前になります。

【シミュレーション・モードを終了する方法】 シミュレーション・モードを終了する場合は、 プルダウンメニューから

「Simulate」 → 「End Simulattion」 を選択します(図 3-21)。 VHDL エディタが使えるモードに戻ります。

図 3-21 シミュレーション・モードを終了する手順 3.5.2 入力波形の設定

モジュール:adder_4 をシミュレーションするためには、入力端子に入力信号を設定する必要があります。 adder_4 の入力端子は、“A, B : in std_logic_vector(3 downto 0);”なので、A と B の値のすべての組み合わせを

入力信号に設定して、設計したVHDL記述が正しいかどうかをシミュレーションします。 A、Bともに16通り[10進表

示で、0~15、2 進表示では、A[3..0] / B[3..0] = 0000 ~ 1111]あるので、全部で 256 通りの組み合わせがあります。

この入力信号の組み合わせを、図 3-22 のようなパターンと想定して、網羅的にシミュレーションを実行します。 [入力パターンの仕様]

信号 B: 周期:1 で初期値:0→最終値:15 まで1ずつカウントアップし、16 回繰り返す 信号 A: 周期:16 (=信号 B の 1×16)で初期値:0→最終値:15 まで1ずつカウントアップする (備考)

-信号 B の最小周期毎に区切って信号 A と B の値の組み合わせを“パターン”と呼びます。 従って、 上記の場合は、(A,B)=(0,0)、(0,1)・・・・・(F,F) [Hex 表示]の 256 パターン(=16×16)となります。

-実際は、“パターン”に実時間(基本的に任意の長さで OK)を割り当ててシミュレーションします。

図 3-22 入力信号 A、B の入力パターン

「Simulate」 → 「End Simulattion」 を選択

16 16

1 1

Page 11: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

83

今回は、入力パターンの設定に、“Objects”ウィンドウでポップアップするメニューを使用します(図 3-23)。

図 3-23 入力信号 A のパターン設定画面の起動

上記の操作により、“Create Pattern Wizard”画面(図 3-24)がポップアップされるので、図 3-22 の条件に従って、

信号 A の入力波形(入力パターン)を設定します。 信号 B のパターン周期を 20us とすると、信号 A のパターン周期は、 320us[20x16]となります。

図 3-24 入力信号 A の“Create Pattern Wizard”画面

図 3-25 counter 信号の設定画面

① “Objects”ウィンドウで信号:A を選択

② 右クリックでメニューをポップアップして、

「Modify」→「Apply Wave」 を選択

① “Signal Name”と“Range”を確認: 信号 A(3:0)

② “Counter”を選択

③ “End Time”を、“5120”[=320x16]に設定

④ “Time Unit”を、”us“に変更

⑤ 「Next」をクリック [ ⇒ 図 3-25 に移動 ]

[<Pattern: counter>画面がポップアップされます]

⑥ Start/End Value を確認

⑦ “Time Period”を”320“[=20x16]に設定

⑧ “Time Unit”を、”us”に変更

⑨ “Count Direction”を、“Up”に設定

⑩ “Step Count”を、“1”に設定

⑪ 「Finish」をクリック

Page 12: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

84

「Finish」を選択すると、入力信号:A の波形が Wave ウィンドウに表示されます(図 3-26)。

図 3-26 入力信号:A の入力波形

信号 A はバス信号なので、初期状態では、ビット表示されますが、

信号名にカーソルを合わせて、右クリックすると図 3-27 がポップアッ

プされるので、「Radix」 → 「Unsigned」を選択すると 10 進表示さ

れます。 [波形エディタの表示コントロール・コマンド] 波形エディタの以下のコマンドで表示をコントロールします。

図 3-27 バス幅の基数の表示変更

[波形エディタの時間表示単位の変更方法] この部分の初期値は、“ps”となっているので、以下の手順で、表示したい時間単位に変更します。

2 倍に拡大

1/2 倍に縮小

全体表示

カーソルを中心に 2 倍拡大

① 時間表示部にマウスを移動して右クリックすると

上記画面がポップアップされるので、

「Grid & Timeline Properties…」を選択

② 右画面に移るので、

“Time units”を、“us”に変更

③ 「OK」をクリック

Page 13: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

85

同様にして、入力信号:B の設定を行います(図 3-28、図 3-29)。 [手順] “Objects”画面で信号 B を選択して選択して(図 3-23 参照)、“Create Pattern Wizard”画面(図 3-28)を

ポップアップさせ、図 3-22 の条件に従って、信号B の入力波形(入力パターン)を設定します。 パターン幅は、

(信号 B のパターン周期:) 20us (全体の整合性が取れれば、自由に設定可能)と設定します。

図 3-28 入力信号:B の“Create Pattern Wizard”画面

図 3-29 入力信号 B の入力波形の設定

上記の作業により、入力信号:B が波形ウィンドウに追加され、図 3-30 のように、表示されます。

図 3-30 入力信号 A、B が設定された画面

① “Signal Name”と“Range”を確認: 信号B(3:0)

② “Counter”を選択

③ “End Time”を、“5120” [=20x256]に設定

④ “Time Unit”を、”us“に変更

⑤ 「Next」をクリック [ ⇒ 図 3-29 に移動 ]

[<Pattern: counter>画面がポップアップされます]

⑥ Start/End Value を確認

⑦ “Time Period”を”20“に設定

⑧ “Time Unit”を、”us”に変更

⑨ “Count Direction”を、“Up”に設定

⑩ “Step Count”を、“1”に設定

⑪ 「Finish」をクリック

Page 14: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

86

3.5.3 出力信号の設定 現在のシミュレーション画面は、モジュール:adder_4 のシミュレーションを実行する環境になっているので、

“Objects”画面の“Name”欄には、adder_4 の VHDL で記述した入出力端子名と内部信号名が表示されいます。 port ( A, B : in std_logic_vector(3 downto 0); S : out std_logic_vector(3 downto 0); CO: out std_logic);

signal C1, C2, C3: std_logic; ← 別の名前にしてある場合は、その名前になります。 (2)では、入力信号の波形(パターン)を設定しましたが(信号 A と B)、シミュレーション実行時には、シミュレーション

結果を見たい信号を“波形画面の信号名欄”に設定する必要がありますので、シミュレーション結果を見たい信号を “Objects”画面から“波形画面の信号名欄”にドラッグします(図3-31)[信号を選択したまま(左ボタンを押したまま)、

“波形画面の信号名欄”に移動します]。 なお、シミュレーションを実行する前に“信号名欄”に信号名を設定しないと

結果を表示できないので、この作業は必ず行ってください。

図 3-31 シミュレーション結果を表示したい信号の設定

[本図では、出力信号 S(3:0)と CO が設定されています。 Adder_4 の内部信号である C1、C2、C3 の

シミュレーション結果を波形エディタに表示したい場合は、“信号名欄”に希望の信号名を設定します。]

3.5.4 シミュレーションの実行

以上で、入力信号の設定とシミュレーション結果を表示したい信号の設定が済んだので、 「Simulate」 → 「Run」 → 「Run All」 (図 3-32)と選択して、シミュレーションを実行します・

図 3-32 シミュレーションの実行方法

シミュレーション結果を表示したい 信号をドラッグします。

Page 15: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

87

3.5.5 シミュレーション結果 シミュレーションの実行が終了すると(瞬時に終了します)、図 3-33 のように、実行結果が表示されます。

全体のシミュレーションが実行されていることを確認します。

図 3-33 シミュレーションの実行結果後の表示

図 3-34 実行結果を拡大したもの

図 3-33 のようにシミュレーション結果を全体表示したものは、正しい結果が得られているか判断が難しいので、

適宜拡大表示して、実行内容を調べて、シミュレーション結果が正しいかどうかを確認します。 例えば、 A: 7(0111) + B:15(1111) ⇒ S: 6(0110)、 CO: 1 A: 8(1000) + B: 2(0010) ⇒ S: 2(0010)、 CO: 0

とシミュレーション結果が表示されているので、正しく動作していることが判ります。

以上で、4ビット加算モジュール:adder_4 のシミュレーションは、完了です。 正しい結果が得られるまで、VHDL記述を変更して、シミュレーションを実行してください。 VHDL を変更する場合は、シミュレーション・モードを以下の

ように終了させ(図 3-35)、VHDL の編集/コンパイルを実行して、再度シミュレーション・モードに移ります。

図 3-35 シミュレーション・モードの終了(quit)方法

Page 16: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

88

シミュレーション・モードを終了するとき、以下の画面(図 3-36)が表示されます。 これは、シミュレーション時に 入力した入力波形(例えば、信号 A、B の波形)を保存するかどうかを確認しています。 「はい」を選択: 入力した波形(パターン)を保存して、次回のシミュレーション時に利用できます。

保存場所は、プロジェクトディレクトリの下に、“wave.do” というデフォルトのファイル名で保存

されます。 なお、図 3-37 の方法で保存する場合は、別のファイル名で保存することも可能で

すが、ファイルの拡張子は、“*.do” としてください。 「いいえ」を選択: 保存は行いません。 既に保存している場合は、こちらを選択します。

図 3-36 入力パターンの保存確認画面

[参考] 入力パターンのファイル名を指定して保存する方法

図 3-37 入力パターンを保存する別の手順

① 「File」 → 「Save Format …」 を選択 ② “Save Format”画面がポップアップするので、保存する

ファイル名を指定します。既定値は、“wave.do”です。 これを変更すると希望のファイル名で保存できますが、 拡張子は、“.do” とします。

③ 「OK」 を選択

Page 17: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

89

なお、保存したファイルは、シミュレーション・モードで入力信号を設定する代わりに、以下のコマンドを実行すると

入力信号が波形エディタにロードされます(図 3-37)。

図 3-37 保存した入力パターンをロードする手順 (6) ModelSim の終了方法

ModelSim を終了させる方法は、以下の 2 つの方法があります。 ウィンドウ右上の を選択するが、「File」 → 「Quit」を選択する(図 3-38)。

上記の方法により、図 3-38(右)の画面がポップアップするので、 「はい」を選択します。 ModelSim が衆力します。 図 3-38 ModelSim の終了手順(左)と確認画面(右)

① 「File」 → 「Load」 → 「Macro File」 を選択 ② “Open Format”画面がポップアップするので、

入力パターンを保存したファイル名を選択

③ 「開く」 を選択します。

波形エディタに入力信号が表示されます。

Page 18: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

90

3.6 “4ビット加算器: adder_4_top.vhd”のシミュレーション実行 3.5 章で、“4ビット加算モジュール:adder_4.vhd”のシミュレーションを実行して、設計した機能が正しく動作するこ

とを確認したので、本項では、4ビット加算器の最上位回路(図 1-60 参照)のシミュレーションを実行します。 シミュレーションする VHDL 記述は、既に設計した“adder_4_top.vhd”(図 2-25)を用います。

3.6.1 ファイルの移動とプロジェクトメンバーの追加

- QuartusⅡで作成した“adder_4_top.vhd”を Modelsim に取り込みます。 手順に関しては、“3.2 VHDL ファ

イルの作成”を参照してください。 - QuartusⅡで使用した“peripheral_DE0.vhd”に関しては、シミュレーション用にカスタマイズが必要なので、

シミュレーション用にカスタマイズした“peripheral_sim.vhd”を用います。 ⇐ 【重要】 “http://www.ed.tus.ac.jp/~jte401/” に置いてありますので、アクセスして、現在の作業(プロジェクト)ディレク

トリ[Z:/modelsim/adder_4bit/]の下にダウンロードして下さい。 - adder_4_top.vhd の peripheral_DE0 を peripheral_sim に変更する。

以上の作業により、必要な2つの VHDL ファイル: adder_4_top.vhd と peripheral_sim.vhd がプロジェクト・ディレ

クトリに追加されるので、“3.3 プロジェクトメンバーの管理”の手順に従って、この 2 つのファイルをプロジェクトメン

バーに追加します。 これらの結果、ディレクトリ下のファイルとプロジェクトメンバーは、図 3-39 となります。

図 3-39 プロジェクト[Z:/modelsim/adder_4bit/]下のファイル一覧(左)とプロジェクトメンバー(右) 3.6.2 コンパイルの実行

追加した2つのファイルをプロジェクトメンバーに追加した後、「Compile」 → 「Compile All」 を選択して、 コンパイルを実行します。 追加した2つのファイルは、QuartusⅡで既にコンパイルを実行して確認されているので、

正常に終了して、Status は “✔” となります(なるはずです)(図 3-39(右))。 3.6.3 評価ボード:DE0 の入力/出力信号(パターン)の仕様

“4ビット加算器”のシミュレーションをする場合、評価ボード:DE0 の入出力部品の性質とそれらをどのように利用

しているか(仕様)を理解して、入力/出力信号(パターン)を設定する必要があります。 [4ビット加算器: adder_4_top の entity 文]

entity adder_4_top is port( clk, reset, A, B, EQUAL : in std_logic; LED0 ,LED1, LED2, LED3 : out std_logic_vector(7 downto 0));

end adder_4_top;

[上図は、コンパイル後の状態です]

Page 19: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

91

(1)入力信号

入力信号は、以下の仕様で入力されます。

① clk入力 システムクロックを使用。 50Mz (=20ns/周期)。

② reset、A、B、EQUAL入力

DE0のボタンスイッチ(BTN0、BTN1、BTN2)と

スライドスイッチ(SW0)を使用(図 3-40)。

入力信号とスイッチとの割り当ては以下の通り。

reset : BTN1 A : BTN2 図 3-40 スイッチの配置 B : BTN0 EQUAL: SW0 [ボタンスイッチの仕様]

DE0 のボタンスイッチは、図 3-41 のように、“a 接点スイッチ”が搭載されています。 “a 接点スイッチ”は、“押したときに回路が接続する”仕様なので、ボタンを押下すると、例えば H2 は、 グランドに接続されます。 論理値で考えると、“1 → 0”と変化します。 従って、ボタンスイッチから 入力するreset、A、B信号は、 のような波形になります。

図 1-104 信号 EQUAL の入力波形の設定

図 3-41 ボタンスイッチの仕様

[スライドスイッチの仕様]

スライドスイッチは、図 3-42 のように、上方にスライドと“論理値:1”、下方にスライドすると“論理値:0”と なるので、スライドスイッチから入力する EQUAL 信号は、以下のような波形になります。

[EQUAL 信号の波形]

図 3-42 スライドスイッチの仕様

10ns 10ns

SW0 BTN2 BTN1 BTN0

a接点スイッチ FPGA

push push

Logic “1”

Logic “0”

上方にスライド

下方にスライド

Page 20: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

92

(2)出力信号 4ビット加算器の出力は、DE0 に搭載されている4個の7segLED(dot 付)に表示されます。

DE0 には、図 3-43 のようにアノードコモン型の7segLED(dot 付)が搭載されているので、8本[a ~ dp]の 各入力に低電圧(論理値:0)を印加すると、対象の LED が発光します。 例えば、入力端子[a ~ dp]に、 以下のような電圧(論理値で表記)が印加された場合、segment のbとcが発光するので、“1”が表示されます。

[入力端子名] a b c d e f g dt

[印加論理値] 1 0 0 1 1 1 1 1

図 3-43 7segLED(dot 付)の仕様

4ビット加算器では、4個の7segLED(dot 付)を以下のように使用しています。

[入力信号 A、B を表示する場合] EQUAL 信号 = ‘ 0 ’ LED0 : 入力信号 B を 16 進表示 LED1 : (無表示:すべての segment を OFF) LED2 : (無表示:すべての segment を OFF) LED3 : 入力信号 A を 16 進表示

[計算結果を表示する場合]

EQUAL 信号 = ‘ 1 ’ LED0 : 計算結果の 16 進表示の1桁目 LED1 : 計算結果の 16 進表示の2桁目 LED2 : “=”を表示 LED3 : “=”を表示

a

c e

d

f

g

dp

a

b

c

d

e

f

g

dp A~Dot に低電圧(論理値:0)を印加すると

ダイオードが ON 状態になり、発光する

“ 1 “ が表示される

HEX3 HEX2 HEX1 HEX0

入力信号 A 入力信号 B

6h+3h=09h

HEX3 HEX2 HEX1 HEX0

Page 21: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

93

3.6.4 シミュレーションの実行 3.6.3(1)の入力信号の情報を基に、入力パターンを設定して、シミュレーションを実行します。 手順通りに

操作して(3.5 章参照)、モジュール: adder_4_top を選択して、シミュレーション環境を起動します(図 3-44)。

図 3-44 シミュレーション環境起動手順と起動後の画面

図 3-44 の“Objects”画面には、入力端子名、出力端子名、

adder_4_top の内部信号名がリストアップされているので (図 3-45)、4ビット加算モジュール:adder_4 の場合と 同様に、入力信号パターンを設定します。

図 3-45 (図 3-44 の)“Objects”画面

① +work をクリックして、下位階層を表示

[8 つのモジュール名が表示される]

② adder_4_top をクリック

⇒ シミュレーション環境を起動

Page 22: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

94

(1)入力パターンの設定 4 ビット加算器のシミュレーションでは、既に内部回路の4ビット加算モジュール:adder_4 のシミュレーションが

実行され機能確認がされているので、全体回路として、以下の機能の確認を行います。 この確認を行うために、 パターン幅=20us、128 パターン(=20X128us)の入力信号の設定を行います。

- 入力パターンから信号 A と B を正しく数えられるか? - リセット信号:reset が正しく動作するか? - それぞれの7segLED に、仕様通りに、正しい信号情報が出力されているか? - モード信号:EQUAL に従って、表示が切り替わるか?

① 信号:clkの設定 [50Mz=20ns のクロックの設定]

図 3-23 のように、“Object”画面で“clk”を選択して、手順通りに、 「Modify」→「Apply Wave」 を選択して、“Creat Pattern Wizard”画面

から以下のように設定します(図 3-46)。

図 3-46 信号:clkの設定画面

② 信号 A、B の設定 信号 A は、ボタンスイッチの押下回数で入力するので、“a接点スイッチ”の仕様に合わせて、入力信号として 以下のようなパターンを設定します。

- 初期値:’1’、160us 毎に’1’と’0’をトグル(=周期 320us) ⇒ 8パターン毎に状態値が変化 - 図中の(下向き)矢印毎に、ボタンスイッチが押下されたと想定 信号 A の入力数 = [ (Ta+160)/320 ] mod 16 《 ← [ ]は、ガウス記号 》 (例) Ta=1000us の場合、 [(1000+160)/320] mod 16 =3 ⇒ 信号 A に“3”が設定される

10ns 10ns

① “Signal Name”を確認 ② 「Clock」を選択 ③ “End Time”と“Time Unit”を”2560 us“に設定 ④ 「Next」を選択 ⑤ 右上の波形のようなサイクルするために、

“Initial Value” ⇒ “ 0 ” “Clock Period” ⇒ “ 20 ” “Time Unit” ⇒ “ ns ” “Duty Cycle” ⇒ “ 50 ” に設定

⑥ 「Finish」を選択

160 us 160 us

320 us 320 us 320 us 320 us

Page 23: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

95

信号 B も同様に、入力信号として、以下のようなパターンを設定します。 - 初期値:’1’、10us 毎に’1’と’0’をトグル(=周期 20us) ⇒ 1パターン毎に状態値が変化」 - 図中の(下向き)矢印毎に、ボタンスイッチが押下されたと想定 信号 B の入力数 = [ (Tb+10)/20 ] mod 16 《 ← [ ]は、ガウス記号 》 (例) Tb=100us の場合、 [(100+10)/20] mod 16 =5 ⇒ 信号 B に“5”が設定される

上記信号 A、B の設定は、「Modify」 → 「Apply Wave」 ⇒ “Creat Pattern Wizard”画面で、手順通りに、

以下のとおり設定します(図 3-47)。

図 3-47 信号 A と B の設定画面

③ 信号: RESET、EQUAL の設定 RESET はボタンスイッチ、EQUAL はスライドスイッチから入力されるので、以下の入力波形となります。 どのようなパターンを設定するかは任意ですが、ここでは、以下のように設定します。 - RESET: 550us でリセット信号が入り、50us 継続して[Duration]、600us で解除される - EQUAL: 0 ~ 1500us: ‘ 0 ’、1500 ~ 2100us: ‘ 1 ‘、2100 ~ 2560us: ‘ 0 ‘

[信号:reset の入力波形] [信号:EQUAL の入力波形]

10us 10us

20us 20us 20us 20us 20us 20us 20us

[信号 A ] - 「Clock」を選択 - ”End Time“ ⇒ ” 2560 “ - ”Time Unit” ⇒ ” us “ - “Initial Value” ⇒ “ 1 ” - “Clock Period” ⇒ “ 320 ” - “Duty Cycle” ⇒ “ 50 ”

[信号 B ] - 「Clock」を選択 - ”End Time“ ⇒ ” 2560 “ - ”Time Unit” ⇒ ” us “ - “Initial Value” ⇒ “ 1 ” - “Clock Period” ⇒ “ 20 ” - “Duty Cycle” ⇒ “ 50 ”

2560 us

550 us 50 us [Duration]

2560 us

1500 us 600 us

Page 24: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

96

これらの波形の設定は、以下のように、操作を組み合わせて行います。 まず、手順通り、“Objects”画面で、 信号:reset を選択して、「Modify」 → 「Apply Wave」 ⇒ “Creat Pattern Wizard”画面を表示します。

図 3-48 のように、「Constant」を選択して、“Value”を”1“に設定します。

図 3-48 信号:RESET を value=’1’に設定

上記の操作により、波形エディタに、図 3-48 のように、信号:RESET が表示されます(状態値:1が継続)。

この状態で、波形エディタの”RESET“を選択して、図 3-49(a)の”Edit Mode“コマンドを”ON“状態(図(b))のよう

に、反転します)にして、”Insert Pulse“コマント(図(c))を選択すると、”Edit Insert Pulse“画面(図(d))がポップ

アップするので、所望の RESET 波形になるように値を設定します。 この”Insert Pulse“コマントは、”Time“で

指定した時間から”Duration“で指定した時間幅の状態値を反転します。 この操作は、繰り返し可能です。

(a)“Edit Mode”コマンド (b)“Edit Mode”コマンドの選択状態 (c) “Insert Pulse”コマンド

(d) “Edit Insert Pulse”画面 図 3-49 信号:RESET にパルス信号を挿入する手順

① “Signal Name”を確認 ② 「Constant」を選択 ③ “End Time” ⇒ ” 2560 “

“Time Unit” ⇒ ” us “ を選択 ④ 「Next」を選択 ⑤ “Value” ⇒ “ 1 ” に設定 ⑥ 「Finish」を選択

① 信号名を確認 ② “Duration” ⇒ ” 50 “

“Time” ⇒ ” 550 “ “Time Unit” ⇒ “ us ” に設定

③ 「OK」を選択

Page 25: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

97

以上の操作により、図 3-50 のように、所望通りの信号:RESET が設定できます。

図 3-50 設定を完了した信号:RESET

信号:EQUAL も同様に、まず“Creat Pattern Wizard”画面で「Constant」 = ‘ 0 ‘としてから、

“Edit Insert Pulse”画面で、図 3-51 のように設定します。

図 3-51 信号:EQAUL にパルス信号を挿入する手順

以上、(4-1)の操作により、図 3-52 のように入力波形(パターン)が設定されます。

図 3-52 入力信号をすべて設定した状態 (2) シミュレーションの実行

入力信号を設定した後、シミュレーションを実行する前に、“Objects”画面から、結果を見たい信号をドラッグします。

今回は、図 3-53 のように、“Objects”画面のすべての出力信号と内部信号をドラグしてください。

図 3-53 シミュレーションを実行する直前の状態

① 信号名を確認 ② “Duration” ⇒ ” 600 “

“Time” ⇒ ” 1500 “ “Time Unit” ⇒ “ us ” に設定

③ 「OK」を選択

シミュレーションを実行する前に、“Objects”画面から これらの信号をドラッグします。

Page 26: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

98

Hex a b c d e f g dot

0 0 0 0 0 0 0 1 1

1 1 0 0 1 1 1 1 1

2 0 0 1 0 0 1 0 1

3 0 0 0 0 1 1 0 1

4 1 0 0 1 1 0 0 1

5 0 1 0 0 1 0 0 1

6 0 1 0 0 0 0 0 1

7 0 0 0 1 1 0 1 1

8 0 0 0 0 0 0 0 1

9 0 0 0 0 1 0 0 1

A 0 0 0 1 0 0 0 1

B 1 1 0 0 0 0 0 1

C 0 1 1 0 0 0 1 1

D 1 0 0 0 0 1 0 1

E 0 1 1 0 0 0 0 1

F 0 1 1 1 0 0 0 1

1E(=) 1 1 1 0 1 1 0 1

他 1 1 1 1 1 1 1 1

以上の操作後、「Simulate」 → 「Run」 → 「Run All」(図3-32 参照)を選択して、シミュレーションを実行します。 図 3-54 がシミュレーション実行後の画面です。

図 3-54 シミュレーション実行後の波形エディタの画面 (3)シミュレーション結果の確認

4ビット加算器:adder_4_top のシミュレーションでは、以下の内容を確認することが目的でした。 - 入力パターンから信号 A と B を正しく数えられるか? - リセット信号:RESET が正しく動作するか? - それぞれの7segLED に、仕様通りに、正しい信号情報が出力されているか? - モード信号:EQUAL に従って、表示が切り替わるか?

[事前準備]

(1) 信号:a_count_sig、b_count_sig、add の数値表示を、(各信号を選択した後、) 右クリック → 「Radix」 → 「Hexadecimal」 を選択して、16 進表示にしておきましょう (図 3-27 参照)。

(2) 数値[16 進表示]情報を7segLED(アノードコモン型)へ変換表は以下のとおりです。

Page 27: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

99

① シミュレーション開始時の状況 (図 3-55) 10us で信号 B の最初の立下りエッジが入力されるので、b_count_sig(ボタンスイッチ 2 の押下回数の合計)が

“1”となり、add (=a+b)が“1”となっています。 この時の LED の表示は、以下のとおりです。 LED0: “10011111” [⇒ 1h ] ; b_count_sig を 16 進数で表示 LED1: “11111111” [⇒ 全セグメント OFF ] ; EQUAL=”0”の時の仕様 LED2: “11111111” [⇒ 全セグメント OFF ] ; EQUAL=”0”の時の仕様 LED3: “0000011” [⇒ 0h ] ; a_count_sig を 16 進数で表示

次に、30us で信号 B の 2 回目の立下りエッジが入力されるので、b_count_sig が”2”になり、同時に、 LED0: “00100101” [⇒ 2h ] に変化している。 他の LED は変化しない。 ⇒ 正しく動作

図 3-55 シミュレーション開始時の状況

② 160us 付近のシミュレーションの状況 (図 3-56) 160us で信号 A の最初の立下りエッジが入力されるので、a_count_sig(ボタンスイッチ 0 の押下回数の合計)

が“1”となり、この時、b_count_sig は、[(160+10)/20=]“8”なので、add は、[1+8=]“9”となります。 また、この時、LED の表示は、LED3 だけが、“0”表示から LED3: “10011111” [⇒ 1h ] に変化しています。 ⇒ 正しく動作

図 3-56 150us 付近のシミュレーションの状況

Page 28: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

100

③ 550us 付近のシミュレーションの状況 (図 3-57); RESET の確認 550us から 600us まで(Duration:50us)、RESET 信号が“ON”になるので、550us で、a_count_sig、 b_count_sig が初期化され、“0”になっています。 600us で reset 信号が解除された後、610us で信号 B の立

下りエッジが入力されるので、b_count_sig がカウントアップしています。 ⇒ RESET が正しく動作

図 3-57 550us 付近のシミュレーションの状況(RESET の確認)

④ 1500us 付近のシミュレーションの状況 (図 3-58) 1500us から 2100us まで、EQUAL= ’1’が入力されるので、LED には add が表示され、 LED0 には、add の下位 4 ビットを Hex 表示、LED1 には、add(4)を表示となります。 1500us の時点では、a_count_sig は [(1500-600+160)/320 mod 16=] “3”、 b_count_sig は[(1500-600+10)/20 mod 16=]“13” (= Dh) ⇒ add=”10000“ (= 10h )なので、

LED0: “00000011” [⇒ 0h ] ; add の下位4ビットを 16 進数で表示 LED1: “10011111” [⇒ 1h ] ; add の上位1ビットを表示 LED2: “11101101” [⇒ = ] ; EQUAL=’1’ の時の仕様 LED3: “11101101” [⇒ = ] ; EQUAL=’1’ の時の仕様 ⇒ EQUAL が正しく動作

【確認】 2100us で、EQUAL=“0”の戻り、正しし動作しているかを確かめて下さい。

図 3-58 1500us 付近のシミュレーションの状況(EQUAL= ‘1’ の確認)

Page 29: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

101

3.7 “テストベンチ”によるシミュレーションの実行 これまでのシミュレーションの実行では、入力パターンの設定は波形エディタの機能を使って行いましたが、手順

が少し面倒で手間が掛かりました。 それを改善し、効率よくシミュレーションを実行できるのが、“テストベンチ”によ

るシミュレーションの実行です。 [VHDL 仕様] テストベンチの構造

テストベンチの記述構造は、基本的にモジュールの記述方法と同じで、以下構造となります。

(VHDL モデル定義文)

use 使用するライブラリ名;

(エンティティ文)

entitiy エンティティ名 is

end エンティティ名;

(アーキテクチャ文)

architecture アーキテクチャ名 of エンティティ名 is

- DUT(Device Under Test)のコンボーネント宣言

- 入出力信号の宣言

- 定数の定義 等

begin

- DUT の呼び出し(インスタンス)

- 入力パターンの記述

end アークテクチャ名;

(コンフィグレーション文)

configuration コンフィグレーション名 of エンティティ名 is

for アークテクチャ名

end for;

end コンフィグレーション名;

テストベンチ

シミュレーション実行

(テスト)したいモジュール

(DUT)をインスタンス

クロック、リセット

等の設定

入力信号の

パターンの生成

シミュレーション

結果の表示等

-コンフィグレーション文は、テストベンチ 特有の記述です。

-ここで指定したコンフィグレーション名で シミュレーションの実行モジュールが 作られます。

-process 文内に所望の入力パターンを 記述する。 色々な記述が可能です。

-DUT をインスタンスする(呼び出し)

-テストしたいモジュール(DUT)を通常通り component 宣言します。

-component の port 内の入出力名は、 すべて signal 宣言します。 初期値の設定

も可能です。

-テストベンチの entity 宣言は、エンティティ

名だけで、port 文を宣言しません

Page 30: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

102

3.7.1 4ビット加算モジュール:adder_4 のシミュレーションをテストベンチで実行 (1)テストベンチの VHDL 記述

4ビット加算モジュール:adder_4 の“テストベンチ”を VHDL で記述します(VHDL の入力は、図 3-9 参照)。 「New」 → 「Source」 → 「VHDL」の順にクリックして、VHDL 編集画面をオープンして、図 3-59 のとおり入力して、

ファイル名:“ adder_4_tb ”で保存して下さい。

-エンティティ名: adder_4_tb ← モジュール名に“_tb”を付けるような規則にすると、そのモジュールの テストベンチ(tb)であることがすぐに分かります(制限はありません)。

-アーキテクチャ名: SIM ← シミュレーションなので、“SIM”とします(制限はありません)。 -インスタンス名: DUT ← 自由に名前付けできます。 -コンフィグレーション名: cfg_adder_4_tb ← エンティティ名に“cfg_”を付けるような規則にすると、 判別がしやすくなります(制限はありません)。

図 3-59 4ビット加算モジュール(adder_4)のテストベンチ記述: adder_4_tb

テストベンチの entity文には、

port 文は不要です。

シミュレーションするモジュールを

component 宣言します。

adder_4 の入出力を

全てsignal宣言します。

初期値の設定も可能で

す。

A、Bには、初期値として、

“1111”が設定されます。

パターン幅=“20 us”を定数文字:

STEP として定義します。

adder_4 をインスタンス名:DUT として配置(呼び

出し)します。 port には、signal 宣言した名前を

指定します。

基本的にこの4行の記述と

なるので、コンフィグレーション名

とエンティティ名を変更するだ

けで OK です。

Page 31: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

103

(2)入力パターンの設定 4ビッド加算モジュールの入力信号(パターン)は、以下のとおりです(図 3-22 参照)。

テストベンチでの入力パターンに設定は、process begin ・・(パターン記述)・・ end process; で行います。 なお、この process 文は、無限に繰り返されます。

[入力信号:B の記述]

STEP(=“20us”)毎にBの値を+1されるので、

右のような記述になります。

Time=0usでは、Bの初期値が“1111”なので、

“1111”+‘1’=“0000”となります [Bは4ビットの変数なので、オーバーフローして、“0000”に戻る]

“wait for STEP;”は、入力をSTEP(=“20us”)進めるということなので、STEP進めた後に、“B <= B +‘1’;”に

もどり、Bを+1カウントアップします。 これを無限に繰り返すので、信号Bが設定できます。

[入力信号:A の記述]

信号Aも信号Bと同様に記述できますが、“for ~ loop”文を

使った記述をしてみます。

“ for I in 0 to 15 loop ”は、“end loop; ”の間に書かれた処理文

を変数: I が0 → 15まで変化する間、すなわち16回繰り返し、

loop文をます。

信号Aは、信号Bと同様に初期値が“1111”なので、Time=0usで

値が“0”となり、STEP*16(=“320us”)進めた後に、変数Iが

+1カウントアップされ、再び“ A <= A + '1'; wait for STEP*16; “

の処理がされ、Aを+1カウントアップし、320us勧められます。

これが16回繰り返されるので、信号Aを設定でします。 loop文が終了すると、

“ assert false severity failure; ”が実行され、シミュレーションは強制終了されます。

以上の結果として、Aは0→15、Bは0→15を16回繰り返す入力パターン[320x16=5120us]が設定できます。

【重要】 process文は無限に繰り返されるので、この“ assert false severity failure; ”がないと、シミュレーションは終了

せず、継続され続けます。 従って、ハードのリソースがなくなる続けられますので、場合により、甚大な影響が発

生する可能性がありますので、必ず忘れずにこのassert文をどこかに記述しましょう。

(3)プロジェクトメンバーへの追加とコンパイルの実行

図3-59のテストベンチの入力が済んだら、手順通りに、現在のプロジェクトディレクトリ(Z::/modelsim/adder_4bit/)

に、ファイル名:adder_4_tb.vhdで保存して下さい。

保存しただけではプロジェクトメンバーに追加されないので、“3.3 プロジェクトメンバーの管理”に従って、 “Projects”画面で操作して、テストベンチ:adder_4_tb をプロジェクトメンバーに追加して下さい。

プロジェクトメンバー登録後のaddert_4_tbのStatusは、 となっているので、adder_4_tbを選択して、

「Compile」 → 「Compile Selected」でコンパイルを実行します。 図3-59の記述は正しいので、正常に終了します。

エラーが発生する場合は、入力にミスがあるので、メッセージを参考にして、修正して下さい。

16 16

1 1

process begin

B <= B + '1'; wait for STEP;

end process;

process begin

for I in 0 to 15 loop

A <= A + '1'; wait for STEP*16;

end loop;

assert false severity failure;

end process;

Page 32: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

104

(4)テストベンチによるとシミュレーションの実行 「Sumulate」 → 「Start Simulation」 もしくは、“Library”画面から通り、手順通りに作業して、+workを展開して

下位階層を表示すると、 ができています(このファイルができていない場合は、adder_4_tbの コンパイルが正常に終了していません)。 このコンフィグレーション名のファイルがテストベンチで作成したシミュレ

ーションの実行モジュールです(図3-60)。 これをダブルクリックすると、シミュレーションモードに移り、adder_4を

シミュレーションする環境が整います(図3-61)。

図 3-60 シミュレーション実行モジュールの選択

図 3-61 cfg_adder_4_tb 選択後、起動するシミュレーション実行画面

[シミュレーションの実行]

図 3-61 のように、”Objects“画面からシミュレーション結果を見たい信号名を波形エディタにドラッグした後、

「Simulate」 → 「Run」 → 「Run All」 と選択して、シミュレーションを実行します。

① +work の+をクリック ② 右のように展開し、下位階層に

cfg_adder_4_tb が存在 ③ cfg_adder_4_tb をダブルクリック

“Objects”画面に表示されている信号を ここにドラッグする

Page 33: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

105

シミュレーションの実行が終了すると、図 3-62 の画面が表示され、adder_4_tb の 31 行目に記述した

“ assert false severity failure; ”で強制終了したことが示されます。

図 3-62 シミュレーションを強制終了したことを示す画面

“Wave“タグを選択して、シミュレーション結果を表示すると、図 3-63 のようになっている(はずな)ので、

前回のシミュレーションと同じ結果になっているか、詳細を確認してください。

図 3-63 cfg_adder_4_tb で実行したシミュレーション結果

Page 34: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

106

3.7.2 4ビット加算器:adder_4_top のシミュレーションをテストベンチで実行 (1)テストベンチの VHDL 記述

4ビット加算器:adder_4_top のテストベンチを VHDL で記述します。 前節と同様に、VHDL 編集画面をオープン

して、テストベンチを図 3-64 のとおり入力して、ファイル名:“ adder_4_top_tb ”で保存します。 -エンティティ名: adder_4_top_tb ← モジュール名に“_tb”を付けます。 -アーキテクチャ名: SIM ← シミュレーションなので、“SIM” とします。 -インスタンス名: DUT -コンフィグレーション名: cfg_adder_4_top_tb ← エンティティ名に“cfg_”を付けます。

図 3-64 adder_4_top_tb のテストベンチ: adder_4_top_tb.vhd

5~20行目までは、adder_4 の記述を参考にして、

それぞれを確認しながら丁寧に入力します。

configuration 文も定型的な記述になるので、

コンフィグレーション名とエンティティ名を

確認して、記載します。

Page 35: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

107

(2)入力パターンの設定 [信号:clk の記述]

4ビット加算器で用いるクロック信号は、上図のように、10ns 周期で ‘0’ と ’1’ を繰り返すので、

process 文を使って、右上のように記述します。 クロック信号の記述として定番なので、覚えておきましょう。

「’0’を代入して、10ns 後に、’1’を代入して、10ns 進める」を

無限に繰り返します。 なお、定数変数の STEP(=“20us”)を

使う場合は、右のような記述になります。

ここで、STEP/2000 = 20us/2000 = 10ns です。

[信号:A、B の記述]

信号:B

信号:A

信号AもBも周期的な“10”の繰り返しなので、上記の

信号:clkと同様に、右のように記述します。

信号:Bでは、周期をSTEP/2 (= 20us/2 = 10us) で、

信号:Aでは、周期をSTEP*8 (= 20us*8 = 160us) で

指定しています。 勿論、上記のclkのように、

10 us、160 us と直接時間で指定しても良いです。

[信号:reset、EQUAL の記述]

[信号:reset の波形]

[信号:EQUAL の波形]

信号 reset と EQUAL は、上記のように、周期的な

信号ではないので、右上のように、process 文中で、値が変化するタイミングを直接時間で指定します。

【重要】 このprocess文中で、“ assert false severity failure; ” を記述します。

process begin

clk <= '0'; wait for 10 ns;

clk <= '1'; wait for 10 ns;

end process;

10ns 10ns

process begin

clk <= '0'; wait for STEP/2000;

clk <= '1'; wait for STEP/2000;

end process;

160 us 160 us

320 us 320 us 320 us 320 us

10us 10us

20us 20us 20us 20u 20us 20us 20us

process begin

B <= '1'; wait for STEP/2;

B <= '0'; wait for STEP/2;

end process;

process begin

A <= '1'; wait for STEP*8;

A <= '0'; wait for STEP*8;

end process;

process begin

reset <= '1'; EQUAL <= '0';

wait for 550 us; reset <= '0';

wait for 50 us; reset <= '1';

wait for 900 us; EQUAL <= '1';

wait for 600 us; EQUAL <= '0';

wait for 460 us;

assert false severity failure;

end process;

2560 us

550 us

50 us [Duration]

2560 us

1500 us 600 us

Page 36: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

108

(3)プロジェクトメンバーへの追加とコンパイルの実行

図3-64のテストベンチの入力が済んだら、手順通りに、現在のプロジェクトディレクトリ(Z::/modelsim/adder_4bit/)

に、ファイル名:adder_4_top_tb.vhdで保存するとともに、プロジェクトメンバーに追加して下さい。

プロジェクトメンバー登録後、「Compile」 → 「Compile Selected」でコンパイルを実行します。 adder_4_tbと同様に

図3-64の記述は正しいので、正常に終了します。 エラーが発生する場合は、入力にミスがあるので、メッセージを

参考にして、修正して下さい。

(4)テストベンチによるとシミュレーションの実行 「Sumulate」 → 「Start Simulation」 もしくは、“Library”画面から通り、手順通りに作業して、+workを展開して

下位階層を表示すると、 ができています(図3-65、このファイルができていない場合は、 adder_4_top_tbのコンパイルが正常に終了していません)。 これをダブルクリックすると、シミュレーションモード

に移り、adder_4_topをシミュレーションする環境が整います(図3-66)。

図 3-65 シミュレーション実行モジュール(cfg_adder_4_top_tb)の選択

図 3-66 cfg_adder_4_top_tb 選択後、起動するシミュレーション実行画面

Page 37: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

109

図 3-66 の起動後の画面の“Objects”画面には、テストベンチ:adder_4_top_tb 内の信号だけが表示されていますが、

シミュレーション結果では、adder_4_top 内の a_count_sig、b_count_sig、add 信号の結果も確認したいので、以下のよう

にして、所望の信号を表示させます(図 3-67)。 その後、波形エディタへドラッグします(図 3-68)

図 3-67 adder_4_top 内の信号を“Objects”画面に表示

図 3-68 “Objects”画面から波形エディタへドラッグ

[シミュレーションの実行]

図 3-68 のように、”Objects“画面からシミュレーション結果を見たい信号名を波形エディタにドラッグした後、

「Simulate」 → 「Run」 → 「Run All」 と選択して、シミュレーションを実行します。

シミュレーションの実行が終了すると、図 3-69 の画面が表示され、adder_4_top_tb の 41 行目に記述した

“ assert false severity failure; ”で強制終了したことが示されます。

adder_4_top_tb の代わりに、 DUT(addert_4_top)を選択すると、“Objects”

画面に DUT 内の信号名が表示されます。

Page 38: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

110

図 3-69 シミュレーションを強制終了したことを示す画面

“Wave“タグを選択して、シミュレーション結果を表示すると、図 3-70 のようになっている(はずな)ので、

前回のシミュレーションと同じ結果になっているか、詳細を確認してください。

図 3-70 cfg_adder_4_top_tb で実行したシミュレーション結果

Page 39: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

111

din(3)

din(2)

din(1)

din(0)

dout(9)dout(8)dout(7)dout(6)dout(5)dout(4)dout(3)dout(2)dout(1)dout(0)

1

0

0

0

0000001000

0100000000

4. 課題2: 『自分の名前を表示させよう』の設計

本章では、実習課題2として、『自分の名前を表示させよう』を設計します。 これは、自分の名前を含んだ文字列

(32 文字以内)を、DE0 の4個の 7segLED に右から左に流れるように表示させるものです(1秒毎に移動)。

本課題ではデコーダ回路を使うので、VHDL でどのように記述するかを実習します。

まず、ModelSim上で設計してシミュレーションで機能を確認した後、QuartusⅡに設計したVHDL記述を移して、

実機:DE0 で最終確認をします。

4.1 デコード回路の設計

デコード回路は、符号化されたデータをもとのデータに戻す回路のことです。 例えば、2 進数を 10 進数に変換し

て出力する働きをもった回路です。 図 4-1 の回路では、4 ビットの 2 進数を入力し 10 進数に変換する機能ですが、

10 ビット出力信号 dout の各桁を 10 進数の 0 から 9 に割り当て、該当するビットを 1 にすることで実現しています。

この例では、2 進数"1000"が入力されているので、出力は 10 進数の 8 にあたる dout(8)が 1 になります。

図 4-1 デコ一ド回路の例 (参考)

エンコーダとは、例えばキーボードの 'A' というアルファベットを、計算機内部で使用するアスキーコード(ASCII)に変換する装置のことを指します。 一般には、人間が直接識別したりする情報を、計算器が扱いやすい情報(符

号)に変換するための装置(符号器)です。 一方、デコーダは、このエンコーダの逆の操作をする装置です。 - エンコード(encode, 符号化) : デジタルデータを一定の規則に従って、目的に応じた符号に変換すること - デコード (decode, 復号化) : 符号化されたデータをもとのデータに戻すこと

このデコーダを VHDL で記述する場合は、process 文と case 文を使って記述します。

[VHDL の仕様] process 文、if文、case 文

〇 process 文 process 文は、アーキテクチャ部に記述し、複雑な(1行では表現できない)論理回路の記述に用います。 process 文の記述は、次のとおりです。

《センシティビティリスト》

信号名をカンマで区切って並べたリストで、ここに記述された信号が変化するたびに begin と end で囲まれた

順次処理文を最初から順番に実行し、次にセンシティビティリストの信号が変化するまで動作を停止します。

《順次処理文》

実体を記述する式で、基本的に記述さえた順番に一気に実行されます。 この記述の中で条件分岐をさせる

ために、if文と case 文が使えます。

process (センシティビティリスト) begin

<順次処理文>

end process;

Page 40: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

112

〇 if文 if 文は、process 文中に記述し、以下の記述となります(“elsif”のスペルに注意[elseif ではない])。 条件式に基づいて、処理文の実行の可否が選択されます。 条件式が“真”であれば、thenに続く順次処理文が

実行され、“偽”であれば、elsif もしくは else に続く順次処理文が実行されます。 従って、条件式は、boolean 型

でなければいけません。 条件式は上から順番に判断されるため、順次処理文に優先順位が付きます。 〇 case 文

case 文は、式の値によって、指定した複数の逐次処理のうちいずれか 1 つを実行します。 即ち、式の値が分

岐値と等しい場合、"=>" の後の順次処理を実行します(多方向分岐が可能)。 case 文の記述は、次のとおりです。 ここで、case 文の場合にはすべての条件式が同時に実行されるので、 同じ値が複数使われることはできません。 また、すべての取り得る値を記述する必要があります。 従って、 最後に、“when others => 文”を必ず記述します(“others”は、その他すべての場合を表します)。

[記述例] セレクタ(右図)の記述例を以下に示します。 (1) case 文で記述した例: stg_logic_vector を使った場合

library IEEE;

use IEEE.std_logic_1164.all;

entity M_BEHAVIOR is

port (SELS: in std_logic_vector(0 to 1);

A,B,C,D : in std_logic;

M : out std_logic);

end M_BEHAVIOR;

architecture RTL of M_BEHAVIOR is

begin

process(SELS, A, B, C, D) begin

case SELS is

when ”00” => M <= A;

when ”01” => M <= B;

when ”10” => M <= C;

when others => M <= D;

end case;

end process;

end RTL;

if 条件式 then 順次処理文

[ elsif 条件式 then 順次処理文 ]

[ else 順次処理文 ]

end if;

case 式 is

when 値 => 順次処理文;

when 値|値|値 => 順次処理文;

when 値 to 値 => 順次処理文;

∙ ∙ ∙

when others => 順次処理;

end case ;

M

SELS

A

B

C

D

SELSは、std_logic_vectorで宣言しているので、

その状態値は、9x9=81 値となります。

“when others” ですべての状態を記述します

Page 41: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

113

(2) case 文で記述した例: bit_vector を使った場合 (3) if then else/elsif 文で記述した例:

library IEEE;

use IEEE.std_logic_1164.all;

entity M_BEHAVIOR is

port (SELS : in bit_vector(0 to 1);

A,B,C,D : in std_logic;

M : out std_logic);

end M_BEHAVIOR;

architecture RTL of M_BEHAVIOR is begin

process(SELS, A, B, C, D) begin

case SELS is when ”00” => M <= A;

when ”01” => M <= B;

when ”10” => M <= C;

when “11” => M <= D;

end case;

end process;

end RTL;

SELS を、bit_vector で宣言した場合は、

その状態値は、2x2=4 値となるので、

“00, 01, 10, 11” の4値を記述すれば、

すべての場合を記述することになります。

library IEEE;

use IEEE.std_logic_1164.all;

entity N_BEHAVIOR is port (

SELS : in std_logic_vector(1 downto 0);

A,B,C,D : in std_logic;

M : out std_logic);

end N_BEHAVIOR;

architecture RTL of N_BEHAVIOR is begin

process(SELS,A,B,C,D) begin

if (SELS = "01") then M <= A;

if (SELS = "01") then M <= B;

if (SELS = "10") then M <= C;

else M <= D;

end if;

end if;

end if;

end process;

end RTL;

library IEEE;

use IEEE.std_logic_1164.all;

entity S_BEHAVIOR is port (

SELS : in std_logic_vector(1 downto 0);

A,B,C,D : in std_logic;

M : out std_logic);

end S_BEHAVIOR; architecture RTL of S_BEHAVIOR is

begin

process(SELS,A,B,C,D) begin

if (SELS = "00") then M <= A;

elsif (SELS = "01") then M <= B;

elsif (SELS = "10") then M <= C;

else M <= D;

end if;

end process;

end RTL;

Page 42: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

114

4.2 7segLED デコーダ

ここでの 7segLED デコーダとは、入力信号を所望の 7segLED の表示に変換する働き

を持った回路です。 既に説明した通り、DE0 の 7segLED は、アノードコモン型(右図。

カソードコモン型もあります)で、内部の LED のアノード側が共通になっています。 この

ため、LED を点灯するには、点灯したいセグメントを 0(low)に、それ以外のセグメントを

1(high)にする必要があります。

図 4-2 は、7segLED に、0~9、E、.(ドット)を表示した例です。

このような表示を得るためのデコード回路を設計するためには、入力信号がどのような

仕様かを確認する必要があります(入力信号の仕様によって、回路が変わります)。

例えば、入力信号を BCD コード(4 ビット)で考えてみます。

[BCD(Binary Coded Decimal)]

デジタル回路で 10 進数を扱う場合のコードで、4ビットの 2 進数に分けて表現した

ものです。 例えば、6410を BCD コードで表すと、“0110_0100”となります。

図 4-2 7segLED の表示例

入力信号が BCD コードで図 4-2 のような表示をするための変換テーブルは、表 4-1 のようになります。 ここで、BCD コードの 10~14 は“E”、15 は“.(ドット)”を、表示するものとします。

表 4-1 変換テーブル: BCD コードと’7segLED の表示信号

[(注意)アノードコモン型]

BCD a b c d e f g dot

0 0 0 0 0 0 0 1 1

1 1 0 0 1 1 1 1 1

2 0 0 1 0 0 1 0 1

3 0 0 0 0 1 1 0 1

4 1 0 0 1 1 0 0 1

5 0 1 0 0 1 0 0 1

6 0 1 0 0 0 0 0 1

7 0 0 0 1 1 1 1 1

8 0 0 0 0 0 0 0 1

9 0 0 0 0 1 0 0 1

10~14 1 0 0 1 1 1 1 1

15 1 1 1 1 1 1 1 0

Page 43: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

115

この条件での 7segLED デコーダーの VHDL 記述は、図 4-3 のようになります。

本課題2では、この記述が基本となるので、入出力のビット数、case 文の記述の仕方等を理解して下さい。

なお、BCD_7segLED.vhd は、次の“課題3”で用います。

図 4-3 7segLED デコーダーの記述例: BCD_7segLED.vhd

-- Decoder; from BCD code to 7segLED

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity BCD_7segLED is port(

BCD_in : in std_logic_vector(3 downto 0);

Seg_out : out std_logic_vector(7 downto 0));

end BCD_7segLED;

architecture RTL of BCD_7segLED is

begin

process(BCD_in) begin

case BCD_in is

when "0000" => seg <= "00000011"; -- 0

when "0001" => seg <= "10011111"; -- 1

when "0010" => seg <= "00100101"; -- 2

when "0011" => seg <= "00001101"; -- 3

when "0100" => seg <= "10011001"; -- 4

when "0101" => seg <= "01001001"; -- 5

when "0110" => seg <= "01000001"; -- 6

when "0111" => seg <= "00011111"; -- 7

when "1000" => seg <= "00000001"; -- 8

when "1001" => seg <= "00001001"; -- 9

when "1111" => seg <= "11111110"; -- .(dot)

when others => seg <= "11111111";

end case;

end process;

end RTL;

BCD_7segLED

BCD_in(3..0) seg_out(7..0)

Page 44: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

116

4.3 課題2 『自分の名前を表示させよう』の仕様とVHDL記述

4.3.1 開発仕様 設計する回路は、DE0 上の4個の 7segLED に、1秒毎に左に流れるように、0~9の数字を表示させた後に、

自分の名前をアルファベットで表示させるものです(図 4-4)。

0123456789_I_am_自分の名前

[例えば、“0123456789_I_am_tokuya_fujioka.”と表示します(31文字)。]

図 4-4 課題2 『自分の名前を表示させよう』の出力表示

[開発仕様]

① 入力: クロック信号: システムクロック:50MHzを入力する。

STOP信号: Button0 から入力し、動作の停止/再開をコントロールする。

・停止: ボタン押下時点での表示をそのまま継続する。

・再開: 次のボタン押下で、表示状態から表示を再開する。

リセット信号: Button1 から入力し、即時に初期状態に戻し、“0123”から表示を始める。

② 出力: DE0 の4個の 7seegLED を使って、上記図 4-4 のとおり表示する。 今回の仕様では

“最大 32 文字まで”表示します。 文字数がオーバーする場合は各自で工夫して下さい。

4.3.2 モジュール構成

『自分の名前を表示させよう』のモジュール構成(ブロック図)は、図 4-5 のとおりです。 moji_deco_top : 『自分の名前を表示させよう』の最上位回路(トップモジュール)

peripheral_moji: 入力信号の取り込み処理と動作信号の生成処理を実行(ダウンロードする)

conversion_ascii: peripheral_moji の出力から表示する文字列の ascii コードにデコード

decoder_7seg: ascii コードを 7segLED の表示信号にデコード

図 4-5 課題 2:『自分の名前を表示しよう』のブロック図

上記の文字列が1秒毎に左に流れるように表示される。

CNV0 DEC0 CLK

STOP

RESET

conversion_ascii decoder_7seg

CNV1 DEC1

CNV2 DEC2

CNV3 DEC3

S0(5) A0(7)

S1(5) A1(7)

S2(5) A2(7)

S3(5) A3(7)

LED0

LED1

LED2

LED3

HEX0

HEX1

HEX2

HEX3

PERI

deco0

deco1

deco2

deco3

moji_deco_top peripheral_moji

今回設計する部分

Page 45: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

117

deco0 (5bit) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 … 27 28 29 30 31

文字列 0 1 2 3 4 5 6 7 8 9 _ I _ a m _ … i k a .

asciiコード(10進) 48 49 50 51 52 53 54 55 56 57 95 73 95 65 77 95 … 73 75 65 46 32

【図 4-5 の解説】

図中の PERI、CNV1~3、DEC0~3 は、それぞれのモジュールのインスタンス名です。

入力部分 - CLK には、DE0 から 50MHz(20ns)のクロックが入力されます。 - STOP 信号は、DE0 の BUTTON0 から入力し、停止/再開をトグルします。 - RESET 信号は、DE0 の BUTTON1 から入力し、押下と同時に、全体を初期化します。

peripheral_moji 部分 (提供されたものをダウンロードして使用します)

- 50MHz のクロックを分周し、“1Hz”の分周クロックを生成し、入力数を 5 ビットのカウンターでカウントして、

その値を deco0 から 5 ビットで出力しています。 従って、カウンターの値は、0~31 で変化します。 - deco1 ← deco0 - 1、 deco2 ← deco0 – 2、 deco3 ← deco0 – 3 が代入されて、出力されます。

この結果、deco1、2、3 にはそれぞれ1秒遅れの値が出力されることになり、この基本信号を利用すれば、 HEX0 → HEX3 の方向に向かい文字が流れて行くように表示できます。

- STOP が押下される毎に、表示の動作が“停止 / 開始”をトグルします。 - RESET が押下されると、すべてを初期化し、deco0 に“3”を出力します(→ deco3 が“0”になる)。 - このモジュールは、“http://www.ed.tus.ac.jp/~jte401/”からダウンロードして使ってください。 【重要】 実機では、分周周波数は“1Hz”の仕様ですが、シミュレーション実行時は、シミュレーション時間を

短縮するために、分周周波数を“1MHz(=1us)”に設定して実行します。 従って、 ダウンローとした“peripheral_moji.vhd”の分周周波数は、“1MHz”に設定されています。

conversion_ascii 部分

- deco0 から出力される基本信号は、5 ビットなので 0~31 の数字がトグルします。 この数字の 0 から順番に

表示する文字列:“0123456789_I_am_自分の名前.”を順番に割り当てて、それぞれの文字に対応した

ASCII コードにデコードして、7ビットで出力します。 入力端子名: order(4..0)、 出力端子名: ascii(6..0)

decoder_7seg 部分 - ASCII コードに変換された文字コード(7bit)を入力して、7segLED の入力信号となる表示データ(8bit)に

デコードして出力する。 入力端子名: ascii(6..0)、 出力端子名: seg(7..0)

出力部分

- 7segLED を駆動するために必要な 8bitの信号 (表示する文字列になっている)

(備考) モジュール:conversion_ascii は、peripheral_moji から出力される基本信号を表示する文字列の ascii コードに

変換していますが、基本信号を直接7segLEDの入力信号にデコードすることもできるので、機能的には、このモ

ジュールは不要です。 ただ、シミュレーション実行後の検証をするときに、7segLED の入力信号のビット列を確

かめるのは判り難いので、結果の表示を判り易くするために一度 ASCII の文字コードに変換します。 このよう

な機能の追加や 1Hz→1Mhz のような仕様の変更は、シミュレーションを効率的に実行するために、良く行われ

ます。 他にもいろいろありますので、的確に把握して下さい。

Page 46: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

118

4.3.3 変換テーブルの作成 conversion_ascii と decoder_7seg で用いる文字の変換コードは、表 4-2 のとおりです。

表中の“7segLED 表示”の部分は、図 4-6 でビット列を作成して完成させてください。

表 4-2 英数字記号の ASCII コード表

文字 10 進コード 2 進コード 7segLED 表示

(abcdefg+dt: アノードコモン型)

空白 32 0100000 11111111

.(ドット) 46 0101110 11111110

0 48 0110000

1 49 0110001

2 50 0110010

3 51 0110011

4 52 0110100

5 53 0110101

6 54 0110110

7 55 0110111

8 56 0111000

9 57 0111001

= 61 0111101 11101101

A 65 1000001

B 66 1000010

C 67 1000011

D 68 1000100

E 69 1000101

F 70 1000110

G 71 1000111

H 72 1001000

I 73 1001001

J 74 1001010

K 75 1001011

L 76 1001100

M 77 1001101

N 78 1001110

O 79 1001111

P 80 1010000

Q 81 1010001

R 82 1010010

S 83 1010011

T 84 1010100

U 85 1010101

V 86 1010110

W 87 1010111

X 88 1011000

Y 89 1011001

Z 90 1011010

_ (アンダースコア) 95 1011111 11101111

ビット列(8bit)を記入して下さい

Page 47: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

119

図 4-6(1) 英数字の 7 セグメント LED 表示

図 4-6(2) 英数字の 7 セグメント LED 表示

a b c d e f g 0

0 0 0 0 0 0 1 1

a b c d e f g 0

Page 48: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

120

図 4-6(3) 英数字の 7 セグメント LED 表示

図 4-6(4) 英数字の 7 セグメント LED 表示

a b c d e f g 0

a b c d e f g 0

Page 49: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

121

4.3.4 ModelSim 上で新規プロジェクトの作成 以上で、『自分の名前を表示しよう』を設計するための準備ができたので、VHDL記述をします。 まずは、

ModelSim上の全く新しい環境で設計を行うので、以下の条件で新規プロジェクト:moji_deco を作成します。 “3.1 ModelSim の起動と新規プロジェクトの作成方法”を参考にしてください。 - Project Name: moji_deco - Project Location: Z:/modelsim/moji_deco - Default Library Name: work (← 既定値そのまま)

4.3.5 “conversion_ascii.vhd”のVHDL記述

VHDLエディターは、“3.2 VHDL ファイルの作成”を参考にして、起動してください。 “4.2 7segLED デコーダ”を参考にして、図 4-7 の VHDL 記述を完成させ、ファイル名:conversion_ascii.vhd で 保存して下さい(“Z:/modelsim/moji_deco/conversion_ascii.vhd”で保存されます)。

図 4-7 文字割り当て&ascii コード変換モジュール(conversion_ascii.vhd)

order(4..0) ascii(6..0)

conversion_ascii

-- Module: conversion_ascii for moji_deco

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity conversion_ascii is port(

order :

ascii :

end conversion_ascii;

architecture RTL of conversion_ascii is

begin

process (order) begin

case order is

when -- 0: 0

when -- 1: 1

when -- 2: 2

when

..

..

when others => ascii <= “11111111";

end case;

end process;

end RTL;

Port 文の記述 (入出力端子の詳細を記述して下さい)

case 文の(分岐条件:)when 文をすべて記述して下さい。

(図 4-3 の 7segLED のデコーダを参考) when 文の行数は、 「表示する文字数 + 1 (when others 行)」行 となります。

-- ~ 行末までは、

コメントとなります

Page 50: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

122

4.3.6 “decoder_7seg.vhd”の VHDL 記述 図 4-8 の VHDL 記述を完成させて、ファイル名:decoder_7seg.vhd で保存して下さい。

図 4-8 ascii コード→7segLED デコーダ (decoder_7seg.vhd)

seg(7..0) ascii(6..0)

decoder_7seg

-- Decoder "ascii code" to "7segLED code (anode common)" library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;

entity decoder_7seg is port (

); end decoder_7seg;

architecture RTL of decoder_7seg is begin

process(ascii) begin case ascii is

end process; end RTL;

Port 文の記述 (入出力端子の詳細を記述して下さい)

(図 4-3 の 7segLED のデコーダを参考) case 文の(分岐条件:)when 文を、表 4-2 の変換テーブル中の “2 進コード → 7segLED 表示”に従って、すべて記述して下さい。

[“7segLED 表示”の部分は完成させてください]

when 文の行数は、

・0 ~ 9、A ~ Z、空白、=、.(ドット)、_(アンダースコア); 40 行、 ・when others 行); 1 行

の 41 行となります。

Page 51: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

123

4.3.7 『自分の名前を表示させよう』の最上位回路:moji_deco_top.vhd の VHDL 記述 図 4-5 の最上位回路のブロック図の内容に従って、図 4-9 の VHDL 記述を完成させて下さい。

入力端子名: CLK、STOP、RESET 出力端子名: LED0(8)、LED1(8)、LED2(8)、LED3(8) 内部信号名: S0(5)、S1(5)、S2(5)、S3(5) [← 基本信号]

A0(7)、A1(7)、A2(7)、A3(7) [← ascii コード]

図 4-9 最上位回路の VHDL 記述(moji_deco_top.vhd)

--Top Module

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity moji_deco_top is

port(

);

end moji_deco_top;

architecture RTL of moji_deco_top is

component peripheral_moji

port ( clk, reset, stop : in std_logic;

deco0, deco1, deco2, deco3 : out std_logic_vector(4 downto 0));

end component;

component decoder_7seg

port ( ascii : in std_logic_vector(6 downto 0);

seg : out std_logic_vector(7 downto 0));

end component;

signal S0, S1, S2, S3 : std_logic_vector(4 downto 0);

signal A0, A1, A2, A3 : std_logic_vector(6 downto 0);

begin

PERI: peripheral_moji port map ( clk,reset,stop,S0,S1,S2,S3 );

CNV0: conversion_ascii port map ( S0, A0 );

CNV1: conversion_ascii port map ( S1, A1 );

CNV2: conversion_ascii port map ( S2, A2 );

CNV3: conversion_ascii port map ( S3, A3 );

DCD0: decoder_7seg port map ( A0, LED0 );

DCD1: decoder_7seg port map ( A1, LED1 );

DCD2: decoder_7seg port map ( A2, LED2 );

DCD3: decoder_7seg port map ( A3, LED3 );

end RTL;

CLK LED0(7..0)

moji_deco_top

STOP

RESET

LED1(7..0)

LED2(7..0)

LED3(7..0)

Port 文の記述 (上記外形図を参照)

conversion_ascii の componet 文を記述 (conversion_ascii.vhd の entity 宣言を参照)

全ての内部信号の signal 文を記述言を

各インスタンス間の接続を記述 (図 4-5 のブロック図を参照)

Page 52: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

124

4.3.8 テストベンチのVHDL記述

これまで実習してきたように、シミュレーションには次の2つの実行方法があります。

[実行方法1] 最上位回路:moji_deco_top を選択して、入力パターンを波形エディタの機能 (「Modify」 →

「Apply Wave」…)を使って設定し(“3.5(2) 入力波形の設定”参照)、実行する。

[実行方法2] 最上位回路:moji_deco_top のテストベンチを記述して、実行する (← 推奨)

moji_deco_top の入力信号は、CLK、STOP、RESET です。 CLK にはシステムクロック信号(50MHz)を入力し、

STOP と RESET は任意の時間に入力して、所望の仕様通りに動作するかを確認します。 例えば、以下の波形を

入力してシミュレーションを実行し、正しく動作するかどうかを検証します。

[注意] STOP も RESET もボタンスイッチから入力されるので、以下のような入力波形になります

[RESET 信号] [STOP 信号]

以上の条件からテストベンチを記述すると、図 4-10 のようになります。

図 4-10 moji_deco_top のテストベンチ: moji_deco_top_tb.vhd

--Testbench for module: moji_deco_top

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity moji_deco_top_tb is

end moji_deco_top_tb;

architecture SIM of moji_deco_top_tb is

component moji_deco_top port( CLK, STOP, RESET: in std_logic;

LED0,LED1,LED2,LED3 : out std_logic_vector (7 downto 0));

end component;

signal CLK: std_logic := '0' ;

signal STOP, RESET: std_logic := '1' ;

signal LED0, LED1, LED2, LED3 : std_logic_vector (7 downto 0);

constant STEP: time := 20 ns ;

begin

U0: moji_deco_top port map(clk, reset, stop, LED0, LED1, LED2, LED3 );

process begin

clk <= '0'; wait for STEP/2; clk <= '1'; wait for STEP/2;

end process;

process begin

wait for 10.3 us ; RESET <= '0'; wait for 4.5 us ; RESET <= '1';

wait for 30.7 us ; STOP <= '0'; wait for 2.0 us ; STOP <= '1';

wait for 8.2 us ; STOP <= '0'; wait for 3.8 us ; STOP <= '1';

wait for 20.5 us ;

assert false severity failure;

end process;

end SIM;

configuration cfg_moji_deco_top_tb of moji_deco_top_tb is

for SIM

end for;

end cfg_moji_deco_top_tb;

80 us

10.3 us

4.5 us

80 us

45.5 us

2 us

20.5 us

3.8 us

8.2 us

port 文のない entity 文(enntity 名: moji_deco_top_tb

moji_deco_top の component 宣言

全ての入出力端子 の signal 文 CLK,STOP,RESET は、初期値を

設定しています

moji_deco_top のインスタンス:U0

CLK(50MHz)の設定

RESET と STOP の設定

合計 80us でシミュレーションの実行を強制終了

Configuration 文の定型的記述 -コンフィグレーション名: cfg_moji_deco_top_tb -エンティティ名: moji_deco_top_tb -アークテクチャ名: SIM

Page 53: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

125

4.4 “moji_deco_top.vhd”のシミュレーション実行

4.4.1 VHDL 記述のコンパイル

以上の作業を行うと、プロジェクトのディッレクトリ:Z:/modelsim/mojid_deco/の下に、図 4-11 のように、

作成した 4 つの VHDL ファイル(conversion_ascii.vhd、decoder_7seg.vhd、moji_deco_top.vhd、moji_deco_top_tb.vhd)と

http://www.ed.tus.ac.jp/~jte401/からダウンロードした peripheral_moji.vhd の合計5つの VHDL ファイルが保存され

ています。

図 4-11 保存されている VHDL ファイル一覧

これらのファイルを手順通りにプロジェクトメンバーに追加して(“3.3 プロジェクトメンバーの管理”参照)、

コンパイルを実行すると、図 4-12 のように、各メンバーの Status が となります。

このコンパイルが正常に終了しないと次に進めないので、コンパイル時に出力されるエラーメッセージをよく読んで

(しっかり読むとエラーの内容が判ります)、丁寧に修正作業を行って下さい。 殆どのエラーは、入力ミスによるもの

なので、メッセージが出力された行の付近をよく見ると、入力ミスを見つけられます。 エラーがなくなるまで、根気強

く調べて下さい。

図 4-12 プロジェクトメンバーが正常にコンパイルされた状態

Page 54: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

126

4.4.2 シミュレーション・モードの起動

コンパイルが正常に終了した後、“Library”画面で、+work を展開すると、図 4-13 のように、

シミュレーションの実行モジュール: が作られているので、これをクリックして、

シミュレーションを実行します。 図 4-14 がシミュレーションモード起動直後の画面です。

図 4-13 シミュレーション・モードの起動: “テストベンチ”モジュールを選択

図 4-14 シミュレーション・モード起動直後の画面

cfg_moji_deco_top_tb をダブルクリックすると シミュレーション・モードに移ります(起動します)。 なお、「Simulate」 → 「Start Simulation」と選択しても、

シミュレーションモードに移れます。

Page 55: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

127

4.4.3 シミュレーションの準備: 実行結果を表示したい信号名の選択

図 4-14 のように、シミュレーション・モード起動直後の波形エディタには

まだ信号が登録されていないので、“Objects”画面の“Name”一覧から信号を

選択して、波形エディタにドラッグしますが、起動直後は、右のような名前が

一覧されているだけです。 これは、テストベンチ: moji_deco_top_tb の signal 文

で宣言されている信号名がリストアップされたものです。

結果を見たい信号が階層下のモジュールにある場合は、以下ように処理して、

波形エディタに追加します。

図 4-15 のように、+moji_deco_top_tb を展開すると、

U0(テストベンチ内の moji_deco_top のインスタンス名)が表示されるので、

クリックすると、“Objects”画面の表示が右のようになり、U0:moji_deco_top で宣言されている全ての入出力端子名や

ネット名がリストされます(このリストには、moji_deco_to_tb のすべての信号名を含むので、この部分を波形エディタに

ドラッグすると良いですね)。

図 4-15 インスタンス名を選択して信号名を“Objects”画面に表示

さらに、図4-16 のように、インスタンス:U0 下のインスタンス名PERI:periphera_moji、インスタンス:PERI 下のインスタ

ンス名 CNTR:counter(モジュール:peripheral_moji の内部モジュール)を選択していくとそれぞれの信号名がリストさ

れるので、シミュレーション結果を見たい信号を波形エディタにドラッグすると結果の解析がしやすくなります。

図 4-16 階層内の結果表示したい信号を選択

インスタンス名:U0 をダブルクリックすると、 テストデバイス:moji_deco_top 内の全ての 信号名が表示されます。

Page 56: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

128

上記のような信号の選択を行って、波形エディタで並べ替えを行うと、図 4-17 のような画面になります。

なお、この中に選択されている信号名: count、clk_sig、counter0(5)は、ダウンロードした peripheral_moji 内で使われ

ている信号名で、以下の内容です。

count (integer 型): システムクロック(50MHz)を数える信号。 Sim 時は、0 → 24(トグル)と変化。

clk_sig (std_logic 型): Sim 時は、1MHz に分周したクロック信号。

counter0 (std_logic_vector(4 downto 0)): deco0(5)に出力する基本信号。 0 → 31(トグル)と変化。

図 4-17 信号選択を行ったシミュレーション実行前の波形エディタ

4.4.4 シミュレーションの実行

以上の準備をして、「Simulate」 → 「Run」 → 「Run All」と選択して(図3-32 参照)、シミュレーションを実行します。

“assert false severity failure;”が機能して、シミュレーションを 80us 実行した後に、強制終了します。

図 4-18 は、シミュレーション実行後の波形エディタ-で全体を表示した画面です。 80us まで実行されています。

図 4-18 シミュレーション実行後の全体表示画面

Page 57: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

129

4.4.5 シミュレーション結果の検証

波形エディタでバス信号を表示する場合、表示の基数(radix)を変更できるので(図3-26参照)、信号毎に適切な基

数に変更すると見やすくなります。 「Radix」 → 「.. Decimal / Unsigned / Hexadecimal / Ascii ..」で選択します。

count、counter(5)、S0~S3: 「Unsigned」を選択すると、10 進数表示になります。

A0(6) ~ A3(6): asci コードが出力されているので、「Ascii」を選択します。 設計が正しく行われていると、

この信号に、表示したい文字列が(Sim なので)“1us”ずつずれて出力されます。 このように、

シミュレーション結果の確認をしやするのが、conversion_ascii モジュールを挿入した目的です。

① clk_sig の確認: 1Mhz のクロック信号になっているか? (Sim 時)

実機では 1 秒毎に文字が移動する仕様ですが、効率的にシミュレーションするために、周期を 1us に変更してい

るので、それが正しく動作しているかを確認します。 このシミュレーションが正しければ、実機で1s に変更すれば

よいということになります。 図 4-19 のように、clk(周期:20ns)をカウントして、count が 0→24 と変化し、その周期

に合わせて、clk_sig が 20x25=500us 周期で“10”をトグルしているので、正しく 1Mhz のクロックになっています。

図 4-19 clk_sig 信号の確認

② RESET 動作の確認: リセット機能が正しく動作しているか?

図 4-20 のように、10.3us でリセットが“ON”になり、次の clk_sig の立ち上がりエッジで初期化されます。

14.8us でリセットが“OFF”され(4.5us の間、リセットが掛かっている)、次の clk_sig の立ち上がりエッジから再び

counter0(5)がカウントアップされています。 すなわち、reset が正しく動作しています。 なお、初期化された時、

4 つの 7segLED は、“0123”と表示されていることに注意して下さい。

図 4-20 RESET 信号の確認

Page 58: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

130

③ STOP 信号の確認: 停止/再開機能が正しく動作しているか?

図 4-21 のように、45.5us(幅 2us)で最初の STOP 信号が入力されて“停止”状態となり、55.7us で次の STOP 信

号が入力されるので、動作が“再開”しています。 よって、STOP が正しく動作しています。

図 4-21 STOP 信号の確認

さらに、各文字に対して、正しく 7segLED 用の信号にデコードされているかを確認してください。

以上で、課題2:『自分の名前を表示させよう』のModelSimを使ったシミュレーションでの機能確認、すなわち、所望の

機能を満たした設計は完了しました。 次は、設計し機能確認した VHDL 記述を QuartusⅡに移して、実機:DE0 で正しく

動作するかを確認します。

Page 59: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

131

4.5 課題2:『自分の名前を表示させよう』の実機評価

4.5.1 QuartusⅡの新規プロジェクトの作成と VHDL 記述の取り込み

ModelSim 上で設計した『自分の名前を表示させよう』の VHDL ソースを QuartusⅡに移して、実機評価するために

以下の内容で、新規プロジェクトを作成します(“1.2 QuartusⅡでの新規プロジェクトの作成方法”参照)。

- 作業用ディレクトリ: Z:/quartus2_work/moji_deco_DE0

- プロジェクト名: moji_deco_DE0

- TOP 階層名: moji_deco_DE0

- [Package] FBGA [Pin count] 484 [Speed grade] 6 ⇒ EP3C16F484C6 を選択

以上のように新規プロジェクト:moji_deco_DE0 を作成した後、ModelSimで作成したVHDL記述をこのプロジェク

ト下に取り込みます。 VHDL 記述はテキストファイルなので、“2.3 VHDL ファイルの作成”を参考にして、 moji_deco_top.vhd、 conversion_ascii.vhd、 decoder_7seg.vhd、 peripheral_moji.vhd

の 4 つの VHDL ファイルを取り込み、同じ名前で保存して下さい。

4.5.2 シミュレーション回路から実機評価回路への変更

シミュレーション時に指摘した通り、シミュレーションを効率的に実行するために、本来の仕様を少し変更している

ので、それらを元の仕様に戻す必要があります。 ここでは、最もシンプルな変更として、次の 2 つを実施します。

(1)チャタリング防止回路の挿入

[チャタリング現象]

チャタリングは、スイッチを入れたり切ったりするときに発生する現象です(図 4-22)。 家庭用の電灯の スイッチ等では、チャタリングを意識することはありませんが、高速で動作するハードウェアでは非常に 重要な現象です。 スイッチを ON/OFF すると、スイッチの接点の汚れや接点の振動などにより、非常に 短い時間ですが、ON と OFF が図のように繰り返される現象が発生します。 これが、“チャタリング”と 言われる現象です。 チャタリングが発生する時間は非常に短く、通常数 ms から、長くても 30ms 程度と 言われています。 従って、家庭用の電灯の ON/OFF ではこのような瞬間的な ON/OFF は無視できますが、 数 ns 周期で動作するデジタル回路では、この時間は非常に長く、無視できません。 例えば、スイッチの 押下回数を数えるデジル回路でチャタリングが発生すると、1 回のスイッチ操作にもかかわらず、複数回の 押下があったと判断して、誤動作の原因になります。 従って、通常のデジタル回路では、チャタリング現象 に影響を受けないように、入力信号にチャタリング防止回路を挿入して、誤動作を防いでいます。

図 4-22 スイッチのチャタリング現象

Page 60: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

132

CLK

STOP

RESET

LED0

LED1

LED2

LED3

HEX0

HEX1

HEX2

HEX3

moji_deco_DE0

clk LED0(7..0)

I3: moji_deco_top

stop

reset

LED1(7..0)

LED2(7..0)

LED3(7..0)

clk

I1: chattering

SW_in SW_out

clk

I2: chattering

SW_in SW_out

chat_STP

chat_RST

[チャタリング防止回路: chattering.vhd ]

図 4-23 のようなチャタリング防止回路(モジュール)を準備しているので、http://www.ed.tus.ac.jp/~jte401/ から

ダウンロードして使ってください。

図 4-23 チャタリング防止回路の機能

[実機評価用最上位回路: moji_deco_DE0.vhd ]

実機に実装する回路では、チャタリング現象を考慮する必要があるので、図 4-24 のように、入力信号:STOP と

RESET にチャタリング防止回路( chattering.vhd )を挿入して、入力信号を整形してから、シミュレーション時の最

上位回路( moji_deco_top.vhd )に入力します。 これにより、moji_deco_top の入力端子: stop と reset には、 シミ

ュレーション時と同様に、チャタリングを含まない正常な信号が入力されます。

図 4-24 実機評価用最上位回路(moji_deco_DE0)のブロック図

図 4-25 の実機評価用最上位回路: moji_deco_DE0.vhd を、以下の情報を使って完成させ、保存して下さい。

(chattering.vhd の entity 文)

entity chattering is port ( clk, SW_in : in std_logic;

SW_out : out std_logic );

end chattering;

(チャタリング除去された信号名)

STOP信号 ⇒ chat_STP、 RESET 信号 ⇒ chat_RST [ ← 任意の名前で OK ]

[moji_deco_DE0.vhd中のsignal文]

signal chat_RST, chat_STP : std_logic;

clk

chattering

SW_in SW_out

50Mhz(システムクロック)

チャタリング発生信号 チャタリング除去信号

Page 61: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

133

図 4-25 実機評価用最上位回路: moji_deco_DE0 の VHDL 記述

(2)分周周波数の変更

シミュレーション時は、分周周波数を“1MHz (=1us)”にしてありましたが、実機では、“1Hz (=1s)”に変更する必要が

あります。 そのためには、QuartusⅡに持ち込んだ“peripheral_moji.vhd”の一部を修正する必要があります。

図 4-26 のように、peripheral_moji.vhd の 22 行目に“CYCLE”という定数が宣言されているので、この値を変更します。

“1MHz (=1us)”の時は、500ns [= 20ns x 25 ]毎に“01”がトグルするように、”25“に設定してあります。

“1Hz (=1s)”にするので、500ms [= 20ns x ? ]毎にトグルするように、正しい値に変更して下さい。

図 4-26 peripheral_moji.vhd の変更箇所

-- Top mojule for DE0 library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all;

entity moji_deco_DE0 is port( CLK, RESET, STOP : in std_logic; LED0,LED1,LED2,LED3 : out std_logic_vector (7 downto 0)); end moji_deco_DE0;

architecture RTL of moji_deco_DE0 is component chattering port ( clk, SW_in : in std_logic; SW_out : out std_logic ); end component; component moji_deco_top port ( CLK, RESET, STOP : in std_logic; LED0,LED1,LED2,LED3 : out std_logic_vector(7 downto 0)); end component;

signal chat_RST, chat_STP : std_logic;

begin

CHAT_R: chattering port map (CLK, RESET, chat_RST); CHAT_S: chattering port map (CLK, STOP, chat_STP); MJDECO: moji_deco_top port map (CLK, chat_RST, chat_STP, LED0, LED1, LED2, LED3);

end RTL;

component 文を記述 - チャタリング防止回路: chattering.vhd - シミュレーション用最上位回路: moji_deco_top.vhd

回路を記述: コンポーネント宣言したモジュールをインスタンスして、接続

signal 文を記述

Sim 時は、“25”に設定されているので、

500ms で“0”と”1”がトグルするように

計算して、正しい値を設定して下さい、

Page 62: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

134

4.5.3 ファイルとプロジェクトメンバーの確認

以上の作業を行うと、図 4-27 のように、プロジェクトディレクトリ: …/moji_deco_DE0 の下に、以下の 6 つの

ファイルができています(左図)。 これが大元なので、正しくできていることを確認してください。

またこの時、“Project Navigator”画面の“Files”タグにプロジェクトメンバーがリストアップされています(右図)。

もし、ここに、同じ 6 つのモジュールが登録されていない場合は、“図 2-25 プロジェクトメンバーの管理の方法”を参

考にして、正しいメンバーリストにしてください(ここが正しくないと、後の処理がうまく動作しません)。

図 4-27 登録されてファイル名(左)とプロジェクトメンバー

4.5.4 コンパイル

QuartusⅡのコンパイルは、必ずトップ回路を指定します。 今回は、moji_deco_DE0.vhd をトップレベルにして

コンパイルするので、“2.9 VHDL のコンパル”のように、(moji_deco_DE0.vhd を編集状態にして、)

「Project」 → 「Set as Top-Level Entity」、もしくは、“ ctrl + shift + j ”で、トップレベル回路に設定します。

この後、「Processing」 → 「Start Compilation」でコンパイルを実行します。 出力メッセージに致命的エラー(メッセー

ジ画面に赤字で表示される)がないことを確認してください。 もし、ある場合は、内容をよく読んで、指摘の箇所を修

正して、再度コンパイルして下さい。 殆どの場合、単なる入力ミスなので、よく内容を確かめれば必ず修正できます。

コンパイルが正常終了しなければ次に進めませんので、しっかりデバッグして下さい。

4.5.5 端子割り当て

moji_deco_DE0.vhd のコンパイルが終わった

ら、「Assignments」 → 「Pin Planner」を開いて、

端子割り当てを行います。 ピン割り当て表ファイ

ル: pin_moji_deco.xlsx は、指定された場所か

らダウンロードします。 ピン配置をコピーして、

(“All Pins”の)”Location“に貼り付けてください

(図 4-28)。 【重要】 Pin Plannerのピン並びとピン割り当て

表ファイルのピン並びが一致しているかを確認し

て、正しく割り当てを行ってください。

[プロジェクトで一度端子割り当てを行うと、 その割り当てが保存されます(勿論、修正は 可能です)]

図 4-28 “Location”への端子(ピン)割り当て

pin_moji_deco.xlsx のピン名を、Location 欄すべて(35 行) を選択してから、「Edit」→「Paste」で割り当てる

Page 63: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

135

4.5.6 端子割り当て後に再コンパイル 端子割り当てを行った後、(moji_deco_DE0.vhd をとトップレベルにして、)再コンパイルします。 その結果、

FPGA の端子信号と評価ボード上の部品(ボタンスイッチ、7segLED 等)が接続され、実機評価モジュール (コンフィグレーション・データ/ファイル、実機モジュール等と呼びます)が作成されます。

4.5.7 実機:DE0 での動作確認

メニューバーから、「Tools」→「Programmer」を選択して、“Programmer”画面を起動します(図 4-29)。

(コンフィグレーション・ファイルの表示方法)

“Add Fil..”をクリックすると以下の画面がポップアップするので、“output_files”をクリックして、

コンフィグレーション・ファイル: moji_deco_DE0.sof を選択します。

図 4-29 起動直後の“Programmer”画面

この部分に、コンフィグレーション・ファイルが表示されていない場合は、 “Add File…”を選択して、下記のように、コンフィグレーション・ファイルを 表示させます。

「JTAG」を選択

“USB Blaster [USB..0]”をとなっていることを確認 “No Hardware”となっている場合は、「Hardware Setup」を

クリックして、“USB Blaster [USB..0]”を設定する。

Page 64: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

136

上記の操作により、“Programmer”画面は、図 4-30 のようになり、「Start」を選択すると、コンフィグレーション・ ファイルのダウンロードが始まり、“Progress”が“100%”になれば、ダウンロードは完了です。

図 4-30 コンフィグレーション・ファイルのダウンロードが完了した画面

ダウンロードが終了したら、DE0 上で設計したプログラムが動作しているので(図 4-31)、所望通りに機能が

実現されているどうかを確認してください。

図 4-31 DE0 で動作確認

コンフィグレーション・ファイルが表示されている。 “Program/Configure”にチェックする。

“100%”になれば、 ダウンロードは完了です。

0123456789_I_am_自分の名前.

Button_0: 動作の停止/再開

Button_1: リセット

Page 65: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

137

【参考資料1】 “端子割り当て”について コンパイル時にエラーメッセージが出なかったにも拘わらず、DE0 の LED 表示がおかしいというような場合があり

ますが、この場合は、以下の原因が考えるので、確認をしてください。

(1) すべての 7segLED の表示がおかしい場合: 端子の割り当て(ピン配置)がずれているかも?

“All Pins”の“Node Namd”とダウンロードした“pin_moji_deco.xlsx”のピン名が一致していることを確認する。 正しい場合は、“Node Name”と”Location“が一致しているかどうかを確認する。 間違っている場合は、 図 4-32 のように、正しく割り当てられるように操作して下さい。

図 4-32 端子割り当ての確認内容

(2)個々の表示文字が正しくない場合

Decoder_7seg や conversion_ascii でのデコードが間違っているので、内容を確認して修正する。

【参考資料2】 エラーメッセージの解析

メッセージ画面には、多くのメッセージが表示(出力)されますが、対応する必要があるのは、fatal エラーで、赤色

で出力されるエラーメッセージ(図 4-33)です。 Fatal エラーが表示されたら、まずはその英文を読んで内容を確認し

て下さい。 簡単な英文なので、読めば理解できます。 出力された最初のエラーメッセージから対応していきます。

図 4-33 Fatal エラーメッセージを確認

“Node Name”と“Location”の対応が “pin_moji_deco.xlsx”の対応と一致するように、 割り当てる(ソート機能等を使用する)

モジュール: count_ex_miss.vhd の 12 行目の“)”付近で文法エラーがあるということなので、 この行の付近の文法エラーなる原因を探します(文字の入力ミスや抜けが多い)。

Page 66: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

138

5. 課題3: 『1分時計』 の設計

5.1 順序回路の設計 順序回路とは、現在の入力と過去の入力から回路の状態が決まる回路です。 過去の入力とは、記憶回路に記憶

された値なので、順序回路は組み合わせ回路と記憶回路から構成される回路となります。 記憶回路とは、一般にフ

リップフロップ(FF、レジスタとも呼ばれる)やラッチを指し、FF 自身も順序回路です。 一般的に、記憶回路には、動作する(データを記憶して出力する)タイミングを取るための「クロック信号」が入力さ

れます(クロック信号は、“0”と“1”がトグルするパルス波形です)。 クロック信号に同期させる場合は、一般にクロッ

クの“立ち上がりエッジ”もしくは“立ち下がりエッジ”に合わせてタイミングを取ります。 このタイミングの取り方を

VHDL で記述するには、IF 文の条件に、event 文を使用します。 [VHDL の仕様] if 文、event 文

〇 if文 (“4.1 デコード回路の設計”で説明) if 文は、process 文中に記述し、以下の記述となります(“elsif”のスペルに注意[elseif ではない])。 条件式に基づいて、処理文の実行の可否が選択されます。 条件式が“真”であれば、thenに続く順次処理文が

実行され、“偽”であれば、elsif もしくは else に続く順次処理文が実行されます。 従って、条件式は、boolean 型

でなければいけません。 条件式は上から順番に判断されるため、順次処理文に優先順位が付きます。 〇 event 文

event 文は、同期式順序回路において状態遷移を起因パルス信号の立ち上がり/立ち下がりエッジで実行する

かどうかの指定するための記述であり、次のように記述します。 (条件式は、カッコで囲わなくてもよい)

(記述例) if ( clk’event and clk=’1’) then ・・・ : 信号:clkの立ち上がりエッジで、then 以下を処理する

if clk’event and clk=’0’ then ・・・ : 信号:clkの立ち下がりエッジで、then 以下を処理する

(使用例) 図 5-1 に示した信号の時間変化を記述したものをタイムチャートと呼びます。 図中の使用例では、 信号:clk の立ち上がりエッジ[ if (clk’event and clk=’1’ ) ]のみで、din の状態値を dout に出力するので [ then dout <= din ]、dout の状態値は、clk の周期の間、din の状態値が保持(ラッチ)されます。 従って、dout は、図のように、clk に同期した信号になります。

図 5-1 同期のタイミングチャート

if (信号’event and 信号 = ‘1’) then ・・・

elsif ・・・ else ・・・

end if;

if 条件式 then 順次処理文

[ elsif 条件式 then 順次処理文 ]

[ else 順次処理文 ]

end if;

clk

din

dout

If ( clk’event and clk =’1’ ) then dout <= din;

end if;

clk の立ち上がりエッジ時のみで,dinの値

を dout に出力するので、doutの値は clk の 周期の間、保持(ラッチ)されます。

Page 67: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

139

(設計事例) D-FF の VHDL 記述

D-FF は、クロックの立ち上がり(立ち下がり)時の D を出力します。 この動作は、process 文(“4.1”参照)を使

って動作をそのまま表現すれば、簡単に記述できます。 回路(図)を意識せずに設計できるところが VHDL の

利点です。 一般に、D-FF にはリセット機能が付加されます。 これは、強制リセットのために、クロックに非同

期で働きます。 つまり、リセットがオンとなればクロックに関係なく即座に出力が 0 となります。

図 5-2 リセット付き D-FF

図 5-2 に示した D-FF の動作を VHDL で記述すると、process 文と if 文を用いて、次のようになります。

(コメント) リセット信号:rst は、クロック信号:clk と非同期に動作するので、if 文でリセットの動作を clk と別に

記述します。 このように記述することにより、rst に変化があったときに、直ちに動作します。 上図の場合、リセットは負論理で動作するので、if 文の条件には rst = '0'と記述しています。

(補足説明) セットアップタイムとホールドタイム

D-FF はクロックに同期した設計が行われるので、クロックの立ち上がり前後で入力 D が変化してはいけない

時間帯がありますにおいて(同期設計される他の素子も同様です)。 一般的に、クロックの立ち上がり前をセッ

トアップタイム、立ち上がり後をホールドタイムと呼びます(図 5-3)。 この時間帯で D が変化した場台、メタ・ス

テーブル(meta-stable)と呼ばれる出力 Q の値が保証されない不定な状態に陥ってしまいます。

図 5-3 セットアップタイムとホールドタイム

D Q

clk

rstリセット

clk

rst

D

Q

クロック

セットアップタイム

データ

ホールドタイム

process (clk, rst) begin if (rst = '0') then Q <= '0';

elsif ( clk 'event and clk = '1') then Q <= D; end if:

end process:

Page 68: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

140

[D-FFのVHDL記述]

図 5-2 の D-FF の VHDL 記述は、図 5-4 のようになります。 上記の process 文をモジュールに仕上げただけ

ですが、内容を確認しておきましょう。

図 5-4 D-FF のVHDL記述(D-FF.vhd)

library IEEE ;

use IEEE. std_logic_1164. all ;

entity D_FF is

port( clk, rst, D : in std_logic;

Q : out std_logic);

end D_FF;

architecture RTL of D_FF is

begin

process(clk, rst) begin

if( rst = '0') then Q <= '0';

elsif( clk' event and clk = '1' ) then Q <= D;

end if;

end process;

end RTL;

Page 69: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

141

5.2 カウンターの設計

同期回路の基本となる D-FF を複数個組み合わせることで様々な機能を持った順序回路を設計できます。 ここでは、そのうちの1つである“カウンター”の設計について説明します。 カウンターとは、その名の通り、数をカウ

ントする機能を持った回路です。 時計の動作は、このカウンタが基本となっています。 ここで扱うカウンタは同期型

とするので、カウンタの動作は process 文を用いて、同期記述部の中に記述します。 カウンタ動作の例として、1ず

つカウントアップする式は、次のように書き表せます。 この式では、信号 A に A を代入しています。 A <= A + ‘1 ‘;

既に述べたように VHDL 記述では出力信号を入力として再利用することは禁止しているので、この式で使われてい

る A は、内部信号でなければいけません。 次に、カウントする値の上限を決めなければいけません。 これは、どこ

までカウントするかによって、データのビット数が決まるからです。 カウンタの代表的な例として、10 進カウンタが挙

げられます。 これは、0~9 までカウントし、9 までカウントしたらリセットしてまた 0 からカウントし直します。 カウン

タの上限値が 9 なのでデータのビット数は、4bit となります。 カウントの上限値を変更することで様々なカウンタを設

計することが出来ます。 図 5-5 は、4ビットカウンター: counter_4bit.vhd の記述例です。 単純に counter(3..0)に+’1’しているだけなので、

counter の値は、“1111”(=15) → “0000”(=0)に戻ります。 図 5-6 は、couunter_4vit.vhd のテストベンチのシミュ

レーション結果です。 正しく動作していることが判ります。

図 5-5 4 ビットカウンターの記述例: counter_4bit.vhd

図 5-6 counter_4bit.vhd のシミュレーション結果

--4bit Counter

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity counter_4bit is

port( CLK, RST: in std_logic;

count: out std_logic_vector(3 downto 0));

end counter_4bit;

architecture RTL of counter_4bit is

signal counter: std_logic_vector(3 downto 0);

begin

process ( CLK, RST ) begin

if ( RST = '1' ) then counter <= "0000";

elsif ( CLK'event and CLK = '1') then

counter <= counter + "0001";

end if;

end process;

count <= counter;

end RTL;

出力信号を入力として記述できないの

で、内部信号:counter でカウントする

内部信号を出力に代入する。

Page 70: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

142

5.3 課題3: 『1分時計』の仕様と VHDL 記述

5.3.1 ModelSim 上で新規プロジェクトの作成 『1分時計』の個々のモジュールのシミュレーションを実行するために、以下の条件で、ModelSim上に新しい

プロジェクト:one_minute を作成します(“3.1 ModelSim の起動と新規プロジェクトの作成方法”を参照)。 - Project Name: one_min_clock - Project Location: Z:/modelsim/ one_min_clock - Default Library Name: work (← 既定値そのまま)

5.3.2 開発仕様 システムクロックを分周して、DE0 の4個の 7segLED に、1/100 秒単位で 60 秒を表示する「1 分時計」を設計する

(図 5-7)。 (HEX3) (HEX2) (HEX1) (HEX0)

図 5-7 「1 分時計」の表示

[開発仕様] ① 入力: クロック信号: システムクロック:50MHz(=20ns/周期)を入力

リセット信号: Button2 から入力し、即時に“00.00”を表示する(非同期設計)

② 出力: 図 5-7 のとおり、4 個の 7segLED を使って、

HEX3:10 秒の桁、 HEX2:1 秒の桁、 HEX1:1/10 秒の桁、 HEX0:1/100 秒の桁

を表示し、“00.00”から“60.00”秒までを繰り返します。 なお、HEX2 は、ドットを表示させる。

5.3.3 モジュール構成

DE0 上に実現する『1分時計』: one_min_clock_top.vhd のブロック図は、図 5-8 のとおりです。

入力のシステムクロック:50MHz(=20ns/周期))を分周し、100Hz(=10ms/周期)の基準信号を生成して、 順次 10 進カウンタと 6 進カウンタで数え上げて、それぞれの桁の数字(BCD コードで出力)を表示する構成になって

います。 なお、1秒の桁の 7segLED は、ドットを表示させます。

図 5-8 課題 3:『1分時計』(one_min_clock_top.vhd)のブロック図

clk

reset

LED0

LED1

LED2

LED3

HEX0

HEX1

HEX2

HEX3

one_min_clock_top

[チャタリング防止回路]

chattering

chat_rst

clk_10ms

clk_100ms

BCD_7segLED

[分周回路]

Div_10ms

bcd seg

bcd seg

bcd seg

bcd seg

clk clk_div clk_sig

reset bcd

up_sig 10 進

カウンタ

clk_sig

reset bcd

up_sig 10 進

カウンタ

clk_sig

reset bcd

up_sig 10 進

カウンタ

clk_sig

reset bcd

up_sig 6 進

カウンタ

clk_1s

clk_10s

bcd0_sig

bcd1_sig

bcd2sig

bcd3_sig

Page 71: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

143

【図 5-8 の解説】 図中には、モジュール名を記載していますが、インスタンス名は記載していないので、各自適切に決めてください。 なお、内部信号名は、chat_rst、clk_10ms、clk_100ms、clk_1s、clk_10s、bcd0/1/2/3_sig としていますが、判別し

やすいように適当に付与しただけなので、各自で任意に付与しても問題ありません。 チャタリング防止回路 chattering.vhd

課題2で使った回路と同じものを使用するので、所定の場所からダウンロードしてください(既にダウンロードし

てあるので、それを使っても良いです)。 分周回路 Div_10ms.vhd

カウンタ-を使って、基準信号となる 100Hz のクロック波形(Duty:50%)を分周します。 図 5-5 のカウンターの記述例を参考にして、新規に作成します。

- INPUT: clk(50MHz のクロック、 - OUTPUT: clk_div(100Hz のクロック) (機能) 入力信号のクロックの数を数えて、所望の周期になるようなクロックを生成する。

(記述例) 例えば、周期:20ns のクロックが 5 回入力される毎に“1”と“0”をトグルするような信号を

出力すると周期:20nsx5=100ns ⇒ 周期:200ns(=5MHz)のクロックが生成されます。 これを、VHDL で記述すると、architecture 文は以下のようになります(図 5-9)。

図 5-9 分周回路の architecture 文の記述例 [VHDL仕様] 整数型の宣言

上記の、“ signal counter : integer range 0 to 500000 :=1; ”は、内部変数:counter を“integer(整数型)”

として宣言する場合に用います(下の行で、clk_sig を“std_logic”と宣言しているのと同等です)。

“ range 0 to 500000 ”は、変数の値域を宣言しています(“std_logic_vector”の“(3 downto 0)” と同じで

す)。 この宣言は省略可能ですが、省略した場合は“32 ビット”の変数として扱われます。

“ :=1 ”は、初期値の設定です(counter の初期意を1に設定ています)。 ここでは、変数が整数型なので、

“ :=1 ”となっていますが、std_logic の場合は、その下の行のように、“ :=’1’ ”のようにビット表現になります。

多ビットの場合は、” :=”0001” ”のようになります。

architecture RTL of Div_10ms is

signal counter : integer range 0 to 500000 :=1;

signal clk_sig : std_logic :='1';

begin

process (clk) begin

if (clk'event and clk='1') then

if (counter >= 5) then

clk_sig <= not clk_sig;

counter <= 1;

else counter <= counter + 1;

end if;

end if;

end process;

clk_div <= clk_sig;

end RTL;

counter が“5 以上”になるまでは、“+1”ずつカウントアップする。

counter の値が“5 以上”になったら、clk_sig を

反転して、counter の値を初期化する。

下記参照

clk の立ち上がりエッジで、then を実行する。

内部変数:clk_sig を準備します。 :=’1’ は、初期値を‘1’に設定する 場合の記述方法です。 この初期値

の設定は、必須です(初期値を設定

しないと、“不定”になります。

内部信号を出力に代入する

Page 72: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

144

【重要】 50MHz(=20ns/周期) → 100Hz(=10ms/周期)へ分周するには、この設定値をどうすればよいかを 計算して、正しく分周して下さい

10 進カウンタ (カウントアップ機能付き) CNT10.vhd 1 段目の 10 進カウンターは、基本信号となる分周クロック:

100Hz(=10ms/周期)を入力して、クロックのカウント数を 出力の bcd から BCD コード(4 ビット)で出力します。 また、 カウント数が 9 になった後に、カウントアップ信号を up-sig に 出力します。 カウントアップ信号は、右のような波形に なるようにします(入力信号の周期の 10 倍で、アップ信号が 出力されます)。

reset 信号を入力し、“非同期”で counter を初期化します。 これを、1/10 秒の桁と 1 秒の桁で実行します。

6 進カウンタ CNT06.vhd

機能的には、CNT10 と同じですが、10 秒の桁なので、 6 進カウンタになります。 また、カウントアップする必要が ないので、CNT10 の出力端子:up-sig は、削除します。

BCD-7segLED デコーダ BCD_7segLED.vhd

カウンターから出力される BCD コード(4 ビット)を 7segLED の 入力信号にデコードします。 図 4-3 を参照してください。

5.4 シミュレーションでの機能確認

これまでと同様に、まずModelSimでシミュレーションして機能を確認しますが、図5-8のブロック図を見ても判り通

り、大変繰り返しの多い機能であることが判ります。 例えば、60 秒間にシステムクロックは、30 億回(=50MHzx60)

サイクルするので、これを波形エディタで表示することは困難で全く意味がありません。 従って、シミュレーションで

は、個々のモジュールが正しく動作してしるかを確認して、図 5-8 の回路は、QuartusⅡで実現して、実機評価で最終

確認をします。 5.4.1 Div_10ms.vhd と CNT10.vhd の設計と確認

この 2 つのモジュールを設計(VHDL で記述)して、その機能を確認すれば、殆ど問題なさそうなので、 図 5-10 のようなサブ回路:Parts.vhd を作成して、それぞれの記述が正しくなされているかどうかをシミュレーション

で確認します。 サブ回路:Parts.vhd は、設計したDiv_10ms.vhdとCNT10.vhdを単純に配置して接続したもので、

図 5-8 の部分回路になっています。

図 5-10 Div_10ms と CNT10 の機能確認するためのサブ回路:Parts.vhd のブロック図 これを、テストベンチを使ってシミュレーションしますが、分周回路で 10ms に分周するのは無駄なので(既に実習

したとおりです)、この回路のシミュレーションでは、“ 10us ”(実機の 1/1000)に分周するように設定して、シミュ

レーションします。 この場合、10us 周期のクロックは 5us で ‘1’ と ‘0’ をトグルするので、 5us=20ns×250 と

なり、図 5-9 の counter の値の上限を、“250”と設定します。

clk_sig

reset

bcd

up_sig CNT10

▼ ▼

▼ 9 9

1 1

clk_sig

reset bcd CNT06

bcd seg BCD_

7segLED

clk

Parts

clk_10ms

clk_100ms

[分周回路] Div_10ms

clk_sig

reset

bcd

up_sig

[10 進カウンタ] CNT10

clk clk_div bcd(3..0)

reset

Page 73: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

145

[Parts.vhd のテストベンチの記述] Parts.vhdのシミュレーションは、(これまで実習したとおり)テストベンチを記述します。 入力波形の記述は自由

ですが、例として以下の内容で記述して見ます。 clk: 初期値: ’1’ (signal 文で設定)、10ns 周期で“10”をトグル ⇒ システムクロック:50MHz(duty:50%) reset: 初期値: ’1’ (signal 文で設定)、 3215ns で’0’にして(リセット“ON”)、2 us 後に’1’の戻す(リセット

“OFF”)、その後、500us シミュレーションを実行して、“ assert false severity failure; “文で 強制終了させます。 以下の記述となります。

[Parts.vhd のシミュレーションの実行結果]

① reset 機能の確認

今回の設計では、“リセットは非同期”としているので、実際にそのように動作しているかを確認します。

入力波形として、clk の立ち上がりエッジとは全く異なるタイミング:3215ns でリセットを“ON”しています。 図 5-11 のように、リセットが“ON”した 3.125us(3125ns)で CNT10 の出力:bcd が“0000”になっており、 リセット機能が非同期で正しく動作していることが判ります。

図 5-11 Parts.vhd の“ reset<=’0’ ”付近のシミュレーション結果

② Div_10ms の出力:clk_10ms と CNT10 の出力:信号 bcd の確認

Parts.vhd のシミュレーションでは、システムクロックを 10us(実機の 1/1000)に分周するように修正して、 シミュレーションしています。 従って、Div_10ms の出力信号:clk_10ms の周期は、10us となります。 図 5-12 で正しく動作していることが確かめられます。 なお、Div_10ms.vhd には“reset”が入力されないので、

clk_10ms は reset 信号に影響されませんが、シミュレーションの結果もそのようになっています。 また、CNT10の出力信号:bcdは、リセット後、基準信号:clk_10msの最初の立ち上がりエッジ(t=10usの所)

でカウントアップして、正しく動作しています。

図 5-12 Parts.vhd の信号:clk_10ms と bcd のシミュレーション結果

Page 74: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

146

③ CNT10 の出力:clk_100ms の確認 CNT10.vhd では、基準信号の clk_10ms を入力して、bcd と共に、入力信号の 10 倍周期のカウントアップ

信号(duty:10%)を出力します。 Parts.vhd のシミュレーションでは、入力信号の周期は 10us なので、 出力信号の周期は、100us となりますが、図 5-13のとおり、所望の結果になっています。

図 5-13 Parts.vhd の信号:clk_100ms のシミュレーション結果

5.4.2 BCD_7segLED.vhd の設計と確認

この設計は、ほぼ図4-3 のままです。 図4-3 では、ドットを表示するようにデコードしていますが、「1 分時計」では

不要なので削除します。 1 秒の桁は、ドットを表示しますが、どのようにするかは、各自で考えてください。 入力 BCD コード: 0 ~ 9 ⇒ 対応する表示のビット列(8 ビット)にデコード

A ~ F ⇒ すべてのセグメントを非点灯(=”11111111”)

[BCD_7segLED.vhd のテストベンチの記述] 入力は BCD コードだけなので、16 種類の入力パターンを生成するだけで OK です(ドットを表示しないとして)。 以下のように、for ~ loop 文を使うとシンプルに記述できます。 loop 文を出た後、“ assert false severity failure; “文でシミュレーションを強制終了させます。

[BCD_7segLED.vhd のシミュレーション結果]

BCD_7segLED.vhd のシミュレーション結果は、図 5-14 のとおりです。 各自で詳細を確かめて下さい。

図 5-14 BCD_7segLED.vhd のシミュレーション結果

5.5 課題3:『1 分時計』の実機評価 5.5.1 QuartusⅡの新規プロジェクトの作成

『1 分時計』の実機評価をするために、QuartusⅡ上に、以下の内容で新規プロジェクトを作成します

(“1.2 QuartusⅡでの新規プロジェクトの作成方法”参照)。

- 作業用ディレクトリ: Z:/quartus2_work/one_min_clock

- プロジェクト名: one_min_clock

- TOP 階層名: one_min_clock

- [Package] FBGA [Pin count] 484 [Speed grade] 6 ⇒ EP3C16F484C6 を選択

Page 75: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

147

5.5.2 (実機評価用)『1 分時計』: one_min_clock_top の設計

実機用の『1 分時計』の回路を、“図 5-8 課題 3:『1 分時計』のブロック図”に従って、設計します。 必要なモジュールは、7つのモジュールですので、適切に準備して下さい。

one_min_clock_top.vhd : 最上位回路。 図 5-8 に従って、QuartusⅡで入力する chattering.vhd : moji_deco_DE0.vhd で使ったものを使用するか新たにダウンロードする Div_10ms.vhd : ModelSim で設計したものを修正して使用する。

【重要】 Sim では 10us に分周しているので、“ 10ms ”に分周するように修正する。 CNT10.vhd : MoselSim で設計したものをそのまま使用する。 CNT06.vhd : 仕様に合わせて、CNT10.vhd を修正する。 BCD_7segLED.vhd : MoselSim で設計したものをそのまま使用する。 ドット表示なし。 BCD_7segLED_dot.vhd : BCD_7segLED.vhd でドットを表示したもの。

【コメント】 1 秒の桁のドット表示をする工夫はいろいろあります。 他の方法で実現しても問題ありません。 各自考えてください、

5.5.3 ファイルとプロジェクトメンバーの確認

以上の作業を行うと、図 5-15 のように、プロジェクトディレクトリ: …/ one_min_clock の下に、以下の7つの

ファイルができています(左図)。 これが大元なので、正しくできていることを確認してください。

またこの時、“Project Navigator”画面の“Files”タグにプロジェクトメンバーがリストアップされています(右図)。

もし、ここに、同じ7つのモジュールが登録されていない場合は、“図 2-25 プロジェクトメンバーの管理の方法”を参

考にして、正しいメンバーリストにしてください(ここが正しくないと、後の処理がうまく動作しません)。

図 5-15 登録されてファイル名(左)とプロジェクトメンバー

5.5.4 コンパイル

QuartusⅡのコンパイルは、必ずトップ回路を指定します。 今回は、one_min_clock_top.vhd をトップレベルにして

コンパイルするので、“2.9 VHDL のコンパル”のように、(one_min_clock_top.vhd を編集状態にして、)

「Project」 → 「Set as Top-Level Entity」、もしくは、“ ctrl + shift + j ”で、トップレベル回路に設定します。

この後、「Processing」 → 「Start Compilation」でコンパイルを実行します。 出力メッセージに致命的エラー(メッセー

ジ画面に赤字で表示される)がないことを確認してください。 もし、ある場合は、内容をよく読んで、指摘の箇所を修

正して、再度コンパイルして下さい。 殆どの場合、単なる入力ミスなので、よく内容を確かめれば必ず修正できます。

コンパイルが正常終了しなければ次に進めませんので、しっかりデバッグして下さい。

Page 76: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

148

5.5.5 端子割り当て

one_min_clock_top.vhd のコンパイルが終わっ

たら、「Assignments」 → 「Pin Planner」を開い

て、端子割り当てを行います。 ピン割り当て表フ

ァイル: pin_one_min.xlsx は、指定された場所

からダウンロードします。 ピン配置をコピーして、

(“All Pins”の)”Location“に貼り付けてください

(図 5-16)。 【重要】 Pin Plannerのピン並びとピン割り当て

表ファイルのピン並びが一致しているかを確認し

て、正しく割り当てを行ってください。

[プロジェクトで一度端子割り当てを行うと、 その割り当てが保存されます(勿論、修正は 可能です)]

図 5-16 “Location”への端子(ピン)割り当て

5.5.6 端子割り当て後に再コンパイル

端子割り当てを行った後、(one_min_clock_top.vhd をとトップレベルにして、)再コンパイルします。 その結果、

FPGA の端子信号と評価ボード上の部品(ボタンスイッチ、7segLED 等)が接続され、実機評価モジュール (コンフィグレーション・データ/ファイル、実機モジュール等と呼びます)が作成されます。

5.5.7 実機:DE0 での動作確認

メニューバーから、「Tools」→「Programmer」を選択して、“Programmer”画面を起動し、コンフィグレーション・ データをダウンロードして、動作確認を行います。 正しく動作していることを、時計と比較して、確かめて下さい。

pin_one_min.xlsx のピン名を、Location 欄すべて を選択してから、「Edit」→「Paste」で割り当てる

Page 77: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

149

6. 『追加仕様版: 4 ビット加算器』の設計

課題1:『4 ビット加算器』の仕様の問題点の1つは、出力が“16 進(Hexadecimal)表示”であることです。

従って、この 16 進表示を“10 進(decimal)表示”に仕様変更して、再設計します。 この仕様変更により、比較的簡単

に VHDL 設計ならではの追加仕様が実現できるので、設計変更して見てください。

6.1 ModelSim 上で新規プロジェクト作成 この追加仕様は、まずModelSimで設計して、シミュレーションで機能確認した後、QuartusⅡで実機確認するので、

ModelSim 上に新規プロジェクトを作成しますを実行するために、以下の条件で、ModelSim 上に新しい プロジェクト:adder_expand を作成します(“3.1 ModelSim の起動と新規プロジェクトの作成方法”を参照)。 - Project Name: adder_expand - Project Location: Z:/modelsim/ adder_expand - Default Library Name: work (← 既定値そのまま)

6.2 『追加仕様版1_加算器』の開発仕様とブロック図

[追加仕様版1_加算器の開発仕様]

① 入力: クロック信号: システムクロック:50MHzを入力する。

入力信号 A: Button2 の押下回数を入力数とする。

入力信号 B: Button0 の押下回数を入力数とする。

リセット信号: Button1 から入力し、即時に初期状態、すなわち A と B の入力数を“0”にする。

EQUAL信号: SW0 から入力する。 下側にスライド: 0、上側にスライド: 1

② 出力: EQUAL=’0’: 入力信号 A を HEX2/3 に 10 進数で表示する。

入力信号 B を HEX0/1 に 10 進数で表示する。

EQUAL=’1’: 加算モジュールの結果を、HEX0/1 に 10 進数で表示する。

この時、HEX2/3 には、“=”を表示する。

[ブロック図]

実機用の追加仕様版1_加算器:adder_expand_DE0 のブロック図は、図 6-1 のとおりです。

図 6-1 追加仕様版1_加算器(adder_expand_DE0)のブロック図

adder_expand_DE0

A

B

RESET

EQUAL

システムクロック

(50MHz)

カウンター

波形整形(チャタリング)

SW0

加算

回路

BCD 化

BCD 化

BCD 化

カウンター

Hex0

Hex1

Hex2

Hex3

1

表示信号の選択

BCD_7segLED

(Hex3) (Hex2) (Hex1) (Hex0)

Page 78: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

150

[図 6-1 の詳細]

課題1と追加仕様版1との違いは表示機能の違いだけです。 その違いを実現するには、課題1で提供されていた

peripheral_DE0.vhd(もしくは、peripheral_sim.vhd)を修正する必要があります。 図6-1は、peripheral_DE0.vhdを展開

して、追加仕様版1で必要なすべての機能を記載しています。 ここで使われている機能は、課題2と3で設計した

機能も含め、すべて実習した機能なので、これまでの VHDL 記述を利用して実現することができます。

なお、ModelSim で設計するときは、最上位回路を、“adder_expand.vhd”としてください。

チャタリング防止回路 chattering.vhd

すでに実習したとおり、この回路は、実機用回路で必要なモジュールなので、シミュレーション時は不要です。

実用回路で使用する場合、提供されているモジュールをそのまま使用して下さい。

カウンター Counter_4bit.vhd

入力信号 A と B の入力回数(立下りエッジの数)を数えます。

図 5-5 を参考にして、作成して下さい([重要] この記述では、

立上りエッジでカウントしています)。

加算回路 adder_4.vhd

入力信号 A と B の加算モジュールですが、すでに実習で設計しているので、それを利用します。 なお、

そのまま利用してもよいですが、以下のように修正するとよりシンプルになります。

(推薦する変更) 出力端子の統合

Port ( ….

S: out std_logic_vector (3 downto 0); S: out std_logic_vector (4 downto 0));

CO: out std_logic );

BCD 化 Binary2bcd.vhd

このモジュールで入力の 2 進数を表示桁毎に BCD 化します。

[機能] (入力) bin_in (5 ビットの 2 進数)

⇒ bin_in を 10 進数表示した場合の

・一の位の数字の BCD を bcd1 に出力

・十の位の数字の BCD を bcd1 に出力

例えば、bin_in に、“1100”が入力された場合、10 進数表示は“12”なので、

bcd1 <= “0001”; bcd2 <= “0010”; が出力されます(1と2の BCD は、“0001”、“0010”です)。

機能的には上記のとおりですが、これをどのように実現するかは、検討が必要です。

1つの方法は、以下のとおりです(他の方法でも構いません。各自検討して見てください)。

[10進数:N の各位の数字を取り出す方法]

一の位の数字 = N - (N/10) * 10

十の位の数字 = (N/10 に対して、上式を繰り返せばよいので、) N/10 - ((N/10)/10) * 10

百の位の数字 = (同様に考えて、) N/100 - ((N/100)/10) * 10

(以下、同様)

(例) N=231 の場合: N = 231 → 231 - ( 231/10) * 10 = 231-230 = 1 ← 一の位の数字

N/10 = 23 → 23 - ( 23/10) * 10 = 23 - 20 = 3 ← 十の位の数字

N/100 = 2 → 2 - ( 2/10) * 10 = 2 - 0 = 2 ← 百の位の数字

上記の方法を用いる場合、2 進数よりも 10 進数で処理した方が考えやすいですが、入出力信号が std_logic_vector

宣言されているので、型変換を行う必要があります。 この型変換を VHDL で記述する場合、表 6-1 のような関数

が準備されていますが、ライブラリ・パッケージが異なるので、“VHDL モデル定義”部の記述に注意が必要です。

c_in rst

count(3..0) Counter

_4bit

出力信号 S(3..0)と CO を統合して、S(4..0)にする

bin_in(4..0) bcd1(3..0) Binary

2bcd bcd2(3..0)

Page 79: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

151

表 6-1 「型変換」関数とライブラリ・パッケージ

関数名 機能内容

std_logic_1164 パッケージ内

To_stdlogicvector(A) bit_vector から std_logic_vector への変換

To_bitvector(A) std_logic_vector から bit_vector への変換

To_stdlogic(A) bit から std_logic への変換

To_bit(A) std_logic から bit への変換

std_logic_arith パッケージ内

CONV_std_logic_vector(A、ビット幅) intege、unsigned、signed から std_logic_vector への変換

CONV_INTEGER(A) unsigned、signed から integer への変換

std_logic_unsigned パッケージ内

CONV_INTEGER(A) std_logic_vector から integer への変換

Binary2bcd.vhd は、図 6-2 のようになります。 完成させて、利用して下さい。

図 6-2 Binary2bcd.vhdの記述

このモジュールの入力は、入力信号 A/B(4 ビット)もしくは加算結果 ADD(5 ビット)なので、バス幅が違います。

このように、幅の異なる入力信号を同一モジュールで処理するには少し工夫が必要です。

具体的には、binary2bcd をインスタンスするときに、

連接演算子:&を使って、以下のように工夫します。

BCD_A : Binary2bcd (‘0’&A, A_bcd1, A_bcd2 );

BCD_B : Binary2bcd (‘0’&B, B_bcd1, B_bcd2 );

BCD_ADD : Binary2bcd (ADD, ADD_bcd1, ADD_bcd2 );

‘0’ & A は、A=”1100”とすると

この演算子:&の結果、“01100” が

Binary2bcd に入力されることになり

入力のビット数が一致します。

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.std_logic_arith.all;

entity Binary2bcd is

port( bin_in : in std_logic_vector(4 downto 0);

bcd1 : out std_logic_vector(3 downto 0);

bcd2 : out std_logic_vector(3 downto 0));

end Binary2bcd ;

architecture RTL of Binary2bcd is

signal N_in,N1,N2: integer range 0 to 63;

begin

N_in <= CONV_INTEGER(bin_in);

N2 <= N_in / 10;

N1 <= N_in - (N2*10);

bcd1 <= CONV_std_logic_vector( N1, 4);

bcd2 <= CONV_std_logic_vector( N2, 4);

end RTL;

ライブラリ・パッケージを指定

入出力端子を指定

表 6-1 の関数を使って、上記の手法で、一/十の位の数字を抽出して、 BCD(std_logic_vector)で出力する機能を記述。

- N_in: 入力 bin_in を integer へ型変換したもの - N1/N2 は、一/十の位の数字(integer 型)

N-in、N1、N2 を interger 型(6bit)

で signal 宣言する。

Page 80: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

152

表示信号の選択 Selector.vhd

このモジュールでは、信号:EQUAL 状態(0/1)に従って、

7seegLED に表示する信号を選択します。

モジュールの外形は、右図のとおりですので、この内容に

従って、VHDL を記述して下さい。

EQUAL=’0’: 信号 A を HEX0/1 に表示する。

信号 B を HEX2/3 に表示する。

EQUAL=’1’: 演算結果:ADD を HEX0/1 に表示する。

この時、HEX2/3 には、“=”を表示する。

BCD-7segLED デコーダ BCD_7segLED.vhd

上記の“表示信号の選択”モジュールから出力される BCD コード (4 ビット)を 7segLED の入力信号にデコードします。 『1分時計』で使用したモジュールをそのまま使えますが、 “=”を表示するための工夫が必要です。

6.3 シミュレーション実行

設計した追加仕様版1_加算器(4ビット):adder_expand.vhd のシミュレーションを実行し、正しく設計できているかを

確認します。 課題1で使用したテストベンチ(adder_4_top_tb.vhd)のエンティティ名と DUT を adder_expand.vhd に変更

すれば、そのまま利用できます。

6.4 追加仕様版 1_加算器の実機評価

シミュレーションでの機能確認が済んだら、これまで通り、設計したVHDL記述をQuartusⅡに移して、実機:DE0で

の動作確認をします。

6.4.1 QuartusⅡの新規プロジェクトの作成 『追加仕様版1_加算器』の実機評価をするために、QuartusⅡ上に、以下の内容で新規プロジェクトを作成します。

- 作業用ディレクトリ: Z:/quartus2_work/adder_expand_DE0

- プロジェクト名: adder_expand_DE0

- TOP 階層名: adder_expand_DE0

- [Package] FBGA [Pin count] 484 [Speed grade] 6 ⇒ EP3C16F484C6 を選択

6.4.2 (実機評価用)『追加仕様版1_加算器』: adder_expand_DE0 の設計

実機用の『追加仕様版1_加算器』の回路を、“図 6-1 追加仕様版1_加算器(adder_expand_DE0)のブロック図”に 従って設計しますが、チャタリング防止回路(chattering.vhd)を挿入するだけでよいので(他の変更点はありません)、

課題2の『自分の名前を表示しよう』と同じ方法で処理すると簡単です。 6.4.3 ファイルとプロジェクトメンバーの確認後、コンパイルの実行

プロジェクトディレクトリ: …/ adder_expand_DE0 の下のファイルと“Project Navigator”画面の“Files”タグに

プロジェクトメンバーが正しくリストアップされていることを確認後、adder_expand_DE0.vhd をトップレベル回路に

設定して(「Project」 → 「Set as Top-Level Entity」、もしくは、“ ctrl + shift + j ”)、コンパイルを実行します。

出力メッセージに致命的エラー(メッセージ画面に赤字で表示される)がないことを確認してください。 これまで通り、

このコンパイルが正常終了しなければ次に進めませんので、しっかりデバッグして下さい。

A_bcd1(3..0) bcd0(3..0)

Selector

bcd2(3..0)

A_bcd2(3..0)

B_bcd1(3..0) B_bcd2(3..0)

ADD_bcd1(3..0) ADD_bcd2(3..0)

bcd3(3..0)

bcd1(3..0)

clk EQUAL

bcd seg BCD_

7segLED

Page 81: 3. シミュレーションによるVHDL 記述の検証jte401/2017/2017_text_2.pdf73 3. シミュレーションによるVHDL記述の検証 これまでは、 QuartusⅡ上で、回路図とVHDLで4ビット加算器を設計してきました。

153

6.4.4 端子割り当て

コンパイルが終わったら、「Assignments」 → 「Pin Planner」を開いて、端子割り当てを行います。 課題1と同じ端子(ピン)割り当て表: pin_adder4.xlsx を使用します。 これまでと同様、Pin Planner のピン並びと ピン割り当て表ファイルのピン並びが一致しているかを確認して、正しく割り当てを行ってください。

6.4.5 端子割り当て後に再コンパイル

端子割り当てを行った後、(adder_expand_DE0.vhd をとトップレベルにして、)再コンパイルして、実機評価 モジュール(コンフィグレーション・データを作成します。

6.4.6 実機:DE0 での動作確認

メニューバーから、「Tools」→「Programmer」を選択して、“Programmer”画面を起動し、コンフィグレーション・ データをダウンロードして、動作確認を行います。 正しく動作していることを、確かめて下さい。

6.5 『追加仕様版2_加算器(7ビット)』の開発

以上の追加仕様で課題1の「4ビット加算器」の表示が10進数になり、格段に使いやすくなりましたが、さらに

以下のような追加仕様を実現して見ましょう。

〇 『追加仕様版2_加算器(7ビット)』の開発仕様

追加仕様版1では、信号 A と B の表示が2桁になったので、4ビット(0~15)以上の数字が表示できるようになり、

0~99 までの数字を表示できますので、加算器のビット拡張が可能です。

従って、「追加仕様版2」では、以下のように、ビット拡張した仕様にします。

-入力信号 A と B: 0~99 まで入力可(4ビット→7ビットに拡張)。 99 から 0 に戻る。

-加算結果の表示(EQUAL=’1’のとき)は、 加算結果を、HEX0/1/2 に 10 進数で表示し、HEX/3 には“=”を

表示する。 従って、“=005”、“=034”、“=2017”という表示結果になります。

-他の仕様は、そのままとする。

以上の追加仕様を各自で実現してください。

6.6 『乗算演算』機能の追加

課題1では「加算演算」機能を実現していますが、「乗算演算」機能を追加することも可能です。 例えば、

「7ビット加算/乗算器」とするには、「追加仕様版2_加算器(7 ビット)」に以下の機能を追加すればよいです。

-追加仕様版2_加算器の機能はすべてそのままにする。

-乗算機能を追加する: 単純に、MUL <= A * B: で実現する (⇒ MUL のビット幅に注意する)

-MUL の表示はスライトスイッチ SW1 を使って、0~9801 (=99x99) なので、SW1=’1’の時に、

HEX3~0 に表示する。 SW0 と SW1 が同時に’1’の時は、SW1 を優先する。

-SW1 が追加されるので、端子割り当て表: pin_adder4.xlsx への追加が必要ですが、実際には、 「Pin Planner」で直接作業するのが簡単です。 “図 1-55 FPGA(EP3C16F484C6)のピン番号”を 参考にして、正しく割り当てを行ってください。

上記の内容で機能追加し、シミュレーションで確認後、実機で動作確認をしてください。

以上