2-4 課題2: 『自分の名前を表示させよう』 2-4-1jte401/2016/2016_text_2.pdfbcd...
TRANSCRIPT
105
2-4 課題2: 『自分の名前を表示させよう』
2-4-1 デコーダ回路の設計
デコーダ回路とは、エンコーダの逆の機能で、例えば2進数を10進数に変換して出力する働きをもった回路です。 図 2-38の回路では、4ビットの 2進数を入力し 10進数に変換する機能ですが、10ビット出力信号 doutの各桁を 10進数の0から9に割り当て、該当するビットを1にすることで実現しています。 この例では、2進数"1000"が入
力されているので、出力は 10 進数の 8 にあたる dout(8)が 1 になります。 デコーダを VHDL で記述する場合は、process 文と case 文を使って記述します。
BCD コード ディジタル回路で 10 進数を扱う場合、一般に 4 ビットの 2 進数に分けて表現します。 これを BCD(Binary Coded Decimal: 2 進化 10進数)コードと呼びます。 例えば、64 を BCD コードで表すと"0110_0100"となります。 このことから図 2-38 のデコーダを BCD デコ一ダとも呼びます。
din(3)
din(2)
din(1)
din(0)
dout(9)dout(8)dout(7)dout(6)dout(5)dout(4)dout(3)dout(2)dout(1)dout(0)
1
0
0
0
0000001000
0100000000
図 2-38 デコ一ダ回路
(VHDL の仕様) process 文
process 文とは if 文や case 文に対応する回路が含まれるブロックを定義するものです。 process 文は次のように記述します。
起因リスト(センシティビティリスト)には、信号名をコンマで区切って並べます。 起因リスト内の信号の値に変化があ
ったときだけ文列が作動します。 これまでどおり、文列とは回路の作動に必要な各種の文を並べたものです。 最後の end process の process は省略して、end だけでもよいことになっています。
case文
case 文では式の値によって、指定した複数の逐次処理のうちいずれか 1 つを実行します。 (意味) 式の値が分岐値と等しい場合、"=>" の後の順次処理を行う。
case 文の構造は、次のようになっています。 case 式 is
when "分岐値" => 順次処理; when "分岐値" => 順次処理;
∙ ∙ ∙ when others => 順次処理;
end case ; 未定義の記述が無いように、最後の行に分岐値以外の値(others)の処理を明示します。
process(起因リスト) begin 文列 end process;
106
Case 文を用いたセレクタの記述例を、図 2-39 に示します。
すべての場合を包括する必要があるためothers文を使用する
Process文(SELS,A,B,C,D)
process(センシティビティ・リスト)begin
シーケンシャル文
end process;
case文
case 式 iswhen 選択子 => シーケンシャル文;when 選択子 => シーケンシャル文;
・・
when others => シーケンシャル文;end case;
図 2-39 case 文記述例
2-4-2 7 セグメントデコーダ
7セグメントデコーダとは、7セグメント LEDに数字(16進数)が表示できるように、
2進数のデータを変換する働きを持った回路です。 図2-40のように、7セグメン
ト LED は、数字用の 7 個の LED に小数点用のドット、合計 8 個の LED が使用さ
れています。 DE0 の 7 セグメント LED は、アノードコモン型(右図。カソードコモ
ン型もあります)で、内部の LED のアノード側が共通になっています。 このため、
LED を点灯するには、点灯したいビットを 0(low)にし、それ以外のビットは、
1(high)にそれぞれする必要があります。
図 2-41 は、7 セグメントデコーダの VHDL の記述例です。 入力信号は、BCD コ
ード(4 ビット)で、出力信号は、1 個の 7 セグメント LED の駆動に必要な 8 ビット
幅の信号になります。 通常、これを記述する場合は、”std_logic_vector”というバ
ス記述を使用します。
【検討】 図 2-41 に記述が、図 2-40 の動作(状態)を正しく記述できているかを
丁寧に検証して下さい。 この VHDL の記述には、多くの不適切な個所が ありますので、全ての箇所を正しく把握して下さい。
107
図 2-40 7 セグメント LED
図 2-41 7 セグメントデコーダ記述例(7seg_ex.vhd)
108
2-4-3 課題2: 7 セグメントデコーダを使って、自分の名前を表示させよう~
設計する回路は、DE0 上の 4 個の 7 セグメント LED に、右から左に流れるように、以下の文字列を表示させる ものです(図 2-42)。 [表示する文字列] 0123456789_I_am_自分の名前.
0123456789_I_am_自分の名前
図 2-42 課題2 『自分の名前を表示しよう』
この設計では、以下の 4 つの機能を持ちます。
① 7 セグメント LED に 0~9 までの数字を表示させた後、自分の名前をアルファベットで表示 ② シミュレーションを行う際に、結果を見やすくするための ASCII 表示変換 ③ DE0 の BUTTON0(STOP)を押すと動作の停止/再開(peripheral 内のカウンタの停止/再開) ④ DE0 の BUTTON1(RESET)を押すと初期状態に戻る(0表示。peripheral 内のカウンタが最初の値になる) (※) みなさんに作ってもらうのは①、②部分のデコーダです。③、④は配布した peripheral 内で行います。
図 2-43 は、設計する回路のブロック図です。
図 2-43 課題のブロック図
109
【図 2-43 の解説】
入力部分 CLK には、DE0 から 50MHz のクロックが入る STOP には、DE0 の BUTTON0 を接続する RESET には、DE0 の BUTTON1 を接続する peripheral_moji 部分 50MHzのクロックを分周し、分周したクロックから現在の表示文字数をカウントアップ。 表示順序番号とする 現在の表示順序番号を deco0 から 6bit で出力する 現在の表示順序番号から-1 した表示順序番号を deco1 から 6bit で出力する(deco2 は-2 したもの、deco3 は-3
したものを出力する)。 つまり、文字が HEX0~3 の方向に向かい、流れて行くように表示される。 STOP が入力されると、表示の動きを停止 / 開始する RESET が入力されると、表示順序番号を初期値に戻す conversion_ascii 部分 表示順序番号は、6bit なので、0~63 の数字がトグルします。 各数字(表示順序番号)の表示する文字列:
“0123456789_I_am_自分の名前.”を割り当てて、ASCII コード(8bit)にデコードして出力する moji_deco 部分 ASCII コードに変換された文字コード(8bit)を入力して、7 セグメント LED の入力信号となる表示データ(8bit)に
デコードして出力する。 出力部分 7 セグメント LED を駆動するために必要な 8bitの信号 (表示する文字列になっている) 作成上の注意 ① 設計は、新しい作業フォルダと新しいプロジェクト名で行って下さい。 例 (Z:/ quartus2_work/moji_deco) ② peripheral の出力信号は、表示順序番号:”000000”、”000001”、”000010”、・・・、”111111”を繰り返します。
その順番に、“表示する文字列”を割り当てて、7 セグメント LED に順番に表示されるようにします。 ③ 表示順序番号に従って出力される 7 セグメント LED に送られる文字の表示データは、シミュレーション時の結果
の表示が判り難いので、結果の表示を判り易くするために一度 ASCII の文字コードに変換します(conversion_
ascii.vhd)。 その後、ASCII の文字コードを 7セグメント LED の入力信号に変換して下さい(moji_deco.vhd)。 (※)ASCII コードへの変換は、表 2-4 を参照して下さい。
例えば、ASCII コードで「0」と表示させるには 10 進コードで「48」と入力する必要があるので、 conversion_ascii の出力端子(ascii)には 2 進数で”110000”と出力します。
④ 図 2-41 の 7 セグメントデコーダ記述例(7seg_ex.vhd)と 図 2-48、図 2-49 の作成例(conversion_ascii.vhd、moji_deco.vhd)を参考にして、作成して下さい。
⑤ 7セグメント LEDの数字表示例を、図2-44に示します(一番右列の”0”は、LED右下の小数点 decimal point)。表の必要な部分を埋めてください。 一番左列の数値は、文字コードとみなすことができます(プログラムでは、
一番左列の数値は、ASCII コードに対応した表示データ(ascii))。 LED の各セグメントの点灯箇所を黒く塗りつ
ぶしていますが、ビット表記は、アノードコモン型(‘0’で点灯、‘1’で消灯)になっています。
110
表 2-4 英数字記号の ASCII コード表
ASCII_10 進コード 文字(グラフィック)
32 空白
46 .(ドット)
48 0
49 1
50 2
51 3
52 4
53 5
54 6
55 7
56 8
57 9
61 =
65 A
66 B
67 C
68 D
69 E
70 F
71 G
72 H
73 I
74 J
75 K
76 L
77 M
78 N
79 O
80 P
81 Q
82 R
83 S
84 T
85 U
86 V
87 W
88 X
89 Y
90 Z
95 _ (アンダースコア)
127 削除
111
a b c d e f g 0
0 0 0 0 0 0 1 1
図 2-44 英数字の 7 セグメント LED 表示①
a b c d e f g 0
図 2-45 英数字の 7 セグメント LED 表示②
112
a b c d e f g 0
図 2-46 英数字の 7 セグメント LED 表示③
a b c d e f g 0
図 2-47 英数字の 7 セグメント LED 表示④
113
図 2-48 ASCII 変換記述例(conversion_ascii.vhd)
114
図 2-49 デコーダー記述例(moji_deco.vhd)
115
2-4-4 コンパイル、シンボル化、トップ回路図の作成
課題を作成出来た人は、conversion_ascii と moji_deco の名前で保存をして下さい(図 2-50)。
図 2-50 保存(moji_deco.vhd)
保存が終わったら conversion_ascii と moji_deco をそれぞれトップレベルに設定しコンパイルを行ってください。 エラーがなくなれば、それぞれのシンボルを作成してください(シンボル化)(図 2-51)。
①File → Create/_Update→ Create Symbol Files for Current Fileを選択
図 2-51 シンボル化(moji_deco.vhd)
116
作成した conversion_ascii とmoji_decoは、デコード機能しかありませんので、表示順序番号の発生やその他の
機能を実現するために、peripheral_moji.vhd を使用する必要があります。 (※) 4bit 加算器で使用した peripheral_DE0.vhd とは、別のファイルですので注意して下さい。
“http://www.ed.tus.ac.jp/~jte401/”からダウンロードした peripheral_moji.vhd を現在作業しているフォルダ (Z:/quartus2_work¥moji_deco)にコピーして下さい。 コピーをしてきたら、QuartusⅡで開きます(図 2-52)。 peripheral_moji.vhd を開いたらコンパイル、シンボル化を行ってください。
①File→Openを選択
②peripheral_moji.vhdを選択
③開くをクリック
図 2-52 File の Open(peripheral_moji.vhd) ○ トップレベル回路図の作成
peripheral_moji.vhd 、conversion_ascii、moji_deco を使って、トップレベル回路図を作成します。 回路図エディタを起動して、回路を入力します(p.25 参照)。 「File」-「New」を選択すると New 画面が表示される
ので、「Block Diagram/Schematic File」を選択して、「OK」を選択すると回路図エディタ画面が表示されます。 peripheral_moji、conversion_ascii、miji_deco のシンボルを図 2-53 のように配線して下さい。 (※) 入力端子の名前は、大文字にして下さい(C,R,STOP)。 (※) シンボル「conversion_ascii」の出力につなぐバスには、ascii0[7..0]、ascii1[7..0]、ascii2[7..0]、
ascii3[7..0]と名前をつけて下さい。
配線が終わったら、「moji_deco_top」の名前で保存をして下さい。 保存したら、コンパイルを行って、エラーが無い事を確かめてください。 エラーがある場合は、エラーが無くなるま
で修正します。
117
図 2-53 トップレベル回路(moji_deco_top.bdf)
118
2-4-5 シミュレーション
設計した moji_deco_top のシミュレーションを行います (シミュレータは、ModelSim を使います)。 設計した moji_deco_top.bdf の Schematic ファイルを VHDL ファイルに変換して下さい(テキスト p43 参照)。
ModelSim は、以下の 2 つの方法で起動します。
1. デスクトップのアイコンによる起動
⇒ModelSim がインストールされていれば、ディスクトップに「ModelSim SE-64 10.3a」の アイコンが生成されます。このアイコンをダブルクリックします。
2. スタートメニューからの起動 ⇒Windows のスタートメニューから、「コンピューター」-「ローカルディスク(C:)」- 「Modeltech64_10.3a」-「Win64」-「modelsim.exe」を選択すると起動します。
正常に起動すると図 2-54 の画面が表示されます。
図 2-54 ModelSim の起動画面
119
(1) 新規プロジェクトの作成 プロジェクトを作成します。 「File」 → 「New」 → 「Project」の順にクリックします(図 2-55)。
図 2-55 新規プロジェクトの作成
以下の画面が表示されるので、Project Name、Project Location、Default library Name を設定します(図 2-56)。
図 2-56 新規プロジェクトの設定画面
作業ディレクトリが存在しない場合は、「はい(Y)」をクリックして作業フォルダを作成します(図 2-57)。
図 2-57 作業フォルダ作成の確認画面
120
作成したプロジェクトにファイルを追加するかの画面を、Close をクリックして閉じます(図 2-58)。
図 2-58 Add items to the Project 画面
ModelSim でシミュレーションする VHDL ファイルの作成をします。 「New」 → 「Source」 → 「VHDL」の順にクリックします(図 2-59)。
図 2-59 VHDL ファイルの作成画面①
121
VHDL のエディタが開いたら、QuartusⅡで作成した moji_deco.vhd の VHDL ソースをコピー&ペーストします (図 2-60)。 (※) VHDL のソースは、直接打ち込んでも構いません。
図 2-60 VHDL ファイルの作成画面②
作成した VHDL ファイルを保存します。 「File」 → 「Save As…」の順にクリックします(図 2-61)。
図 2-61 作成した VHDL ファイルの保存画面① ファイル名に「moji_deco.vhd」を入力して、「保存」を選択します(図 2-62)。
122
図 2-62 作成した VHDL ファイルの保存画面②
同様にして、peripheral_moji.vhd、conversion_ascii.vhd、moji_deco_top.vhdの4つのVHDLファイルを作成し、
作業フォルダ内(Z:/quartus2_work/moji_deco/testbench)に保存して下さい。
次に、作成した VHDL ファイルをプロジェクトに追加します。 プロジェクトタブの中で右クリックして、「Add to Project」 → 「Existing File」を選択します(図 2-63)。
図 2-63 作成した VHDL ファイルのプロジェクトへの追加画面
「Browse」をクリックし、追加するファイルを選択します(図 2-64)。
123
図 2-64 Add file to Project 画面
作業フォルダ(Z:/quartus2_work/moji_deco/testbench)に作成した VHDL ファイル(moji_deco.vhd、peripheral_moji.vhd、conversion_ascii.vhd、moji_deco_top.vhd)を選択して、「開く」をクリックします(図 2-65)。
図 2-65 Select files to add to project 画面
選択すると以下の画面に戻るので、「OK」を選択すると VHDL ファイルがプロジェクトに追加されます(図 2-66)。
図 2-66 Add file to Project 画面
VHDL ファイルが正常にプロジェクトに追加されると、以下の画面のようになります(図 2-67)。
124
図 2-67 vhd ファイルを追加し終わった画面
シミュレーションをし易くするために、peripheral_moji.vhd のソースコードを一部変更します。 「peripheral_moji.vhd」を右クリックして「Edit」を選択し(図 2-68)、ソースコードの 100 行目の cnt の値を 100 に、
ソースコードの 135 行目の cnt の値を 50 に変更して下さい(図 2-69、図 2-70)。
図 2-68 peripheral_moji.vhd のソースコードの一部変更画面①
125
図 2-69 peripheral_moji.vhd のソースコードの一部変更画面②
図 2-70 peripheral_moji.vhd のソースコードの一部変更画面③
変更し終わったら、「上書き保存」を選択して保存します(図 2-71)。
図 2-71 変更した VHDL ファイルの保存画面
126
(2) VHDL ファイルのコンパイル 追加された VHDL ファイルをコンパイルします。 「Compile」 → 「Compile All」を選択して、コンパイルします(図 2-72)。
図 2-72 追加した VHDL ファイルのコンパイル画面
コンパイルが成功すると、図 2-73 のようにチェックマークが入ります。 コンパイルでエラーが出たときは、バツマークが入ります。
図 2-73 コンパイル成功画面
127
(※) ModelSim のコンパイルでエラー(Status にバツマークが入る)が出たときは、以下の方法を参考にして、 エラーを修正して下さい(図 1-74、図 1-75)。
修正が完了したら保存して、もう一度コンパイルしてください(エラーが消えない場合は、同じ操作をして、 エラー箇所を修正し、コンパイルでエラーが出なくなるまで続けてください)。
図 1-74 コンパイルでのエラー発生画面
図 1-75 コンパイルでのエラー修正画面
128
(3)シミュレーションの準備 シミュレーションするファイルを選びます。 Libraryウィンドウのworkを展開すると出てくる「moji_doco_top」を右クリックし、出てきたメニューからSimulateを選択します。 Object ウィンドウに信号が出てきます(図 2-76)。
図 2-76 Libraryの選択画面
(4)波形の入力 インプットが clk、reset、アウトプットが ascii0、ascii1、ascii2、ascii3(内部信号)なので、clk、reset に入力波形を 設定して行きます。 Object ウィンドウの右クリックメニュー「Modify」→「Apply Wave」から波形を作ります。 まず信号 clk の設定を行います(図 2-77、図 2-78)。
図 2-77 信号 clk の入力波形の設定
129
図 2-78 信号 clk の入力波形の設定
「Finish」を選択すると、clk の入力信号の波形がWave ウィンドウに表示されます(図 2-79)。
図 2-79 入力信号(clk)の波形
130
次に、信号 reset の設定を行います(図 2-80、図 2-81)。
図 2-80 信号 reset の入力波形の設定
図 2-81 信号 reset の入力波形の設定
131
「Finish」を選択すると、reset の入力信号の波形がWaveウィンドウに表示されます(図 2-82)。
図 2-82 入力信号(reset)の波形
作成した moji_deco_top の回路は、「reset ボタンを押す」と 7 セグメント LED に表示される文字がシフトしていく という仕様なので、「reset ボタンを押す」という波形を入力します。 「reset」の信号名を左クリック → 「Edit Mode」 → 「Insert Pulse」を選択してパルス波形を作ります(図 2-83)。
図 2-83 信号 reset にパルス波形の入力
Duration、Time、Time Unit を設定して、「OK」を選択します(図 2-84)。
図 2-84 信号 reset にパルス波形の入力
132
「OK」を選択すると、Wave ウィンドウ画面の信号 reset の波形にパルス波形が入力されます(図 2-85)。
図 2-85 信号 reset にパルス波形の入力
Object ウィンドウから、Wave ウィンドウにシミュレーションする信号を移します。 インプットclk、resetは、先程の作業で移したので、次にアウトプットascii0、ascii1、ascii2、ascii3を移動させます。
Object ウィンドウで移動させる信号を選択し、Wave ウィンドウにドラッグして移動させます。 これで clk、reset、ascii0、ascii1、ascii2、ascii3 の 6 つの信号がWave ウィンドウに表示されます(図 2-86)。
図 2-86 内部信号 ascii0、ascii1、ascii2、ascii3 をWave ウィンドウにドラッグ
133
(5)シミュレーションの実行 シミュレーションは、「Simulate」-「Run」-「Run-All」を選択すると実行を開始します(図 2-87)。
図 2-87 シミュレーションの実行
シミュレーションが正常に終了すると、結果が表示されます(図 2-88)。
図 2-88 シミュレーションの実行後の画面
シミュレーション実行後の波形表示に対して、基数を変更する事ができます。 波形表示の中で、信号 clk、reset、ascii0、ascii1、ascii2、ascii3の結果が 2進数で表示されています。 シミュレーション結果を見やすくするために、
信号 ascii0、ascii1、ascii2、ascii3 を ASCII に表示します。
まず、信号 ascii0 をマウスの左ボタンで選択して、右ボタンをクリックするとプルダウンメニューが表示します。
「Radix」欄の候補から「ASCII」を選択します(図 2-89、図 2-90)。 同様にして信号 ascii1、ascii2、ascii3 も ASCII 表示します(図 2-91)。
134
図 2-89 信号 ascii0 の ASCII 表示の設定
図 2-90 信号 ascii0 の ASCII 表示
図 2-91 信号 ascii0、ascii1、ascii2、ascii3 の ASCII 表示
135
2-4-6 端子割り当て
Modelsim でのシミュレーションの結果、設計した回路が正しく動作していることを確認できたら、実機(DE0)で 動作確認を行います。
(※) 作成した回路の実機へのダウンロードは、QuartusⅡで行います(ModelSim 環境ではありません)。
moji_deco_top.bdf のコンパイルが終わったら、Assignments の Pin Planner を開いてください。 ピン割り当て表ファイル「moji_deco_pin.xlsx」(指定された場所からダウンロードします)から、 ピン配置をコピーして、Location に貼り付けてください(図 2-92)。 (注) Pin Planner とピン割り当て表ファイル「moji_deco_pin.xlsx」のピン名の並びが 一致していることを確認してください。
図 2-92 ピン配置
再びコンパイルすると、図 2-93 のように、ピン情報が付加されます。
136
図 2-93 ピン情報の付加
137
2-4-7 動作確認
テキスト p.73 を参考にして、コンフィグレーション・データを評価ボードにダウンロードします。
ダウンロードが終わったら図 2-95 を参考に動作を確認して下さい。
0123456789_I_am_自分の名前
[BUTTON0]動作の開始/停止
[BUTTON1]リセット
図 2-95 動作確認
図 2-94 Programmer 画面
138
2-5 課題3: 『チャタリング防止回路の設計』
(VHDL の仕様) この設計で使う文法を先に説明します。 if 文
if 文は、条件が成立するか否かにより、回路動作の二者択一を記述するもので、次のように記述します。
後述する条件式(論理式や関係式)の値が、真であれば then に続く文列が実行され、偽であれば else に続く文列 が実行されます。 else に続く文列が不要であれば、次のように記述出来ます。
else に続く文列が1個の if 文だけの時には、else と if を連結して、次のように記述することもできます。 138149 event 属性
event 属性とは、同期式順序回路において状態遷移を起因パルス信号の立ち上がりエッジで実行するか、 あるいは、立下りエッジで実行するかを指定するための記述であり、次のように記述します。 パルスの立ち上がりエッジの場合、
パルスの立下りエッジの場合、
2-5-1 順序回路
順序回路とは、現在の入力と過去の入力から回路の状態が決まる回路です。 過去の入力とは、記憶回路に記憶
された値なので、順序回路は、組み合わせ回路と記憶回路から構成される回路となります。 記憶回路とは、一般
にフリップフロップ(FF)を指し、FF 自身(レジスタとも呼ばれます)も順序回路です。 一般的に、記憶回路には、動作する(データを記憶して出力する)タイミングを取るための「クロック」と呼ばれる信号
が入力されます。 クロック信号は 0 と 1 のパルス波形で、タイミングの条件は、同期を取る場合、一般にクロック
の立ち上がりエッジもしくは立ち下がりエッジに合わせてタイミングを取ります。 このタイミングを VHDL で記述す
るには、IF 文の条件に、次のような特殊な記述をします。 下の記述は、クロックの立ち上がりエッジの場合です。 クロック同期の記述
(注意) clk は、クロック信号の名前で、任意の名前で構いませんが、わかりやすくするために clk としました。 立ち下がリエッジの場合は clk = '0'と記述します。
図 2-96 同期のタイミングチャート
if 条件 then 文列 else 文列 end if;
if 条件 then 文列 end if;
if 条件 then 文列 elsif 条件 then 文列 else 文列 end if ;
if (clk 'event and clk = '1') then
if 信号’event and 信号 = ‘1’ then ・・・ end if;
if 信号’event and 信号 = ‘0’ then ・・・ end if;
139
図 2-96 に示した信号の時間変化を記述したものをタイムチャートと呼びます。 図 2-96 では、クロックの立ち上が
りエッジでdinのデータがdoutに出力され、それ以外ではdoutのデータが変化せずそのままの状態が続きます。
この状態をラッチと言います。 クロックと周波数の関係を考えると、20MHzは 2 千万クロックとなり、1 クロックあたりの時間を計算すると 50ns と
なります。 つまり、クロックを速くすれば、回路が高速に動作することになります。 高速なクロックは、制御回路な
どの高速な動作を必要とする回路に用いられます。 時計の動作を例にとると、時計は 1 秒間に一回カウントする
ので、カウント命令を与えるための制御回路は高速なクロックで動作させ、実際にカウント用のクロックは 1Hz とし
ます。 このようにパルス波形を周波数の低いパルス波形にすることを分周させるといい、分割するための回路を
分周器と呼びます。 ◇ フリップフロップ
フリップフロップには、RS-FF、 T-FF、JK-FF、D-FF の 4種類が存在します。 同期回路として頻繁に利用されるのは、D-FF です。 また、VHDL で記述できるのも D-FF だけです。 ここでは、参考までに、各フリップフロップの動作について説明します。
(注意) Q' は、Q 次の状態を指しています。 は、Q を反転させたものです。
S Q
R
S R Q Q'0 0 0 00 0 1 10 1 0 00 1 1 01 0 0 11 0 1 11 1 0 –1 1 1 –
S
RQQ–
Q–
J K Q Q'0 0 0 00 0 1 10 1 0 00 1 1 01 0 0 11 0 1 11 1 0 11 1 1 0
RS-FFJ Qclk
K Q–
clkJKQQ
JK-FF
–
D Q
clk Q–
D-FF
clkD
QQ–
D Q Q'0 0 00 1 01 0 11 1 1
T Q
clk Q–
T-FF
clkTQQ–
T Q Q'0 0 00 1 11 0 11 1 0
図 2-97 フリップフロップの種類
RS-FF 「R」は「リセット」、「S」は「セット」の意味で使われます。 タイムチャートから S が 1 でR が 0 のとき Q(出力)に 1がセットされます。 逆に、Sが 0でRが 1のときQがリセット(0になる)されます。 S とQがともに 1の場合は
次の状態が予測できないので、入力禁止とされています。 状態遷移表から Q の状態が変化するのは、(R=1、Q=1)、 (S=1、Q=0)の場台です。
JK-FF タイムチャートからクロックの立ち上がりに同期して、J が 1 で K が 0 のとき Q に 1 がセットされます。 逆に、 J が 0 で K が 1 のときリセットされます。 J と K がともに 0 のときは状態遷移表からわかるように、状態は変化し
ません(現在の値が 0 なら次の値も 0 のまま)。 J と K がともに 1 のときは、次の値は現在の値を反転したものに
なります。 D と Q の値が異なる場合です。状態遷移表から Q の状態が変化するのは(K=1、Q=1)、(J=1、Q=1)、 (J=1、K=1)の場合です。
140
D-FF 「D」は「Delay(遅延)」や「Data(データ)」の意味で使われます。 タイムチャートからクロックが立ち上がった時の D を出力とします。 状態遷移表から Q の状態が変化するのは、D と Q の値が異なる場合です。
T-FF 「T」は「トグル(toggle)」または「トリガ(trigger)」の意味で使われます。 タイムチャートからクロックに同期して、Tが
1の場合、その時点でのQの値が反転されます。 それ以外の場合、0の値はそのままで変化しません。 遷移表
から 0 の状態が変化するのは、T が 1 の場合のみです。 2-5-2 D-FF の設計
D-FFはすでに説明したように、クロックの立ち上がり(立ち下がり)時のDを出力します。 では、この動作をVHDLで記述しましょう。 プロセス文を使って動作をそのまま表現すれば、簡単に設計できます。 回路図を意識せずに
設計できるところが VHDL の利点です。 一般に、D-FF にはリセット機能が付加されます。 これは、強制リセット
のために、クロックに非同期で働きます。 つまり、リセットがオンとなればクロックに関係なく即座に出力が 0 とな
ります。
D Q
clk
rstリセット
clk
rst
D
Q
図 2-98 リセット付き D-FF
図 2-98 に示した D-FF の動作を VHDL で記述するにはプロセス文と IF 文を用いて次のように記述します。
process (clk, rst) begin if (rst = '0') then Q <= '0' else if (clk 'event and clk = '1') then Q <= D end if: end process:
(注意) リセットは非同期なので、if 文でリセットの動作をクロックとは別に記述します。 図 2-98 の場合のリセットは、負論理で動作するので if 文の条件には rst = '0'と記述します。
D-FFでの注意事項
D-FF において、クロックの立ち上がり前後で入力D が変化してはいけない時間帯があります。 一般的に、 立ち上がり前をセットアップタイム、立ち上がり後をホールドタイムと呼びます。 この時間帯でDが変化した場台、
メタ・ステーブル(meta-stable)と呼ばれる出力Q の値が保証されない不定な状態に陥ってしまいます。
クロック
セットアップタイム
データ
ホールドタイム
図 2-99 D-FF における注意事項
141
行数 VHDL 本文
1 2
library IEEE ; use IEEE. std_logic_1164. all ;
3 4 5 6 7
entity dff is port(clk, rst : in std_logic; D : in std_logic; Q : out std_logic); end dff;
8 9 10 11 12 13 14 15 16 17 18
architecture RTL of dff is begin process(clk, rst) begin if( rst = '0') then Q <= '0'; elsif( clk' event and clk = '1' ) then Q <= D; end if; end process; end RTL;
図 2-100 D-FF の設計(dff.vhd)
[図 2-100 の解説] ① VHDL モデル定義(1~2 行)
1 行目でライブラリ宣言 2 行日でパッケージ宣言
② エンティティ文(3~7 行) 3 行目でエンティティ宣言、 4~6 行目でポート宜言(clk:クロック入力、rst:リセット入力、D:1 ビット入力データ、Q:1 ビット出カデータ)、 7 行目でエンティティ終了
③ アーキテクチャ文(8~18 行) 8 行目でアーキテクチャ宣言 9 行目でアーキテクチャ開始 10 行目で起因リストの定義 11行目でプロセス文の開始 12~13 行目でリセット動作の記述 14~15 行目でクロック同期の記述 16 行目で if 文終了 17 行目でプロセス文終了 18 行目でアーキテクチャ文終了。
142
2-5-3 カウンタの設計
同期回路の基本となる D-FF の性質は理解出来たと思うので、これから代表的な順序回路を VHDL で設計して行
きます。 D-FF を複数個組み合わせることで様々な機能を持った順序回路を設計することが出来ます。 ここでは
そのうちの 1 つであるカウンタの設計について説明します。 カウンタとは、その名の通り、数をカウントする機能を持った回路です。 時計の動作は、このカウンタが基本とな
っています。 ここで扱うカウンタは同期型とするので、カウンタの動作は process文を用いて、同期記述部の中に
記述します。 カウンタ動作の例として、1ずつカウントアップする式は、次のように書き表せます。 A <= A + ‘1 ‘;
この式では、信号A に A を代入しています。 すでに述べたように VHDL 記述では出力信号を入力として再利用
することは禁止しているので、この式で使われている A は、内部信号でなければいけません。 次に、カウントする値の上限を決めなければいけません。 これは、どこまでカウントするかによって、データの
ビット数が決まるからです。 カウンタの代表的な例として、10 進カウンタが挙げられます。 これは、0~9 まで
カウントし、9までカウントしたらリセットしてまた0からカウントし直します。 カウンタの上限値が9なのでデータの
ビット数は、4bit となります。 カウントの上限値を変更することで様々なカウンタを設計することが出来ます。
図 2-101 にカウンタの記述例を示しました。 (注意) 記述に整合性が取れていない箇所があるかもしれないので、各行を確認して下さい。
図 2-101 カウンタ記述例(count_ex.vhd)
143
2-5-4 チャタリング現象
チャタリングは、スイッチを入れたり切ったりするときに発生する現象です。 家庭用の電灯のスイッチで、チャタリ
ングを意識することはまずないと思いますが、高速で動作するハードウェアでは非常に重要です。 スイッチをON/OFFすると、スイッチの接点の汚れや接点の振動などにより、非常に短い時間ですが、ONとOFFが図のように繰り返される現象が発生します。 これが、“チャタリング”と言われる現象です。
チャタリングが発生する時間は非常に短く、通常数msから、長くても30ms程度と言われています。 従って、家庭
用の電灯の ON/OFF ではこのような瞬間的な ON/OFF は気がつきませんが、ディジタル回路は、数 ns 周期の
クロックでも動作しますので、この時間は非常に長いことになります。 従って、カウンタのクロックにチャタリング
が発生すると、1 回のスイッチ操作でいくつものクロックが入力されることになり、誤動作の原因になります。 チャタリングの防止回路はいくつか考えられますが、簡単な回路として図のような回路があります。 この回路では、スイッチの入力を D-FF で受けて、その出力を回路のスイッチ入力として使います。
図 2-102 スイッチのチャタリングの様子
図 2-103 チャタリング防止回路
144
2-5-5 課題 3:チャタリング防止回路の設計(仕様)
(※) QuartusⅡで、新しいプロジェクトを作成して作業して下さい。 例: z:¥ quartus2_work¥chatter 図 2-104 は、チャタリング防止回路の例です。 この回路を使って、チャタリング防止回路の機能を確かめます。 使われているモジュールは、chatter、count_ex_miss、conversion_ascii、moji_deco の 4 つです。 chatterモジュールはこれから設計しますが、他のモジュールは既にVHDL記述があるので、それを再利用します。
各VHDLソースを今回作業する新しいプロジェクト下に持ち込んで、再度コンパイルとシンボル化を実行して、エラ
ーが無い事ことを確かめておきましょう。 chatter モジュールの設計(後述)ができたら、この回路図の配線をして、実機(DE0)で動作確認を行います。 ピン割り当ては、図中のピン情報に従って、割り当てて下さい。
[回路の概要] ボタンスイッチ1の押下回数が正しく LED に表示される。 → チャタリングが発生すると正しくカウントされない
→ チャタリング周波数を変えて、正しく数えられるように調整する(チャタリング防止) (入力) クロック(clk): 50Mhz [PIN_G21]、 Button1の押下信号(SW) [PIN_G3] リセット(rst) [PIN_H2] (出力) 押下回数の表示(LED0[7..0]) [PIN_E11~PIN_D13]
図 2-104 チャタリング防止回路の例
[chatter モジュールの仕様]
Chatter モジュールは、以下の2つの手法(仕様)を使います。 (手法1) チャタリングしている時間よりも長いサンプリング周期で 1 回サンプリングして、押下回数を数える この場合、サンプリング周期が長すぎると、押下自体を検出できなくなる可能性がある(図 2-105)。 (手法2) サンプリング周期をもっと短くし、スイッチを押したときの信号レベルを複数回(ここでは、6 回)サンプリ
ングし、サンプリングした点ですべての値が押下なら 1回の押下信号を出力する(図 2-106)。 [実習で確かめること] 各手法で、チャタリングを防止できるサンプリング周期を確かめて下さい。 [実習時の注意]
(1) “押下”の処理は、A 接点、B 接点スイッチで異なるため、後述のスイッチの情報を確認して下さい。
(2) VHDLのソースを何度も変更するので、工夫して、効率的に実習して下さい。
145
【DE0 のプッシュボタンスイッチについて】
DE0 のプッシュボタンスイッチの接続図は、 図 2-105 のようになっています。
BUTTON0 → H2、 BUTTON1 → G3、 BUTTON2 → F1
に接続されています(ピン割り当て情報)。 各ボタンは、3.3V でプルアップされており、DE0 では a 接点のプッシュスイッチが使われているので、 スイッチを押していない時、論理値‘1’’ 押している間だけ、 論理値‘0’
となります。 (※) a 接点,b 接点
a 接点: スイッチを押下、またはトグルスイッチを閉じる方に切り替えることで接点が閉じ電流が流れます。
b 接点: スイッチを押下、またはトグルスイッチを開く方に切り替えることで接点が開き電流が止まります.
a 接点の記号
b 接点の記号
(VHDL の仕様) 2 進数のビット演算 と バスの結合
- 1 and 1 and 1 = 1; ⇔ (not 0) and (not0) and (not0) =1; - A の否定の信号を内部信号の B に入れたいときの記述: B <= not A ; - バスの結合: (関係演算子) &[連接]の機能
4bit
1bit
5bit
4ビットの信号と1ビットの信号を組み合わせ5ビットの信号を作りました。詳しく説明しますと、下の図のように、5ビットのADDという信号の、4ビット目にcoの1ビットの信号を、3~0ビット目に4ビット信号S[3..0]を信号を各ビット順を揃えて合成しています。
4 3 2 1
ADD[4..0]
co
0
s[3..0] 上記と同様の機能は、VHDL では以下のように記述します。
ADD<= co & S ;
(注) &は、連接機能で、and と書くと全く別の意味になります。
使用時には、ADD、co、S 等の変数のビット数を考慮する必要があります。
146
◇ 手法 1 のチャタリング防止回路の記述例 (図 2-105。モジュール名: chatter) DE0 には、50MHz の外部クロックがありますが、このクロックは、チャタリングの防止クロックに使うには速すぎる
ので、分周します。 このプログラムでは、赤枠の数値を大きくすることでサンプリング周期を長くしています。 もし、枠部分が 15 ならば 16bit の分周器になり、周波数は 1/65536 となるので約 763Hzのクロックとなります。
図 2-105 手法1のチャタリング防止回路の記述例 (chatter.vhd)
147
◇ 手法2のチャタリング防止回路の記述例 (図 2-105。モジュール名:prevention_of_chattering_kadai)
chattを左シフトさせます
chatt(5)~chatt(0)について前回のテキストのヒント①から考える
counterの最上位のビットが’1’のときにsamplingを’1’にしている→28分周
SW_INの入力を反転させている(プッシュスイッチを押すと ‘1’)
chattの最上位ビットを捨てます
図 2-106 手法2のチャタリング防止回路の記述例 (prevention_of_chattering_kadai)
16 行目: 入力信号SW_IN の反転信号を swsig 代入 (DE0 のプッシュスイッチが a接点型のため); 34 行目: サンプリングした swsig を chatt 変数(6 ビット)に蓄積します。 chatt のデータを 1 ビット左シフトさせ、
swsig を chattの最下位ビットに入力します。 すなわち、chatt(4)~chatt(0)と swsig を&(連接演算子)で
結合させます。 37 行目 chatt(5)~chatt(0)の全ビットが'1'の時だけ sw_out が1'となり、スイッチが押下されていると判断します。 サンプリング周期の変更: 11 行目と 21 行目の counter(7)の’7’を変更すると、任意に変更できます。
148
以上で、課題2:『自分の名前を表示しよう』と課題3:『チャタリング防止回路』の設計と評価ボードを使った実機動作の
確認は、終了です。 ここで使った設計手法は、以下の通りです。
◇ (QuartusⅡ上で、) 各下位階層モジュールは、VHDL で設計 [⇐ コンパイルエラー無し]
→ (QuartusⅡ上で、) トップレベル回路は、回路図エディタで作成 [⇐ コンパイルエラー無し]
→ (ModelSim へ移り、) シミュレーションの実行 [⇐ シミュレーションエラー無し]
→ (QuartusⅡに戻り、) 実行モジュールを作成し、実機での動作確認 [⇐ 実動作エラー無し]
(注) 課題 3 では、シミュレションの実行をしません。
本講座では、実習3日目終了までに、全員が課題2、3を終了することを目標としますので、課題2、3が早く終了した受
講者は、直ぐに課題 4 に進むのではなく、以下の追加仕様を実習して、各受講者の進捗状況を合わせます。
以下の実習には、“テストベンチ”(テスト対象モジュール[DUT(Design Under Test)]をシミュレーションするためのトッ
プモジュールで、ここでは VHDLで記述します) の考え方と実行方法を習得しますので、是非チャレンジして下さい。
[追加仕様2] (以下の順番で、できる所まで実習しましょう)
1.課題2の追加仕様
1) (QuartusⅡ上で、) トップレベル回路を VHDL記述し、コンパイル後、実機確認する。
・ModelSim上に、トップレベル回路の VHDL記述がありますが、自分で記述して見ましょう
→ 全モジュールを VHDLで記述したことになります(=回路図がなくても設計できる)
2) (ModelSim 上で、) テストベンチを作成して、シミュレーションを実行する。
⇐ テストベンチの記述方法は、プレゼン資料の“5.テストベンチ”等を見て下さい。
① 7segLED デコーダ単体(moji_deco)のテストベンチを作成し、シミュレーションする。
・小モジュールで テストベンチの考え方&記述方法を習得する。
・新しいプロジェクトを作成し、moji_deco を持ち込んで、作業するとトラブルが少ないです。
・プレゼン資料の記述例は、入力が ascii コードではなく、バイナリなので注意して下さい。
② 全体回路のテストベンチを作成し、全体シミュレーションを実行する
・既存のプロジェクト上で、テストベンチだけを作成すれば OK です。
・図 2-69、70 のチャタリング周波数の変更と deco 出力周期の変更は忘れずに行ってください。
[以降の追加仕様は、スキップしてもよいです]
3) (可能であれば、) サイクルを変更する: 64 秒→32 秒 [5 ビット化]
・peripheral_moji を読んで、元々64 秒[6ビット]サイクルで動作しているものを 32 秒に変更する。
2.課題3の追加仕様
1) この課題では、シミュレーションは行っていないので、トップレベル回路の VHDLはまだありませんので、
トップレベル回路を VHDL記述し、コンパイル後、実機確認して下さい。
→ 全モジュールを VHDLで記述したことになります(=回路図がなくても設計できる)。
[以降の追加仕様は、スキップしてもよいです]
2) 文字列を4つの LED に表示する。
・課題2の『自分の名前』と同様に、表示する文字列を、4 つの LED に流れるように表示する。
・peripheral_moji を理解して、トップレベル回路を検討して再記述する必要があります。
149
2-6 課題4: 『1 分時計』
(※) QuartusⅡで、新しいプロジェクトを作成して作業して下さい。 例: z:¥ quartus2_work¥one_min_clock 1 分を正確に計る時計『1分時計』を設計します。 以下のような機能を持ったモジュールを VHDL で記述して、 シンボル化を行い、図 2-107 のように配線して、top 回路を設計します。
(入力) クロック(clock) : 50MHz、 リセット(reset) : ボタンスイッチ(Button2) (出力) 7 セグメント LED×4 (LED0,LED1,LED2,LED3) ① 分周回路 ② カウンタ(リセット機能付き): 10 進カウンタと 6 進カウンタ ③ チャタリング防止回路 ④ デコーダ
2-6-1 『1 分時計』の仕様と構成
[機能] - 実機(DE0)にダウンロードするとカウントをスタート - 7 セグメント LED を 4 つ使う。 セグメントの左から 10 秒,1 秒,0.1 秒,0.01 秒の桁を表示させる。 - 60.00 秒までカウントすると同時に 00.00 秒表示に戻る。 - reset を押すと、初期状態(00.00)になる。
[必要なパーツ] ① 分周回路: カウンタを使ってデューティ 50%の波形を作る回路(dividing.vhd) → 新規に作成(後述)
- INPUT: clk(50MHzのクロック - OUTPUT: clk_div(100Hzのクロック)
② チャタリング防止回路(chatter.vhd) → 課題 3 の設計を使用する(手法1,2のどちらかを使用)
- INPUT: clk(50MHzのクロック), SW_in : reset 入力のチャタリング防止を行う - OUTPUT: SW_out
③ 10 進カウンタ(カウントアップ機能付き)(count10_co.vhd) → 既存のものを修正して利用する
- INPUT:count10_co_in(クロックの入力。 1 段目は、分周回路の出力:100Hzのクロックを入力する。 2 段目からは、count_up からの出力を入力する。 reset。
- OUTPUT:count_up(シグナルの counter が 9 までカウントしたらカウントアップ信号 count_up を出力)、 count10_co_out(counter の値を出力する.デコーダに合わせるために 6bit 出力にする)
④ 6 進カウンタ(count6_co.vhd) → ③と同様のもので、6 進にしたものを設計する
- INPUT:count6_co_in、 reset - OUTPUT:count_up, count6_co_out
⑤ ASCII 表示変換回路(conversion_ascii.vhd) → 課題 2 で設計したものを利用する(簡略化できる)
- INPUT:order(10 進カウンタ、6 進カウンタからの 6bit の入力) - OUTPUT:seg(7 セグメントデコーダへの 8bit 出力)
⑥ 7 セグメントデコーダ(moji_deco.vhd) → 課題 2 で設計したものを利用する(簡略化できる)
- INPUT:led(ASCII 表示変換回路からの 8bit の入力) - OUTPUT:seg(7 セグメント LED への 8bit 出力)
150
151
2-6-2 カウンタ回路の設計
[100Hzのクロックの生成] 設計する『1分時計』は、1/100 秒から表示するので、100Hzのクロックをカウントすることになりますので、 DE0 の 50MHzのクロックから分周して、100Hzのクロックを作り出します。 なお、今回生成するクロックの dutyは 50%とします。 すなわち、図 2-108のように、周期が 10msで 5m 秒間 ’0’、5m 秒間 ‘1’のクロックです。 具体的には、クロックのレジスタを 5m 秒毎に反転させて生成しますが、50MHZ の入力クロックをどの様に数える
かを考えて、設計します。
10m sec
5m sec5m sec
図 2-108 duty が 50%の 100Hz のクロック
[8 進カウンタの VHDL 記述例] 図 2-109 が、8 進カウンタの記述例です。 注意点は、n進カウンタを作る時には、カウンタの上限値を n にする のではなく、“n-1”にすることです。 下記の 8 進カウンタの場合は、”8-1”で 7(=111)になります。
(111)2=(7)10
1 65430 2 7 07 21
7までカウントした後に0
図 2-109 8 進カウンタの記述例
152
[100Hzクロックの分周回路の設計] 分周するために必要なカウント値の 10 進と 2 進表記は、以下の通りです。
(249)10 = (11111001)2 (2499)10 = (100111000011)2 (24999)10 = (110000110100111)2 (249999)10 = (111101000010001111)2
(2499999)10 = (1001100010010110011111)2
100Hzクロックを生成する分周回路の VHDL の記述例は、図 2-110 の通りです。 入力信号:clk が 50Mhz で、出力信号: clk_divが、100Hzのクロック(duty:50%)です。 必要な個所に適切な記述をして、完成させて下さい。
counterが指定の値になるまでカウント.指定の値になったらクロックレジスタを反転させる
クロックレジスタの反転
p.11 Q2の値-1※次のページのシミュレーションでは(11111001)2を入れて下さい
図 2-110 分周回路の記述例(dividing.vhd)
どの値にするか?
153
2-6-3 シミュレーション
各モジュールの VHDL記述が完成したら、モジュール毎にシミュレーションを行い、設計した各回路が正常に 動作することを確認します。 なお、全体回路(図 2-107)のシミュレーションは、時間が掛かるので、今回は実行しません。 実行モジュールを 生成して、DE0 にダウンロードして、直接機能を確認します。
[100Hz分周回路(duty:50%)のシミュレーション: dividing.vhd ] (1) VHDL ファイルのコンパイル
テキスト p 32 を参考にして、作成したファイルをコンパイルして下さい。 (2) Modelsim の起動
テキスト p 43 を参考にしてModelsim を起動して下さい。 (3) シミュレーションの準備 → 新しく ModelSim のプロジェクトを作成します。
今回作成する ModelSim のプロジェクトは以下のように設定して下さい。
ModelSim のプロジェクト内に dividing.vhd、chatter.vhd、count10_co.vhd、count6_co.vhd、moji_deco.vhd、 conversion_ascii.vhd を作成し(コピーして持ち込む)、コンパイルして下さい。 コンパイルが成功したら、Library ウィンドウ work を展開すると出てくる「dividing」を右クリックし、出てきたメニューから simulate を選択します。
Object ウィンドウに信号が出てきます(図 2-114)。 (4) 波形の入力
この分周回路は、50MHzから 100Hzを生成するものでした。 これをそのままシミュレーションして、100Hzの クロックの1周期を見ようとすると、シミュレーション時間がかかってしまいますので、ここでは50MHzから100kHzを生成ものを少し書き直しをして、シミュレーションします。 図 2-110 の※部分のように、(11111001)2を入れて、 期待通りの分周ができるかどうかを確かめて、機能確認をします。 インプットが c lk、アウトプットが c lk_div なので、c lk に入力波形を設定します。 Object ウィンドウの右クリックメニュー「Modify」→「Apply Wave」から入力波形を作ります(図 2-111、112)。
図 2-111 信号 clk の入力波形の設定
Project Name : one_min_clock Project Location : Z:/quartus2_work/ one_min_clock /testbench Default Library Name : work
154
図 2-112 信号 clk の入力波形の設定
これで入力信号の波形がWave ウインドウに表示されます(図 2-113)。
図 2-113 入力信号の波形
155
Object ウィンドウからWaveウィンドウにシミュレーションする信号を移動させます。 インプットの c lk は、先程の作業で移動させたので、次にアウトプットの c lk_div を移動させます。 Object ウィンドウで移動させる信号を選択し、Wave ウィンドウにドラッグして移動させます。 これで c lk と c lk_divの 2 つがWave ウィンドウに表示されます(図 2-114)。
図 2-114 出力信号 clk_divをWave ウィンドウにドラッグ
(6) シミュレーションの実行 シミュレーションは、「Simulate」-「Run」-「Run-All」を選択すると実行を開始します(図 2-115)。
②Run
①Simulateを選択
③Run -All
図 2-115 シミュレーションの実行
156
シミュレーションが正常に終了すると結果が表示されます(図 2-116、117)。
図 2-116 シミュレーションの実行後の画面
図 2-117 dividing.vhd のシミュレーション結果
157
[10 進カウンタ:count10_co.vhd のシミュレーション] dividing.vhd のシミュレーションのときと同様にして、Modelsim を起動して下さい。 インプットが count10_co_in、reset、アウトプットが count10_co_out、count_up なので、 count10_co_in、reset に入力波形を設定します。 Object ウィンドウの右クリックメニュー「Modify」→「Apply Wave」から入力波形を作ります。 まず信号 count10_co_in の設定を行います(図 2-118、119)。
図 2-118 信号 count10_co_in の入力波形の設定
図 2-119 信号 count10_co_in の入力波形の設定
158
次に、信号 reset の設定を行います(図 2-120、121)。
図 2-120 信号 reset の入力波形の設定
図 2-121 信号 reset の入力波形の設定
dividing.vhd をシミュレーションしたとき(p50)と同様に、出力信号(count10_co_out、count_up)を Wave ウィンドウにドラッグして、「Simulate」-「Run」-「Run-All」を選択すると実行を開始します。 シミュレーションが正常に終了すると結果が表示されます(図 2-122)。
図 2-122 シミュレーションの実行後の画面
159
波形表示では、バス信号の表示基数を変更する事ができます。 バス信号A、B、Sの結果が 2進数で表示されて
いるので、これを 10 進数で表示します。 信号 count10_co_out をマウスの左ボタンで選択して、右ボタンをクリッ
クするとプルダウンメニューが表示します。「Radix」欄の候補から「Unsigned」を選択します(図 2-123,124)。
図 2-123 信号 count10_co_out の 16 進数表示の設定
図 2-124 count10_co.vhdのシミュレーション結果(基数変更後)
160
[6 進カウンタ:count6_co.vhd のシミュレーション] 基本的には、10 進カウンタ(count10_co.vhd)と同じ手順で進めます. インプットが count6_co_in、reset、アウトプットが count6_co_out、count_up なので、count6_co_in、reset に 入力波形を設定します。 まず、信号 count6_co_in の設定を行います(図 2-125、126)。
図 2-125 信号 count6_co_in の入力波形の設定
図 2-126 信号 count6_co_in の入力波形の設定
次に、信号 reset の設定を行います(図 2-127、128)。
図 2-127 信号 reset の入力波形の設定
161
図 2-128 信号 reset の入力波形の設定
dividing.vhdをシミュレーションしたとき(p50)と同様に、出力信号(count6_co_out、count_up)をWaveウィンドウ
にドラッグして、「Simulate」-「Run」-「Run-All」を選択すると実行を開始します。 シミュレーションが正常に終了すると結果が表示されます(図 2-129)。
図 2-129 count6_co.vhd のシミュレーション結果
162
[チャタリング防止回路:chatter.vhd のシミュレーション] 基本的には、10 進カウンタ(count10_co.vhd)と同じ手順で進めます. インプットが clk 、SW_in、アウトプットが SW_out なので、clk 、SW_in に入力波形を設定します。 まず、信号 clk の設定を行います(図 2-130、131)。
図 2-130 信号 clk の入力波形の設定
図 2-131 信号 clk の入力波形の設定
163
次に、信号SW_in の設定を行います。 今回の入力信号にはチャタリングのような波形を作る必要があります。 入力はボタンを押していない時に'1'になるので、常に 1 になるように、入力信号を設定後にチャタリングのような 波形を設定します(図 2-132、133)。
図 2-132 信号SW_in の入力波形の設定
図 2-133 信号SW_in の入力波形の設定
164
SW_in の信号にチャタリングとなる波形を設定します。 SW_in の信号を選択した状態で、「Edit Mode」→「Insert Pulse」を選択します(図 2-134)。
図 2-134 信号SW_in の入力波形の設定
「Insert Pulse」を選択すると以下のようなウィンドウが出るので、Duration:5、Time:20、Time Unit:μs を 入力して「OK」を選択します(図 2-135)。
図 2-135 信号SW_in でのパルス波形の設定
図 2-134、図 2-135 と同様にして、以下のようにパルス波形を設定していきます。
図 2-136 信号SW_in でのパルス波形の設定
165
図 2-137 信号SW_in でのパルス波形の設定
図 2-138 信号SW_in でのパルス波形の設定
図 2-139 信号SW_in でのパルス波形の設定
166
dividing.vhd をシミュレーションしたとき(p50)と同様に、出力信号(SW_out)をWave ウィンドウにドラッグして、
「Simulate」-「Run」-「Run-All」を選択すると実行を開始します。 シミュレーションが正常に終了すると結果が表示されます。(図 2-140)
図 2-140 chatter.vhd のシミュレーション結果 2-6-4 動作確認
全てのシミュレーションが終わったら図 2-107 のように TOP の回路を組み,『1 分時計』の回路を完成させます。 これまで通り、ピン割り当てを行い、コンパルして、実行モジュールを作成したら、DE0 にダウンロードして、 動作確認を行います。 正しく動作していることを、時計と比較して、確かめて下さい。
167
以上で、課題4:『1分時計』の設計と評価ボードを使った実機動作の確認は終了し、本講座の目標達成です。
ここで使った設計手法は、以下の通りで、より実践に近い手法を使っています。 特に、全体回路のシミュレーションで
は、シミュレーションに適した回路構成に変更してることがポイントです(課題1、2 でも同様です)。
◇ (QuartusⅡ上で、) 各下位階層モジュールは、VHDL で設計 [⇐ コンパイルエラー無し]
→ (QuartusⅡ上で、) トップレベル回路は、回路図エディタで作成 [⇐ コンパイルエラー無し]
→ (ModelSim へ移り、) シミュレーションの実行 [⇐ シミュレーションエラー無し]
・モジュール毎にシミュレーションして、機能を確認
・最後に、トップレベル回路で全体シミュレーションを実行
→ (QuartusⅡに戻り、) 実行モジュールを作成し、実機での動作確認 [⇐ 実動作エラー無し]
なお、4 日目の達成目標が早く終了した受講者は、以下の追加仕様を実習して、より実践的な「論理回路設計手法」を
実習して、理解を深めて下さい。
[追加仕様3]
1) ModelSim 上で、全てのモジュールを VHDLで設計する。
・これまでの実習で、必要なモジュールの VHDL記述は存在します(必要であれば、修正して下さ)。
2) 下位モジュール毎に、テストベンチを使って(入力に、波形エディタを使わない)、シミュレーションする。
3) トップレベル回路をシミュレーション用回路に変更して、全体シミュレーションする。
・チャタリング防止回路は、オフする (→ VHDL記述でコメントに、全体の整合を取る)
・分周周波数を 10μs に変更して、60ms 時計としてシミュレーションする。
[以下は、時間に合わせ実施して下さい(実習の再確認になります)]
4) ModelSim 上で設計した VHDLのソースを、QuartusⅡに持ち込んで、トップレベル回路をトップに指定して、
コンパイルし、エラーが無いことを確認して、ピン割り当てを行い、実行モジュールを作成してください。
後は、実機にダウンロードして、機能確認を行います。
168
【参考資料1】 エラーメッセージが出た場合 エラーメッセージが出たらまずは、英文を読んで考えてください.若い行のエラーから順に対応していきます.
①Errorタブを選択
②エラーメッセージが出てくる
③行番号が出てきます.エラーメッセージは上から考えて行きます.後は英文を読みましょう.
図 3-1 エラーメッセージ
169
【参考資料2】 ピン配置について コンパイル時にエラーメッセージが出なかったが、DE0 の LED 表示がおかしいというようなとき、 ピン配置がずれているということが考えられます. まず、TOP の各 input,output の node-name がテキストのものと同じであることを確認します。 同じであったならば、下の図 3-2 の手順で Location の貼り付けを行って下さい.
①Node Nameをクリック
②Node Nameの並び順を合わせる
QuartusⅡ 配布したEXCELファイル
③Locationを貼り付ける
図 3-2 Node Name の位置でクリックしてノード名を昇順にソートしてから location 情報を貼り付ける