論理回路設計 - 東京理科大学jte401/files/2019_text_1.pdf1 【2019...

103
1 2019 年度前期(集中講義)】 論理回路設計 (非常勤講師) 藤岡 督也 【開講時間】 6 15 日(土) 10 30 分~17 :40 2 時限から 5 時限) 6 22 日(土) 10 30 分~17 :40 2 時限から 5 時限) 6 29 日(土) 10 30 分~17 :40 2 時限から 5 時限) 7 06 日(土) 10 30 分~16 00 2 時限から4時限) 【開講場所】 葛飾キャンパス講義棟 2 ターミナル室(1【その他】 講習の資料は、http://www.ed.tus.ac.jp/~jte401/に置いてありますので、 ダウンロードした後、各自で印刷して、必ず毎回持参してください。 なお、論理回路の教科書も忘れずに持参してください。 東京理科大学 基礎工学部 電子応用工学科 学籍番号 氏名

Upload: others

Post on 13-Jun-2020

11 views

Category:

Documents


0 download

TRANSCRIPT

1

【2019 年度前期(集中講義)】

『 論理回路設計 』

(非常勤講師)

藤岡 督也

【開講時間】

6 月 15 日(土) 10 時 30 分~17 時:40 分 (2 時限から 5 時限)

6 月 22 日(土) 10 時 30 分~17 時:40 分 (2 時限から 5 時限)

6 月 29 日(土) 10 時 30 分~17 時:40 分 (2 時限から 5 時限)

7 月 06 日(土) 10 時 30 分~16 時 00 分 (2 時限から4時限)

【開講場所】

葛飾キャンパス講義棟 2 階 ターミナル室(1)

【その他】

講習の資料は、http://www.ed.tus.ac.jp/~jte401/に置いてありますので、

ダウンロードした後、各自で印刷して、必ず毎回持参してください。

なお、論理回路の教科書も忘れずに持参してください。

東京理科大学 基礎工学部 電子応用工学科

学籍番号

氏名

2

【本テキストの主な内容】 ページ

1.VHDL の概要 5

2.評価ボード: DE0-CV の説明 25

3.Quartus Prime Lite の起動方法と新規プロジェクトの作成方法 30

4.『半加算器』の評価ボードによる動作確認

4.1 動作確認するための全体回路 38

4.3 Quartus Prime Lite での VHDLふぁいるの作成:データ入力 41

4.4 VHDL記述のコンパイル 46

4.5 端子割り当て(ピンアサイン) 48

4.6 実行モジュールのダウンロード 52

4.7 評価ボードでの動作確認 55

4.8 「RTL Viewer」の利用方法 56

5.『全加算器』の評価ボードによる動作確認

5.1 「全加算器:full_adder2」の実機評価用全体回路 60

5.4 周辺回路の設計と VHDL記述 62

5.5 全体回路(トップモジュール)の設計と VHDL記述 64

5.6 全体回路の端子(ピン)割り当て 66

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

6.1 ModelSim の起動と新規プロジェクトの作成方法 71

6.3 VHDLファイルのコンパイル 77

6.4 “全加算器: full_adder2”のシミュレーション実行 79

6.6 全加算器の“全体回路: top_full_adder”のシミュレーション実行 89

6.7 “テストベンチ”によるシミュレーションの実行: “全体回路: top_full_adder” 97

7.『4 ビット加算器』の設計

7.1 入力処理部の設計と機能検証: 4 ビットカウンター:Bit4_counter.vhd 105

7.2 出力処理部の設計と機能検証: 標示信号変換回路2:Bit4_to_7segLED.vhd 108

7.3 「4 ビット加算器(含む、演算処理部)」の設計と機能検証: adder_4bit.vhd 112

7.4 「4 ビット加算器」の実機動作確認 118

7.5 【追加課題】 「4 ビット加算器:adder_4bit」の出力表示の 10 進数化 123

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

8.1 課題2: 『自分の名前を表示させよう』の開発仕様 130

8.3 「分周回路:divide_vlock」 の設計と機能検証 132

8.4 「基準信号生成回路: base_signal」の設計と機能検証 134

8.5 「表示信号変換回路3:BS_to_7segLED」の設計と機能検証 138

8.6 「自分の名前を表示させよう:My_Name」の設計と機能検証 142

8.7 「自分の名前を表示させよう:My_Name」の実機動作確認 145

9.課題3: 『ストップ・ウォッチ』 の設計

9.1 課題3: 『ストップ・ウォッチ』の開発仕様 150

9.2 評価用回路を利用したシミュレーションによる機能検証 153

9.4 「制御信号発生回路:signal_gen」の設計と機能検証 154

9.5 「10 進/6 進カウンタ: CNT10/CNT06」の設計と機能検証 156

9.6 「評価用回路: parts_test」の設計と機能検証 159

9.7 「ストップ・ウォッチ: stop_watch」の実機動作確認 162

3

0.はじめに

本講座では、ハードウェア記述言語:VHDLを用いて論理回路(デジタル回路)の設計を実習します。 具体的には、

設計の現場で実用的に使用されている設計ツール(EDAツール)を使って、与えられた課題を設計し、評価ボードを使

って正しく動作するかを確認します。 従って、論理回路設計の考え方、設計工程と設計フローの理解、設計デバッグの

方法、さらに EDA ツールの操作技術等を実務レベルで習得することができます。

- DE0-CV (Terasic 社製): Altera 社製 FPGA:CycloneⅤを搭載した評価ボード(実機)

- Quartus Prime Lite (Altera 社製): Altera 社製 FPGA で設計するための EDA ツール

- ModelSim (Mentor 社製): デファクト・スタンダードの VHDLシミュレーター

本テキストは、上記の目的を達成するために、図 0-1 の設計フロー/実習内容のように、回路構成等の設計仕様が

確定した時点からスタートして、VHDL を使って、どのように設計/デバッグし、実機で動作確認するのか、の手順を記

載していますので、記載順に従って、実習を進めてください。 なお、実習/設計は、同様の作業を繰り返しながら進め

るので、テキストのそれぞれの内容は、簡易マニュアルとしても講義全体を通じで使用します。 個々の内容をしっかり

確認し理解しながら実習を進めてください。

実習する課題とその具体的な内容は、以下の通りです。

【課題1】 加算器: 半加算器、全加算器、4 ビット加算器、(追加課題)

【課題2】 自分の名前を表示させよう

【課題3】 ストップ・ウォッチ、(追加課題)

【課題1】 簡単な課題を使って、Quartus Prime Lite と ModelSim 上での設計手順(設計フロー)を理解する。

- Quartus Prime Lite で、半加算器と全加算器を VHDL で記述(設計)して、評価ボードで動作確認する。

← Quartus Prime Lite 上での作業フロー & 階層設計の仕方 を習得する。

- ModelSim 上で、設計した全加算器のシミュレーションを実行する。

← ModelSim 上での設計フローとシミュレーションの実行の仕方を習得する。

- 4 ビット加算器を ModelSim で設計して、シミュレーションで機能確認した後、設計した VHDL記述を

Quartus Prime Lite に持ち込み、評価ボード(実機)で動作確認する。 この時、シミュレーション用回路と

実機用回路の違いを理解する。

← “シミュレーションで機能確認→実機確認”という実務設計フローを習得する。

【課題2】 主に、組み合わせ回路の VHDL設計を実習し、実機評価を行う。

- 与えられた仕様(開発仕様)を正確に分析してから、VHDL で設計する手順を確認する。

【課題3】 主に、順序回路の VHDL設計を実習し、実機評価を行う。

- 与えられた仕様を具体化した後、全体回路のシミュレーションを実行して機能確認するのではなく、

評価用回路(部品のモジュールから構成)を使って、効率良くシミュレーションを実行し、その後、実機で

全体回路を仕上げ、機能確認する手順を確認する。

【お願い】 本テキスト内で使用しているファイル名やモジュール名等は便宜上付けたもので、別の名前にする

ことも可能ですが、実習をスムースに行うために、できるだけそのまま使用してください。

4

Quartus

Prime Lite ModelSim 内容

本講座では、デザインエントリ(回路機能の入力方法)として、 - ハードウェア設計記述言語:VHDL による設計

を実習します。 現在、大規模デジタル回路の設計は、 “言語による設計”が中心なので、実習を通して、その考え方と 具体的な設計手順(設計フロー)を理解することが目的です。

デザインエントリ(設計した)VHDL 記述自体が正しいかどうか を確認します。 Quartus Prime Lite の場合は、具体的に 論理合成可能かどうかまで確認します。 - 入力記述ミス、仕様ミス、名前の不整合等の確認 - 階層間チェック等の確認(Quartus Prime Lite の場合) 等が含まれ、ここが正常終了しないと次工程に進めません。 発生するエラーの内容は多岐にわたるので、出力されるエラー メッセージをよく読んで、効率よくデバッグして下さい。

デザインエントリし、コンパイルでエラーフリーにした後、 その記述内容が正しく所望の機能を実現しているかどうかを シミュレーションを実行して確認します(機能検証)。 後工程からの戻りを無くす大切な設計工程です。 本講座では、シミュレーターとして、ModelSim を使います。 シミュレーションの実行方法は、言語設計で可能となった “テストベンチ”による実行方法を実習/習得します。 さらに、 シミュレーション用回路と実回路との違いも理解します。

(以降は、実機動作確認をすための、Quartus Prime Lite 上での設計工程です)

実習で用いる評価ボード『DE0―CV』上の FPGA の端子と 設計データの入出力端子の割り当てを指示します。 この工程により、設計データの入出力端子と入出力デバイス を正確に接続できるようになり、実機動作が可能になります。

端子割り当て(ピンアサイン)後に、再コンパイルすることにより、 入出力デバイスと設計データが正しく接続され、DE0-CV 上で 動作する実行モジュール(コンフィグレーション・ファイル)が 作成されます。

作成されてコンフィグレーション・ファイル(*.sof)を DE0-CV 上の FPGA に書き込みます。

設計した LSI を実際の装置に搭載して、動作確認を行う工程を 実機評価と呼びますが、今回は評価ボードを実機に見立てて、 設計データの動作検証を行います。

図 0-1 設計フローと実習内容

機能シミュ レーション

コンパイル

実機評価

デザインエントリ:

ハードウェア記述言語

(HDL)による設計

ダウンロード

コンパイル

端子割り当て(ピンアサンイ)

5

1.VHDLの概要

ハードウェアの設計は、これまで、基本論理素子(AND, OR, NOT など)を用いて紙面上に回路図を書いたり、コンピュ

ータ上でマウスを使って回路を入力する回路図エディタを使用して設計されてきましたが、現在はハードウェアを言語で

表現できるハードウェア記述言語(HDL:Hardware Description Language)を用いて、ハードウェア・デバイスの設計が行

れてます。 このハードウェア記述言語を用いることで、ハードウェア・アーキテクチャの設計からレイアウト設計・テスト

に至る一連の工程の中で、動作レベルやゲートレベルなどの記述を用いたトップダウン設計を行うことが可能となり、

設計の生産性/信頼性が飛躍的に向上しています。

ハードウェア記述言語は、具体的な回路などを考慮せずに動作だけを記述すればハードウェアの動作を定義するこ

とができるようになっており、ソフトウェアプログラミングの手法と違和感なくハードウェアの設計を行うことができます。

様々な種類がありますが、その中でも世界的に多く用いられている言語は VHDL(VHSIC_HDL)と Verilog_HDL です。

これらのハードウェア記述言語によるシステム開発のメリットは、主に以下のとおりです。

設計の互換性 :

VHDLや Verilog_HDLは、IEEE(米国電気電子協会) で規格化されたハードウェア記述言語です。

規格化されたことで、安心して採用することができるとともに、規格を満たす EDA システムでは

基本的にソース の書き換えをすることなく実行できることが保証される。

様々な設計手法およびテクノロジのサポート :

トップダウン/ボトムアップ設計手法、同期対非同期設計あるいはマイクロプログラム/ワイヤード・

ロジックような設計テクノロジがサポートされる。

テクノロジおよびプロセスからの独立性 :

実装デバイスとしての CMOS や ECL等のプロセスから独立しており、それらを意識することなく

システム動作等のシミュレーションが実行できる。

広範囲な記述能力 :

システム・レベルからゲートレベルまで記述できる一貫した構文規則を備えている。

また、それらのレベルを混在させて記述してもシミュレーションが実行できる。

大規模な設計と設計の再利用 :

言語仕様として、分割設計をサポートしており、設計情報の部品化等を容易に実現できるため

大規模なシステムの設計も可能である。

[VHDL の歴史]

VHDLは、ハードウェア記述言語の一種で、1980 年代に米国国防総省の主導によって開発された言語です。

1985 年に仕様が一般公開され、1987 年以降、IEEE 1076-1987 や IEEE 1164-1993 として標準化されて以来、HDLの

標準的仕様として多く採用されています。

VHDLは,米国国防省の VHSIC(Very High Speed Integrated Circuit)委員会で 1981 年に提唱されました。 当時、

急速な半導体プロセスの進歩に合わせて、大規模 IC開発の大幅な設計期間短縮が求められており、そこで直接ロジッ

ク・ゲートを回路図で入力するのではなく,ハードウェア記述言語(HDL)で設計することが提唱されました。 こうして、

1983年にVHDLの仕様作成が始まり、1985年に作業が完了し、1986年にはマニュアルにまとめられ、バージョン 7.2と

して公開されました。 その後、1986 年には IEEE(米国電気電子技術者協会)による標準化作業が、VASG(VHDL

Analysis & Standardization Group)委員会で始まり、1987 年 5 月には LRM(言語仕様書;Language Reference Manual)が

作成され、12月に IEEE Std 1076-1987として承認されました。 さらに、1992年に文法の改訂作業が行われ、1995年に

IEEE Std 1076-1993 として承認されました。 一方、1989 年に、VHDLシミュレータや VHDL記述からロジック回路を生

成するソフトウェア(論理合成ツール)が EDA ベンダから販売されるようになり、実際の論理回路設計に用いられるよう

になったことにより、急速に普及しました。 現在の大規模設LSI設計が実現できるようになったのは、VHDLや Verilog

HDL といったハードウェア記述言語の進歩に寄るものと言われています。

6

1. 1 VHDL の仕様概要

1.1.1 VHDL の基本ルール

VHDL記述を行うにあたり、覚えておくべき注意項目がいくつかあります。 これをまずしっかり頭に入れましょう。

[コメント]

回路中にある信号が変化する(“イベントが起こる”と言います)とその信号に依存する全ての信号が同時に

変化します。 この様に、並列に動作することを一般にコンカレント処理と呼びます。 これとは対照的に、

記述された順番に依存することをシーケンシャル(順次)処理と呼びます。 シーケンシャル処理は、VHDLの

文法である process 文(プロセス文)の中で行われます(詳細は、process 文の項目で説明します)。

以上を具体的に例を使って説明すると以下のようになります。 ここで、”<=”は、信号を入力する時の記号で、

右から左へ代入しています。 ”=>”はその逆です。

(記述例 1)

B にイベントが起これば、2 行が同時に実行されます。

Fにイベントが起これば、2 行目は動作しますが 1 行目は全く動作しません。

(記述例 2)

B にイベントが起こり、2 行が同時に実行され、D にもイベントが起きるので

1行目の式が再度評価され、Cにイベントが伝達されます。 しかし、Dのイベントは、

順番で言えば B に起こったイベントの後になるので、1 行目の式は 2 回評価される

ことになり、Cには順番の違ったイベントが 2 つ伝えられることになります。

(記述例 3) 文法違反の例

VHDL では、同じ信号に対して、2 ヶ所以上からイベントを伝達することは認めてい

ません。

C <= A and B; D <= F and B;

C <= D and B; D <= A and B;

A <= B and C; A <= E and D;

① VHDL を記述する際は半角英数字で記述すること ② VHDL では大文字と小文字は区別されない ③ 回路は並列動作をするので、回路動作記述文における順序は関係なし [下記コメント参照] ④ 信号名に予約語は使えない

予約語の例として、 begin, entity, case, process などがあり、一般に VHDL の構文として 定義されている用語は使えない

⑤ 出力信号を入力信号として再利用することは禁止

7

VHDL モデル定義

エンティティ文

アーキテクチャ文

1.1.2 VHDL の基本構造

VHDLの記述は、大きく以下の3つの構造に分けられ、必ずこの順番で記述します。

(1) VHDLモデル定義(パッケージ宣言)

(2) エンティティ文(エンティティ宣言)

(3) アーキテクチャ文(アーキテクチャ宣言)

(1) VHDLモデル定義(パッケージ宣言)

VHDL で使用するライブラリの宣言(※1)とパッケージの呼び出し(※2)を行います。 簡単に言えば、VHDL記述に

必要となる道具を準備する段階です。 この VHDLモデル定義は、VHDL記述の最初で必ず行います。

通常、左記のように記述しますので、定型として覚えましょう

(特に、use IEEE.std_logic_1164.all; は必須です)。

(※1) ライブラリ宣言: Library 文

VHDLには、さまざまな設計データが格納されたライブラリが用意されており、ライブラリ宣言により格納されている

データを呼び出すことができます。 ライブラリ宣言の記述は、上記のように行います。 これは、そのまま“IEEE”

というライブラリを呼び出していることを意味します。 呼び方は「ライブラリ・アイトリプルイー」です

(※2)パッケージ呼び出し: use 文

パッケージとは、データタイプ(後述(4)参照)、各種の演算子や標準関数などを定義したものです。 IEEE の標準

ライブラリパッケージ(※3)は必須のものなので、上記のとおり、必ず記述が必要です。 なお、VHDLのパッケー

ジとして、std_logic_1164、std_logic_unsigned、 std_logic_arith の 3 つを覚えて下さい[(※3)参照]。

(※3) IEEE の標準ライブラリパッケージ

(1) std_logic_1164 (スタンダード・ロジック・イチイチロクヨン)

このパッケージは、std_logicの基本関数の呼び出しに使用します。

通常、std_logic、std_logic_vector を使って設計するので、このパッケージを必ず宣言する必要があります。

(2) std_logic_unsigned (スタンダード・ロジック・アンサインド)

このパッケージは、std_logic、std_logic_vector を使った符号無し演算関数を呼び出しに使用します。

(3) std_logic_arith (スタンダード ロジック アリス)

このパッケージは、std_logic、std_logic_vector を使った算術演算関数を呼び出しに使用します。

なお、上記の記述で、“.all”を付加しているのは、パッケージの内部で定義されている全ての関数を使用可能と

するためのもので、定型の記述方法です。

Library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all;

8

(2)エンティティ文(エンティティ宣言)

エンティティ文は、外部との入出力インターフェースを定義する部分です。 例えば、回路を 1 つのシンボル箱で

表現した場合、箱につける名前(シンボル名)と入出力部の端子名(入力/出力ポート名)を定義します。

図 1-1 は、半加算器(half_adder)のシンボル図ですが、シンボルの左側のラインは入力ポート(in)、右側のライン

は出力ポート(out)を表し、シンボル名:half_adder がエンティティ名になります。

図 1-1 半加算器(half_adder)のシンボル

[エンティティ文の記述仕様]

(入出力ポート宣言)

以上の仕様に従って、図 1-1 の半加算器のエンティティ文を VHDLで記述すると次のようになります。

なお、各入出力信号のデータタイプ: std_logic については、(4)で説明します。

(説明) エンティティ名: half_adder

入力ポート名: A、B - A と B の入力端子は、1ビットの std_logic で処理する

出力ポート名: S、CO - S と CO の出力端子は、1ビットの std_logic で処理する

entity エンティティ名 is

end エンティティ名;

port ( 入力ポート名 : in データタイプ;

・・・・・

出力ポート名 : out データタイプ );

entity half_adder is

port ( A, B : in std_logic;

S, CO : out std_logic );

end half_adder;

入出力ポート宣言

half_adder

A

B

CO

S

エンティティ

入力端子

(ポート)

出力端子

(ポート)

9

(3)アーキテクチャ文 (アーキテクチャ宣言)

アーキテクチャとは、回路構造を意味します。 先ほど説明したエンティティ文が回路の外部構造に当たり、

これから説明するアーキテクチャ文が、回路の内部構造に当たります。

エンティティ文で外部構造、すなわち

外部からの見え方を指定します。

アーキテクチャ文で、回路の内部構造

すなわち、内部回路を記述します。

図 1-2 アーキテクチャ文(回路の内部記述)

図 1-2 は、ハーフアダー回路の例です。 sig1、sig2 は、内部信号名で、回路素子間をつなぐ信号を示しています。

アーキテクチャ文中に宣言して、素子間の接続関係を示すために使用します。 図 1-2の回路構造は、VHDLに用意

されている論理ゲートを用いて記述しています。 もっと複雑な回路になると回路図を意識して記述することが困難に

なるので、機能を考えて記述を行います。

[アーキテクチャ文の記述仕様] (半加算器の場合の記述例)

図 1-3 アーキテクチャ文の記述例

(説明)

アーキテクチャ名: 内部構造を意識した名称を付けますが、通常“RTL”とすることが多いです。

宣言文: 回路内部で使用する信号名、定数、関数を定義します。

signal 文(信号宣言)、constant 文(定数宣言)、type 文(型宣言)等があります。

(例) signal 文の記述

- 内部信号宣言では、データタイプ名の前に{in、out}などの方向をつけません。

- 内部信号宣言は、必要なければ、記述する必要はありません。

VHDL本体: 回路の動作を記述する文で並列(同時)処理する文の集合です。 すなわち、書かれた文の

順序でなく、イベントが伝搬された順番に動作します。 なお、VHDL記述では、ポート文で定義

した出力信号を入力信号にフィードバック(再利用)することを禁止しているので、出力信号を入力

信号として利用する場合は、内部信号を宣言して、出力信号を内部信号に代入し、この内部信号

を入力信号に代入することで実現できます。 内部信号の宣言は、signal 文で行います。

以上を参考にして、図 1-2 のアーキテクチャ文の基本構造を記述した例は、上記図 1-3 のとおりです。

アーキテクチャ名: RTL

エンティティ名: half_adder

内部信号名&テータタイプ: sig1、 sig2 (共に)std_logic タイプ

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

<宣言文>

begin

<VHDL本体>

end アーキテクチャ名;

signal 信号名(, 信号名・・・): データタイプ;

architecture RTL of half_adder is

signal sig1,sig2: std_logic;

begin

<VHDL本体>

end RTL;

10

1.1.3 VHDL のデータタイプ

VHDLはデータタイプ(データの型)に厳格な言語です。 すべての信号、変数、定数、パラメータは、そのデータ

タイプを指定する必要があります。 代入文の左辺と右辺は同じデータタイプでなけらばならず、またサブプログラム

の戻り値も同じデータタイプである必要があります。 違っている場合はコンパイルエラーが出ます。

本授業では、最もよく使われている std_logic と std_logic_vector データタイプを用いて設計します。

(1) std_logic データタイプ

IEEE-1164 仕様で、標準的なデータタイプとして定義されているもので、複数のドライバが信号上で競合した場合

の論理値を解決するリゾリューション・ファンクションを持ちます。std_logic に関するファンクションや定数、変数などは

std_logic_1164 パッケージ内に定義されているので、パッケージ宣言で、use IEEE.std_logic_1164.all; を宣言します。

std_logic の各論理値は、以下の9値です。

‘0’、‘1’、‘X’: 強ストレングスの論理値0、論理値1、不定値

‘L’、‘H’、‘W’: 弱ストレングスの論理値0、論理値1、不定値

強ストレングスと弱ストレングスが同一信号上で競合した場合は、強ストレングスの値が有効

‘Z’ : 信号がドライブされていないハイインピーダンス状態

‘U’ : 初期化されていない(Uninitialize)論理値

‘-’ : ドントケア(don’t care)

(2) std_logic_vector データタイプ

std_logic データタイプの多ビット信号であることを表し、次のように記述します。

- バス幅(dimension)は、信号のビットの順番とビット数(信号の数)を表します。 各状態値は上記の 9 値です。

例えば、以下のような記述と内容になります。

(記述例)

A: in std_logic_vector ( 0 to 3 ); ・・・ 4 ビットバス信号で、A(0), A(1), A(2), A(3)と昇順となります。

A: out std_logic_vector ( 3 downto 0 ) ・・ 4 ビットバス信号で、A(3), A(2), A(1), A(0)と降順となります。

- (値の代入方法)

Vector タイプへの値の代入は、2 進/8 進/16進数で行うことができます。 ビット基数として、

B(2 進数)[省略可能]、O(8 進数)、X(16 進数)を用います。

(例) B”0100_1101“、”01001101“、O”115“、X”4D“

[参考]

データタイプには他にもありますが、回路記述で使う主なものは以下のとおりです。

- bit データタイプ

論理値を‘0’または‘1’の 2値だけで表したもの。

- bit_vector データタイプ

bit データタイプの多ビット信号であることを表し、次のように記述します。

B: in bit_vector ( 0 to 3 ); ・・・ 昇順の 4 ビットバス信号で、各状態値は 0/1 です。

B: out bit_vector ( 3 downto 0 ) ・・ 降順の 4 ビットバス信号で、各状態値は 0/1です。

- integer データタイプ

正及び負の整数を表し、32 ビットまで、すなわち整数の範囲は-2147483647~2147483647 です。

- boolian データタイプ

真(True)と偽(False)の 2 つの値を持つ列挙タイプ

信号名[、信号名・・・]: (入出力属性) std_logic_vector ( バス幅 );

信号名[、信号名・・・] : (入出力属性) std_logic;

11

1.1.4 VHDL のオブジェクト・クラス

定数(constant)、信号(signal)、変数(variable)があります。

信号は、ハードウェアの接続を表現するもの(配線やレジスタ(記憶素子)等)で、代入時に遅延があります。

変数は、プロセス文などの内部で有効なデータの保存場所として用いられ、プログラム言語と同様に、遅延がなく、

順序的に評価され即座に代入が実行されます。

(使用例) constant WIDTH: integer := 8; [整数型定数WIDTHの値を8にする]

・・・

If ( I >= WIDTH ) then … [整数型変数 I が WIDTH(=8)以上のとき、then 以下を実行]

(使用例) signal A,B,C,D: std_logic :=’0’;

signal S1, S2: std_logic;

signal Vec: std_logic_vector(3 downto 0) :=”0000”;

signal counter : integer range 0 to 500000 :=1;

- 信号名:counter を integer(整数)タイプとして宣言する

- range 0 to 500000 は、変数の値域を宣言しています。 この宣言は省略可能ですが、

省略した場合は“32 ビット”の変数として扱われます。

- :=1 は、初期値の設定です(counter の初期値を1に設定します)。

[信号代入文例]

A <= B and C;

D <= A when S1=’1’ else B when S2=’1’ else C;

(使用例) process (S1,S2)

variable V1, V2: std_logic;

[信号代入文例] begin

V1 := S1 and S2;

V2 := S1 xor S2;

F <= V1 & V2;

end process

(定数宣言構文) constant 定数名[、定数名・・・]: データタイプ [:= 値];

(宣言場所) architecture, process文の宣言部

(信号宣言構文) signal 信号名[、信号名・・・]: データタイプ [:= 値];

(宣言場所) architecture の宣言部

(変数宣言構文) variable 変数名[、変数名・・・]: データタイプ [:= 値];

(宣言場所) process 文の宣言部

12

1.1.5 VHDL の演算子

演算子(Operator)は、1 つまたは複数のオペランド(Operand)に演算を適用し、算術演算や論理演算などを

実行します。 演算子は、パッケージ内で定義されており、演算結果は、呼び出したパッケージに依存します。

(1) 定義済みのVHDL演算子 [パッケージ: std_logic_unsigned, std_logic_signed, std_logic_arith ]

[論理演算子] std_logic、bit、boolean に使用可能

not (論理否定)、 and (論理積)、 or (論理和)、 nand (NAND)、

nor (NOR)、 xor (EX-OR)、 xnor (EX-NOR; VHDL93)

[関係演算子] 全データタイプに使用可能。 幅違いは下位が有効

= (等しい)、 /= (等しくない)、 < (小さい)、 <= (小さいまたは等しい)、

> (大きい)、 >= (大きいまたは等しい)

[算術演算子]

+ (加算、プラス符号)、 - (減算、マイナス符号)、 * (乗算)、 / (除算)、

** (べき乗)、 abs (絶対値)、 mod (モジューロ)、 rem (剰余)

[シフト・ローテイト演算子] 一次元配列型に使用可能

sll (左へ論理シフト)、 sla (左へ算術シフト)、 rol (左へ回転シフト)、

srl (右へ論理シフト)、 sra (右へ算術シフト)、 ror (右へ回転シフト)

[ s: shift, l: left, r: right, l: logical, a: arithmetic, ro: rotate ]

[連接演算子] &

signal CO: std_logic;

signal SUM: std_logic_vector (3 downto 0);

signal ADD: std_logic_vector (4 downto 0);

信号 SUM と CO を1つの信号ADD にする場合、

連接演算子:”&”を用いると

ADD <= CO & S;

と記述します[“&”は、連接機能で、and と書くと全く別の意味になります]。

なお、以下のように記述することも可能です。

ADD(3 downto 0) <= SUM(3 downto 0);

ADD(4) <= CO;

(2) 演算子の優先順序

各演算子の優先順位は、以下の通り定義されている(高い順)。

(高い) 特殊: not、 **、 abs

乗除演算子: *、 /、 mod、 rem

正負の符号演算子: +、 -

加減演算子と連接: +、 -、 &

関係演算子: =、 /=、 <、 >、 <=、 >=

(低い) 論理演算子: and、 or、 nand、 nor、 xor、 xnor

4 3 2 1

ADD[4..0]

co

0

s[3..0]

13

1.1.6 VHDL の属性(アトリビュート)

属性は、信号や変数などに付加された値で、シングルクォートと属性名を付加することで、値を得ることができます。

VHDLには数多くの属性が定義されていますが、回路記述なもの、および便利なものは以下の通りです。

属性(アトリビュート) 対象 意味 値

遅延属性 S’event

信号 変化があったか否か 真(true)か

偽(false) S’stable 安定していたか否か

配列属性

A’left

配列型(複数ビット)

の信号、変数、定数

最左ビットの位置 整数

A’right 最右ビットの位置 整数

A’range ビット幅の範囲 レンジ

A’length ビット幅 整数

(1) 遅延属性

タイミングに関する状態を認識するために使用します。 指定した状態に一致していれば、ブール値:true を

不一致であれば、ブール値:false を戻します。 これらの属性は、if 文や wait 文などの条件式で使用します。

- 信号:CLK に変化があり、その信号状態が CLK=’1’であれば、then 以下を実行するので、

信号:CLK の立上りエッジを検出します。

- 条件式の括弧:()は、記述しなくてもよいです(記述した方が読みやすくなりますが)。

(使用例) 図 1-4 に示した信号の時間変化を記述したものをタイムチャートと呼びます。 図中の使用例では、

信号:clk の立ち上がりエッジ[ if (clk’event and clk=’1’ ) ]のみで、din の状態値を dout に出力するので

[ then dout <= din ]、dout の状態値は、clk の周期の間、din の状態値が保持(ラッチ)されます。

従って、dout は、図のように、clk に同期した信号になります。

図 1-4 タイミングチャート

- 指定された時間だけ値が変化していなければ、ブール値:true を、それ以外はブール値:false を戻します。

従って、上記の記述は、属性が実行された時刻の前:1.4ns の間に DATA 信号の値に変化があれば、

then 以下を実行します。 例えば、セットアップ時間の確認などに用います。

(補足説明) セットアップタイムとホールドタイム

クロックに同期した設計では、クロックの立ち上がり前後で入力信号が変化してはいけない時間帯があり、

一般的に、クロックの立上がり前をセットアップタイム、立上がり後をホールドタイムと呼びます(図 1-5)。

設計では、上記のような記述を用いて、この時間を確認します。

図 1-5 セットアップタイムとホールドタイム

クロック

セットアップタイム

データ

ホールドタイム

(event文)if (CLK’event and CLK =‘1’) then …..

clk

din

dout

If ( clk’event and clk =’1’ ) then dout <= din; end if;

clk の立上がりエッジ時のみで、din の値を

dout に出力するので、dout の値は clk の

周期の間、保持(ラッチ)されます。

(stable文)if not DATA’stable (1.4 ns) then …..

14

(2) 配列属性

配列のもつ配列範囲の値を戻す属性(アトリビュート)です。 この属性により、サブプログラムに引き渡された

入力側のインデックス範囲を知ることができます。

1.1.7 順次処理文

順次処理文は、プロセスまたはサブプログラム内で使用し、記述している順序に従って1つずつ実行されます。

プロセスは順次処理文で構成されていますが、アーキテクチャ(architecture)内の各プロセスは全て並行的に処理

され、プロセスの外部で宣言された信号やポートの値を読み書きすることで、ほかの部分と通信します。

アーキテクチャ内のプロセス文、信号代入文、ブロック文やコンポーネント・インスタンスは、それ自体はそれぞれ

独立に動作するために、『並行処理文』と呼ばれます。 これらの並行処理文を信号を用いて接続することで、回路

動作や回路構造を設計します。

(1) process 文

process 文は、ハードウェア動作を表現する1つの実行単位であり、アーキテクチャ部に記述します。 それぞれの

process 文は、並行的に実行されます。 センシティビティ・リストまたは wait 文のどちらかによって実行が制御されま

すが、同時に両方を記述することはできません。

[重要] プロセスは繰り返し実行されます。 従って、プロセス内の最後の処理文が実行されると、プロセスの最初

の処理文に戻り、再びプロセスを実行します。 なお、センシティビティ・リストが指定されている場合は、

最後の処理文が実行されてから、センシティビティ・リスト内に指定されたいずれかの信号が変化するまで、

実行処理が停止されます。

process 文の構文は、次のとおりです。

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

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

順次処理文を最初から順番に実行されます。 なお、組合せ回路をプロセス文で記述するときは、センシティ

ビティリストには、すべての入力信号を記述する必要があります。

《順次処理文》

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

if文と case 文が使えます。

signal DATA: std_logic_vector (15 downto 0);

…….

DATA’left ---- 15を戻す

DATA’right ---- 0を戻す

DATA’range ---- (15 downto 0)を戻す

DATA’length ---- 16を戻す

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

[プロセス宣言部: 変数宣言、定数宣言、タイプ宣言、サブプログラム宣言]

begin

<順次処理文: 信号代入文、変数代入文、if 文、case文、loop 文、wait 文、exit 文等>

end process;

15

(2) if文

if 文は、process 文中に記述し、以下の記述となります(“elsif”のスペルに注意[elseif ではない])。

条件式に基づいて、処理文の実行の可否が選択されます。 条件式が“真”であれば、thenに続く順次処理文が実行

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

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

if 文の構文は、次のとおりです。

(3) case 文

case 文は、式の値と一致した分岐に指定した順次処理文を実行します。 即ち、指定した式を計算し、評価した結

果と一致する分岐値を持つ when 文の処理文を実行します。 when 文で指定する分岐には、“|”による複数値の指

定、“to“による範囲の指定が可能です。 式や分岐値には、整数型、列挙型、配列型の式を指定することができます

が、値はスタティックな式またはスタティックな範囲を持ち、式と分岐値のタイプは一致する必要があります。

case 文の場合、すべての条件式が同時に実行されるので、同じ値が複数使われることは許されず、すべての取り

うる値を記述する必要があります。 しかし、毎回すべての場合を記述するのは大変なので、when othres が用意さ

れています(“others”は、その他すべての場合を表します)。

case 文の構文は、次のとおりです。

(4) loop 文

Loop 文は、繰り返し記述を簡略化するために用い、for 文(for-loop 文)と while 文(while-loop 文)があります。

for 文は、指定した整数の範囲だけをループを実行し、while 文は条件が true の間ループを実行します。 なお、

for 文のループ回数を示す識別子は、ループ文にローカルな変数として宣言され、その値は配列型のインデックスと

して使用できますが、信号や変数へ直接代入することはできませんので、外部(loop文外)に同一の名称をもつ信号

や変数があっても区別されます。

また、loop 文内の処理をスキップしたり、抜け出したりするために、next 文と exit 文が使用できます。

loop 文(for 文、while 文)の構文は、次のとおりです。

if 条件式 then <順次処理文>

{[ elsif 条件式 then <順次処理文> ]}

[ else <順次処理文> ]

end if;

case 式 is

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

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

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

∙ ∙ ∙

when others => <順次処理>;

end case ;

[for(for-loop)文] for 変数名 in 整数範囲 loop <順次処理文>;

end loop;

[while(while-loop)文] while 条件(式) loop <順次処理文>;

end loop;

16

next 文と exit の構文は、次のとおりです。

(注)when 文がない場合、next 文では end loop;までスキップし、exit 文では loop 文を抜け出します。

(使用例)

- ループ変数 Lが3の時、順次処理文2が - 信号A=B が成り立つ時、ループを抜ける

スキップされる

(5) wait 文

wait 文は、プロセス文の起動制御を行うために用います。 wait on, wait until, wait forがあります。 なお、

wait 文とセンシティビティ・リストを同時に使用することはできません。

next 文と exit の構文は、次のとおりです。

- on: 指定した信号のいずれか一つが変化するまで

- until: 指定した条件が成り立つまで

- for: 指定した時間が経過するまで、処理を一時停止する。

指定条件のいずれか一つが成立すると、その wait 文の次の文から処理を再開する。 なお、何の指定もない

wait 文を用いると、wait 文を処理した段階で、その wait 文のある process文は永久に停止する。

(使用例)

process begin

wait on SIG_A, SIG_B;

wait for 20ns;

wait until A>5;

wait until clock’event and clock=’1’;

wait on A, B until C > D for 10ns ;

- この使用例では、

・信号A、B の少なくともいずれか一方の値が変化するか、 あるいは、

・信号C、D の間に“C > D”なる関係が成立するか、 あるいは、

・10[ns]の時間が経過するまで、

処理を一時停止する。

[next文] next when 条件(式) <順次処理文>;

[exit文] exit when 条件(式);

for L in 0 to 7 loop

<順次処理文 1>;

next when L = 3;

<順次処理文 2>;

end loop;

for N in 0 to 7 loop

<順次処理文>;

exit when A = B;

end loop;

Wait [ on 信号名 {,信号名…}] [ until 条件 ] [ for 時間 ]

17

1.1.8 構造化記述

構造化記述を行うには、回路内で使用する構成要素( “コンポーネント”、“素子”、“パーツ”等と呼びます)をコン

ポーネント文で宣言し、それを回路内で識別するためのラベル(“インスタンス名”と呼びます)を付けて配置し(“イン

スタンスする”と言います)、その入出力端子と内部信号を接続して、回路を設計します。

(構造化記述の手順)

① コンポーネントの宣言; 半加算器:half_adder の例

(説明) コンポーネント名は、half_adder となります。 [ component コンポーネント名 ]

port 文の部分は、半加算器:half_adder の VHDL記述の entity 文と同じです。

コンポーネント宣言のエンド文は、必ず“end component;”です。

② コンポーネント(素子)をインスタンス(配置)し、信号を接続する(関連付ける)

階層構造を記述するには、コンポーネント宣言したコンポーネントをインスタンスして実現します。この文の構造

は、以下のとおりです。 インスタンス名を変更すると、同じコンポーネントを複数回使うことができます。

- port map 文: 各インスタンスの入出力ポートと外部信号、内部信号との関連付けを行います。

接続の方法には、名前による関連付けと位置付けによる関連付けの 2 種類があります。

[名前による関連付け]

インスタンスされたコンポーネントのポートと接続される信号をそれぞれの名前で関連付けを行います。

仕様は、以下のとおりです。 入力 in、出力 out に関わらず、“=>”の左側がコンポーネントの端子(ポート)名、

右側がそれに繋がる信号名です。 また、名前で関連付けを行うので、ポート名の記述順序は任意です。

(記述例) この記述方法で、コンポーネント:harf_adder をインスタンス名;H1、H2 でインスタンス(配置)した場

合、以下のようになります。

H1: harf_adder port map ( A => A, B => B, S => sig2, CO => sig1 );

H2: harf_adder port map ( A => sig2, B =>CIN, S =>S, CO => sig3 );

[位置による関連付け]

コンポーネント宣言の入出力ポートの記述順に従って接続する信号を記述して、関連付けを行います。

(コンポーネント宣言における端子の位置)

(port map 文に記述する接続する信号名の位置)

(記述例) この記述方法で、コンポーネント:harf_adder をインスタンス名;H1、H2 でインスタンス(配置)した場

合、以下のようになります。

H1: harf_adder port map ( A , B, sig2, sig1 );

H2: harf_adder port map ( sig2, CIN, S, sig3 );

component half_adder

port ( A, B : in std_logic;

S, CO : out std_logic);

end component;

port map ( 端子名 => 信号名,端子名 => 信号名,・・・);

port map ( ①, ② : in std_logic; ③, ④ : out std_logic );

port map ( ①につなげる信号名, ②につなげる信号名, ③につなげる信号名, ④につなげる信

インスタンス名: コンポーネント名 port map ( 入出力ポートと内部ネットの接続を記述する ) ;

18

1.1.9 テストベンチの構造

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

(VHDL モデル定義文)

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

(エンティティ文)

entity エンティティ名 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 文を宣言しません

19

1.2 VHDL 記述例

1.2.1 半加算器: half_adder.vhd

図 1-6(a)は、半加算器の論理回路図の一例です。 この論理回路図をVHDL記述したものが図 1-6(b)です。

(通常このような記述はしませんが、VHDLの仕様を理解するために記述しています)。

図 1-6(a) 半加算器: half_adder の論理回路図の一例

図 1-6(b) (a)の論理回路図の VHDL記述: half_adder.vhd

(VHDL記述内容の説明)

図 1-6(b)の VHDLの記述は、以下の三つのブロックに区別できます。

[(1行目) -- ~ (行末)まではコメントとして処理されます]

① VHDLモデル定義(2~3 行): 使用するライブラリを宣言します

② エンティティ文 (5~8 行): モジュール名:half_adder と入出力端子を定義します

③ アーキテクチャ文 (10~17行): モジュールの内容を記述します

-(11 行目) 内部で使用する信号:sig1、sig2 とその属性:std_logic を定義します

-(13 行目) 入力信号A とB の nand 演算の結果を内部信号 sig1 に出力する

-(14 行目) 入力信号A とB の or 演算の結果を内部信号 sig2 に出力する

-(15 行目) sig1 の not 演算の結果を出力信号に出力する

-(16 行目) sig1 と sig2 の and 演算の結果を出力信号に出力する

[注意] アーキテクチャ文の 13 行目~16 行目を以下のようには、記述できません。

出力信号:CO が入力信号として扱われています (⇐ 出力信号 S に出力信号CO が入力されている)

VHDL では、“出力信号を入力信号として扱えない”ので、コンパイルエラーとなります。

CO <= A and B;

S <= not CO and ( A or B );

--half_adder

library IEEE;

use IEEE.std_logic_1164.all;

entity half_adder is

port( A, B : in std_logic;

S, CO : out std_logic );

end half_adder;

architecture RTL of half_adder is

signal sig1, sig2: std_logic;

begin

sig1 <= A nand B;

sig2 <= A or B;

CO <= not sig1;

S <= sig1 and sig2;

end RTL;

sig1

sig2

A

B

CO

S

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

20

1.2.2 全加算器: full_adder.

(1) 階層化による論理回路設計

全加算器:full_adderは、下位桁から桁上がり(キャリー)を考慮した加算器です。 図1-7(a)は、半加算器(half_adder)

を二つ組み合わせて実現した論理回路図です。 この回路図を使って、全加算器を VHDL で記述したものが図 1-7(b)

です。

図 1-7(a) 全加算器(full_adder)の回路構成

図 1-7(b) (a)の論理回路図の VHDL記述: full_adder.vhd

(VHDL記述内容の説明)

① VHDLモデル定義(1~2 行): 使用するライブラリを宣言します

② エンティティ文 (4~6 行): モジュール名:full_adder と入出力端子を定義します

③ アーキテクチャ文 (8~17 行): モジュールの内容を記述します

-(09~11 行目) 回路内で使用するモジュールを宣言して、階層設計を実現します。

半加算器:half_adder(図 1-6(b))の entity 部を記述します。

-(12 行目) 信号:sig1、sig2、sig3 とその属性:std_logicを定義します。

-(14、15 行目) component 文で宣言された半加算器をインスタンス名:H1、H2 で

インスタンスして階層設計します。 Port map で上下階層を接続します。

-(16 行目) 内部信号 sig1と sig3 の or 演算の結果を出力信号CO に出力します。

--full_adder

library IEEE;

use IEEE.std_logic_1164.all;

entity full_adder is port(A,B,CIN : in std_logic;

S,CO: out std_logic);

end full_adder;

architecture RTL of full_adder is

component half_adder port(A,B : in std_logic;

S,CO: out std_logic);

end component;

signal sig1, sig2, sig3 : std_logic;

begin

H1: half_adder port map (A,B,sig2,sig1);

H2: half_adder port map (sig2, CIN, S, sig3);

CO <= sig1 or sig3;

end RTL;

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

sig1

sig2 A

B

A

B

CO

S half_adder

CIN

sig3

CO

S

A

B

CO

S half_adder

H1

H2

21

(2) 真理値表による機能設計

全加算器(full_adder)の真理値表は、下表のとおりです。 この真理値表を使って、全加算器の動作を VHDLで

記述して、設計することもできます(動作記述)。 図 1-8 が cse 文を使った VHDL の記述例です。

図 1-8 全加算器の動作を VHDL で記述した例:full_adder2.vhd (動作記述)

(VHDL記述内容の説明)

アーキテクチャ文 (7~22 行)内の記述内容は、以下のとおりです。

-(08 行目) signal 文で内部信号名:INPUT とその属性:std_logic_vector(2 downto 0)を定義します。

-(10 行目) 入力信号:CIN、B、A を連接して、INPUT に代入します。

-(11 行目) process 文で入力信号:INPUT の変化をセンスします。

-(12~21 行目) case 文とwhen 文を使って、INPUT の値で分岐して、出力信号:CO、S に対応する

状態を出力します。 std_logic の状態値は 9 値なので、他の全ての組み合わせも

記述する必要があり、others を用います。

-(22 行目) case 文、process 文、architecture 文それぞれの end 文です。

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

library IEEE;

use IEEE.std_logic_1164.all;

entity full_adder2 is

port(A,B,CIN : in std_logic;

S,CO: out std_logic);

end full_adder2;

architecture RTL of full_adder2 is

signal INPUT : std_logic_vector(2 downto 0);

begin

INPUT <= CIN & B & A;

process (INPUT) begin

case INPUT is

when “000” => CO <= `0`; S <= `0`;

when “001” => CO <= `0`; S <= `1`;

when “010” => CO <= `0`; S <= `1`;

when “011” => CO <= `1`; S <= `0`;

when “100” => CO <= `0`; S <= `1`;

when “101” => CO <= `1`; S <= `0`;

when “110” => CO <= `1`; S <= `0`;

when “111” => CO <= `1`; S <= `1`;

when others => CO <= `X`; S <= `X`;

end case; end process; end RTL;

A

B

CO

S

全加算器の真理値表

CIN

22

1.2.3 セレクタのいろいろな記述方法

[セレクタの機能]

セレクタ信号:SELS に従って、入力信号:A、B、C、C を選択して、

出力信号:Mに出力する。

SELS: “00” のとき、 入力信号:A ⇒ 出力:M

SELS: “01” のとき、 入力信号:B ⇒ 出力:M

SELS: “10” のとき、 入力信号:C ⇒ 出力:M

SELS: “11” のとき、 入力信号:D ⇒ 出力:M

図 1-9 セレクタのシンボル図とその機能

(1) case 文を使ったて VHDL記述: stg_logic_vector(左)、bit_vector(右)を使った場合

(VHDL記述内容の説明)

-シンボル図に従って、entity 文でモジュール名:M_BEHAVIOR、入力信号:A、B、C、D(std_logic)、

出力信号:M(std_logic_vector)、セレクタ信号:SELS を定義します。

-architecture 内の process で入力信号の SELS, A, B, C, Dの状態変化をセンスして、どれかの信号が

が変化したときに case文の内容を実行します。

-両者の違いは、SELS の宣言内容です。

左側は std_logic_vector(0 to 1)、右側は bit_vector(0 to 1)で宣言しています。

std_logic の状態値は 9 値なので 9x9=81 通り、bit_vector の状態値は 2 値なので 2x2=4 通りの組み合わ

せがあるので、記述内容もそれに従って書き方となっています。

bit_vector の場合 4通りしかないので、“00, 01, 10, 11” の 4 通り全てを記述すればよいですが、

std_logic の場合 81通りあるので、全てを記述するのは無駄なので、others を使って、それまでの

when 文で記述した状態値以外全ての場合の動作を記述します。 上記の例(左側)では、SELS の

状態値が“00, 01, 10”以外の場合、入力信号:D が出力信号:Mに出力されます。

[重要] std_logic を使用する場合、状態値が 9 値であることを忘れずに、適切に記述しましょう。

これに関連したエラーメッセージも多く出力されるので、注意しましょう。

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;

M

SELS

A

B

C

D

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;

23

(2) if then else/elsif 文を使った VHDL記述

(VHDL記述内容の説明)

-シンボル図に従って、entity 文でモジュール名:N_BEHAVIOR、入力信号:A、B、C、D(std_logic)、

出力信号:M(std_logic_vector)、セレクタ信号:SELS を定義します。

-architecture 内の process で入力信号の SELS, A, B, C, Dの状態変化をセンスして、どれかの信号が

が変化したときに process文内の内容を実行します。

-両者の違いは、if 文だけで記述した場合(左側)と if/elsif 文を使って記述した場合(右側)です。

両方ともに SELS は std_logic_vector(0 to 1)で宣言しているので、SELS は 81 通りありますが、

“00, 01, 10”以外の状態値の場合、入力信号:D が出力信号:Mに出力されます(else M <= D;)。

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 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 = "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;

24

1.2.4 D-FF の VHDL 記述

フリップフロップ (flip-flop) は、2進法の基本である 1 ビットの情報を一時的に"0"または"1"の状態として保持(記

憶)することができる論理回路で、順序回路の基本要素です。 FFはその構造と機能によって、RS型(SR型とも呼ば

れ、Set-Reset の略)、JK 型(語源不明)、D 型(Delayed の略)、T 型(Toggle の略)といった種類に分類されます。

D-FFは、クロック (clk) 端子の立ち上がりエッジでD入力の値をQ出力として出力します。 この動作は、process

文を使って、動作をそのまま表現すれば、簡単に記述できます。 回路(図)を意識せずに設計できるところが VHDL

の利点です。 一般に、D-FFにはリセット機能が付加されます。 これは、強制リセットのために、クロックに非同期で

働きます。 つまり、リセットがオンとなればクロックに関係なく即座に出力が 0 となります。

図 1-10 リセット付き D-FFのタイミングチャート

[D-FFのVHDL記述]

図 1-10 のタイミングチャート(動作)に従って、D-FFを VHDL記述すると図 1-11 のようになります。

図 1-11 D-FFのVHDL記述(D-FF.vhd)

(VHDL記述内容の説明)

-(04~07 行目) entity 文でモジュール名:D-FF、入力信号:clk、rst、D(std_logic)、

出力信号:Q(std_logic を定義します。

-(10 行目) process 文で入力信号:clk、rstの状態変化をセンスします。

-(11 行目) rst は非同期で処理するので、まず rst 信号を確認します。

なお、rstは内部で反転されるので、状態値:’1’がリセット状態です。

-(12 行目) clk信号が立上りエッジであれば、Q<=D;を実行します。

上記の記述で、図 1-10 のタイミングチャートの動作が記述されていることを確認して下さい。

D Q

clk

rstリセット

clk

rst

D

Q

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 = '1') then Q <= '0';

elsif( clk' event and clk = '1' ) then Q <= D;

end if;

end process; end RTL;

01

02

03

04

05

06

07

08

09

10

11

12

13

14

25

2. 評価ボード: DE0-CV の説明

2.1 評価ボードの概要

図 2-1 が評価ボード[実習ボードもしくは実機と呼ぶ]: Terasic 社製DE0-CV の外観です。

図 2-1 評価ボード: DE0-CV

[主な搭載部品] の説明普請の搭載 FPGA

- 電源スイッチ: ON/OFFスイッチです。

- USB ポート: USB ケーブルで PCと接続します(電源供給もされるので、電源コード接続不要)。

- 搭載 FPGA: Altera社製: Cyclone V (E Base) 5CEBA4F23C7

[FBGA パッケージ、484 ピン、速度グレード:7] が搭載されています。

(注)設計データから作成される実行モジュール(*.sof)は、ここにアップロードされます。

- Button スイッチ: a接点型(次節参照)の押しボタンスイッチが 4 個(KEY0~3)搭載されています。

- Slide スイッチ: スライドスイッチが 10 個(SW0~9)搭載されています

- 7-Segment Display (7segLED) : 7セグメントの表示デバイスが 6 個搭載されています。

[注意] スイッチとして上記以外に、

(Button Switch:KEY4)FPGA Reset 用

(Slide Switch:SW10) RUN/PROG 用 (上側にスライドされている)

がありますが、本実習では使わないので、絶対に操作しないでください。

26

2.2 入力デバイス: ボタンスイッチとスライドスイッチの仕様

(1)ボタンスイッチ: KEY0 ~ KEY3

DE0-CV のボタンスイッチ:KEY0~3 は、図 2-2 にように接続されています。

図 2-2 ボタンスイッチと FPGA の接続

[ボタンスイッチの仕様]

ボタンスイッチには、以下のように、2 つのタイプがあります。

a接点型: スイッチを押すと接点が繋がり

電流が流れる

b接点型: スイッチを押すと接点が離れて

電流が止まる

図 2-2 のとおり、DE0-CV には、“a 接点型スイッチ”が搭載されていますので、“ボタンを押したときに回路が

接続”します。 例えば、ボタンスイッチ:KEY0 を押下すると、それが接続されている FPGA の入力ピン

(ピン名:PIN_U7)の電圧が VCC3P3(DE0-CV では 3.3Vです)から GND(通常 0V)に変化します。

すなわち、状態値(論理値)で考えると、“1 → 0”と変化します。 これを波形で考えると以下のようになり、

この変化を正確にセンスすれば、“ボタンが押下されたこと”、さらには、“押下された回数”を入力情報として

得ることができます。

[ボタンスイッチの入力状態の変化]

各ボタンスイッチが接続されている FPGA のピン名

push push

27

(2)スライドスイッチ: SW0 ~ SW9

DE0-CV のスライドスイッチ:SW0~9 は、図 2-3 にように接続されています。

図 2-3 スライドスイッチと FPGA の接続

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

スライドスイッチは、図 2-3のように、上方にスライドすると“論理値:1”、下方にスライドすると“論理値:0”と

なります。 例えば、スライドスイッチ:SW0 を下方にスライドすると、それが接続されている FPGA の入力ピン

(ピン名:PIN_U13)が論理値(状態値):0に、下方にスライドすると論理値(状態値):1 にセットされます。

これを波形で考えると以下のようになり、入力情報として取り込むことができます。、

[スライドスイッチの入力状態の変化]

☆ ボタンスイッチ: KEY0~3/スライドスイッチ:SW0~9 と FPGA のピン接続情報

(含む、システムクロック(50MHz)入力端子情報)

各ボタン/スライドスイッチと接続されている FPGA のピン番号は、表 2-1 のとおりです。

なお、システムクロックが入力される FPGA のピン番号も含んでいます。

表 2-1 入力デバイスのピン接続情報

名称 デバイス記号 FPGA の PIN 番号

クロック (50MHz) PIN_M9

ボタン

スイッチ

KEY0 PIN_U7

KEY1 PIN_W9

KEY2 PIN_M7

KEY3 PIN_M6

スライド

スイッチ

SW0 PIN_U13

SW1 PIN_V13

SW2 PIN_T13

SW3 PIN_T12

SW4 PIN_AA15

SW5 PIN_AB15

SW6 PIN_AA14

SW7 PIN_AA13

SW8 PIN_AB13

SW9 PIN_AB12

上方にスライド

下方にスライド

ALTERA Cyclone V

各スライドスイッチが接続されている FPGA のピン名

28

2.3 出力デバイス: 7-Segment Display (7segLED) の仕様

DE0-CV には、表示デバイスとして 6 個のアノードコモン型の 7-Segment Display(HEX0~5)[以降、7segLED]が

搭載されており、各Displayの 7 つのセグメント(LED)がそれぞれ FPGA に接続されています。

HEX5 HEX4 HEX3 HEX2 HEX1 HEX0

図 2-4 DE0-CV に搭載されている表示デバイス:6 個の7segLED

[7segLED の仕様]

7segLED は、名称のとおり、7つのセグメントすなわち 7つの LED から構成されており、それぞれの LED を

ON/OFFすることによって、所望の文字を表示しますが、7segLED には、図 2-5 のように、アノードコモン型と

カソードコモン型の 2 つのタイプがあります。 本実習で使用する評価ボード:DE0-CV には、アノードコモン型

が搭載されているので、その仕様に従って印加電圧を制御することになります。

図 2-5 7segLED のアノードコモン型とカソードコモン型

- アノードコモン型: 各 LED のアノード側が共有され、High 電位(論理値:1)の印加されるので、

カソード側に Low 電位が印加されるとその LED が発光する。

- カソードコモン型: カソード側が共有されので、アノード側に Hi 電位を印加すると発光する。

(アノードコモン型の 7segLED の表示例)

(セグメント番号) 6 5 4 3 2 1 0

(印加論理値) 1 0 0 0 0 0 0

[説明] セグメント:0~5には、論理値:0(Low電位)に印加されるので、それぞれのLEDが発光しますが、

セグメント:6 は、論理値:1が印加されるので発光せず、上図の通り、“0”が表示されます。

0 1 2 3 4 5 6

common

アノードコモン型

0 1 2 3 4 5 6

common

カソードコモン型

ALTERA

Cyclone V

29

☆ 7segLED: HEX0 ~ HEX5 と FPGA のピン接続情報

各 LED のセグメント番号と接続されている FPGA のピン番号は、表 2-2 のとおりです。

この表は大切です。 その意味を正確に把握しておきましょう。

表 2-2 7segLED のピン接続情報

デバイス記号 セグメント番号 FPGA の PIN 番号

HEX0

HEX0[0] PIN_U21

HEX0[1] PIN_V21

HEX0[2] PIN_W22

HEX0[3] PIN_W21

HEX0[4] PIN_Y22

HEX0[5] PIN_Y21

HEX0[6] PIN_AA22

HEX1

HEX1[0] PIN_AA20

HEX1[1] PIN_AB20

HEX1[2] PIN_AA19

HEX1[3] PIN_AA18

HEX1[4] PIN_AB18

HEX1[5] PIN_AA17

HEX1[6] PIN_U22

HEX2

HEX2[0] PIN_Y19

HEX2[1] PIN_AB17

HEX2[2] PIN_AA10

HEX2[3] PIN_Y14

HEX2[4] PIN_V14

HEX2[5] PIN_AB22

HEX2[6] PIN_AB21

HEX3

HEX3[0] PIN_Y16

HEX3[1] PIN_W16

HEX3[2] PIN_Y17

HEX3[3] PIN_V16

HEX3[4] PIN_U17

HEX3[5] PIN_V18

HEX3[6] PIN_V19

HEX4

HEX4[0] PIN_U20

HEX4[1] PIN_Y20

HEX4[2] PIN_V20

HEX4[3] PIN_U16

HEX4[4] PIN_U15

HEX4[5] PIN_Y15

HEX4[6] PIN_P9

HEX5

HEX5[0] PIN_N9

HEX5[1] PIN_M8

HEX5[2] PIN_T14

HEX5[3] PIN_P14

HEX5[4] PIN_C1

HEX5[5] PIN_C2

HEX5[6] PIN_W19

30

3. Quartus Prime Lite の起動方法と新規プロジェクトの作成方法

3.1 Quartus Prime Lite の起動方法

Quartus Prime Lite は、以下の方法で起動します (版数は少し違うかもしれません)。

〇 デスクトップのショートカットによる起動

以下の方法で、デスクトップ上にショートカットを作成して、利用して下さい。

[ショートカットの作成方法]

・ デスクトップの「マイコンピューター」から「ボリューム(C:)」-「intelFPGA_lite 」-「18.0」

-「quartus」-「bin64」-「quartus.exe」を右クリックして、ポップアップメニューから

「ショートカット作成」を選択する。

(参考)スタートメニューからの起動

Windows のスタートメニューから、「Quartus Prime Lite」を選択しても、起動できます。

上記の操作で正常に起動すると図 3-1 の画面が表示されますが、その前に以下の画面が表示される場合は、

“Run the Quartus Prime software” を選択して、”OK“をクリックして下さい。

(お願い)

ツール起動後の詳細な状況に関しては、全てを書き切れませんので、それぞれの状況に応じて、

臨機応変に対応してして下さい。

- “Run the Quartus Prime software” を選択 - “OK”をクリック

31

図 3-1 起動画面(1)

-新規プロジェクトを作成する場合: “New Projet Wizard”をクリックして、“3.2 Quartus Prime Lite での

新規プロジェクトの作成方法“に移ります。

-既存のプロジェクトをオープンする場合: 指定の場所をクリックして、目的のプロジェクトを選択します。

図 3-2 のような起動画面になります。

図 3-2 起動画面(2)

-プロジェクト・ナビゲータにはプロジェクトで使用する設計ファイルなどが表示されます。

(新規の場合は、何も表示されません)

-ステータス・ウィンドウにはプロジェクトの処理状態が表示されます。

既存プロジェクトをオープンする場合: “Recent Projects”にリストされている該当の プロジェクト名をクリックします。 リストされていない場合は、“Open Project”を クリックして、目的のプロジェクトを捜します。

新規プロジェクトを作成する場合: “New Projet Wizard”をクリックします。

プロジェクト・ナビゲータ

“ステータス”画面

32

3.2 Quartus Prime Lite での新規プロジェクトの作成方法 ※この部分は、しっかり覚えておきましょう。

Quartus Prime Lite では、「プロジェクト」という単位で設計データを管理するので、新規の設計を始める前に、プロ

ジェクトの作成を行います。 図 3-3 にプロジェクトの設定手順を示します。

図 3-3 プロジェクト作成フロー

3.2.1 プロジェクト名の指定

「File」をクリックして、「New Project Wizard」を選択します(図3-4)。 “Introduction”画面がポップアップされるので、

「Next」を選択すると、“Directory, Name, and Top-Level Entity”画面(図 3-5)が表示されます。 この画面では、作業

用ディレクトリ(データの保存場所)、プロジェクトの名前、TOP階層名(エンティティ名)を指定します。

図 3-4 新規プロジェクト作成のウィザードの起動

プロジェクト名の指定

Project Type と Add Files の指定

デバイス・ファミリと ターゲット・デバイス名の指定

サードパーティ・ツールの指定

設定の確認

- 「File」 → 「New Project Wizard」を選択 - “Introduction”画面がポップアップするので、

指示に従って、必要な情報を入力していきます。 - (この画面は何もせずに、) 「Next」を選択

33

図 3-5 Directory, Name, and Top-Level Entuty 画面

上記3つの項目を設定して(ここでは、上記テキストどおりに入力してください)、「Next」ボタンをクリックします。

(*)に指定したディレクトリが存在しない場合には、図 3-6 に示すダイアログが開き、ディレクトリの新規作成の

確認がポップアップされるので、「Yes」を選択してください。

図 3-6 ディレクトリの新規作成を確認する画面

【重要】 プロジェクトの作業用ディレクトリ[上記(*)で設定したディレクトリ名]

- このディレクトリ下に、*.qpf[qpf:Quartus Project File]、例えば、half_adder.qpf、が作成され、

プロジェクト全体が管理されます。

- プロジェクトで設計するデータ(VHDL記述)は、全てこのディレクトリの下に保存されるので、

常に意識しておきましょう。

作業用ディレクトリ: Z:/Q_PrimeLite/adder

プロジェクト名 : half_adder

TOP階層名 : half_adder

「Yes」を選択

Next を選択

プロジェクト名がそのまま表示されます

(*)

34

3.2.2 Project Type と Add Files 設計ファイルの指定

[Project Type]

“Empty project” を選択状態して、「Next」を選択します(図 3-7)。

図 3-7 Projet Type 画面

[Add Files]

設計途中のデータや、過去に設計したデータに変更を加える場合はファイル名を指定しますが、今回は、

新規に設計を行うため、何も指定せずに、「Next」ボタンを選択します(図 3-8)。

図 3-8 Add Files 画面

「Next」を選択

- “Empty project”を選択後、 - 「Next」を選択

35

3.2.3 デバイス・ファミリの指定

「Family, Device & Board Settings」画面です。 ここでは、評価ボード:DE0-CVに搭載されている FPGAの属性を指

定します。 DE0-CV には、以下の FPGA が搭載されているので、図 3-9 のように、各選択項目を選択します。

(Altera 社製) Cyclone V シリーズ: 5CEBA4F23C7

[484 ピン、FBGA パッケージ、スピードグレイド:7]

【重要】 この指定に従って、実行ファイルが生成されるので、正確に指定してください。

- 「Device family」は、「Family」 は、“Cyclone V [E/GX/GT/SX/SE/ST]”、

「Device」 は、“Cyclone V E Base“ を選択します。

- 「Show in ‘Available device’ list」では、「Package」は、“FBGA”、

「Pin count」は、“484”、

「Speed grade:」は、“7” を選択します。

(「Specific device selected in ‘Available device’ list」を選択状態して)

- 「Available devices」に表示されいる list から、「5CEBA4F23C7」 を選択します。

[← 注意して、正しく選択してください]

図 3-9 Family, Device & Board Settings画面

“5CEBA4F23C7” を選択

Family: Cyclone V …

Device: Cyclone V E Base Pin count : 484

Speed grade: 7

「Next」を選択

Package : FBGA

36

3.2.4 サードパーティ・ツール指定

「EDA Tool Settings」画面です。 サードパーティのツールを使用する場合は、この画面(図 3-10)で設定しますが、

今回は、Quartus Prime Lite のツールしか使わないので、下記のように指定されていることを確認して、「Next」を

選択してください。

図 3-10 EDA Tool Settings 画面

3.2.5 設定の確認

「Summary」画面(図 3-11)です。 これまで行った設定を確認することができます。 誤りがあれば、「Back」ボタンを

選択して、修正を行います。 確認後、「Finish」ボタンを選択すると、新規プロジェクトの設定が完了します。

図 3-11 Summary 画面

“Simulation”は、<None> を選択

「Next」を選択

「New Project Wizard」で設定した内容が一覧されるので、

正しく設定されていることを確認後、「Finish」 を選択

37

「Finish」ボタンを選択すると、New Project Wizard が終了して、図 3-12 に示す画面が表示されます。

- プロジェクト・ナビゲータで“Hierarchy”を選択すると(選択されているはず)、

Cyclone V: 5CEBA4F23C7 [← Device で選択したデバイス]

half_adder

- Quartus Prime Lite のタイトルバーに

作業用ディレクトリのパス名: z:/Q_PrimeLite/adder/half_adder – half_adder

と表示されているので、必ず確認してから、次のステップに進みましょう。

図 3-12 New Project Wizard 終了後の画面

このタイトルバーの部分に、 「z:/Q_PrimeLite/adder/half_adder – half_adder」と表示される

- “Hierarchy”を選択 - Cyclone V: 5CEBA4F23C7

>half_adder と表示される

プロジェクト名

38

4. 『半加算器』の評価ボードによる動作確認

4.1 動作確認するための全体回路

半加算器の VHDL記述は、図 4-1[図 1-6(b)と同じ]のとおりです。

図 4-1 半加算器の VHDL記述:half_adder.vhd [図 1-6(b)と同じ]

この設計が正しいかどうかを確認するためには、評価ボード(実機):DE0-CV の仕様(第 2 章参照)に合わせて、

全体回路の仕様を決定し、全体回路と周辺回路を設計する必要があります。

[全体回路の仕様]

実機評価用の全体回路(half_adder_top)の構成は、図 4-2のようになります。

DE0-CV の入力デバイスで入力信号を入力し、半加算器の演算結果を表示デバイスに表示します。

(入力) スライドスイッチ:SW0 と SW1 から入力信号A、B を入力する。

SW0 → (入力信号) A、 SW1 → (入力信号) B

(出力) 表示デバイス:HEX0~3 に入力信号A、B、演算結果CO、S を表示する。

HEX3: (入力信号) B、 HEX2 → (入力信号) A

HEX1: (出力信号) CO、HEX0 → (出信号) S

図 4-2 半加算器の実機評価用の全体回路:half_adder_top

--half_adder

library IEEE;

use IEEE.std_logic_1164.all;

entity half_adder is

port( A, B : in std_logic;

S, CO : out std_logic );

end half_adder;

architecture RTL of half_adder is

signal sig1, sig2: std_logic;

begin

sig1 <= A nand B;

sig2 <= A or B;

CO <= not sig1;

S <= sig1 and sig2;

end RTL;

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

SW1

SW0

入力信号:B

入力信号:A

入力信号:B

入力信号:A

出力信号:CO

出力信号:S

B

CO

S

A 半加算器

周辺回路

入力信号処理部 出力信号処理部

全体回路 システムクロック:50MHz

39

4.2 半加算器の実機評価用全体回路の VHDL 記述: half_adder_top.vhd

4.1のとおり、全体回路は、以下の構成になっています。

全体回路(最上位回路、トップモジュール): half_adder_top

├ 半加算器: half_adder

└ 周辺回路: peripheral_half

〇周辺回路: “入力信号処理部”(入力信号を読み込む)と“出力信号処理部”(半加算器の演算結果と

入力信号を表示デバイス用の出力信号に変換して出力する)の機能が含まれますが、まずは

実習全体の流れを理解するために、準備した「周辺回路:peripheral_half」を利用します。

なお、「周辺回路:peripheral_half.vhd」 の“entity 宣言部”は、図 4-3 のように記述されている

ので、全体回路の component 宣言は、これを利用します。

図 4-3 周辺回路:peripheral_half.vhd の entity 宣言部

(端子の説明)

- (入力端子)CLK、A、B: クロック信号、半加算器への外部からの入力信号

- (入力端子)S_in、CO_in: 半加算器の演算結果

- (出力端子)A_out、B_out: 雑音を除去した半加算器への入力信号

- (出力端子)LED0~LED3: 表示デバイスへの出力信号(7 ビット幅)

[全体回路(トップモジュール):half_adder_top の回路構成]

半加算器:half_adder と周辺回路:peripheral_half で構成される全体回路(トップモジュール)の回路図は、

図 4-4 のようになります。 各名称は、それぞれの entity 宣言部の名前と一致しています。

図 4-4 全体回路の回路構成: half_adder_top

entity peripheral_half is

port( CLK, A, B: in std_logic;

S_in, CO_in: in std_logic;

A_out,B_out: out std_logic;

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

end peripheral_half;

周辺回路: peripheral_half

全体回路: half_adder_top

A_in

B

CO

S

A 半加算器

B_in

CLK CLK

A

B

LED3

LED2

LED1

LED0

HEX3

HEX2

HEX1

HEX0

7

CO_in

S_in

A_out

B_out

7

7

7

a-sig

b-sig

S_sig CO_sig

40

[全体回路(トップモジュール)のVHDL記述: half_adder_top.vhd]

図 4-4 のVHDL記述が図 4-5 です。 “1.1.8 構造化記述”を参考にしてください。

図 4-5 全体回路(トップモジュール)の VHDL記述: half_adder_top.vhd

(記述内容の説明: 図 4-4を参照してください)

-(05~08 行目) entity 文でモジュール名:half_adder_top と入出力端子名を定義します。

-(11~16 行目) component 文で周辺回路:peripheral_half を宣言します。

-(17~20 行目) component 文で半加算器:half_adder を宣言します。

-(21 行目) この回路内で用いる内部信号名を宣言します(図中の信号名を参照)。

-(23~27 行目) 周辺回路:peripheral_half をインスタンスして、各端子にそれぞれの信号を接続します。

-(28~29 行目) 半加算器:half_adder をインスタンスして、各端子にそれぞれの信号を接続します。

上記記述では、「名前による関連付け」(“1.1.8 構造化記述”参照)でインスタンス間を接続していますが、

図 4-4 の内容が正しく記述されていることを確認して下さい。

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

-- Top module for half adder

library IEEE;

use IEEE.std_logic_1164.all;

entity half_adder_top is

port(CLK, A_in, B_in : in std_logic;

HEX0,HEX1,HEX2,HEX3 : out std_logic_vector(6 downto 0));

end half_adder_top;

architecture RTL of half_adder_top is

component peripheral_half

port(CLK, A, B: in std_logic;

S_in, CO_in: in std_logic;

A_out,B_out: out std_logic;

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

end component;

component half_adder

port(A, B : in std_logic;

S, CO: out std_logic);

end component;

signal a_sig, b_sig, S_sig, CO_sig: std_logic;

begin

INST1: peripheral_half

port map(CLK => CLK, A => A_in, B => B_in,

A_out => a_sig, B_out => b_sig,

S_in => S_sig, CO_in => CO_sig,

LED0 => HEX0, LED1 => HEX1, LED2 => HEX2, LED3 => HEX3);

INST2: half_adder

port map(A => a_sig, B => b_sig, S => S_sig, CO => CO_sig);

end RTL;

41

4.3 Quartus Prime Lite での VHDL ファイルの作成: データ入力

Quartus Prime Lite で VHDLファイルを作成する手順は、以下のとおりです。

4.3.1 半加算器と全体回路のVHDL記述の入力&保存

[操作手順](図 3-12 の画面上で)

- 「File」→「New」 を選択後、ポップアップウィンドウ中の 「VHDL File」 を選択し、「OK」を選択します(図 4-6)。

- VHDLエディタが表示される(図 4-7)ので、VHDL記述:半加算器「[half_adder(図 4-1)と全体回路

「half_adder_top (図 4-5)」を入力します。

図 4-6 VHDLを記述するエディタの起動方法

図 4-7 VHDLエディタ画面

- 「File」 → 「New」を選択後、

- 「VHDL File」を選択

- 「OK」を選択

エディタ画面

VHDL1.vhd と表示される

42

- まず、半加算器:half_adder の VHDL記述を図 4-1 に従って入力します。

- 入力した VHDLは、 「File」 → 「Save As…」 を選択して、保存します(図 4-8)。 このコマンドは、新規に

作成した場合に使うので、「名前を付けて保存」画面(図 4-9)がポップアップされます。 ここで保存するファイル

名を指定しますが、ここでは、“half_adder.vhd” として下さい。 特に、ファイルの拡張子は、“.vhd” として下さい

[VHDLファイルの拡張子は、“.vhd” で統一します]。 「保存」ボタンを選択すると保存されます。

なお、既存のファイルを変更して同じ名前で保存する場合は、「Save」 コマンドを使います。

- 同様にして、全体回路(トップモジュール):half_adder_top.vhd も入力して、(この名前で)保存します。

図 4-8 記述した VHDLファイルを新しいファイル名で保存

図 4-9 新規保存する場合の「名前を付けて保存」画面

- エディタ画面で入力した VHDL記述を、(新しい)名前を

付けて保存する場合は、「Save As..」を選択

- VHDL記述を編集後、上書き保存する場合は、「Save」を

選択 (もしくは、“Ctrl+S”)

半加算器の VHDL 記述

- 「ファイル名」を指定

半加算器: hal_adder.vhd

全体回路: hal_adder_top.vhd

- 「ファイルの種類」は、 “VHDL(*.vhd,*vhdl)” を選択

- 「保存」を選択

プロジェクトの作業用ディレクトリ名が表示されている

43

4.3.2 周辺回路: peripheral_half のダウンロード

前述[4.2]のとおり、半加算器の実機検証用回路の全体構成は、以下のようになっています。

全体回路(最上位回路、トップモジュール): half_adder_top

├ 半加算器: half_adder

└ 周辺回路: peripheral_half

この3つのモジュールの内、半加算器:half_adderとトップモジュール:half_adder_topのVHDL記述は入力したので、

残りは、「周辺回路:peripheral_half」だけです。 この作成には、現段階では、少し時間がかかるので、全体の流れの

習得を優先して、既に設計されたものを利用します。

[peripheral_half.vhd のダウンロード&プロジェクトメンバーへの追加]

- このモジュールは、“http://www.ed.tus.ac.jp/~jte401/” に置いてあります。

- 上記をアクセスして、ファイルをダウンロードし、VHDLエディタに paste して、この名前で保存します。

(“*.vhd”ファイルは、テキストファイルです)。

- プロジェクトメンバーに追加する

4.3.3 Quartus_Prime_Lite でのプロジェクトメンバーの管理 [⇐ 重要]

Quartus_Prime_Lite で設計する場合、VHDLをコンパイルしたり、実行モジュールを作成したりするために、

プロジェクトメンバーを正しく管理することが重要です。 4.3.1と4.3.2の作業で3つのモジュールを入力/

保存しましたが、これらのモジュールをプロジェクトメンバーとして登録(認識)する必要があります。

[プロジェクトメンバーの確認方法]

Quartus Prime Lite の画面内に、「Project Navigator」画面(図 4-10)があり、「Files」を選択すると、現在の登録

(認識)されているプロジェクトメンバーのモジュール名が表示されます。 設計ソースをコンパイルしたり、実行モ

ジュールを作成するためには、必要なモジュールがプロジェクトメンバーに登録されていないと正しく処理されない

ので、常に意識してこのメンバーリストに過不足がないかを確認することが大切です。

これまでの作業で、現在のプロジェクトメンバーには、

- half_adder.vhd

- half_adder_top.vhd

- peripheral_half.vhd

の3つのモジュールが登録されています(はずです)。 もし、メンバー一覧が上記のとおりでない場合は、

以下の操作でメンバーの管理を行ってください。

図 4-10 「Project Navigator」画面

現在登録されているプロジェクトメンバーの一覧です。

これまでの作業が正しく処理されていれば、以下の3つのモジュール名が

登録されているはずです。

- half_adder.vhd、 half_adder_top.vhd、 peripheral_half.vhd

「Files」を選択する

44

[プロジェクトメンバーの管理(追加/削除)方法]

プロジェクトメンバーの管理は、プルダウンメニューの「Project」をクリックして(図 4-11)、

- Add Current File to Project

- Add/Remove Files ino Project

を選択操作して行います。

図 4-11 プロジェクトメンバーの管理の方法

図 4-12 「Project Navigator」画面から「Add/Remove files to Project」の選択

[オープンしているファイルを追加する場合]

- メンバーに追加したいモジュールを

エディタでオープンして表示する

(編集できる状態にする)

- 「Add current file to Project」を選択する

- 編集中のモジュールがプロジェクトメンバーに

追加される。

[プロジェクトの作業ディレクトリ下の

モジュールをメンバーに追加する場合]

- 「Add/Remove files to Project」を選択する

- “Setting”画面(図 4-13)がポップアップする

- 手順に従って操作すると、所望のモジュール

がプロジェクトメンバーに追加される。

なお、上記の「Add/Remove files to Project」は、

図 4-12 のように、「Project Navigator」画面で 「Files」を表示した状態で、”Files”を右クリック しても、選択することができます。

”Files”を右クリックすると、「Add/Remove files to Project」が

表示されるので選択すると、“Setting”画面(図 4-13)がポップ

アップします。

[プロジェクトメンバーから削除する方法]

「Project Navigator」画面にリストされているプロジェクトメンバーから削除したいモジュール名を選択して、

“del”キーを押下すると、プロジェクトメンバーから削除する(remove)ことができます。

なお、この操作により、プロジェクトメンバーから削除されますが、プロジェクトの作業ディレクトリからは

削除されませんので、再度メンバーとして登録することができます。

45

図 4-13 “Add/Remove Files ino Project”選択後にポップアップされる“Setting”画面

[参考] この“Setting”画面は、プルダウンメニュー:「Assignments」 → “Settings (Ctrl+Shift+E)“

と操作してもポップアップすることができます。

図 4-14 “Setting File”画面

現在登録(認識)されているプロジェクトメンバーの一覧

モジュール名を選択して、“Remove”をクリックすると

メンバー登録から削除されます。

ここを(左)クリックすると、“Setting File”

画面が(図 4-14)がポップアップします。

プロジェクトの作業ディレクトリが表示されます

プロジェクトの作業ディレクトリに保存されているモジュール(.vhd)が

すべて標示されるので、プロジェクトに追加したいモジュールを

選択して、「開く」をクリックすると、図 4-13 に戻ります。

全ての作業が完了したら、「OK」を選択

46

4.4 VHDL 記述のコンパイル

入力した VHDL記述が正しいかどうかを、コンパイルを実行して、確認します。

4.4.1 半加算器: half_adder.vhd のコンパイル

Quartus_Prime_Lite でコンパイルを実行する場合、必ずコンパイルしたい回路を“最上位回路(トップレベル)”として

指定する必要があります。 ここでは、まず半加算器のコンパイルを実行して見ます。

[最上位回路(トップレベル)の指定方法: “Set as Top-Level Entity” の設定]

以下の方法のどれかで設定することができます。

- 「Project Navigator」のモジュールを選択して、右クリックすると画面がポップアップされるので、

そのメニューから 「Set as Top-Level Entity」を選択すると、選択したモジュールがトップレベルに

設定されます(図 4-15)。

- トップレベルしてコンパイルしたいモジュールをエディタで表示します。 図 4-15 は、half_adder.vhd を

表示しています。 ここで、以下の操作を行うと、所望のモジュールがトップレベルに設定されます。

・ 「Project」 → 「Set as Top-Level Entity」と選択する (図 4-16)

・ Ctrl+Shift+J

図 4-15 “Set as Top-Level Entity”を設定する画面①

図 4-16 “Set as Top-Level Entity”を設定する画面②

上記の操作後、図 4-17 のように、 “Messages”画面に、所望のモジュール(ここでは、hlaf_adder)に

トップレベルが変更されたことが表示されるので、必ず確認して下さい。

[(注)英文のとおり、このメッセージは、トップレベルが変更された場合にのみ出力されます.]

図 4-17 “Set as Top-Level Entity”が正しく指定されたメッセージ

- half_adder.vhd を選択後、右クリックして、 ポップアップメニューで、“Set as Top-Level Entity”を選択

- half_adder.vhd を選択して、 Ctrl+Shift+J でもよい

- half_adder.vhd をエディタに表示 - 「Project」

→ “Set as Top-Level Entity”を選択

47

[コンパイルの実行]

(前節でトップレベル回路に指定した) 半加算器:half_adder を最上位回路としてコンパイルを実行します。

Quartus Prime Lite のコンパイルは、VHDL記述した内容が言語仕様として間違いがないかを確認し、設定された

FPGA デバイスに従って論理合成/配置/実行モジュールの作成までを実行します。 従って、このコンパイルが

正常終了しないと次の作業工程に進めないので、しっかりデバッグして下さい。 殆どの原因は、記述ミスです。

[コンパイルの実行方法](図 4-18 ⇒ 図 4-19:正常にコンパイルが実行さた後の画面)

コンパイルは、以下の3つの方法で実行できます。。

- 「Processing」 → 「Start Compilation」を選択する

- ツールバーのアイコンで、 (Start Compilation)を選択する

- Ctrl+L を実行する

図 4-18 コンパイルの実行方法

図 4-19 半加算器:half_adder のコンパイル実行後の画面

このアイコンをクリックすると コンパイルが実行される

「Top-level Entity Nme」が “half_adder”

になっていることを確かめましょう。

- “Tasks”画面は、コンパイルの実行に合わせて、表示が変化しますが、コンパイルが

正常に終了すると、このように、5 つ ✔ が表示されます。

- “Messages”画面に、“Full Compilation was successful.” が表示されていることを確認しましょう。

ここに、赤文字のメッセージが表示された場合は、Fatal エラーが発生しているので、内容を解析し

修正して、再コンパイルします。 [この作業の繰り返しなので、根気よく、デバッグして下さい]

48

4.4.2 全体回路:half_adder_top のコンパイルの実行

半加算器:half_adder のコンパイルを正常終了させた後、評価ボード(実機)で実行する全体回路:half_adder_top の

コンパイルを実行します。

[全体回路:half_adder_top のコンパイル実行の手順](4.4.1参照)

- 「Set as Top-Level Entity」を実行して、トップレベル回路を、“half_adder_top” に変更する

- (前節の)コンパイルの実行方法に従って、コンパイルを実行する

- コンパイル実行後の画面で、正常終了していることを確認する(図 4-20)

図 4-20 全体回路:half_adder_top のコンパイル実行後の画面

4.5 端子割り当て(ピンアサイン)

4.4.2で実行した全体回路のコンパイルで、FPGA で実行する“実行モジュール”が作成されますが、

実際に動作させるためには、もう1つ重要な作業工程があります。 “端子割り当て(ピンアサイン)”です。

全体回路:half_adder_top は、図 4-21 のように、システムクロック、SW0/1 から入力し、HEX0/1/2/3 に出力する

仕様なので、この接続情報を “端子割り当て(ピンアサイン)”で与えます。

図 4-21 入出力デバイスとの接続仕様

- 「Top-level Entity Nme」が “half_adder_top”であることを確認する

- “Tasks”画面で、5 つ ✔ が表示され、コンパイルが正常に終了したkとを確認する

- “Messages”画面で、“Full Compilation was successful.” が表示されていることを確認する。

[Fatal エラー(赤文字のメッセージ)があるとこの表示はされません]

SW1

SW0

入力:B

入力:A

HEX3

入力:B

出力:CO

出力:S

FPGA

全体回路:half_adder_top

CLK

B-in

A-in

HEX3

HEX2

HEX1

HEX0 入力:A

システムクロック HEX2 HEX1 HEX0

49

4.5.1 端子接続情報

図 4-21 の全体回路の仕様から、全体回路:half_adder_top の入出力端子(信号)名と FPGA のピン番号(ピン名)の

接続情報:端子(ピン)割り当て表は、表 4-1 のようになります。 [参照:表 2-1、表 2-2]

表 4-1 半加算器の端子(ピン)割り当て表

全体回路の

信号名 属性

FPGA の

PIN 番号 備 考

CLK 入

PIN_M9 システムクロック

A-in PIN_U13 ボタンスイッチ:SW0

B-in PIN_V13 ボタンスイッチ:SW1

HEX0[0]

PIN_U21

7segLED:

HEX0

HEX0[1] PIN_V21

HEX0[2] PIN_W22

HEX0[3] PIN_W21

HEX0[4] PIN_Y22

HEX0[5] PIN_Y21

HEX0[6] PIN_AA22

HEX1[0]

PIN_AA20

7segLED:

HEX1

HEX1[1] PIN_AB20

HEX1[2] PIN_AA19

HEX1[3] PIN_AA18

HEX1[4] PIN_AB18

HEX1[5] PIN_AA17

HEX1[6] PIN_U22

HEX2[0]

PIN_Y19

7segLED:

HEX2

HEX2[1] PIN_AB17

HEX2[2] PIN_AA10

HEX2[3] PIN_Y14

HEX2[4] PIN_V14

HEX2[5] PIN_AB22

HEX2[6] PIN_AB21

HEX3[0]

PIN_Y16

7segLED:

HEX3

HEX3[1] PIN_W16

HEX3[2] PIN_Y17

HEX3[3] PIN_V16

HEX3[4] PIN_U17

HEX3[5] PIN_V18

HEX3[6] PIN_V19

50

4.5.2 Pin Planner の実行

全体回路の入出力端子(信号)名と FPGA のピン番号(ピン名)の接続は、 「Pin Planner」で行います。

[Pin Planner の起動方法](図 4-22)

- プルダウンメニューで、「Assignment」 → 「Pin Planner」 を選択

- メニューバーで、 (Pin Planner – Ctrl+Shift+N) を選択

図 4-22 「Pin Planner」の起動方法

上記の操作により、「Pin Planner」(図 4-23)が起動します。 正しくコンパイルが実行されていると、画面下の

「All Pins」の「Node Nam」に全体回路:half_adder_top のすべての入出力端子名が表示されるので、確認してください。

図 4-23 「Pin Planner」の起動画面

メニューバーの を選択

51

図 4-23 の「All Pins」の“Lacation”欄に、表 4-1 に従って、図 4-24 のように FPGA のピン番号を割り当てる(アサイ

ンする)ことにより、外部の入力デバイスの信号を取り込んだり、出力デバイスに信号を出力したりすることができる

ようになります。

(例) - A_in の Lacation に PIN_U13 を指定 → ボタンスイッチ:SW0 の状態を A_in に取り込める

- HEX0[6]の Location に PIN_AA22 を指定 → HEX6 のセグメント:6 の LED を ON/OFFできる

[ピン番号の入力方法]

端子割り当て前は、図 4-23 のように、“Lacation”欄は空白になっているので、個々に選択して、

ピン番号と入出力デバイスの対応表に従って、仕様通りにピン番号を1つ1つ入力します。

また、excel 等でピン番号と入出力デバイスの対応関係を準備しておき、copy&paste で入力してもよいですが、

paste 時、予め paste 先の“Lacation”欄を全て選択しておくことが必要なので、注意しましょう。

なお、表 4-2(表 4-1 を並び替えたもの)のような“半加算器の端子(ピン)割り当て表(excel ファイル)”を

準備してあるので、“http://www.ed.tus.ac.jp/~jte401/” からダウンロードして下さい。

表 4-2 半加算器のピン割り当て表

Node Name Direction Location

A_in Input PIN_U13

B_in Input PIN_V13

CLK Input PIN_M9

HEX0[6] Output PIN_AA22

HEX0[5] Output PIN_Y21

HEX0[4] Output PIN_Y22

HEX0[3] Output PIN_W21

HEX0[2] Output PIN_W22

HEX0[1] Output PIN_V21

HEX0[0] Output PIN_U21

HEX1[6] Output PIN_U22

HEX1[5] Output PIN_AA17

HEX1[4] Output PIN_AB18

HEX1[3] Output PIN_AA18

HEX1[2] Output PIN_AA19

HEX1[1] Output PIN_AB20

HEX1[0] Output PIN_AA20

HEX2[6] Output PIN_AB21

HEX2[5] Output PIN_AB22

HEX2[4] Output PIN_V14

HEX2[3] Output PIN_Y14

HEX2[2] Output PIN_AA10

HEX2[1] Output PIN_AB17

HEX2[0] Output PIN_Y19

HEX3[6] Output PIN_V19

HEX3[5] Output PIN_V18

HEX3[4] Output PIN_U17

HEX3[3] Output PIN_V16

HEX3[2] Output PIN_Y17

HEX3[1] Output PIN_W16

HEX3[0] Output PIN_Y16

図 4-24 端子割り当て後の「All Pins」画面

copy & paste

- 半加算器のピン割り当て表を“http://www.ed.tus.ac.jp/~jte401/” からダウンロードして

Excel でオープンする。

- 端子割り当て表の“Node Name”の端子名の並びと「All Pins」の“Node Name”の並びが

一致していることを確認する。 一致していない場合は、excel のソートの機能などを使って

必ず一致させましょう。 [⇐ 重要]

- 端子割り当て表の“Lacation”欄のピン番号を全て copy する。

- 「All Pins」の“Location”は空蘭になっているので(図 4-23 参照)、全ての Node の空欄

(half_adder_top の場合は 31ヶ所)を予め選択しておき、ここに paste する。

- copy&paste 後は、図 4-24 のように、“Location”欄にピン番号が表示されるので、

端子(ピン)名とピン番号が正しく対応しているかを確認する。

52

4.5.3 端子(ピン)割り当て後の再コンパイル

端子(ピン)割り当てが終了した後に、半加算器の実機動作確認回路である全体回路:half_adder_top を最上位回路

に設定して(“Set as Top-Level Entity”を実行)、再度コンパイルを実行します[4.4.2 参照]。

この再コンパイルの実行により、端子(ピン)接続情報を含んだ実行モジュール[コンフィグレーション・ファイル;

FPGA 書き込み用回路ファイル]が生成されるので、これを使って、実機動作の確認を行います。

[備考] 端子割り当ては、一度実行するとその情報はプロジェクト内で保存されます。 従って、その後全体回路を

再コンパイルしても、正しい端子情報を含んだ実行モジュールが生成されますが、端子(ピン)名を変更した

り、入出力端子(ピン)を追加/削除した場合は、再度“Pin Planner”で整合を取る必要があります。

4.6 実行モジュールのダウンロード

評価ボード:DE0-CV を付属の USB ケーブルで PCと接続して、電源を“ON”してください。

「Programmer」を起動して、実行モジュール(コンフィグレーション・ファイル)を評価ボードにダウンロードします。

[Programmer の起動方法](図 4-25)

- プルダウンメニューで、「Tools」 → 「(Programmer」 を選択

- メニューバーで、 (Programmer) を選択

図 4-25 「Programmer」の起動方法

メニューバーの を選択

53

上記の操作で、「Programmer」の起動画面(図 4-26)が立ち上がるので、必要な項目を確認します。

図 4-26 「Programmer」の起動画面

[実行モジュール(コンフィグレーション・ファイル)のダウンロードの実行]

上記の確認項目が全て正しいと、“Start”が選択できる状態になっているので、クリックすると

ダウンロードが始まり、正常終了すると、「Progress:」が“100% [Successful]”と表示されます(図 4-27)。

以上で、半加算器:half_adder の設計が正しいかどうか確認できます。

図 4-27 ダウンロードの実行と正常終了後の状態

USB-Blaster [USB-0] となっていることを確認 ⇒ この表示になっていない場合は、[処置1]を参照

JTAG を選択

File: half_adder.sof となっている ⇒ 必須なので問題ある場合は、[処置2]を参照 [← プロジェクト名.sof (拡張子“.sof”が実行モジュールを示す)]

Device: 5CEBA4F23 と表示されている [← 搭載されているデバイス] Program/Configure: チェック(✔)されている 以上を確認して全ての設定が正しいと “Start”が選択できる状態になっています。

このデバイス名になっていることが必須です。 これ以外の場合は、[処置3]参照

- “Start”をクリック - 「Progress:」が“100% [Successful]”となると正常終了

54

☆ 図 4-26 の確認項目が正しくない場合の処置

[処置1] 「Hardware Setup…」に“USB-Blaster [USB-0]”が表示されていない場合

DE0-CV を接続して、電源が“ON”になっている場合は、基本的に正しく表示されるはずですので、

まず DE0-CV を接続して、電源が“ON”にしてから、以下の処置を行います。。

(処置方法)

「Hardware Setup…」をクリックして、“Hardware Setup”画面(図 4-28)を表示する。

“Currently selected hardware”欄の をクリックすると、“USB-Blaster [USB-0]”が選択できる

状態になっているので、選択して、“Close”を選択すると、図 4-26 の当該部分が正しい表示になります。

図 4-28 「Hardware Setup…」画面

[処置2] 実行モジュールファイル(コンフィグレーション・ファイル)が表示されていない場合

図 4-26 画面の左蘭の「Add File」を選択すると、「Select Programming File」画面(図 4-29)が

ポップアップするので、“output_files”をクリックして、下位のファイルを表示させます。

実行モジュール・ファイル:half_adder.sof が存在するので、これを選択します。 存在しない場合は、

コンパイルが正しく実行されていないので、コンパイルから操作し直してください。

図 4-29 実行モジュール・ファイル(コンフィグレーション・ファイル)の選択

でプルダウン表示して、“USB-Blaster [USB-0]”を選択後、 “Close”をクリックする。

クリックして、下位のファイルを表示させます。

55

[処置3] デバイス名が正しくない場合

プロジェクト作成時の設定が正しくないので、設定し直す必要があります。

再設定後、再コンパイルして、実行モジュールを作成し直してから、「Programmer」を起動します。

[デバイスの再設定の方法] (図 4-30)

図 4-30 デバイス Programmer 画面①

4.7 評価ボードでの動作確認

実行モジュール(コンフィグレーションファイル)のダウンロードが正常終了すると、評価ボード(実機)での

実動作の確認をすることができるようになるので、表 4-3 のスライドスイッチのように操作を行って、表示デバイスが

正しく動作する(表示される)ことを確認して下さい。 仕様通りに動作しない場合は、原因を考えて、正しく動作する

までデバッグを繰り返して、完了させてください。

表 4-3 スライドスイッチの操作と表示内容

スライドスイッチ 入力信号 出力信号 表示デバイス

SW1 SW0 B_in A_in CO S (HEX)5 4 3 2 1 0

0 0 0 0

0 1 0 1

1 0 0 1

1 1 1 0

- 「Assignments」→“Device”を選択

- “Device”画面がポップアップするので、

・「Family」: “Cyclone V [E/GX/GT/SX/SE/ST]” ・「Device」: “Cyclone V E Base“ ・「Package」: “FBGA”、 「Pin count」は、“484”、 「Speed grade:」:“7” ・「Available devices」: 「5CEBA4F23C7」 と評価ボードに搭載されている FPGA の仕様通りに設定

- [OK]を選択

56

【参考】 「RTLViewer」の利用方法

Quertus Prime Liteには、VHDLで設計した回路の論理合成結果を回路図で表示する機能: “RTLViewer”がありま

す。 設計した回路が期待通りに動作しない場合などに、記述した VHDLからどのような回路に論理合成させている

かを直接目で確かめることができるので、デバッグする場合に非常に有効な手段となります。

[RTLViewer の起動方法]

プルダウンメニュー:「Tools」 → 「Netlist Viewers」 → 「RTL Viewer」と選択すると(図 4-31)、

図 4-32 のように、最上位回路(half_adder_top)の回路図が表示されます。 この内容を確認することにより

全体回路:half_adder_top.vhdの記述が正しいかどうかを確かめることができます。

図 4-31 「RTL Viewer」の起動方法

図 4-32 「RTL Viewer」の起動後表示される全体回路:half_adder_top の回路図

“RTL Viewer”の起動方法 - 「Tools」 → 「Netlist Viewers」 → 「RTL Viewer」と選択

VHDL 記述をコンパイルした結果(論理合成結果)から、 生成された回路図: half_adder_top.vhd

全体回路:half_adder_top の階層構造が表示される

左側: Zooming 右側: 画面に合わせて回路図全体を表示

57

[RTLViewer での各操作方法]

下位階層の回路図を表示する方法は、以下のとおりです。

-図 4-32 で表示されているインスタンスの“+”をクリックする(図 4-33)

-図 4-32 で表示されているインスタンスをダブルクリックする(図 4-34)。 単体が表示されます。

-「Netlist Navigator」のインスタンスを右クリックして、“Display in New Tab”をクリックすると、新しい Tab に

選択したインスタンスの回路シンボルが表示され、“+”をクリックすると内部回路が表示されます(図 4-35)。

なお、画面内で右クリックすると、コマンドメニューがポップアップすので、コマントリストから

“Goto Top Level”を選択すると最上回路の回路図に戻ることができます(図 4-34)。

図 4-33 下位階層の表示方法① [インスタンスの“+”をクリックした場合]

図 4-34 下位階層の表示方法② [インスタンスをダブルクリックした場合]

左図の+をクリックすると、下位の回路が 表示され、 をクリックして、回路全体を 表示すると上図のようになります。

58

図 4-35 下位階層の表示方法③

なお、周辺回路:perioheral_half の回路図は、図 4-36 のようになっています。

図 4-36 周辺回路:perioheral_half の回路図

-「Netlist Navigator」→“Display in New Tab”

と選択すると New Tab に選択したインスタンス

の回路シンボルが表示される

-“+”をクリックすると内部の回路図が表示

される

59

5. 『全加算器』の評価ボードによる動作確認

この章では、全加算器の VHDL記述(動作記述): full_adder2 (図 5-1; 図 1-8と同じ)の実機動作確認をします。

半加算器の場合、“周辺回路”と“端子(ピン)割り当て表”は事前に準備されていましたが、ここでは、全て自分で設

計します(一部を除く)。 作業内容は、基本的に半加算器の手順と同じで、以下のようになります。

1) 新規プロジェクト(プロジェクト名:full_adder)を作成する(5.2参照)。

2) 全加算器の VHDL記述(動作記述): full_adder2 (図 5-1)を入力する(full_adder2.vhd)。

3) 周辺回路を設計し、VHDL記述する。

4) 全体回路(トップ回路): top_full_adder を設計し、VHDL記述する。 このモジュールを最上位回路にして

コンパイルを実行し、全体の設計を完了する (コンパイルの fatal エラーを無くして、正常終了させる)。

5) “端子(ピン)割り当て表”を作成し、「Pin Planner」を実行する。

6) 実行モジュール(top_full_adder.sof)をダウンロードして、実機で動作確認する。

もし、正しく動作しない場合は、VHDL記述に戻って修正し、作業を繰り返す。

図 5-1 全加算器の VHDL記述(動作記述): full_adder2.vhd

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

library IEEE;

use IEEE.std_logic_1164.all;

entity full_adder2 is

port(A,B,CIN : in std_logic;

S,CO: out std_logic);

end full_adder2;

architecture RTL of full_adder2 is

signal INPUT : std_logic_vector(2 downto 0);

begin

INPUT <= CIN & B & A;

process (INPUT) begin

case INPUT is

when “000” => CO <= `0`; S <= `0`;

when “001” => CO <= `0`; S <= `1`;

when “010” => CO <= `0`; S <= `1`;

when “011” => CO <= `1`; S <= `0`;

when “100” => CO <= `0`; S <= `1`;

when “101” => CO <= `1`; S <= `0`;

when “110” => CO <= `1`; S <= `0`;

when “111” => CO <= `1`; S <= `1`;

when others => CO <= `X`; S <= `X`;

end case; end process; end RTL;

A

B

CO

S

全加算器の真理値表

CIN

60

5.1 「全加算器 full_adder2」の実機評価用回路: top_full_adder

図 5-1 の「全加算器:full_adder2」の動作を評価ボード(実機)で確認するためには、“半加算器”と同様に、DE0-CV

の仕様に合わせて、入出力仕様を決定し、全体回路:top_full_adder を設計する必要があります。

[全体回路の外部入出力仕様]

全体回路:full_adder2 の入出力デバイスとの接続仕様は、図 5-2 のとおりです。

(入力) システムクロック(50MHz)を入力する

スライドスイッチ: SW0/SW1/SW2 から入力信号A、B、C を入力する。

SW0→ (入力信号) C、 SW1→ (入力信号) A、 SW2 → (入力信号) B

(出力) 表示デバイス:HEX3/4/5 に入力信号A、B、C、HEX0/1 に演算結果CO、S を表示する。

HEX3: (入力信号) C、 HEX4: (入力信号) A、 HEX5 → (入力信号) B

HEX0: (出力信号) S、 HEX1: (出力信号) CO

図 5-2 全体回路の外部接続仕様

[全体回路(トップモジュール):top_full_adder の回路構成]

全体回路: top_full_adder の回路構成は、図 5-3 の通りです。 半加算器では、周辺回路としていた部分が

機能毎に構成要素に分割されています。

- 全加算器: 機能を確認したい回路

- (周辺回路部)

チャタリング制御回路: スライドスイッチからの入力信号の雑音を除去する回路

表示信号変換回路: 回路内部のビット信号を表示デバイス(7segLED)の入力信号に変換する回路

図 5-3 全体回路の回路構成

SW1

SW0

入力: A

入力: B

入力: A

キャリー:C

出力:CO

出力:S

全体回路:top_full_adder

A CO

S

B

全加算器 CIN

FPGA キャリー:C

SW2

システムクロック

(50MHz)

入力: B

CLK

B_in

A_in

C_in

HEX5

HEX4

HEX3

HEX0

HEX1

全体回路:top_full_adder

A

CO

S

B 全加算器

CIN

CLK

B_in

A_in

C_in

HEX5

HEX4

HEX3

HEX0

HEX1

表示信号変換回路

CLK SW-out SW-in

CLK SW-out

SW-in

SW-out SW-in CLK

sin seg

sin seg

sin seg

sin seg

sin seg

b-chat

a-chat

c-chat

co-sig

s-sig

チャタリング

制御回路

61

5.2 新規プロジェクトの作成

“3.2 新規プロジェクトの作成方法”に従って、以下の内容で、“全加算器”の新規プロジェクトを作成します。

最後のシート“Summary”で設定内容が正しいかどうか確認して下さい。

[全加算器のプロジェクトの作成情報]

- 作業用ディレクトリ: Z:/Q_PrimeLite/full_adder

- プロジェクト名: full_adder

- TOP階層名: full_adder

- Family: Cyclone V [E/GX/GT/SX/SE/ST]

- Device: Cyclone V E Base

- Package: FBGA、 Pin count: 484、 Speed grade: 7

- Available device: 5CEBA4F23C7 を選択

5.3 「全加算器:full_adder2」の VHDL 記述の入力とコンパイル

上記の作業の結果、プロジェクト名:full_adder の新規プロジェクトがオープンされるので、この環境下で、

図 5-1 の“全加算器:full_adder2.vhd”を VHDLエディタで入力し、この名前で保存します。 記述ミスがないかを

確かめるために、コンパイルを実行して、正常終了することを確認しましょう。

[全加算器のコンパイルでの確認作業の手順]

- 全加算器:full_adder2 の VHDL記述(図 5-1)を入力して、保存する(“Save As”)

- プロジェクトメンバーに登録されていることを確認して、“Set as Top-Level Entity”に設定する

- コンパイルを実行し、正常終了することを確認する

Fatalエラーがある場合は、内容を確認して、修正します。

[エラーメッセージの例] ≪コンパイルした VHDL記述≫

≪コンパイル実行時の出力メッセージ≫

Fatal エラー(赤字で表示される)ので、解析して、必ず修正が必要です。

(1 行目) full_adder2.vhd の 2 行目の“ibrary”付近で、“syntax error”(文法エラー)がある

というメッセージですので、その原因を考えます。 この場合は、“ibrary”が“library”のミスであると

判りますので、正しく修正します。

(4行目) 1行目のミスを修正すれば、このメッセージは消えます。

(2,3行目) 7行目に文法エラーがあるというメッセージですが、「near text “”」と場所が不明確です。

7行目付近を見直しますが、文法的なエラーはなさそうです。 このような場合、1行目のミスを修正し

て再コンパイルして、まずこのメッセージが消えないかを確認します。 それでも消えない場合は、

詳細に検討します。 このケースでは、途中に見えない不適切な文字コード(全角文字コード等)が

入っていたようで、ソースコードの6,7行目を再記述すると修正されました。

あらゆる可能性を考えて、根気よくデバッグすることが必要です。

62

5.4 周辺回路部の設計とVHDL記述

5.1のとおり、全加算器を実機検証するための周辺回路部のモジュール構成は、以下のようになっています。

ここで、チャタリング制御回路と表示信号変換回路は、半加算器の全体回路では、“周辺回路”を構成していた回路

(参考:図 4-36 perioheral_half の回路図)ですが、全加算器の全体回路では、構成回路として設計します。

それぞれの回路の機能は、以下の通りです。

- チャタリング制御回路: スライドスイッチからの入力信号の雑音を除去する回路

- 表示信号変換回路: 回路内部のビット信号を表示デバイス(7segLED)の入力信号に変換する回路

5.4.1 チャタリング制御回路

外部信号として、スライドスイッチやボタンスイッチのような入力デバイスから信号を取り込む場合、“チャタリング

現象”を制御する必要があります(図 5-4)。 その処理をするのが“チャタリング制御回路: chattering”です。

本講座では、既に設計したものを準備してあるので、ダウンロードして利用します。

図 5-4 チャタリング現象を制御する回路

[チャタリング制御回路: chattering.vhd のダウンロード&プロジェクトメンバーへの追加]

- このモジュールは、“http://www.ed.tus.ac.jp/~jte401/” に置いてあります。

- 上記をアクセスして、ダウンロードし、VHDLエディタに paste して、この名前で保存します。

(“*.vhd”ファイルは、テキストファイルです)。

- プロジェクトメンバーに追加する

≪参考: チャタリング現象≫

チャタリングは、スイッチを入れたり切ったりするときに発生する現象です(図 5-5)。 家庭用の通常のスイッチ

等では、チャタリングを意識することはありませんが、高速で動作するハードウェアでは非常に重要な現象です。

スイッチを ON/OFFすると、非常に短い時間に、ONと OFFが図のように繰り返される現象が発生します。

これが、“チャタリング現象”です。 チャタリングが発生する時間は非常に短く、通常数ms から、長くても 30ms

程度と言われていますが、数 ns 周期で動作するデジタル回路では、この時間は非常に長く、無視できません。

例えば、スイッチの押下回数を数えるデジル回路でチャタリングが発生すると、1 回のスイッチ操作にも拘わらず、

複数回の押下があったと判断して、誤動作の原因になります。 従って、通常のデジタル回路では、チャタリング

現象の影響を受けないように、入力信号にチャタリング制御回路を挿入して、誤動作を防いでいます。

図 5-5 チャタリング制御回路の機能

clk

chattering

SW_in SW_out

50Mhz(システムクロック)

チャタリング発生信号 チャタリング除去信号

63

5.4.2 表示信号変換回路: 7segLED デコーダ

5.1のとおり、全加算器の実機評価用回路では、入力信号: A/B/C、並びに演算結果信号: CO/S を

表示デバイス(7segLED)に表示します。 従って、これらの信号:A/B/C/CO/S を、7segLED の制御信号に

変換する回路が、“表示信号変換回路: Bit_7segLED”です。

[表示信号変換回路: Bit_7segLED の仕様]

図 5-6 のように、状態値:0/1/他が入力されると、その値が表示されるように 7segLED の制御信号を出力する。

(入力) (出力表示例)

0 1 他

1ビットの

std_logic 信号:0/1/他

図 5-6 表示信号変換回路: Bit_7segLED の仕様

上記の回路機能を、変換表で表すと、表 5-1 のようになります。

表 5-1 Bit_7segLED の機能を表す変換テーブル

(アノードコモン型)

入力

信号

7segLED のセグメント番号

6 5 4 3 2 1 0

0 1 0 0 0 0 0 0

1 1 1 1 1 0 0 1

他 1 1 1 1 1 1 1

[表示信号変換回路: Bit_7segLED の VHDL記述]

上記の機能を、case 文を使って VHDL記述すると、図 5-7 のようになります。

図 5-7 表示信号変換回路の VHDL記述: Bit_7segLED.vhd

[表示信号変換回路: Bit_7segLED の入力とコンパイルの実行]

図 5-7 に従って、Bit_7segLED.vhd を入力し、プロジェクトメンバーにリストされていることを確認して、

このモジュール単体でコンパイルして、記述エラーを無くしましょう。

seg(6..0) sin

Bit_7segLED

0 1

2

5 6

3 4

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity Bit_7segLED is

port( sin: in std_logic;

seg: out std_logic_vector(6 downto 0));

end Bit_7segLED;

architecture RTL of Bit_7segLED is begin

process(sin) begin case sin is

when '0' => seg <="1000000"; -- 0

when '1' => seg <="1111001"; -- 1

when others => seg <="1111111";

end case;

end process; end RTL;

01

02

03

04

05

06

07

08

09

10

11

12

13

14

64

5.5 全体回路(トップモジュール)の設計とVHDL記述

図 5-3 のとおり、全加算器を実機評価する全体回路のモジュール構成は、以下の通りです。 全加算器と

表示信号変換回路は、入力してコンパイルが終了し、チャタリング回路はダウンロードしてあるので、後は

全体回路(トップモジュール)を設計すれば、実行モジュールを作成することがきます。

全体回路(トップモジュール): top_full_adder

├ 全加算器: full_adder2

├ チャタリング制御回路: chattering

└ 表示信号変換回路: Bit_7segLED

全体回路の VHDL記述: top_full_adder.vhd は、図 5-3 を参考にして、図 5-8 の必要な個所を穴埋めして、

完成させてください(ピン名、信号名等は、テキスト内のものを使ってください)。

図 5-8 全体回路の VHDL記述: top_full_adder.vhd

( に適切な記述をして、VHDL記述を完成させて下さい)

library IEEE;

use IEEE.std_logic_1164.all;

entity top_full_adder is port(CLK, A_in, B_in, C_in : in std_logic;

HEX0,HEX1,HEX3,HEX4,HEX5 : out std_logic_vector(6 downto 0));

end top_full_adder;

architecture RTL of top_full_adder is

component full_adder2 port(A, B, CIN: in std_logic;

S, CO: out std_logic);

end component;

component chattering port(CLK, SW_in: in std_logic;

SW_out: out std_logic );

end component;

component Bit_7segLED port(sin : in std_logic;

seg : out std_logic_vector(6 downto 0));

end component;

signal a_chat, b_chat, c_chat, s_sig, co_sig: std_logic;

begin

CHATB: chattering port map (CLK, B_in, b_chat);

CHATA: chattering port map (CLK, A_in, a_chat);

CHATC: chattering port map (CLK, C_in, c_chat);

ADDER: full_adder2 port map

(A => a_chat, B => b_chat, CIN => c_chat, S => S_sig, CO => CO_sig);

LED5: Bit_7segLED port map (b_chat, HEX5);

LED4: Bit_7segLED port map (a_chat, HEX4);

LED3: Bit_7segLED port map (c_chat, HEX3);

LED1: Bit_7segLED port map (co_sig, HEX1);

LED0: Bit_7segLED port map (s_sig, HEX0);

end RTL;

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

ポート宣言部です

ポート宣言部です

ポート宣言部です

上記 LED5 に合わせて インスタンス記述します

65

☆ 全体回路: top_full_adder.vhd のコンパイル

前記の作業が終了すると全体回路のコンパイルを実行しますが、実行前に以下を必ず確認して下さい。

- プロジェクトメンバーは、図 5-9 のように、必要な全てのモジュール:

top_full_adder.vhd、 Bit_7segLED.vhd、 chattering.vhd、 full_adder2.vhd、

が、「Project Navigator」_“Files”に登録(リストアップ)されているか?

もし、登録されていないモジュールがある場合は、“4.3 (3) ”に従って、登録管理をして下さい。

- “Set as Top-Level Entity”で、top_full_adder.vhd をトップモジュールに設定する(メッセージ確認)。

この操作をしないと正しくコンパイルされません。

図 5-9 プロジェクトメンバーの確認と“Set as Top-Level Entity”の設定

〇 上記確認後、コンパイルを実行し、コンパイル時の Fatal エラーを修正して、正常終了させます(図 5-10)。

正常終了しないと次の工程に進めないので、Fatal エラーを解析して、根気強くデバッグして下さい。

図 5-10 全体回路:top_full_adder.vhd のコンパイルが正常終了した画面

“Set as Top-Level Entity”で、top_full_adder.vhd

をトップモジュールに設定する

この4つのモジュールが登録されていることを確認する

“top_full_adder ” であることを確認する

“successful” が表示されていることを確認する

66

5.6 全体回路の端子(ピン)割り当て

半加算器の場合と同様に、実行モジュールを正しく動作させるためには、入力デバイスから入力信号を取り込み、

表示デバイスに出力信号を出力する必要があるので、「Pin Planner」で“端子(ピン)割り当て”を行います。

半加算器では、予め“端子(ピン)割り当て表”(表4-1、この内容に対応したexcelファイル)が準備されていましたが、

今回は準備していないので、自分で内容を考えて、実施します。 ただ、全てを1から入力するのは大変で、ミスも多

くなるので、“表2-1 入力デバイスのピン接続情報”と“表2-2 7segLEDのピン接続情報”に対応する“ピン接続情報”

(excel ファイル)を “http://www.ed.tus.ac.jp/~jte401/” に準備してありますので、ダウンロードして活用して下さい。

なお、具体的な端子(ピン)割り当ては、“図 5-2 全体回路の外部接続仕様”に従って、実施して下さい

図 5-11 全体回路:top_full_adder.vhd の「Pin Planner」起動後の画面

“図 5-2 全体回路の外部接続仕様”に従って、全体回路の端子名(信号名)とスライドスイッチの接続関係は、

表 5-2 のようになっているので、この仕様に従って、図 5-11 の「All Pins」の“Location”に対応する FPGA の

PIN番号を設定(アサイン)します。

表 5-2 入力端子の端子割り当て表: 信号名と PIN番号の対応表

信号名 属性 FPGA の PIN番号 備 考

CLK

PIN_M9 システムクロック

A-in PIN_V13 ボタンスイッチ:SW1

B-in PIN_T13 ボタンスイッチ:SW2

C-in PIN_U13 ボタンスイッチ:SW0

copy&paste する

67

同様に、出力端子に関しても、端子割り当て表(表 5-3)に従って、PIN番号を設定します。

表 5-3 出力端子の端子割り当て表: 信号名と PIN番号の対応表

信号名 PIN 番号 備 考

信号名 PIN 番号 備 考

HEX0[0] PIN_U21

7segLED:

HEX0

: HEX3[0] PIN_Y16

7segLED:

HEX3

HEX0[1] PIN_V21

HEX3[1] PIN_W16

HEX0[2] PIN_W22

HEX3[2] PIN_Y17

HEX0[3] PIN_W21

HEX3[3] PIN_V16

HEX0[4] PIN_Y22

HEX3[4] PIN_U17

HEX0[5] PIN_Y21

HEX3[5] PIN_V18

HEX0[6] PIN_AA22

HEX3[6] PIN_V19

HEX1[0] PIN_AA20

7segLED:

HEX1

HEX4[0] PIN_U20

7segLED:

HEX4

HEX1[1] PIN_AB20

HEX4[1] PIN_Y20

HEX1[2] PIN_AA19

HEX4[2] PIN_V20

HEX1[3] PIN_AA18

HEX4[3] PIN_U16

HEX1[4] PIN_AB18

HEX4[4] PIN_U15

HEX1[5] PIN_AA17

HEX4[5] PIN_Y15

HEX1[6] PIN_U22

HEX4[6] PIN_P9

HEX5[0] PIN_N9

7segLED:

HEX5

HEX5[1] PIN_M8

HEX5[2] PIN_T14

HEX5[3] PIN_P14

HEX5[4] PIN_C1

HEX5[5] PIN_C2

HEX5[6] PIN_W19

5.7 端子割り当て後の再コンパイル

端子(ピン)割り当てが終了した後に、半加算器の場合と同様に、全加算器の実機確認回路である全体回路:

top_full_adder_を最上位回路に設定して(“Set as Top-level Entity”を実行)、再度コンパイルを実行します。

この再コンパイルの実行により、端子(ピン)接続情報を含んだ実行モジュール[コンフィグレーション・ファイル;

FPGA 書き込み用回路ファイル]が生成されるので、これを使って、実機動作の確認を行います。

5.8 実行モジュールのダウンロード

評価ボード:DE0-CV を付属の USB ケーブルで PCと接続して、電源を“ON”した後に、「Programmer」を起動

します。 “4.6 実行モジュールのダウンロード”に従って、実行モジュール(コンフィグレーション・ファイル)を評価

ボード:DE0-CV にダウンロードしします。 正しくダウンロードされると、図 5-12 のように、「Programmer」画面の

右上の“Progress”が、“100% Successful”になります。

図 5-12 実行モジュールが正しくダウンロードされた場合の画面(一部)

“Hardware”、“File”を確認して、“Start”をクリックします。 “Progress”が“100% Successful”になると、正常終了です。

68

5.9 実機での動作確認

実行モジュールのダウンロードが正常終了すると、設計した“全加算器”の機能を確認することができます。

表 5-4 のようにスライドスイッチを操作して、表示デバイスに正しく表示できるかを確認して下さい。

仕様通りに動作しない場合は、原因を考えて、正しく動作するまでデバッグを繰り返して、完成させて下さい。

表 5-4 スライドスイッチの状態と表示デバイスの表示内容

スライドスイッチ 入力信号 出力信号 表示デバイス:HEX

SW2 SW1 SW0 B_in A_in C_in CO S 5(B) 4(A) 3(C) 1(CO) 0(S)

0 0 0 0 0

0 1 0 0 1

1 0 0 0 1

1 1 0 1 0

0 0 1 0 1

0 1 1 1 0

1 0 1 1 0

1 1 1 1 1

69

【参考】 全体回路の論理合成後の回路図: RTL Viewer

半加算器の場合と同様に、“RTLViewer”で、全体回路の VHDL記述: top_full_adder.vhd、の論理合成結果を

回路図で確認することができます。

[RTLViewer の起動方法]

プルダウンメニュー:「Tools」 → 「Netlist Viewers」 → 「RTL Viewer」と選択すると、図 5-13 のように、

最上位回路(top_full_adder)の回路図が表示されます。 図 5-14 は、下位階層の回路を一部表示したものです。

“4.8 「RTL Viewer」の利用方法”に従って操作して、論理合成結果を確認して下さい(デバッグに有効です)。

図 5-13 “RTL Viewer”で表示した全体回路(top_full_adder.vhd)

図 5-14 “RTL Viewer”で表示した全体回路(top_full_adder.vhd)

70

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

これまでは、Quartus Prime Lite 上で、半/全加算器を VHDL記述し、その記述内容が正しいかどうかを検証せず、

直接実機用モジュールを作成した後、実機動作確認をしてきました。 簡単な機能ではこの手法でも設計できますが、

通常は実機評価をする前に設計内容が正しいかどうかを、シミュレーションを使って確認します。 そこで、本章では、

以下の内容で、設計した VHDL記述が正しく動作するかどうか、シミュレーションで検証する方法を実習します。

なお、本実習で使用するシミュレータは、VHDLシミュレータのデファクトスタンダードである“ModelSim”です。

- 全加算器:full_adder2.vhd(図 6-1; 図 5-1、図 1-8 ど同じ)単体のシミュレーションを実行する

- 検証内容は、真理値表(表 6-1)に従って、

“入力端子に入力信号を入力すると出力端子に正しい出力信号が出力されるか” を確認する

- 全体回路(top_full_adder)でも同様のシミュレーションを実行する

図 6-1 全加算器の VHDL記述(動作記述): full_adder2.vhd

表 6-1 全加算器の真理値表

入力端子&信号 10 進

表示

出力端子&信号

CIN B A

CO S

0 0 0 0

0 0

0 0 1 1

0 1

0 1 0 2

0 1

0 1 1 3

1 0

1 0 0 4

0 1

1 0 1 5

1 0

1 1 0 6

1 0

1 1 1 7

1 1

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

library IEEE;

use IEEE.std_logic_1164.all;

entity full_adder2 is

port(A,B,CIN : in std_logic;

S,CO: out std_logic);

end full_adder2;

architecture RTL of full_adder2 is

signal INPUT : std_logic_vector(2 downto 0);

begin

INPUT <= CIN & B & A;

process ( INPUT) begin

case INPUT is

when “000” => CO <= `0`; S <= `0`;

when “001” => CO <= `0`; S <= `1`;

when “010” => CO <= `0`; S <= `1`;

when “011” => CO <= `1`; S <= `0`;

when “100” => CO <= `0`; S <= `1`;

when “101” => CO <= `1`; S <= `0`;

when “110” => CO <= `1`; S <= `0`;

when “111” => CO <= `1`; S <= `1`;

when others => CO <= `X`; S <= `X`;

end case; end process; end RTL;

71

6.1 ModelSim の起動と新規プロジェクトの作成方法

6.1.1 ModelSim の起動

ModelSim は、以下の方法で起動します(版数は、少し違うかもしれません)。

〇 デスクトップのショートカットによる起動

以下の方法で、デスクトップ上にショートカットを作成して、利用して下さい。

[ショートカットの作成方法]

・ デスクトップの「マイコンピューター」から「ボリューム(C:)」-「Application」-「modelsim」-「win64」

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

(参考)スタートメニューからの起動

Windows のスタートメニューから、「ModelSim」を選択しても、起動できます。

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

図 6-2 ModelSim の起動画面

(注意) 「Close」を選択すると、前回操作したプロジェクト(後ろ参照)がオープンされるはずですが、

所望の動作をしない場合があるかもしれません。 その場合は、臨機応変に対応して下さい。

基本的には、「Jumpstart」で開始して下さい。

Jumpstart もしくは Close を選択

72

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

図 6-3 “Welcome to ModelSim”画面

- 「Create a Project」を選択すると、“6.1.2 新規プロジェクトの作成”へと続きます。

- 「Open a Project」を選択すると、図 6-4 の“Open Project”画面が表示されるので、“Browse…”から

既存のプロジェクトを選択するか、直接プロジェクト名を入力して、「OK」を選択すると、既存の

プロジェクトをオープンして、継続して作業を続けることができます。

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

図 6-4 “Open Project”画面

(2) 図 6-3 の「Close」を選択すると、図 6-5 のように、

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

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

73

・(新規の場合は、初期画面が表示されますので、)「File」 → 「New」 → 「Project」の順に

クリックして(図 6-6)、“6.1.2 新規プロジェクトの作成”の操作を行います。

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

6.1.2 新規プロジェクトの作成

ModelSim でも Quartus_Prime_Lite と同様に、設計毎にプロジェクトを作成して管理しながら設計を進めます。

ModelSim での最初の実習は、Quartus Prime Lite で設計した“全加算器モジュールの VHDL記述”の

シミュレーションを実行して、機能を確認するので、以下の条件でプロジェクトを作成します。

プロジェクト名: full_adder

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

手順通りに作業すると、以下の“Create Project”画面が表示されるので、上記の条件で、Project Name、

Project Location を設定します(図 6-7)。 Default library Name: work は、自動的に設定されます。

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

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

full_adder と入力

z:/modelsim/full_adder と入力

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

「OK」 を選択

74

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

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

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

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

表示されますが、(特に何も追加しないので、)ここでは、「Close」 をクリックして閉じます(図 6-9)。

図 6-9 Add items to the Project 画面

以上で新規プロジェクトの作成が完了したので、この環境下で具体的な作業を進めていきます。 すなわち、

これから作成する VHDL等のファイルは、ディレクトリ: z:/modelsim/full_adder 下に作成されるので、常に

意識して作業を進めましょう。

[参考] エクスプローラー等で確認すると、z:/modelsim/full_adder/full_adder.mpf というファイルが

作成されおり、このファイルがプロジェクトを管理します。 mpf は、modelsim project file の略です。

6.2 VHDL ファイルの作成

ModelSim で VHDL を作成するには、図 6-10 の手順でオープンした VHDLエディタを利用します。

[VHDLエディタのオープン手順]

「File」 → 「New」 → 「Source」 → 「VHDL」の順にクリック

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

「はい」 を選択

「Close」 を選択

75

最初にシミュレーションする“全加算器: full_adder2.vhd”の VHDL記述は、図 6-1 のとおりです。 これを VHDL

エディタで再度入力しても良いですが、Quartus Prime Lite で作成し動作確認した VHDL記述を利用します。

Quartus Prime Lite で作成したファイルは、ディレクトリ: z:/Q_PrimeLite/full_adder/の下に保存されています。

また、全加算器:full_adder2.vhd(*.vhd)はテキストファイルなので、“ワードパッド”などのテキストエディタでオープン

して、copy&pasteできます。 図6-11は、ModelSimのVHDLエディタにQuartus Prime Liteで作成した full_adder2.vhd

を copy&paste して移し、”Save As…“で保存するところです。

【備考】 「Save As…」は、新規の名前を付けて保存する場合にを用います。

図 6-11 VHDLファイルの copy&paste と保存

「File」 → 「Save As…」 の順にクリックすると、“Save As…”画面(図 6-12)が表示されるので、保存したい

モジュール名を“ファイル名(N)”に指定します。 ここでは、“full_adder2.vhd”です(拡張子は必ず、“.vhd”として

下さい)。 この結果、プロジェクトディレクトリ: z:/modelsim/full_adder/の下に、“full_adder2.vhd”のファイル名で、

(コピーした)VHDLが保存されます。

図 6-12 “full_adder2.vhd”を保存する画面

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

VHDL エディタ

Quartus Prime Lite で入力した

VHDL 記述: full_adder2.vhd

をここに、copy する。

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

ここに、プロジェクトディレクトリ下に 保存されている *.vhd ファイルの 一覧が表示されます。

(最初は何も表示されません)

新規に保存するファイル名を入力

(ここでは、 full_adder2.vhd と入力)

76

[プロジェクトメンバーの管理]

ModelSim でも Quartus Prime Lite と同様に、プロジェクトのメンバーを管理

して、シミュレーションの実行モジュールを作成します。 プロジェクト・ディレクトリに保存した VHDLファイルを以下

の手順でプロジェクトに追加します。

[プロジェクトへ登録/追加する手順](図 6-13)

-“Project”画面の中で右クリックして、「Add to Project」 → 「Existing File」を選択

-“Add file to Project”画面がポップアップされるので、“Browse…”で登録/追加するファイルを選択して、

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

以上の操作の結果、指定した full_adder2.vhd が以下の様にプロジェクトメンバーに追加されます。

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

[プロジェクトから削除する手順](図 6-14)

“Project”画面の中で右クリックして、

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

ポップアップされる“Add file to Project”画面の

“Browse…”で登録/追加するファイルを選択して

「OK」をクリック

削除したいメンバーを選択して、右クリックすると

メニューがポップアップされるので

“Remove from Project”を選択

77

図 6-14 Project メンバーか削除する手順

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

“Project”画面に登録されている VHDLファイルをコンパイルして、記述にミスがないかを確かめます。

[コンパイルの実行方法:](図 6-15)

“プルダウンメニュー”で「Compile」をクリック、もしくは、“Project”画面で右クリックして

- 登録メンバー全てを同時にコンパイルする時: 「Compile」 → 「Compile All」 を選択

- 選択したメンバーだけをコンパイルする時: 「Compile」 → 「Compile Selected」 を選択

(プルダウンメニューから実行する場合) (“Project”画面で実行する場合)

図 6-15 コンパイルコマンドの選択

コンパイルが正常終了すると、図 6-16 のように、“Transcript”画面に”successful“のメッセージが表示され、

“Project”画面の“Status”欄がチェックマーク: ✔ になります。 なお、コンパイルでエラーが出たときは、“✔ ”の

代わりに、バツマーク: ✖ が表示される(図 6-17)ので、メッセージの内容を解析して修正します。

図 6-16 コンパイルが正常終了したとき

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

78

[コンパイルエラーが発生した場合の処置方法]

ModelSim では、コンパイルエラーが発生したしたモジュール

の“Status”欄に、✖が表示されるので、出力されたメッセージ

を解析して、不具合個所を修正します。

図 6-17 コンパイルエラーがある場合の表示

(出力メッセージの例)

≪full_adder2.vhd の 8 行目付近≫

実際の“full_adder2.vhd の 8 行目付近”の記述は上記のようになっており、7 行目の行末の

“;”がない(抜けている ⇐ 文法エラー)ことが判ります。

当該箇所を上記のように正しく修正して、保存して、再コンパイルします。

- 修正後のソースを保存するとき、アイコンメニューの “Save (Ctrl+S))” をクリックしても

