2016 年度前期集中講義 論理回路設計 - 実習 :VHDL によるデジタル回路設計 - 講座の目的実習を通して 専門分野の問題発見 解決の能力を修得する - LSI 設計の基礎知識を得る - 言語 :VHDLによる設計手法を実習する - EDAツールの操作を経験する - FPGAを搭載した評価ボードで動作を確認する 東京理科大学 基礎工学部電子応用工学科 ( 非常勤講師 ) 藤岡督也 1 /100
目次 1. 実習環境の説明 2. 課題 1: 4 ビット加算器 - 参考資料 EDA ツールの付加情報 - VHDL の概要 - テストベンチの記述 3. 課題 2: 自分の名前を表示しよう 4. 課題 3: チャタリング防止回路 5. 課題 4: 1 分時計 参考資料 2
集中講義の日程 1 日目 2 日目 3 日目 4 日目 6 月 18 日 ( 土 ) 2~5 時限 6 月 25 日 ( 土 ) 2~5 時限 7 月 02 日 ( 土 ) 2~5 時限 7 月 09 日 ( 土 ) 3~5 時限 課題 1 加算器 - Quartus Ⅱ の操作と設計手順の習得 - 回路図入力 - シミュレーション - ピンアサイン - 実機での動作確認 課題 1 加算器 - VHDL による設計 実機での動作確認 - VHDL 文法の習得 - 回路図設計との比較 - テストベンチ & 追加仕様 課題 2 名前の表示 課題 3 チャタリンク 防止回路 課題 4 1 分時計 - VHDL 文法の習得 - 設計の実践 & 動作確認 - 言語設計の理解 ( 実習で使用する環境 ) [EDA ツール ] Quartus Ⅱ(Altera 社 ) ModelSim (Mentor 社 : VHDL シミュレータ ) [ ボード ] DE0 (Terasic Technologies 社 ) : (FPGA) Cyclone Ⅲ(Altera 社 ) 搭載 3
実習の内容 各課題を設計して 実機を使って動作を確認する 1. 課題を理解し 設計仕様にまとめる 入力 出力 機能 性能を決める 設計手法を選択する : 回路図入力 / 言語設計 / 両者の混在等 検証内容 ( シミュレーション内容等 ) を決める 2. 選択した設計手法で 回路設計を行う QuartusⅡ: 回路図入力 /VHDL 設計 / 両者の混在 ModelSim : VHDL 設計 3. シミュレーションで 機能確認を行う VHDL シミュレータ :ModelSim を使う 波形入力 or テストベンチを使って実行する 4. 評価ボード :DE0 を使って 実機確認を行う Quartus Ⅱ で実行モジュールを作成する シミュレーション回路と実機評価回路は 異なる場合がある 4
1. 実習環境の説明 5
実習の設計フロー 仕様に基づき 回路を設計する デザインエントリ コンパイル 記述をチャックして 論理合成する 端子割り当て コンパイル - QuartusⅡ - QuartusⅡ - ModelSim デザインエントリ コンパイル シミュレーション FPGA の接続データ ( 実行モジュール ) を作成する 仕様に基づき 回路を設計する 回路の動作を確認する ダウンロード 実機評価 - DE0 実行モジュールを PC から FPGA に書き込む FPGA 上で動作確認をする 6
EDA ツール 設計エントリー : QuartusⅡ - 回路図入力 VHDL 入力 論理合成 (Cyclone 用 ) - 実行モジュールの作成 評価ボード (DE0) へダウンロード 7
EDA ツール VHDL シミュレータ : ModelSim - VHDL 入力 機能 / 論理シミュレーション - 設計確認後 論理合成ツール (Design Compiler 等 ) へ 8
USB 端子 評価ボード :DE0 の外観 電源スイッチ FPGA (Altera) 7seg LED スライト スイッチ ホ タン スイッチ 9
1. 搭載 FPGA: (Family) Cyclone Ⅲ (name) EP3C16F484C6 [Package] 評価ボード :DE0 の概要 FBGA (Fine pitch Ball Grid Array) [Pin count] 484 [speed grade] 6 2. 入力機能 1) ボタンスイッチ : 3 個 (Button0~2) a 接点スイッチ [ b 接点スイッチとの違い ] 2) スライドスイッチ :10 個 (SW0~SW9) 上方にスライド (logic 1 ) 下方にスライド (logic 0 ) 3. 出力機能 - 7seg LED: 4 個 (HEX0~3) アノードコモン型 [ カソードコモン型との違い ] (- 液晶パネルを搭載することも可能 ) 4. 実行モジュールのダウンロード - USB ケーブルを接続して Quartus Ⅱ から実行する [ 詳細は 授業 HP 上のマニュアル ( 英文 ) 参照 ] 10
評価ボード :DE0 のブロック図 USB 端子 スライドスイッチ FPGA 7seg LED ボタンスイッチ 11
DE0 のボタンスイッチの動作 a 接点スイッチ A RST B push push 通常の入力信号 : BS 反転入力信号 : not BS a 接点 : スイッチを押すと接点が繋がり電流が流れる b 接点 : スイッチを押すと接点が離れて電流が止まる 12
DE0 のスライドスイッチの動作 = (PIN 番号 ) D2 E4 E3 H7 J7 G5 G4 H6 H5 J6 Logic 1 (SW 番号 ) SW9 SW8 SW7 SW6 SW5 SW4 SW3 SW2 SW1 SW0 Logic 0 上方にスライド 下方にスライド 通常の入力信号 : SS 反転入力信号 : not SS 13
DE0 の 7seg LED の動作 - アノードコモン型 - 7seg LEDの動作タイプ HEX0 [ 参考 ] LED0[7] LED0[6] LED0[5] LED0[4] LED0[3] LED0[2] LED0[1] LED0[0] E11 F11 H12 H13 G12 F12 F13 D13 a b c d e f g dp e f d g a c b dp ( ピン名 ) (PIN 番号 ) 端子割り当て表 ピンと PAD の整合 14
端子割り当て - FPGA チップはパッケージングされている PAD は PIN に接続されている - パッケージはボード上に実装されている ボード上部品と接続されている (PAD=)PIN から先の接続は変更できない - 入力信号は 決まった PIN から入力する - 出力信号は 決まった PIN へ出力する FPGA チップ FPGA パッケージ 設計回路 FPGA FPGA 搭載ボード 15
ピン割り当て表 加算器の例 [ テキストの表 1-2 ピン割り当て表 (74 頁 ) 参照 ] 設計端子名 入出力 FPGAピン番号 備考 A Input PIN_H2 BUTTON0 B Input PIN_F1 BUTTON2 clk Input PIN_G21 クロック入力 EQUAL Input PIN_J6 SW0 reset Input PIN_G3 BUTTON1 LED0[7] Output PIN_E11 HEX0_a LED0[6] Output PIN_F11 HEX0_b LED0[5] Output PIN_H12 HEX0_c LED0[4] Output PIN_H13 HEX0_d LED0[3] Output PIN_G12 HEX0_e LED0[2] Output PIN_F12 HEX0_f LED0[1] Output PIN_F13 HEX0_g LED0[0] Output PIN_D13 HEX0_dp LED1[7] Output PIN_A13 HEX1_a LED1[6] Output PIN_B13 HEX2_b 16
2. 課題 1: 4 ビット加算器 - 第 1 日目 & 第 2 日目 - 17
4 ビット加算器 の設計回路 [ 課題 ] と全体回路 - 全体回路は 設計回路と周辺回路から構成される - 周辺回路は 回路図シンボルと peripheral_de0.vhd で準備されている - 設計回路と周辺回路を使って 全体回路を設計する -= 被加数 加数 キー入力検出回路 キー入力検出回路 キー入力検出回路 キー入力保持回路 キー入力保持回路 キー入力保持回路 加算器 設計回路 5 4 4 信号選択 & LED 表示制御 8 8 8 8 LED3 LED2 LED1 LED0 - クリア 周辺回路 全体回路 FPGA へダウンロード - クロック クロック分周回路 図 1-56 周辺回路ブロック図 18
4 ビット加算器 の開発仕様 評価ボード :DE0 を使って 4 ビット加算器を設計する 1. 入力データ : ホ タンスイッチを使って 押下回数を入力数とする Button0 : 被加数の入力 HEX0 へ hex 表示 0~F をトグルする Button2 : 加数の入力 HEX3 へ hex 表示 0~F をトグルする Button1 : リセッの入力 button0 と button2 を同時にリセットする 2. 出力データ : 加算結果を 7segLED に表示する 加算結果は hex 表とする ( 00~1E; 4 ヒ ット加算 5 ヒ ット ) HEX0 : 加算結果の下位桁を hex 表示する HEX1 : 加算結果の上位桁を hex 表示する HEX2 : = を表示する HEX3 : = を表示する 3. モード切替 : スライト スイッチを使って 入力 / 出力表示を切り替える SW0 : 0( 入力モード ): 被加数と加数を表示する 1( 出力モード ): 加算結果を表示する 19
実習の進め方 第 1 日目 課題を回路図で設計して 実機 (DE0) で評価する - QuartusⅡ 上で 課題を回路図で入力して設計する ( テキスト : 5 ~ 42 頁 ) - ModelSim 上で シミュレーションして 設計内容を確認する ( テキスト : 43 ~ 65 頁 ) - Quartus Ⅱ 上で 実機用の回路図に編集して 実行モジュールを作成する ( テキスト : 66 ~ 72 頁 ) - 実行モジュール (*.sof) を DE0 にダウンロードして 動作確認を行う ( テキスト : 73 ~ 76 頁 ) 第 2 日目 課題を VHDL で再設計して 実機 (DE0) で評価する - QuartusⅡ 上で 課題を VHDL で再設計する ( テキスト : 77 ~ 97 頁 ) - ModelSim 上で シミュレーションして 設計内容を確認する ( テキスト : 98 ~ 99 頁 ) - Quartus Ⅱ 上で 実行モシ ュールを作成し 動作確認する ( テキスト : 102~103 頁 ) 可能な限り トップ回路も VHDL で設計する : 記述例は テキスト : 100 ~ 101 頁参照 - 早く終わった学生は 次に進まず 追加仕様に挑戦する ( テキスト : 104 頁 ) ( 追加仕様例 ) 入出力の 16 進表示を 10 進表示に変更する peripheral_de0.vhd を理解し 何処を変更するか? 16 進表示 10 進表示に変更するアルゴリズムは? ビット拡張を行う 加数 / 被加数を 99 10 (7 ビット ) まで 結果を 198 10 (8 ビット ) まで 20
4 ビット加算器 の設計内容 - 設計で用いる設計記述の組み合わせ - シミュレーションによる検証 実機による検証 コンパイル 実行モジュール ダウンロード 動作確認 QuartusⅡ 波形エディタテストベンチ + [1 日目 ] [2 日目 ] 回路図記述 ( 変換 ) (VHDL 記述 ) or VHDL 記述 VHDL 記述 加算器のトップ回路 4 ビット演算部 回路図記述 ( 変換 ) (VHDL 記述 ) VHDL 記述 ( 周辺回路 ) Peripheral_DE0 シミュレーションパタンの作成 (VHDL 記述 ) (VHDL 記述 ) [ 図 2-33~35] VHDL 記述 (VHDL 記述 ) Conversion_ascii (VHDL 記述 ) (VHDL 記述 ) (VHDL 記述 ) 21
4 ビット加算器 の全体回路図 Sim 用 -VHDL 記述は図 2-33~ 図 2-35 DE0 用 - トップの記述は VHDL 記述でも OK 22
追加仕様後の開発仕様 Ⅰ. 開発仕様はそのままで 全モジュールを VHDL 記述にする Ⅱ.LED の 16 進表示を 10 進表示に変更する 1. 入力データ : HEX0,1 ( 被加数 ) HEX2,3( 加数 ) 2. 出力データ : HEX0,1( 加算結果 ) HEX2,3( = ) Ⅲ. ビット拡張を行い 2 桁 (0~99) 加算器にする 1. 入力データ : ホ タンスイッチを使って 押下回数を入力数とする Button0 : 被加数の入力 HEX0~1 へ 10 進表示 0~99 をトグルする Button2 : 加数の入力 HEX2~3 へ 10 進表示 0~99 をトグルする Button1 : リセッの入力 button0 と button2 を同時にリセットする 2. 出力データ : 加算結果を 7segLED に 10 進 ( 0~198) 表示する HEX0~2 : 加算結果を10 進表示する HEX3 : = を表示する 3. モード切替 : スライト スイッチを使って 入力 / 出力表示を切り替える SW0 : 0( 入力モード ): 被加数と加数を表示する 1( 出力モード ): 加算結果を表示する 23
全体回路のモジュール構成 adder4bit_top: トップモジュール inst: peripheral_de0: 周辺回路のモジュール inst2: adder_4bit: 4bit 加算器 inst: full_adder inst1:full_adder inst2:full_adder inst3:half_adder inst3: conversion_ascii: LED0 を ascii に変換 inst4: conversion_ascii: LED1 を ascii に変換 inst5: conversion_ascii: LED2 を ascii に変換 inst6: conversion_ascii: LED3 を ascii に変換 24
peripheral_de0 のモジュール構成 peripheral_de0 : 周辺回路 ( 入出力部分等 ) のモジュール peripheral1: peripheral ; 入力信号周りの処理 peri1: msec ; chattering 信号の生成 (2M 2=4M 周期 = 約 80ms) peri2: chatter ; 入力 reset 信号のチャタリング防止 peri3: chatter ; 入力 A 信号のチャタリング防止 peri4: chatter ; 入力 B 信号のチャタリング防止 peri5: chatter ; 入力 equal 信号のチャタリング防止 count1: count : 入力 A 信号のカウント (4bit:0~F) count2: count : 入力 B 信号のカウント (4bit:0~F) selec1: selec : 表示信号を選択し LED 用信号の生成 decoder0: decoder : HEX0 の入力信号へのデコード decoder1: decoder : HEX1 の入力信号へのデコード decoder2: decoder : HEX2 の入力信号へのデコード decoder3: decoder : HEX3 の入力信号へのデコード 25
peripheral_de0 の回路図 - QurartusⅡ の RTL Viewer の Dump shot [ Tools Netlist Viewers RTL viewer ] 26
参考資料 EDA ツールの付加情報 27
QuartusⅡ のプロジェクト ディレクトリ file open 後のポップアップ画面 プロジェクト [ 4bit_vhdl ] をオープンした時のディレクトリ下のファイル一覧 ファイル名と更新日時が正しいかを常にチェックする ファイル名 ( 拡張子以外の部分 ) は 異なる名前にする 古い版を保存したい場合は *_old1.vhd のようにする 複雑になった場合は 新しいプロジェクトを作って 別に管理する 28
QuartusⅡ のプロジェクトメンバー 現在のプロジェクトメンバーの一覧 リストされているファイルを正しく管理する 同名のモジュール名は避ける 変更する場合は 次頁のように行う 29
QuartusⅡ のプロジェクトメンバーの変更 1. オープンしているファイルをメンバーに追加する : Project Add current file to Project 2. プロジェクトディレクトリ下のファイルを使って変更する Project Add/Remove files to Project 30
QuartusⅡ のプロジェクトへのファイルの持ち込み プロジェクトをオープンした状態で File New を選択すると New 画面がポップアップされるので VHDL File を選択する VHDL File 選択後 編集画面が表示されるので 持ち込みたい VHDL 記述を paste し Save As で保存する 31
ModelSim のプロジェクト ディレクトリ プロジェクト ディレクトリ下のファイル一覧 ( プロジェクトメンバーの候補 ) 32
ModelSim のプロジェクト メンバー プロジェクト メンバーの一覧 - トップモジュール以下の全モジュール ( セル ) がリストされている 33
ModelSim のプロジェクト メンバーの変更 Project 画面内で右クリック - Add to Project を使って 変更する 34
ModelSim のプロジェクトへのファイルの持ち込み File Source VHDL の操作で下記の編集ウィンドウが開くので vhdl 記述を paste して 持ち込み Save As で保存する 35
ModelSim: 入力信号の波形入力 4bit 加算器の入力波形の概要 ( テキスト pp.58~) CK ( クロックを指定 ) A 0 1 B 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 reset Equal 重要 0 1 変化や reset 信号により シミュレション結果に注意が必要 CLK: 周期 20us (01:duty50%) 10240ms A : 周期 320ms (01:duty50%) 10240ms 16 x 2 回 B : 周期 20ms (01:duty50%) 10240ms 16 x16 x2 回 Resetの指定例 : 0ms:1 1000ms:0 1200ms:1 Equalの指定例 : 0ms:0 5120ms:1 注意 ResetやEqualの入力方法は テキストpp.130を見て下さい 36
ModelSim: 入力信号の保存 File Save Format で下記画面をポップアップして プロジェクト ディレクト下のフェイル名 : wave.do に save する ( wave は 任意で OK) 37
ModelSim: 保存した入力信号のロード File Load Macro file をクリックすると 右記画面がポップアップするので プロジェクト ディレクト下に Save したフェイル名 (wave.do) を選択して load する 38
VHDL の概要 39
VHDL の歴史 - VHDL: VHSIC Hardware Description Language の略称 - 1981 年米国国防総省 ( 国防高等研究計画局 :DARPA(Defense Advanced Research Projects Agency) の VHSIC 委員会が提唱 VHSIC: Very High Speed Integrated circuit IC の大規模 / 高機能化に伴った 明確に仕様を記述する仕様記述言語 - 1986 年 Version 7.2 リリース IEEE の標準化作業スタート VASG (VHDL Analysis & Standardization Group) 委員会 - 1987 年 LRM( 言語仕様書 ; Language Reference Manual ) 作成 IEEE Std 1076-1987 として承認 - 1993 年 IEEE 1164 を採用 : 9 値の std_logic - その後 IEEE 1076-1993 IEEE 1076-2000 IEEE 1076-2002 IEEE 1076-2008 ( 最新版 ) 40
ハードウェア記述言語 : HDL - Hardware Description Language; HDL - デジタル回路 特に集積回路を設計するためのコンピュータ言語 - ハードウェアの動作仕様を記述するための言語で 電子回路の経時的動作と空間的構造を表現し 構文 (syntax) や意味 (semantics) は ハードウェアの基本的属性である時間や並行性を記述 - 処理を検証するテストベンチ記述ができ シミュレーションが可能 - 論理合成が可能 - Verilog HDL と VHDL が 主要な言語 (IEEEで標準化を推進) RTL (Register Transfer Level) とは? レジスタ間の転送関係を表現したレベル 機能を 代入 if case 等で表現したもの クロックを意識した記述 論理合成 ゲートレベルとは? ゲート回路やフリップフロップ等の接続関係を表現したもの ( 素子と等電位点の列挙 ) ネットリストとも言う 41
VHDL の基本構造 1 論理合成可能 VHDL の文法 回路記述 テストベンチ シミュレーション可能 ライブラリ記述 論理合成不可 回路記述 : 論理合成に適した記述をする 回路の種類ごとに適した記述スタイルがある テストベンチ : 文法を満たしていれば どんな記述でもよい 記述のテクニックを駆使できる 42
VHDL の基本構造 2 library 複数のライブラリ use entity.1つ port architecture architecture process B process A 一つの architectureに複数のprocessを書ける architecture process C 一つの entity に複数の architecture を書ける 一つの entity に複数の architecture を書ける一つの architecture に複数の process を書ける 43
VHDL の基本構造 3 Library Entity port Architecture この部分の信号割当ては process 文の外なので SLS もイベントもない コンカレント ( 非同期, 即時代入, 即時信号割り当て ) 実行される - <= 非同期で即時, コンカレント信号代入, - 条件文 when-else, with-select(others 文で全条件記述 ) - 反復文 generate Process () がない場合は,process 文内の処理を永遠に継続 Process ( センシティビティー リスト信号 ;:SLS) - <= SLS のイベントに同期し同時に信号代入 - := SLS のイベントに同期しシーケンシャルに信号代入 (:= の左辺は,variable 文で定義した変数 ) - 条件文 - case 文, if 文, if-then-elsif 文 制御反復文 loop for loop while loop wait for wait on wait until 合成用の記述に使用するもの ( 回路の合成が可能な記述 ) シミュレーション テストベクタ記述に使用するもの ( 合成困難, 不能 ) 44
VHDL の基本構造 4 - 階層化記述 - Library Entity Architecture 動作記述構造記述 Library Entity port Architecture 動作記述構造記述 Library Entity port Architecture 動作記述構造記述 Configuration テストベンチ設計回路のトップ階層設計回路の下位階層 45
全体構造と記述例 パッケージ の指定 entity エンティティ名 is end エンティティ名 ; architecture アーキテクチャ名 of エンティティ名 bigin 入出力ポート宣言 signal 他の宣言 VHDL 本体 - 動作 機能の記述 is -- 半加算器の記述例 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; [ 図 2-2] 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; end アーキテクチャ名 ; 46
VHDL 記述 & コンパイル時の注意点 1. 規約どおりに記述する - 構文規則を覚えて キーワードとパラメータを正確に記述する 代入文の右辺と左辺でデータイプは同じでなければならない signal s1: std_logic_vector(2 downto 0); signal n1: integer range 0 to; s1 <= 0 s1 <= 000 Error (10517): VHDL type mismatch error at half_adder_bh.vhd(23): std_logic type does not match integer literal n1 <= s1 n1 <= CONV_INTEGER(s1); サブプログラムの戻り値も同じデータタイプでなければならない std_logic の論理値は 9 値である 0 1 X L H W Z U(uninitialize) -(don t care) - ) や ; の数を間違えない () は必ず対になっている ; は 必要な場所と必要ない場所を正確に把握する - 未定義の変数は使えない ( 必ず事前定義 ) 2. コンパル時のエラーは しっかり読む - 必ずしも 的確な記述間違いをメッセージしてくれる訳ではない 47
型の変換 の関数 関数名 std_logic_1164パッケージ内 To_stdlogicvector(A) To_bitvector(A) To_stdlogic(A) To_bit(A) std_logic_arith パッケージ内 CONV_std_logic_vector(A ビット幅) CONV_INTEGER(A) 機能内容 bit_vector から std_logic_vector への変換 std_logic_vector から bit_vector への変換 bit から std_logic への変換 std_logic から bit への変換 integer unsigned signed から std_logic_vector への変換 unsigned signed から integer への変換 std_logic_unsigned パッケージ内 CONV_INTEGER(A) std_logic_vector から integer への変換 48
半加算器の回路図と VHDL 記述 VHDL 記述 ( 図 2-8 参照 ) O 回路図入力 ( 図 2-1 参照 ) コンパイル後 ( 図 2-15 参照 [ 等価 ]) O -- 半加算器の記述例 [ 図 2-2] 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; 機能の動作記述 A B S CO 0 0 0 0 1 0 1 0 0 1 1 0 1 1 1 1 機能のゲート記述 architecture RTL of half_adder_bh is signal AB : std_logic_vector (1 downto 0); begin AB <= A & B; process(a,b) begin if(ab= 00 ) then S<='0'; CO<='0'; elsif(ab="01") then S<='1'; CO<='0'; elsif(ab="10") then S<='1'; CO<='0'; else S<='1'; CO<='1'; end if; end process; end RTL; 49
D-FF の VHDL の記述 -- D-FF1 library ieee; use ieee.std_logic_1164.all; entity D_FF1 is port( R,D,CLK : in std_logic; Q,QB : out std_logic); end D_FF1; ライフ ラリ記述 エンティティ記述 R CLK D Q QB 0 - - 0 1 1 無し 0 変化無し 変化無し 1 無し 1 変化無し 変化無し 1 0 0 1 1 1 1 0 architecture RTL of D_FF1 is signal NODE : std_logic; begin Q <= NODE; QB <= not NODE; process(r,clk) begin アーキテクチャ if (R = '0') then NODE <= '0'; elsif (CLK 'event and CLK = '1') then NODE <= D; end if; end process; end RTL; 50
階層化記述例 library IEEE; use IEEE.std_logic_1164.all; A B X Y L Z C コンポネントインスタンス entity X is port (A, B : in std_logic; C : out std_logic); end X; architecture RTL of X is component Y port( A : in std_logic; D : out std_logic); end component; component Z port( B, D : in std_logic; コンホ ーネント宣言 ( 定義 ) コンホ ーネント宣言 ( 定義 ) C : out std_logic); end component; signal L : std_logic; begin U0 : Y port map ( A => A, D => L ); U1 : Z port map ( D => L, B => B, C=> C ); end RTL; 51
全加算器の回路図と VHDL 記述 [ 図 2-16] [ 図 2-17] 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; ライブラリ記述 エンティティ記述 コンポーネント宣言 アーキテクチャ コンポーネント呼び出し ( コンホ ーネント インスタンス ) 52
case 文 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 bit; M : out bit); end; architecture DSELS 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 DSELS; A B C D SELS M 53
if then else/elsif 文 library IEEE; use IEEE.std_logic_1164.all; entity N_BEHAVIOR is port(sels: in bit_vector(0 to 1); A,B,C,D: in bit; M: out bit); end; architecture DSELS of N_BEHAVIOR is begin process(sels,a,b,c,d) begin if (SELS = 00 ) 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 DSELS; A B C D SELS M library IEEE; use IEEE.std_logic_1164.all; entity S_BEHAVIOR is port(sels: in bit_vector(0 to 1); A,B,C,D: in bit; M: out bit); end; architecture DSELS of S_BEHAVIOR is begin process(sels,a,b,c,d) begin if (SELS = "00") then M <= A; elsif (SELS = "01") then M <= B; elsif (SELS = "10") then M <= C; else M <= D; end if; end process; end DSELS; 54
when else 文 entity J_BEHAVIOR is port (A,B,SEL : in boolean; M : out boolean); end; architecture DSEL of J_BEHAVIOR is begin M <= A when SEL else B; end DSEL; A B SEL M entity K_BEHAVIOR is port (SELS : in bit_vector(0 to 1); A,B,C,D : in bit; M : out bit); end; architecture DSELS of K_BEHAVIOR is begin M <= A when (SELS="00") else B when (SELS="01") else A B C D M end DSELS; C when (SELS="10") else D ; SELS 55
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 bit; M : out bit); end; with select 文 この宣言のとき SELSは 9x9=81 値となり,, 左の記述ではエラー 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 bit; M : out bit); end; architecture DSELS of M_BEHAVIOR begin with SELS select M <= A when 00, end DSELS; B when 01, C when 10, D when 11 ; A B C D SELS architecture DSELS of M_BEHAVIOR begin with SELS select M M <= A when 00, end DSELS; B when 01, C when 10, D when 11 ; この記述を D when others; とすると OK 56
テストベンチの記述 57
シミュレーションとテストベンチ シミュレーション : 設計した回路が正しく動作するかを検証するために 実装前に コンピュータ上でシミュレータを実行すること - 論理シミュレーション : ( 遅延を無限小として ) 論理動作のみ検証 - 遅延シミュレーション : 回路の遅延情報を考慮して動作を検証 設計した回路記述 : VHDL ファイル (DUT; Device Under Test) シミュレータ : テストベンチ : 必要な信号を生成したり 検証を効率よく行うための結果表示などを記述した VHDL ファイル 論理合成しないので 効率良く記述することを優先 テストベンチ クロック リセット等の生成 入力パタンの生成 設計した回路 (DUT) [ 論理合成可能 ] 結果表示等 58
テストベンチの構造 パッケージ の指定 entity エンティティ名 is end エンティティ名 ; architecture アーキテクチャ名 is bigin - DUT の宣言 - 入出力の宣言 - DUT の呼び出し - 波形記述 end アーキテクチャ名 ; configuration コンフィク レーション名 is for アーキテクチャ名 end for; end コンフィク レーション名 ; ライブラリ記述 ポートリストの無いエンティティ記述 アーキテクチャ名 of エンティティ名テストモシ ュール (DUT) のコンホ ーネント宣言 DUT の入出力信号宣言整数の定義 ( クロック周期等 ) DUT の呼び出し宣言 ( インスタンス ) 入力信号の入力波形記述 ( 期待値照合も可能 ) コンフィク レーション名を定義 コンフィク レーション名 of エンティティ名 このコンフィク レーション名でシミュレーターの実行モジュールが作られる 59
テストベンチでの入力波形記述例 count4ld ( ロード機能付き 4 ビットバイナリカウンター ) の入力 J 波形の記述例 : constant STEP: time := 100 ns ; begin U0: COUNT4LD port map( CLK, RST, LD, D, Q ); -- 入力 ;CLK RST LD D process begin CLK <= 0 ; wait for STEP/2; CLK <= 1 ; wait for STEP/2; end process ; -- クロックの記述 -- STEP/2 毎に 01 を繰り返す -- 無限にループする process begin D <= 0000 ; -- 入力 Dに 0000 をセット wait for STEP; RST <= 1 ; -- 1クロック後 リセットをon wait for STEP; RST <= 0 ; -- 1クロック後 リセットをoff wait for STEP*20; -- 20クロック進める D <= 1001 ; LD <= 1 ; -- ロードをonして Dに9をロード wait for STEP; LD <= 0 ; -- ロードをoff wait for STEP*8; -- 8クロック進める D <= 0110 ; LD <= 1 ; -- ロードをonして Dに6をロード wait for STEP; LD <= 0 ; -- ロードをoff wait for STEP*12 ; -- 12クロック進める assert false severity failure; -- シミュレーションの強制終了 wait; end process; 60
10 進カウンタのテストベンチ記述例 1 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; DUT: CNT10 - アップ信号付 10 進カウンター entity CNT10 is port ( count_in, reset : in std_logic; count_up, dot : out std_logic; count_led : out std_logic_vector(4 downto 0) ); end CNT10; architecture RTL of CNT10 is signal count10 : std_logic_vector(4 downto 0); signal count_sig : std_logic; begin process(count_in,reset) begin if reset = '1' then count10 <= "00000"; count_sig <= '0'; elsif (count_in'event and count_in='1') then if (count10 = "01001") then count_sig <= '1'; count10 <= "00000"; else count_sig <= '0'; count10 <= count10 + '1'; end if; end if; end process; count_led <= count10; count_up <= count_sig; dot <= '0'; end RTL; 61
10 進カウンタのテストベンチ記述例 2 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity CNT10_tb is ホ ートリスト無しのエンティティ記述 end CNT10_tb; DUTのコンホ ーネント宣言 architecture SIM of CNT10_tb is component CNT10 port ( count_in, reset : in std_logic; count_up, dot : out std_logic; count_led : out std_logic_vector(4 downto 0) ); end component; signal count_in, reset : std_logic :='0' ; signal count_up, dot : std_logic; signal count_led : std_logic_vector(4 downto 0); constant STEP: time := 10 ms; 信号名 & クロック周期の定義 begin DUT: CNT10 port map (count_in, reset, count_up, dot, count_led); インスタンス名 :DUT でテストモシ ュールをインスタンス 信号名とホ ート名の接続 process begin 入力波形の記述 count_in <= '0'; wait for STEP/2 ; count_in <= '1'; wait for STEP/2 ; end process; process begin wait for STEP; reset <= '1'; wait for STEP; reset <= '0'; wait for STEP*20; wait for STEP; reset <= '1'; wait for STEP; reset <= '0'; wait for STEP*30; assert false severity failure; wait; end process; end SIM; configuration cfg_cnt10_tb of CNT10_tb is for SIM end for; end cfg_cnt10_tb; Duty:50% のクロック ( 周期 10ms) を count_in に入力 2 nd 周期に reset 1 3 rd 周期に reset 0 20 周期進める 23 rd 周期に reset 1 24 th 周期に reset 0 30 周期進める 54 周期後に強制終了 コンフィク レーション記述 コンフィク レーション名: cfg_cnt10_tb エンティティ名: CNT10_tb アーキテクチャ名: SIM コンフィク レーション名で実行モジュールが作られる 62
CNT10_tb のシミュレーション結果 63
7seg_LED の動作記述 7segLED のデコードテーブル 入力信号出力信号 : 7 downto 0 case led is [abcdefg.] when "00000" => seg<="00000011"; -- 0 when "00001" => seg<="10011111"; -- 1 when "00010" => seg<="00100101"; -- 2 when "00011" => seg<="00001101"; -- 3 when "00100" => seg<="10011001"; -- 4 when "00101" => seg<="01001001"; -- 5 when "00110" => seg<="01000001"; -- 6 when "00111" => seg<="00011011"; -- 7 when "01000" => seg<="00000001"; -- 8 when "01001" => seg<="00001001"; -- 9 when "01010" => seg<="00010001"; -- A when "01011" => seg<="11000001"; -- b when "01100" => seg<="01100011"; -- C when "01101" => seg<="10000101"; -- d when "01110" => seg<="01100001"; -- E when "01111" => seg<="01110001"; -- F when "10101" => seg<="11101101"; -- = when others => seg<="11111111"; end case; LED0[7] LED0[6] LED0[5] LED0[4] LED0[3] LED0[2] LED0[1] LED0[0] E11 F11 H12 H13 G12 F12 F13 D13 a b c d e f g dp HEX0 e f [ アノードコモン ] a b g c d dp 64
LED7seg のテストベンチ記述例 1 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity LED7seg is port( dot : in std_logic; led : in std_logic_vector(4 downto 0); seg : out std_logic_vector(7 downto 0)); end LED7seg; architecture RTL of LED7seg is begin process(led) begin if dot='0' then case led is when "00000" => seg<="00000011"; -- 0 when "00001" => seg<="10011111"; -- 1 when "00010" => seg<="00100101"; -- 2 when "00011" => seg<="00001101"; -- 3 when "00100" => seg<="10011001"; -- 4 when "00101" => seg<="01001001"; -- 5 when "00110" => seg<="01000001"; -- 6 when "00111" => seg<="00011011"; -- 7 when "01000" => seg<="00000001"; -- 8 when "01001" => seg<="00001001"; -- 9 when others => seg<="11111111"; end case; DUT: LED7seg - 7seg LED のデコーダー - 入力は binary (ascii コードではない ) - ドット表示の有無で場合分け else case led is when "00000" => seg<="00000010"; -- 0 when "00001" => seg<="10011110"; -- 1 when "00010" => seg<="00100100"; -- 2 when "00011" => seg<="00001100"; -- 3 when "00100" => seg<="10011000"; -- 4 when "00101" => seg<="01001000"; -- 5 when "00110" => seg<="01000000"; -- 6 when "00111" => seg<="00011010"; -- 7 when "01000" => seg<="00000000"; -- 8 when "01001" => seg<="00001000"; -- 9 when others => seg<="11111110"; end case; end if; end process; end RTL; 65
LED7seg のテストベンチ記述例 2 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; ライブラリ記述 entity LED7seg_tb is end LED7seg_tb; architecture SIM of LED7seg_tb is component LED7seg port( dot : in std_logic; led : in std_logic_vector(4 downto 0); seg : out std_logic_vector(7 downto 0)); end component; signal dot : std_logic; signal led : std_logic_vector(4 downto 0) :="01111"; signal seg : std_logic_vector(7 downto 0); constant STEP: time := 1 us; begin DUT: LED7seg port map (dot, led, seg); end SIM; 波形記述 configuration cfg_led7seg_tb of LED7seg_tb is for SIM end for; end cfg_led7seg_tb; ポートリストの無いエンティティ記述 テストモシ ュール :LED7seg のコンホ ーネント宣言 LED7seg の入出力信号で定義する定数を定義する LED7seg を DUT としてインスタンスする 入力信号の波形を定義する (- 出力波形を記述し期待値照合を行う ) コンフィグレーションを定義する [ コンフィク レーション名 : cng_led7seg_tb ] 66
LED7seg のテストベンチ記述例 3 LED7seg の場合の入力波形の記述 constant STEP: time := 1 us; begin DUT: LED7seg port map (dot, led, seg); process begin if led < "01111" then led <= led + '1'; else led <= "00000"; end if; wait for STEP; end process; process begin for I in 0 to 2 loop dot <= '0'; wait for STEP*32; dot <= '1'; wait for STEP*32; end loop; assert false severity failure; wait; end process; 入力信号は dot( スカラー ) と led( ヘ クトル ) led(4 downto 0) の入力信号を生成する - 0000 ~ 01111 (0~15) を STEP(1us) 単位で生成する - 無限に繰り返す dot の入力信号を生成する - 01 を 32STEP 毎に繰り返す - ループを 3 回繰り返した後 assert 文で強制終了する 67
LED7seg_tb のシミュレーション結果 ( 全体表示 )
3. 課題 2: 自分の名前を表示させよう - 第 3 日目 - M _ T O [ 各文字と各セグメントの表示は テキスト pp111 112 を参照 ] 0123456789_I_AM_TOKUYA_FUJIOKA. 自分の名前 [ 注 ] 31 文字なので 5 ビット化 (32 文字 ) が可能 69
名前表示 の開発仕様 [ 実現機能 ] 4 個の 7segLED に 1 秒毎に左に流れるように 0~9 の数字を表示させた後に 自分の名前をアルファベットで表示する [ ボタン仕様 ] Button0(stop): 動作の停止 / 再開停止 : 押下時点での表示をそのまま継続する再開 : 表示状態から次の表示を再開する Button1(reset): 初期状態に戻る (0 表示から始める ) [LED 表示 ] HEX0 : 0123456789_I_am_( 各人の名前をアルファベットで表示 HEX1/2/3 : -1/-2/-3 秒遅れて HEX0を同じ内容を表示 [ モジュール構成 ] - peripheral_moji: 準備されている ボタン動作に従って 1Hz 周期のカウント信号 (0~63) が出力される : deco0~3[5_0] - conversion_ascii: カウント信号を ascii 文字コードに変換 - moji_deco: ascii 文字コードを 7segLED 信号に変換 70
名前表示 のモジュール構成 - 図 2-43 実習課題概要 - 図 2-48 図 2-49 clk stop reset ( 配付モシ ュール ) deco0 0 1 2 3 4 5 6 7 8 9 62 63 deco1 63 0 1 2 3 4 5 6 7 8 61 62 deco2 62 63 0 1 2 3 4 5 6 7 60 61 deco3 61 62 63 0 1 2 3 4 5 6 59 60 (ascii) (7seg) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 _ 11 I 12 _ 13 a 14 m 15 _ 0 1 2 3 4 5 6 7 8 9 _ I _ a m _ ( 1 秒毎にカウントアップする ) ( カウントアップした数をascii 文字と7segに変換する ) 71
実習の進め方 基本的には テキストに従って ( テキスト : 105 ~ 137 頁 ) 設計 実機確認を終了させる 各モジュールを VHDL で設計 トップ回路の回路図作成 (VHDL) シミュレーション 実機確認 課題 1 を全て VHDL で設計できた人は 実習の進め方を以下の順序に変更する こちらの方が好ましい ModelSim 上で設計 (VHDL) QuartusⅡ で実機確認 [ Modelsim ] 新規プロジェクトを作成する 1 conversion_ascii.vhd ( 各自で記述内容が異なる ) moji_deco.vhd 2 moji_deco_top.vhd トップ回路をVHDLで設計する 3 シミュレーションを実行し 正しく機能しているか確認する 可能な人は テストベンチを作成して simを実行して下さい ( 全員の記述内容が同じ ) を作設計する [QuartusⅡ] 新規プロジェクトを作成する 4 端子割り当て後 実機確認 ModelSim からソースを持ち込み ピンアサインをして コンパイルすると実行モジュール (*.sof) が作成される 72
[ 変更した手順の詳細 ] 課題 2 を早く終わった人は テキストの手順の人 以下の内容で再設計する 変更した手順の人 以下の内容の実現していない部分を完了させる 手順変更 & 追加課題 1) 全てを VHDL で記述する トップレベル回路を VHDL 記述し コンパイル後 実機確認する 2) 全体の表示サイクルを変更する 表示サイクル : ( 現在 )64 秒 32 秒 [5 ビット化 ] peripheral_moji.vhd の内部を変更する必要がある 3) テストベンチを作成して シミュレーションを実行する (ModelSim 環境下 ) 1 7segLED デコーダ単体のテストベンチ作成し テストベンチの記述方法を習得する 本資料の テストベンチ の項を参照 2 全体回路のテストベンチを作成し 全体シミュレーションを実行する 73
名前表示 のシミュレーション 1. シミュレーションのための工夫 1) チャタリングの周波数を変更 : 50,000 100 [ 図 2-69] シミュレーションではチャタリングは発生しない ( 削除しても良い ) 2)deco 出力の周期を変更 : 25,000,000 50 [ 図 2-70] シミュレーション時間を短縮するため 図中の 50 は 49 が良い 0~49: 50 実機用 deco 周期 : 20ns 25,000,000 2 =1s Sim 用 deco 周期 : 20ns 50 2=2000ns=2us 2. シミュレーション時の確認内容 1)deco のカウント数に従って 所望の文字列が発生されているか? 2) カウント数が ascii コードに正しく変換されているか? 3)7segLED の信号が正しく生成されている? 4)reset が正しく動作しているか? 5)stop 信号が正しく動作しているか? 1 回目押下 : カウント停止 ( 継続 ) 2 回目押下 : カウント再開 74
名前表示 のテストベンチ記述例 library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity deco_top_tb is end deco_top_tb; architecture SIM of deco_top_tb is component deco_top port(c,r,stop : in std_logic; LED0,LED1,LED2,LED3 : out std_logic_vector (7 downto 0)); end component; signal c, r, stop: std_logic := '1' ; signal LED0,LED1,LED2,LED3 : std_logic_vector (7 downto 0); constant STEP: time := 20 ns ; DUT: deco_top - シミュレーション用回路 begin U0: deco_top port map( c,r,stop,led0,led1,led2,led3 ); process begin c <= '1'; wait for STEP/2; c <= '0'; wait for STEP/2; end process ; process begin wait for STEP*4000 ; stop <= '0'; wait for STEP*100 ; stop <= '1'; wait for STEP*900 ; stop <= '0'; wait for STEP*100 ; stop <= '1'; wait for STEP*1900 ; r <= '0'; wait for STEP*200 ; r <= '1'; wait for STEP*4800 ; assert false severity failure; wait; end process; end SIM; clock 生成 configuration cfg_deco_top_tb of deco_top_tb is for SIM end for; end cfg_deco_top_tb; stop 生成 reset 生成 75
名前表示 のシミュレーション結果 (1) - 全体表示 - 76
名前表示 のシミュレーション結果 (2) - リセット付近 - (ascii コート は 表 2-4 参照 ) 77
名前表示 のシミュレーション結果 (3) - ストップ付近 - (ascii コート は 表 2-4 参照 [ 一部ミス有 ]) 78
4. 課題 3: チャタリング防止回路 - 第 3 日目 - 79
チャタリング防止回路 チャタリング防止回路 - 手法 1& 手法 2 図 2-105 チャタリング防止回路配線例 1 入力 1 入力 1 入力 複数入力 チャタリング発生 0 1 2 3 4 5 6 7 0 2 5 7 8 10 14 0 2 5 7 8 _ m 80
チャタリング現象とサンプリング周波数 [ 図 2-60] チャタリング発生 チャタリング発生 入力信号 高周波数 サンフ リンク 結果 ( 手法 1) 低周波数 サンフ リンク 結果 ( 手法 1) 中周波数 サンフ リンク 結果 ( 手法 1) サンフ リンク 結果 ( 手法 2) 1 1 0 1 1 1 1 81
実習の進め方 基本的には テキストに従って ( テキスト : 138 ~ 148 頁 ) 設計 実機確認を終了させる 各モジュールを VHDL で設計 トップ回路の回路図作成 (VHDL) シミュレーション 実機確認 HEX0 に Button1 の入力に合わせて 文字列 0123456789_I_am_ 自分の名前 を表示させる 時間が無い場合は 手法 1 or 2 のどちらかを設計する ( モジュール構成 ) - chatter: 手法 1 のチャタリング防止回路 prevention_of_chattering_kadai: 手法 2 のチャタリング防止回路 - count_ex: Button1 の押下回数をカウント - conversion_ascii: カウント数を ascii コードに変換 - moji_deco: ascii 文字コードを 7segLED 信号に変換 以上までが 3 日目に達成する目標です 時間が足りない場合は 提供されているソースを利用する 82
5. 課題 4: 1 分時計 - 第 4 日目 - 83
[ 実現機能 ] 1/100 秒まで表示する 1 分時計を作る 60 秒でトグルする ( 表示例 ) 12.34 [ 秒桁に ドットを表示する ] [ ボタン仕様 ] Button0(reset): 初期状態に戻る (00.00 秒表示に戻る ) [LED 表示 ] HEX0 : 1/100 秒 1 分時計 の開発仕様 HEX1 : 1/10 秒 HEX2 : 1 秒 ドット を表示させる HEX3 : 10 秒 [ モジュール構成 ] - dividing: 50MHz(20ns) 100Hz(10ms) への分周回路 - chatter: チャタリング防止回路 ( 既設計 手法 1 2 どちらでも可 ) - count10_co: カウントアップ機能付き 10 進カウンタ - count6_co : カウントアップ機能付き 6 進カウンタ - conversion_ascii: ascii コードへ変換 ( 既設計 簡略化してもよい ) - moji_deco: ascii コードを 7segLED 信号に変換 (( 既設計 簡略化してもよい ) ( 注意 ) ドット表示 をどこに組み込むかを考えること 84
1 分時計 のトップ回路図 [ 入力 ] - CLK: 50Mhz(20ns) - 非同期 reset 周期 :10ms count10_co 0.01 秒の桁 [ 出力 ] 1 2. 3 4 ドットを付ける conversion_ascii 1/100 単位 moji_deco 60 秒で繰り返す count10_co conversion_ascii moji_deco 0.1 秒の桁 count10_co conversion_ascii moji_deco? ドット表示 1 秒の桁 count6 conversion_ascii ドット表示付き moji_deco 10 秒の桁 85
カウンタ回路とその応用 CLK Q[0] Q[1] Q[2] Q +1 CLK 0 1 2 3 4 5 D CLK D CLK D CLK Q Q Q Q[2] Q[1] Q[0] 分周回路 CLK 周波数 : n 周波数 : n/2 周波数 : n/4 周波数 : n/8 カウント数 10 進 2 進 15 1 1 1 1 14 1 1 1 0 13 1 1 0 1 12 1 1 0 0 11 1 0 1 1 10 1 0 1 0 9 1 0 0 1 8 1 0 0 0 7 0 1 1 1 6 0 1 1 0 5 0 1 0 1 4 0 1 0 0 3 0 0 1 1 2 0 0 1 0 1 0 0 0 1 0 0 0 0 0 n / 8 n / 4 n / 2 n 86
実習の進め方 基本的には テキストに従って ( テキスト : 149 ~ 166 頁 ) 設計 実機確認を終了させる 各モジュールを VHDL で設計 トップ回路の回路図作成 (VHDL) シミュレーション 実機確認 実機動作を優先させる 本講座のクリア目標 VHDL で全て設計できるようになった人は 実習の進め方を以下の順序に変更する こちらの方が好ましい VHDL で ModelSim 上で設計 QuartusⅡ で実機確認 ( 可能であれば ) テストベンチを作成し シミュレーションする [ModelSim] 新規プロジェクトを作成する 1 分周回路 (dividing) をVHDLで設計 : 50MHz 100KHz へ分周 Modelsimでシミュレーション テストベンチ or 波形入力 2 カウントアップ機能付き10 進カウンタ (count10_co) をVHDLで設計 Modelsimでシミュレーション テストベンチ or 波形入力 3 6 進カウンター (count6) をVHDLで設計 : カウントアップ機能は不要 Modelsimでシミュレーション テストベンチ or 波形入力 87
[ModelSim] ( 続き ) 実習の進め方 ( 続き ) 4 トップ回路を VHDL で設計し 全体シミュレーションを実行する シミュレーション時間を調整する 60 ms 必須 - dividing を変更する : 100Hz(10ms) 100,000Hz(10μs) に変更 テキストの 152 頁 ( 図 2-110) を参照のこと チャタリング回路を調整する - トップ回路から chatter を削除する ( コメント行にする ) - chatter を変更する テキストの 125 頁 ( 図 2-69) を参照のこと conversion_ascii moji_deco は 前のプロジェクトから持ち込む そのまま使っても 必要な文字だけ (0~9) にスリム化しても良い [QuartusⅡ] 新規プロジェクトを作成する 1 Modelsim から全てのソースを持ち込む 2 dividing 周波数 チャタリング防止回路 (chatter) を仕様通りに戻す dividing 周波数 : 100Hz(10ms) チャタリング防止回路は チャタリングが発生しないように設定する 準備されているものをそのまま使っても良い 3 端子割り当てをして 実機で動作確認 本講座のクリア目標 88
1 分時計 のテストベンチ記述例 - 分周周波数 : 10us 60ms 時計としてシミュレーション library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity minute_top_tb is end minute_top_tb; architecture SIM of minute_top_tb is component minute_top port (clk, reset : in std_logic; LED0,LED1,LED2,LED3 : out std_logic_vector(7 downto 0) ); end component; signal CLK, RST : std_logic := '0' ; signal LED0,LED1,LED2,LED3 : std_logic_vector (7 downto 0); constant STEP: time := 20 ns ; begin U0: minute_top port map ( CLK,RST,LED0,LED1,LED2,LED3 ); process begin CLK <= '1'; wait for STEP/2; CLK <= '0'; wait for STEP/2; end process ; process begin wait for STEP*10000 ; RST <= '1'; wait for step*1000 ; RST <= '0'; wait for STEP*3200000; assert false severity failure; wait; end process; end SIM; configuration cfg_minute_top_tb of minute_top_tb is for SIM end for; end cfg_minute_top_tb; CLK 生成 200us で 20us の幅 RST 生成 Sim 継続時間 RST 後 64ms 実行して 強制終了 89
1 分時計 のシミュレーション結果 1 - RST 入力前後 : 200+20us 後の最初の立ち上がり (225us) でカウントアップ (48 49) 90
1 分時計 のシミュレーション結果 2-1 秒の桁がカウントアップする時 : 1215us(10us 100 サイクル ) 225us で 00.01 なので 1215us で 1 秒の桁が変わる (ascii2:48 49) 91
1 分時計 のシミュレーション結果 3 - 時計が初期に戻る時 : RST 後 60ms で初期状態に戻る 60215us (225us で 00.01 なので ) に全ての表示が 0 (ascii:48) になる 92
参考資料 93
遅延 設計した回路には必ず遅延が存在する 配線遅延 : 配線の長さによる遅延セル遅延 : セル内部で発生する遅延 IN 遅延 IN-A; 1 < 遅延 IN-B; 2 A B 3 C 配線遅延 セル遅延 IN A B 1 2 1 2 C 3 3 94
セットアップ時間とホールド時間 入力信号 クロック セットアップ時間 ホールド時間 D CLK Q Q セットアップ時間 ( Set up time ): クロックのアクティブエッジ ( 立上り or 立下がり ) で データを読み込む為に必要なデータ準備時間 ホールド時間 ( Hold time ): クロックのアクティブエッジ ( 立上り or 立下がり ) で データを読み込む為に必要なデータ保持時間 95
同期回路の遅延計算 1 配線遅延 2 セル遅延 1 2 1 2 1 2 1 F/F Q F/F Q CLK FF 間でクロックの 1 周期内でデータを正しく受け渡す条件 : クロック周期 > 性能向上 ( 高速動作 ) のための対策例 : 前段 FF のセル遅延 + 配線遅延の合計 ( 上図 1) + セル遅延の合計 ( 上図 2)) + 後段 FF のセットアップ時間 素子性能の向上 ( セル遅延 セットアップ時間の改善等 ) クリティカルパス ( 最大遅延パス ) の改善 クロックのずれ ( スキュー ) の改善 ( クロックツリー等 ) 96
組み合わせ回路 出力がそのときの入力の状態のみで決まる回路 - 出力が回路の以前の動作に依存しない すなわち 情報を記憶しない回路で 入力の組み合わせにより出力が決定される 主な組合せ回路 - マルチプレクサ ( セクター回路 ) - デマルチプレクサ ( 分配回路 ) - デコーダ ( 復号化回路 ) - エンコーダ ( 符号化回路 ) - 演算回路 ( 加算器等 ) - コンパレーター ( 一致検出回路 ) A B C D In SELS マルチプレクサ SELS A B C D Out デマルチプレクサ 2 進出力 2 3 2 2 2 1 2 0 エンコーダ 0 1 2 3 4 5 6 7 8 9 10 進入力 97
順序回路 ある時刻 tの出力 Y(t) が 入力 X(t) と内部状態 Q(t) に依存する論理回路 Y(t)=f(X(t),Q(t)) 組合せ回路 +レジスタ - 非同期式 : 回路動作が任意の時刻に発生する入力変化とその順序 ( 状態 ) だけに依存する順序回路 - 同期式 : 回路動作がクロックに同期する順序回路 ラッチとフリップフロップ - 信号 (0 または 1) を一時的に保持する回路 - タイミングを制御するクロック信号に同期して動作する ( 非同期もあり ) ラッチクロック信号がアクティブである間 入力を出力にそのまま出力し クロック信号がインアクティブに変化する時の値を保持する回路 フリップフロップ ( 同期型 ) クロック信号の立ち上がりまたは立ち下りの瞬間 ( エッジ ) の入力データを保持し その値を出力する回路 98
クロック制御の同期式 / 非同期式論理回路 同期式論理回路 レジスタ同士が 同じクロックに同期して動作する クロック周期を前提に回路を考えればよいので 楽に設計できる [ 利点 ] タイミング調整をあまり考えなくていいので大規模回路に向いている [ 欠点 ] クロック信号の分配に細心の注意が 多数のゲートが同時に動作するので 電源電圧 動作速度に影響がある 回路規模が大きくなる傾向がある電力消費と発熱が増加 サイズによるコスト増加 遅延の増加等 非同期式論理回路 レジスタ同士が 違うクロックで動作する 回路全体が簡素化でき クロック周期を気にせず設計できるが 僅かタイミングのずれでグリッジを発生させやすく 誤動作を起こしやすい 温度依存性も高い [ 利点 軽い回路には手軽に使える 必要な時にしかラッチクロックが起きないので費電流が少ない [ 欠点 ] 大規模回路では 予期せぬタイミングトラブルがいろいろな所で発生し 処理に追われ ほぼ設計不可能 ( 最近少し状況が変わってきている ) 99
D-Latch と D-FF D-Latch D Q CLK CLK D CLK=1 D 入力を随時伝達 CLK=0 直前データを保持 Q D-FF D Q CLK CLK D CLK: 0 1 ( 立ち上がりエッジ ) で D 入力を取り込む次のエッジまでその値を保持 Q 100