保存が実行されます(保存する必要がない場合、このアイコンは操作できません。

- コンパイルするとき、“Compile Seteclted”を選択すると当該のモジュールだけがコンパイルされます。

再コンパイル後、“Transcript”欄に“successful のメッセージが出力されて、

“Project”画面の“Status”欄がチェックマーク: ✔ になります。

ダブルクリックすると具体的な内容が表示されます。

“full_adder2.vhd”のコンパイルで Fatal エラーが

1 ヶ所あったことを示しています。

「“full_adder2.vhd”の 8 行目の“end”近くに、“;”が必要」

という意味です。

79

6.4 “全加算器: full_adder2”のシミュレーション実行

6.4.1 シミュレーションするモジュールの選択とシミュレーション・モードへの移行

この操作には、以下のように、2通りの手順がありますが、共に選択したモジュールをシミュレーションする環境が

起動されます。

(1) プルダウンメニューから起動する方法

(プルダウンメニューの)「Simulate」 → 「Start Simulation…」 と選択すると(図 6-17(左))、

”Start Simulation“画面(図 6-17(右))がポップされるので、+work を展開すると、

- work

+full_adder2

となるので、シミュレーションするモジュール: full_adder2 をクリックして、「OK」を選択すると、シミュレーション・

モードへ移行し(図 6-19)、選択したモジュール:full_adder2 のシミュレーションが実行できる環境になります。

なお、シミュレーションするモジュール(full_adder2) をダブルクリックしても良いです。

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

(2) Library”シートからの起動方法

“Library”画面の“Library”シートを選択して、

“+work”を展開すると、図 6-18 のように、

- work

+full_adder2

となります。 ここで、シミュレーションするモジュール:

“full_adder2”を選択して、マウスの右ボタンをクリックする

と、選択メニューがポップアップされるので、左ボタンで

「Simulate」を選択します(図 6-18)。

なお、“full_adder2”をダブルクリックすると、図 6-18 は

表示されず、図 6-19 に直接移ります。 以降は、

(1)と同様に、選択したモジュール:full_adder2 の

シミュレーションが実行できる環境になります(図 6-19)。

図 6-18 “Library”シートから起動画面

80

図 6-19 “full_adder2”のシミュレーション・モードの画面

【重要】 “Wave”画面が表示されない場合は、(プルダウンメニュー)「View」で“Wave”を選択してください

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

“Name”欄には、“full_adder2”で記述した入出力端子名(port 文)と内部信号名(signal 文)が表示されいます。

実際の VHDLでは以下のように記述されているので、“Objects”画面の“Name”欄と一致しています。

(entity部の port宣言)

port(A,B,CIN : in std_logic;

S,CO: out std_logic);

(architecture 部の signal宣言)

signal INPUT : std_logic_vector(2 downto 0); ← 別の名前にしてある場合は、

その名前になります。

【シミュレーション・モードを終了する方法】

シミュレーション・モードを終了する場合は、プルダウンメニューから、「Simulate」 → 「End Simulattion」

を選択すると(図 6-20(左))、確認画面(図 6-20(右))がポップアップされるので、「はい」を選択すると、

VHDLエディタが使えるモードに戻ります。

図 6-20 シミュレーション・モードを終了する手順

「Simulate」 → 「End Simulattion」 を選択後、

確認画面で、「はい」を選択

81

6.4.2 入力波形の設定

全加算器: full_adder2 をシミュレーションするためには、入力端子に入力信号を設定する必要があります。

この入力信号の組み合わせ(“パターン”と呼ぶ)は、状態値を 0/1 の 2 値で考えた場合、表 6-1 のように、

8(=23)通り、すなわち 8 パターンあるので、これらの値のすべての組み合わせを入力信号として入力して、

シミュレーションを実行した後に、その結果を解析すると、設計した回路の動作が正しいかどうか判断できます。

“full_adder2”の入力端子は、A,B,CINなのでそれぞれの状態値の変化を図 6-21 のように設定すると、

全ての組み合わせ(8 パターン)を入力信号に入力することができるので、シミュレーションでこのように設定します。

[入力パターンの仕様]

信号A: 初期値:0、パターン毎に 0 と 1 と変化する

信号B: 初期値:0、2 パターン毎に 0 と 1 と変化する

信号CIN: 初期値:0、4 パターン毎に 0 と 1 と変化する

(注) 2 つの状態の間を切り替えることを“トグル(toggle)する”と言います。

CIN: 0 0

B: 0 1 0 1

A: 0 1 0 1 0 1 0 1

図 6-21 入力信号A、B、CINの入力パターン

[入力パターンの設定方法] - Apply Wave で設定する場合 -

ここでは、入力信号:A、B、CINの設定を“Apply Wave”を使って行います(図 6-22)。

図 6-19 の画面の“Objects”画面で入力信号、例えば“A”を選択して右クリックすると、メニュー画面が

ポップアップするので、“Modify”→“Apply Wave” と選択メニューします(図 6-22)。

図 6-22 “Apply Wave” の起動方法

① “Objects”画面で入力信号(この図では信号:A)を選択

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

“Modify” → “Apply Wave” を選択

1 パターン 8 パターン

82

上記の操作により、“Create Pattern Wizard”の初期画面(図 6-23)がポップアップされるので、入力信号の条件を

指定して、選択した入力信号の入力波形(入力パターン)を設定します。

図 6-23 “Create Pattern Wizard”の初期画面

シミュレーションは、時間の経過に従って各信号の状態を見るので、入力パターンで考えた場合、1 パターンの

時間的な長さを決める必要があります。 ここでは、“1 パターン=100ns”で考えます。 そうすると、入力信号:A は

“初期値:0 の状態から、100ns 毎に 0 と 1 を繰り返し(トグルし)、8 パターン後は 800ns 後となります。”

この内容を指定すると、以下の図 6-24 のようになります。

図 6-24(1) 入力信号:Aの設定内容

図 6-24(2) “Repeater”画面と設定内容

① 「Signal Name」: “full_adder2/A” を確認

② 「Patterns」: “Repeater” を選択

③ 「Start Time」: “0” と設定

④ 「End Time」: “800”[=8 パターン] に設定

⑤ 「Time Unit」を、 ”ns“ に変更

⑥ 「Next」をクリック [⇒ 図 6-24(2)に移動 ]

[<Pattern: Repeater>画面]

⑦ 「Initial Value」: “0” に設定

⑧ 「Change Period」: “100” に設定

⑨ 「Time Unit」: “ns” に変更

⑩ 「Values」: “0”と“1” を設定

“0”を設定して、“more”をクリックすると

欄が追加されるので、“1”を設定します

⑪ 「Finish」をクリック

83

以上の操作後(“Finish”をクリック後、図 6-25 のように、入力信号:A の波形が波形エディタに表示されるので、

100ns毎に状態値“0”と“1”がトグルして、800ns [=8 パターン]まで入力されていることを確かめて下さい。

図 6-25 “入力信号:A”設定後の波形エディタ画面

[波形エディタの操作例]

〇波形エディタの表示コントロール・コマンド: 全体表示、zoom in/out 等

〇 波形エディタの時間軸表示単位の変更方法

この部分の初期値は、“ps”となっているので、以下の手順で、表示したい時間単位に変更します。

〇 波形エディタの Dock/Undock

左図の〇の部分をクリックすると、

波形エディタを本体から独立させたり

組み込ませたり(初期状態)することができます。

1/2 倍に縮小 全体表示

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

- 左図の〇の部分:“Edit Grid & Timeline Properties…”をクリック

もしくは

- 時間表示部にマウスを移動して右クリックすると、メニューが

ポップアップするので、「Grid & Timeline Properties…」を選択

- “Wave Window Prefereces”画面が表示されるので、

“Time units”欄を、“ns”に変更

- 「OK」をクリック ⇒ 時間軸の表示が“ns”に変更

2 倍に拡大

84

同様にして、入力信号:B、CINの設定を行います。 入力信号:A と異なるのは、トグルする周期だけなので、

“Repeater Atributees”画面の“Change Period”の部分にそれぞれの値を入力して、設定します(図 6-26)。

(入力信号:B) (入力信号:CIN)

図 6-26 入力信号:B と CINの設定

以上の操作により、3つの入力信号:A、B、CINが設定され、図 6-27 のように、表示されます。

図 6-27 入力信号:A、B、CINが設定された画面

6.4.3 出力信号の設定

シミュレーションは、設計した回路が入力信号によってどのように動作するか、すなわち出力端子の出力信号が

どのように変化しているかを調べ、その動作が所望の結果になっているかどうかを確認するためのものなので、

シミュレーションによる出力端子(出力信号)の波形を見ることが重要です。

波形エディタでシミュレーション結果の波形を見るためには、シミュレーションを実行する前に、波形エディタの

信号名欄に表示したい(出力)端子名や信号名を

登録することで可能になります。

“全加算器:full_adder2”では、入力端子:A、B、CIN、

出力端子:CO、S、内部信号:INPUT(2 downto 0) [別の

名前にしている場合はその名前]が定義されており、

“Objects”画面の“Name”欄に表示されいるので、

図 6-28 のように、表示したい端子名/信号名を選んで

(複数選択可能)、波形エディタの信号名欄に ドラッグ

します。 図 6-28 出力信号の設定方法

入力信号:B は、“周期:200ns”でトグル

「Change Period」: ”200“

「Time Unit」: “ns” と設定

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

入力信号:CINは、“周期:400ns”でトグル

「Change Period」: ”200“

「Time Unit」: “ns” と設定

85

以上の操作により、シミュレーションを実行するための準備が完了し、図 6-29 のようになります。

図 6-29 シミュレーション実行前の波形エディタの画面

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

シミュレーションの実行は、以下の手順で行います(図 6-30)。

- 「Simulate」 → 「Run」 → 「Run All」 と選択 (注) シミュレーションは瞬時に終了します。

図 6-30 シミュレーションの実行方法

6.4.5 シミュレーション結果

シミュレーションの実行が終了すると、図 6-31 のように、実行結果が表示されます。

全体のシミュレーションが実行されていることを確認し、結果内容の解析を行いますが、内部信号:INPUT は

バス表示されているので、図 6-32 のように、展開表示すると解析が少ししやすくなります。

図 6-31 シミュレーション実行後の画面(1)

86

図 6-32 シミュレーション実行後の画面(2)

(シミュレーション結果の確認[解析])

- INPUT 信号は、“INPUT <= CIN & B & A;”[←“&”は連接演算子]と記述したので、

INPUT(2)=CIN、INPUT(1)=B、INPUT(0)=A となっているはずなので、確認する。 ⇒ 正しい結果である

- 出力信号(端子):CO、S が、表 6-1 の仕様通りに変化しているかを確認する。 ⇒ 正しい結果である

従って、シミュレーション結果が期待通りの動作をしているので、正しく設計されていることが判ります。

以上で、全加算器モジュール:full_adder2 のシミュレーションは、完了です。

正しく動作していない場合は、波形の変化などを解析して、正しい結果が得られるまで、デバッグします。

デバッグ作業は、VHDL記述の変更&コンパイル → シミュレーション実行&解析、すなわち

- (VHDL変更/コンパイルするために) シミュレーション・モードの終了 (図 6-20 参照)

- VHDLを変更し、コンパイルの実行

- シミュレーション・モードへ移り、シミュレーションの実行

という操作の繰り返しなので、操作を間違えずに根気よくデバッグして下さい。

なお、シミュレーション・モードを終了するとき、以下の画面(図 6-33)が表示されます。

これは、シミュレーション実行前に、入力信号を入力した“Apply Wave”のコマンドスクリプトを保存するかどうかを

確認していますので、「はい」か「いいえ」を選んでください。

図 6-33 Wave コマンドスクリプト保存の確認画面

(説明)

「はい」を選択: 最新の“Apply Wave”のコマンドスクリプトを保存しますので、次回のシミュレーション

時に再利用できます。 保存場所は、プロジェクトディレクトリの下に、“wave.do” という

デフォルトのファイル名で保存されます。 なお、図 6-347 の方法で保存する場合は、

別のファイル名で保存することも可能です。 ファイルの拡張子は、“*.do” と固定です。

「いいえ」を選択: 保存は行いません。

(既に保存している場合で、変更したくない場合はこちらを選択します。)

87

[Wave コマンドスクリプトをファイル名を指定して保存する方法]

図 6-34 Wave コマンドスクリプトをファイル名を指定して保存する手順

[保存した Wave コマンドスクリプトを再利用する方法](図 6-35)

保存したファイル(Wave.do もしくは *.do)は、シミュレーション・モードで入力信号を設定する代わりに、

以下のコマンドを実行することにより、再利用できます。 なお、完全には再現できない場合が多いので、

不足している部分は、再度操作する必要があります。タにロードされます。

図 6-35 保存した“*,do”ファイルをロードする手順

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

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

- 「OK」 を選択

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

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

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

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

88

6.5 ModelSim の終了方法

ModelSim を終了させる方法は、以下の 2 つの方法があります。

- ウィンドウ右上の を選択する

- プルダウンメニュー:「File」 → 「Quit」 を選択する(図 6-35)。

上記の方法により、図 3-38(右)の画面がポップアップするので、

「はい」を選択します。 ModelSim が衆力します。

図 6-35 ModelSim の終了手順(左)と確認画面(右)

89

6.6 全加算器の“全体回路: top_full_adder”のシミュレーション実行

本章では、全加算器の実機評価用回路の全体回路:top_full_adder.vhd のシミュレーションを実行します。

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

全体回路:top_full_adder のモジュール構成は、以下のようになっています(5.5参照)。

全体回路: top_full_adder [≡ 最上位回路、トップモジュール ]

├ 全加算器: full_adder2 [← 既にシミュレーション済 ]

├ チャタリング制御回路: chattering

└ 表示信号変換回路: Bit_7segLED

全体回路のシミュレーションでは、チャタリング制御回路は不要なので(6.6.2で説明)、全加算器と同様に、

Quartus_Prime_Lite で設計した全体回路:top_full_adder.vhd と表示信号変換回路:Bit_7segLED.vhd の2つの

モジュールを現在の ModelSim 環境下(プロジェクト名:full_adder)に移動させます。

2つのモジュールを取り込み、プロジェクトメンバーに追加すると、図 6-36 のようになります。

図 6-36 プロジェクト[Z:/modelsim/full_adder/]下のファイル一覧(左)とプロジェクトメンバー(右)

6.6.2 シミュレーション用回路への変更

実機用回路(Quartus Prime Lite 上の回路)とシミュレーションするための回路とは、以下の点が異なります。

[実機用回路とシミュレーション用回路の相違点]

実機では、スライドスイッチやボタンスイッチなどを操作して信号を入力するとき、雑音が発生するので、

“チャタリング制御回路”のような雑音を削除する回路が必要になりますが、シミュレーションでは雑音を

考慮する必要がないので、“チャタリング制御回路”は不要です。 従って、シミュレーション用回路は、

図 5-3 の回路図から、図 6-37 のようになります。 (注)入力端子の変更は、後で説明します。

図 6-37 シミュレーション用全体回路の回路構成

全体回路:top_full_adder

A CO

S

B 全加算器

CIN

INPUT(2..0) HEX5(6..0

HEX4(6..0)

HEX3(6..0)

HEX0(6..0)

HEX1(6..0)

表示信号変換回路

sin seg(6..0)

co_sig

s_sig

sin seg(6..0)

sin seg(6..0)

sin seg(6..0)

sin seg(6..0)

INPUT(1)

INPUT(0)

INPUT(2)

INPUT(1)

INPUT(0)

INPUT(2)

90

[入力端子の変更]

図 6-37 では、図 5-3 の入力端子:CLK、A_in、B_in、C_in から INPUT(2..0)に変更しています。

- CLK 端子は、図 5-3 の中では、“チャタリング制御回路”でしか使用していないので、削除する。

- 入力端子:A_in、B_in、C_in をまとめて、バス信号:INPUT(2..0)として処理する。

“INPUT : in std_logic_vector(2 downto 0); ”と宣言するので、元の入力端子:A_in、B_in、C_in を、

INPUT(2) ⇔ C_in、 INPUT(1) ⇔ B_in、 INPUT(0) ⇔ A_in として処理すると、表 6-1 のように、

“000”~“111”の変化[10 進数では、0~7]に対応させて、処理することができる。

以上の内容を踏まえて、全体回路:top_full_adder.vhd のソースを、以下図 6-38 のように、変更します。

図 6-37 の内容に従って、必要な個所を穴埋めして完成させて下さい。

図 6-38 シミュレーション用全体回路の VHDL記述: top_full_adder.vhd

library IEEE;

use IEEE.std_logic_1164.all;

entity top_full_adder is

port(INPUT : in std_logic_vector(2 downto 0);

HEX0,HEX1,HEX3,HEX4,HEX5 : out std_logic_vector(6 downto 0));

end top_full_adder;

architecture RTL of top_full_adder is

component full_adder2

port(A,B,CIN: in std_logic;

S,CO: out std_logic);

end component;

-- component chattering

-- port(CLK, SW_in: in std_logic;

-- SW_out: out std_logic );

-- end component;

component Bit_7segLED

port(sin : in std_logic;

seg : out std_logic_vector(6 downto 0));

end component;

-- signal a_chat, b_chat, c_chat, s_sig, co_sig: std_logic;

signal s_sig, co_sig: std_logic;

begin

-- CHATB: chattering port map(CLK, B_in, b_chat);

-- CHATA: chattering port map(CLK, A_in, a_chat);

-- CHATC: chattering port map(CLK, C_in, c_chat);

ADDER: full_adder2 port map

(A => INPUT(0), B => INPUT(1), CIN => INPUT(2),S => S_sig, CO => CO_sig);

LED5: Bit_7segLED port map (INPUT(1), HEX5);

LED4: Bit_7segLED port map (INPUT(0), HEX4);

LED3: Bit_7segLED port map (INPUT(2), HEX3);

LED1: Bit_7segLED port map (co_sig, HEX1);

LED0: Bit_7segLED port map (s_sig, HEX0);

end RTL;

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

入力信号を変更

“chattering”は使用しないしないので、 コメント行(“—”から行末までがコメント) にするか、削除する

内部信号は、必要なもの:s_sig と co_sig

だけに変更する。

このインスタンスは不要

A_in、B_in、C_in に対応する

信号名を置き換える

91

6.6.3 コンパイルの実行

以上の修正で全体回路(最上位回路、トップモジュール)は、以下の構成になっています。

全体回路: top_full_adder [← シミュレーション用回路に変更したもの]

├ 全加算器: full_adder2 [← シミュレーションしたもの]

└ 表示信号変換回路: Bit_7segLED [← 変更なし]

これらのモジュールをプロジェクトメンバーに登録して、手順通りに、コンパイルします。

コンパイルが正常終了すると、図 6-39(右)のように、“Status”欄が“?”から“✔”になります。

このコンパイル作業が正常終了しないとシミュレーションできないので、しっかりデバッグして下さい。

図 6-39 コンパイル後の画面(右) [“Status”欄が✔シになる]

6.6.4 シミュレーションモードへの移動

以上の作業で、全体回路:top_full_adder.vhd のシミュレーション準備ができたので、シミュレーションを実行します。

(1)プルダウンメニュー:「Simulate」→「Start Simulation」を選択して、ポップアップする“Start Simulation”画面で、

“+work”を展開して(-workになる)、“top_full_adder”を選択後、「OK」をクリックすると(図 6-40(1))、

シミュレーションモードの初期画面(図 6-41)に移動します。

図 6-40(1) シミュレーションの起動方法(1)

(2)“Library”画面で、“+work”を展開して(図 6-40(2))、

“top_full_adder”を右クリックすると選択メニューが

ポップアップするので、“Simulate”を選択すると、

シミュレーションモードの初期画面(図 6-41)に移動

します。 なお、“top_full_adder”をダブルクリックしても、

図 6-41 に移動します。

図 6-40(2) シミュレーションの起動方法(2)

92

図 6-41 シミュレーションモードの初期画面

6.6.5 入力信号の設定と出力信号の設定

入力信号:INPUT の設定は、全加算器モジュールと同様に、“Apply Wave”で行います。

右図のように、入力信号:INPUT を選択して、右クリックして、コマンドメニューを

ポップアップさせ、”Modify“ → ”Apply Wave“ と選択すると、

“Creat Pattern Wizard”の画面(図 6-42)がポップアップするので、

仕様に合わせて、INPUT の入力信号を設定します。

[INPUT: std_logic_vector (2 downto 0);の入力信号の仕様]

と変化するので、この波形を入力するために、“Select Pattern”は、“Counter”を選択します。

1パターン=100ns なので、“End Time”と“Time Unit”は、800ns とします。

図 6-42(1) “Creat Pattern Wizard”画面の設定

“Objects”欄に、シミュレーションする“top_full_adder.vhd”の 出力端子名: HEX0, HEX1, HEX3, HEX4, HEX5 入力端子名: INPUT 内部信号名: co_sig, s_sig が表示されていることを確認する。

INPUT(2..0) 000 001 010 011 100 101 110 111

1 パターン 8 パターン

① 「Signal Name」: “INPUT” を確認

② 「Patterns」: “Counter” を選択

③ 「Start Time」: “0” と設定

④ 「End Time」: “800”[=8 パターン]に設定

⑤ 「Time Unit」: “ns” を選択

⑥ “Next”をクリック [⇒ 図 6-42(2)に移動]

93

図 6-42(2) “Counter Attributes”の設定画面

以上の操作により、図 6-43 のように、波形エディタに入力信号:INPUT が表示されます。

100ns 毎に、その値が1ずつ count up していることを確かめてください。

図 6-43 入力信号:INPUT 設定後の波形エディタの画面

[出力信号の設定]

シミュレーション結果を確認したい出力信号/内部信号を“Objects”画面から選択して、波形エディタに

ドラッグして(6.4.3参照)、図 6-44 のように、設定します。。

図 6-44 シミュレーション結果表示信号設定後の波形エディタの画面

[<Counter Attributes>設定画面

⑦ 「Start Value」: “000” と設定

⑧ 「End Value」: “111” と設定

⑨ 「Time Period&Unit」: “100 ns” と設定

[← 100ns 毎に count up する]

⑩ 「Counter Type」: “Range” を選択

⑪ 「Count Direction」: ”Up“ を選択

⑫ 「Step Count」: “1” と設定

[← “1”ずつ count up する]

⑬ 「Repeat」: “Forever” を選択

⑭ “Finish”をクリック

94

6.6.6 シミュレーションの実行と結果確認

(1) シミュレーションの実行

(プルダウンメニュー)「Simulate」 → 「Run」 → 「Run All」 を選択して、シミュレーションを実行します。

図 6-45 がシミュレーション実行後の画面です。 正常終了することを確かめてください。

図 6-45 シミュレーション実行後の波形エディタの画面

(2)シミュレーション結果の確認

シミュレーション結果を確認しやすくするために、図 6-46のように、

- “+INPUT”を展開して、“-INPUT –(2) -(1) –(0)”とする。

この結果、 –(2): C_in、 -(1): B_in、 –(0): A_in となります。

- 仕様では、C_in → HEX3、 B_in → HEX5、 A_in → HEX4 なので、–(2) -(1) –(0)の並びに合わせる。

- co_sig → HEX1 なので、co_sig 下に HEX1 を表示させる。

- s_sig → HEX0 なので、 s_sig 下に HEX0 を表示させる。

と並び変えます(信号名を選択して、ドラッグすると表示位置を変更できます)。

図 6-45 信号の表示位置を変更した波形エディタの画面

(確認内容)

- –(2) -(1) –(0)と co_sig、s_sig の結果が、全加算器(full_adder2)の結果と一致していることを確認する。

- HEC0 ~ HEX5 の表示内容が仕様通り、

HEX0:s_sig、HEX1:co_sig、HEX3:-(2)[= C_in]、HEX4:–(0)[= A_in] 、HEX5:-(1)「= B_in」

になっているかを確認する。

⇒ –(2)、-(1)、–(0)、co_sig、s_sig の状態値は“0”か“1”なので、その表示が正しいかどうかを確認する

95

[7segLED 表示の確認]

DE0-CVに搭載されている 7segLEDの表示は、左図のとおりのセグメント番号で、

この 0~6のセグメントへの印加電圧(状態値“0”か“1”)で制御します。

(セグメント番号) 6543210

“0”を表示する場合: 1000000

“1”を表示する場合: 1111001

と出力端子:HEX0~5に出力すれば、7segLED に“0”か“1”が表示されます。

従って、シミュレーション結果で所望どおりに出力信号が出力されいるかを確認します。

図 6-46 は図 6-45 の“400~500ns”の部分です。

INPUT <= “100” なので、

-(2) <=‘1’、-(1) <=‘0’、-(0) <=‘0’

⇒ co_sig <= ‘0’、 s-sig <= ‘1’

となるので、出力信号は、

HEX5(=-(1)) <= ‘0’ ⇒ 1000000

HEX4(=-(0)) <= ‘0’ ⇒ 1000000

HEX3(=-(2)) <= ‘1’ ⇒ 1111001

HEX1(=co_sig) <= ‘0’ ⇒ 1000000

HEX0(= s_sig) <= ‘1’ ⇒ 1111001

となるはずなので、確認します。

→ 右図で正しい結果と確認できます

図 6-46 図 6-45 の 400~500ns 部分

なお、上記で ‘1’ ⇒ 1111001 と読み替えるのは少し複雑なので、16 進表示を使って、‘1’ ⇒ “79”

[← “1111001”を“111_1001”と考えて、16 進表示にすると“7_9”となる]とすると少し楽になります。

[バス信号の表示基数の変更方法]

波形エディタでバス信号を選択(同時に複数選択可能)して、右クリックすると、メニューがポップアップするので

“Radix” → “Hexadecimal”を選択すると、選択信号の基数表示が 16 進になります(図 6-47)。

図 6-47 バス信号の表示基数の変更方法

0 1

2

5 6

3 4

- バス信号を選択(同時に複数可) - 右クリックでメニューをポップアップして “Radix”→“Hexadesimal”を選択 - バス信号の基数が 16 進に変更 [主な基数の選択]

Binary: 2 進数表記 Octal: 8 進数表記 Decimal:10 進数表記(符号付) Unsigned:10 進数表記(符号無し) Hexadecimal:16 進数表記 ASCII: ASCII 文字表記

96

上記の操作により、バス信号の基数を 16 進数表記にすると、図 6-45 の表示は、図 6-48 のようになります。

“40” [=1000000] ⇒ ‘0’、 “79” [=1111001] ⇒ ‘1’なので、再度確認してみて下さい。

図 6-48 バス信号の表示基数を 16 進に変更したシミュレーション結果(図 6-45 と比較)

97

6.7 “テストベンチ”によるシミュレーションの実行: “全体回路: top_full_adder”

これまでのシミュレーションの実行では、入力パターンの設定は波形エディタの機能を使って行いましたが、手順

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

るシミュレーションの実行です。 言語設計の特徴の 1 つです。

[テストベンチの構造]

テストベンチの記述構造は、図 6-49 のとおりで(1.1.9の図と同じ)、ほぼ定型の記述となります。

シミュレーションを実行したいモジュール(DUT:Design Under Test)を呼び出して(インスタンスして)、

入力信号に入力パターンを記述します。 入力パターンを言語で記述できるところが最大のポイントです。

図 6-49 “テストベンチ”の記述構造

(VHDL モデル定義文)

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

(エンティティ文)

entity エンティティ名 is

end エンティティ名;

(アーキテクチャ文)

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

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

- 入出力信号の宣言

- 定数の定義 等

begin

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

- 入力パターンの記述

end アークテクチャ名;

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

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

for アークテクチャ名

end for;

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

テストベンチ

シミュレーション実行

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

(DUT)をインスタンス

クロック、リセット

等の設定

入力信号の

パターンの生成

シミュレーション

結果の表示等

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

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

-この 4 行は、常にこの型にします。

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

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

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

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

も可能です。

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

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

98

6.7.1 テストベンチの記述例: 全体回路: top_full_adder をテストベンチでシミュレーションする場合

全体回路:top_full_adderのテストベンチで記述する回路は、図6-50のようになります。 この構造に従って記述した

全体回路:top_full_adder のテストベンチは、図 6-51 のとおりです。 図 6-49 と比較して、詳細を理解して下さい。

図 6-50 “全体回路:top_full_adder”のテストベンチの回路

図 6-51 “全体回路:top_full_adder”のテストベンチの回路

HEX5

INPUT

[DUT] top_full_adder

HEX4 HEX3 HEX1 HEX0

INPUT

HEX5 HEX4 HEX3 HEX1 HEX0

テストベンチ: tb_top_full

全体回路

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity tb_top_full is

end tb_top_full;

architecture SIM of tb_top_full is

component top_full_adder

port(INPUT : in std_logic_vector(2 downto 0);

HEX0,HEX1,HEX3,HEX4,HEX5 : out std_logic_vector(6 downto 0));

end component;

signal INPUT: std_logic_vector(2 downto 0):="111";

signal HEX0,HEX1,HEX3,HEX4,HEX5: std_logic_vector(6 downto 0);

constant STEP: time := 100 ns;

begin

DUT: top_full_adder

port map (INPUT,HEX0,HEX1,HEX3,HEX4,HEX5);

process begin

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

end process;

process begin

wait for STEP*8;

assert false severity failure;

end process;

end SIM;

configuration cfg_tb_top_full of tb_top_full is

for SIM

end for;

end cfg_tb_top_full;

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

テストベンチの entity名: tb_top_full[= architecture名] だけを宣言し、port 文は宣言しない。

top_full_adder をインスタンス名:DUT で

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

(DUT) top_full_adder を通常通り、component 宣言する。

component 宣言した top_full_adder の port 宣言内の入 出力端子名は、全て signal 宣言する。 定数も宣言する。

configuration宣言です。configuration名は、

cfg_tb_top_fullで、通常“cfg_(entity名)”としますが、 この名前で Sim の実行モジュールが作られます。

process 文で入力パターンを記述する (詳細は後述)

99

(入力信号記述の説明)

入力信号の記述には、process 文を使います。 VHDLでは、入力信号を記述するためにいろいろな仕様が

あるので、順次覚えていきましょう(論理合成されない仕様も含まれています)。

前述のように、INPUT: std_logic_vector (2 downto 0);の入力信号の仕様は、以下の通りです。

この INPUT の記述例は、図 6-52 のようになります。

-INPUT <= INPUT + '1';は、std_logicの演算で、

INPUTの現在の値に‘1“を足します。

-次の wait for STEP; で STEP時間[=100ns]

INPUTの値を保持します。

-process文は、上記の処理を永久に繰り返すので、

INPUTの値は、STEP=100ns毎に’1’増加しますが、

3bitバスなので、“000”~“111”を繰り返します。

-なお、INPUT の初期値は、“111”(図 6-51 の 14 行目)

に設定されているので、入力値は“000”から始まります。

上記の process文は永久に繰り返されるので、シミュレーション時間を制御する必要があります。 色々な方法が

ありますが、最もシンプルな方法は、ある時間で強制終了させることで、図 6-53 のように記述します。

強制終了させるための記述例です。

-単独の process 文内に

STEP*8 = 800 ns 待ってから、

強制終了と宣言します。 その記述文が

assert false severity failure;

です。 この文は必須なので、忘れずに記述します。

6.7.2 全体回路のテストベンチ: tb_top_full.vhd の入力とコンパイル

現在のプロジェクト:full_adder の下で、図 6-51 の全体回路のテストベンチ: tb_top_full.vhd を入力後、

プロジェクトメンバーに追加してコンパイルして下さい。 入力記述のミス等による(Fatal な)コンパイルエラーは

全てデバッグして、正常終了させてください。 正常終了すると、“Project”欄は、図 6-54 になります。

図 6-54 “Project”欄の状態

INPUT(2..0) 000 001 010 011 100 101 110 111

1 パターン 8 パターン

process begin

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

end process;

process begin

wait for STEP*8;

assert false severity failure;

end process;

図 6-52 INPUT の記述

図 6-53 強制終了の記述方法

“Status”欄が、? → ✔ に変わる

100

6.7.3 全体回路のテストベンチ: tb_top_full.vhd の実行

以上で、テストベンチ:tb_top_full.vhd の準備ができたので、テストベンチによるシミュレーションを実行します。

手順通り実行しますが、今回は、実行モジュール: cfg_tb_top_full [← 図 6-51 30 行目の configration 名]が

作成されているので、それを実行します。

- プルダウンメニュー:「Simulate」 → 「Start Simulation」を選択して、“Start Simulation”画面で、“+work”を

展開して、“cfg_tb_top_full”を選択し、「OK」をクリックすると(図 6-55(左)、シミュレーションモードに移動します。

- “Library”画面で、“+work”を展開して(図 6-55(右))、“cfg_tb_top_full”を右クリックすると選択メニューが

ポップアップするので、“Simulate”を選択すると、シミュレーションモードの移動します。

図 6-55 テストベンチによるシミュレーションの実行方法

上記の操作により、図 6-56 のようなシミュレーションモードの初期画面が起動します。 ここからの操作は、

これまでのシミュレーションの実行と同じです。

図 6-56 シミュレーションモードの初期画面

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

101

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

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

「Simulate」 → 「Run」 → 「Run All」と選択して、シミュレーションを実行すると、図 6-57 の画面が表示され、

tb_top_full の 28 行目(この行数は、各人で異なるかもしれません)の“assert false severity failure;”

で強制終了したことが示されます(この意図した“強制終了”で終了していることが大切です)。

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

“Wave”画面を選択し、INPUT 信号を展開して、 で全体表示をすると、図 6-58 と表示されます。

シミュレーションが正しく実行されていることが判ります。 しかし、“Objects”画面に co_sig と s_sig がリスト

されていないので、図 6-45 のように、表示することがでしません。 図 6-45 と同じ表示にするためには、

図 6-59 のように操作します。

図 6-58 シミュレーショ後の“Wave”画面

102

状態を知りたい信号:co_sigと s_sig は、tb_top_full 内の信号ではないので、下位階層を探します。

シミュレーションモードでは、“sim”画面が表示されており、“- tb_top_full”に下に、“+ DUT”となっています。

この“+”をクリックして、"- DUT“とすると、図 6-59 のように、”- DUT“の下に DUT 内すなわち top_full_adder 内の

インスタンス名が表示され、“Objects”画面には、DUT 内の入出力端子名と内部信号名が表示され、ここに

状態を知りたい信号:co_sigと s_sig が存在ますので、これを波形エディタの信号名欄にドラッグします。

図 6-59 下位階層の信号名の取得方法

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

シミュレーションモードで解析中に、図 6-59 のように新たに信号名を追加した場合、再度シミュレーションを

実行する必要がありますが、以下のように処理します。

- (プルダウンメニュー)「Simulate」 → 「Restart」 と選択

- “Restart”画面がポップアップするので、「OK」 を選択する

- シミュレーションのスタート画面に戻るので、「Simulate」 → 「Run」 → 「Run All」 で実行

図 6-59 下位階層の信号名の取得方法

【注意】 シミュレーションの再実行は、条件により(端子名を変更、追加等)実行できない場合があります。

その場合は、一度シミュレーションモードを終了して、変更作業(コンパイル等)を行った後、再度

シミュレーションを起動する必要があります。

“+ DUT”を“- DUT”に変更すると、DUT内の

インスタンス名が表示される。 さらに、

同じ操作で下位階層に移ることも可能です

“- DUT”に変更すると、DUT内の

入出力端子名と内部信号名が

表示されるので、必要な信号を

波形エディタにドラッグする。

103

以上のように、出力表示の追加、表示位置の入れ替えを行って、図 6-48 のように表示させてた

テストベンチ:tb_top_full による全体回路:top_full_adder のシミュレーション結果は図 6-60 のようになります。

図 6-48 と比較するなどして、シミュレーション結果が正しいことを確認して下さい。

図 6-60(1) テストベンチによるとシミュレーション結果: Binary 表示

図 6-60(2) テストベンチによるとシミュレーション結果: Hexadecimal 表示