2017 年度前期集中講義 論理回路設計 - 実習 :VHDL によるデジタル回路設計 - 講座の目的実習を通して 専門分野の問題発見 解決の能力を修得する - LSI 設計の基礎知識を得る - 言語 :VHDLによる設計手法を実習する - EDAツールの操作を経験する - FPGAを搭載した評価ボードで動作を確認する 東京理科大学 基礎工学部電子応用工学科 ( 非常勤講師 ) 藤岡督也 1 /76
1. 実習環境の説明 目次 2. 課題 1: 4 ビット加算器 - 参考資料 EDA ツールの付加情報 - VHDL の概要 3. 課題 2: 自分の名前を表示しよう 4. 課題 3: 1 分時計 5. 課題 4: 追加仕様版加算器 2
集中講義の日程 1 日目 2 日目 3 日目 4 日目 6 月 17 日 ( 土 ) 2~5 時限 6 月 24 日 ( 土 ) 2~5 時限 7 月 01 日 ( 土 ) 2~5 時限 7 月 08 日 ( 土 ) 2~4 時限 課題 1 加算器 - Quartus Ⅱ の操作と作業手順の習得 回路図 /VHDL による設計 ピンアサイン 実機での動作確認 課題 1 加算器 - ModelSim の操作と作業手順の習得 シミュレーションに設計機能の確認 テストベンチの作成 & 実行方法 課題 2 自分の名前の表示させよう 課題 3 1 分時計 課題 4 追加仕様版加算器 ( 追加仕様 ) 10 進表示への変更 ビット拡張 乗算機能の追加 - 設計の実践 & 動作確認 - 言語設計の理解 ( 実習で使用する環境 ) [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 へ出力する [ テキスト図 1-55 参照 ] 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へ16 進表示 0~Fをトグルする Button2 : 被加数の入力 HEX3へ16 進表示 0~Fをトグルする Button1 : リセッの入力 button0とbutton2を同時にリセットする 2. 出力データ : 加算結果を 7segLED に表示する 加算結果は hex 表とする ( 00~1E; 4 ヒ ット加算 加算結果は 5 ヒ ット ) HEX0 : 加算結果の下位桁を 16 進表示する HEX1 : 加算結果の上位桁を 16 進表示する HEX2 : = を表示する HEX3 : = を表示する 3. モード切替 : スライト スイッチを使って 入力 / 出力表示を切り替える SW0 : 0( 入力モード ): 被加数と加数を表示する 1( 出力モード ): 加算結果を表示する 19
実習の進め方 第 1 日目 課題 1 を回路図と VHDL で設計して 実機 (DE0) で評価する - QuartusⅡ 上で 課題を回路図で入力して設計する ( テキスト : 5 ~ 41 頁 ) - 端子割り当て後 実行モジュール (*.sof) を作成し 実機にダウンロードして 動作を確認する ( テキスト : 42 ~ 49 頁 ) - 回路図で設計した同じ回路を Quartus Ⅱ 上で VHDL を使って再設計して 実機で動作を確認する ( テキスト : 50 ~ 72 頁 ) 第 2 日目 課題 1 の VHDL をシミュレーションを実行して 機能を確認する ( テキスト : 73 ~110 頁 ) - 入力パターンを Apply Wave で設定して シミュレーションを実行して 機能を確認する ( テキスト : 82 ~100 頁 ) - テストベンチを記述して シミュレーションを実行して 機能を確認する ( テキスト :101 ~110 頁 ) 20
[QuartusⅡ] 4 ビット加算器 の設計内容 - 設計で用いる設計記述の組み合わせ - [1 日目 ] [2 日目 ] [ModelSim] 実機による検証 コンパイル 実行モジュール ダウンロード 動作確認 4 ビット加算器 ( トッフ モシ ュール ) 回路図 &VHDL 記述 加算演算部 ( 加算モシ ュール ) 回路図 &VHDL 記述 ( 実機用周辺回路 ) peripheral_de0 (Sim 用周辺回路 ) peripheral_sim (VHDL 記述 ) シミュレーションによる検証 コンパイル シミュレーションによる機能検証 + 波形エディタから入力パターンの設定 テストベンチを記述してシミュレーションを実行 21
参考資料 EDA ツールのプロジェクトメンバー管理 22
QuartusⅡ のプロジェクトへのファイルの追加 プロジェクトをオープンした状態で File New を選択すると New 画面がポップアップされるので VHDL File を選択する VHDL File 選択後 編集画面が表示されるので 持ち込みたい VHDL 記述を paste して Save As で保存する 23
QuartusⅡ のプロジェクト ディレクトリ file open 後のポップアップ画面 プロジェクト [ adder_4bit ] をオープンした時のディレクトリ下のファイル一覧 ファイル名と更新日時が正しいかを常にチェックする ファイル名 ( 拡張子以外の部分 ) は 異なる名前にする 古い版を保存したい場合は *_old1.vhd のようにする 複雑になった場合は 新しいプロジェクトを作って 別に管理する 24
QuartusⅡ のプロジェクトメンバー 現在のプロジェクトメンバーの一覧 リストされているファイルを正しく管理する 同名のモジュール名は避ける 変更する場合は 次頁のように行う 25
QuartusⅡ のプロジェクトメンバーの変更 1. オープンしているファイルをメンバーに追加する : Project Add current file to Project 2. プロジェクトディレクトリ下のファイルを使って変更する Project Add/Remove files to Project 26
ModelSim のプロジェクトへのファイルの持ち込み File Source VHDL の操作で編集ウィンドウが開くので vhdl 記述を paste し Save As で保存する 27
ModelSim のプロジェクト ディレクトリ プロジェクト ディレクトリ下のファイル一覧 ( プロジェクトメンバーの候補 ) 28
ModelSim のプロジェクト メンバー プロジェクト メンバーの一覧 - トップモジュール以下の全モジュールがリストされている ( リストされるように管理する ) 29
ModelSim のプロジェクト メンバーの変更 Project 画面内で右クリック - Add to Project を使って 変更する 30
VHDL の概要 31
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 ( 最新版 ) 32
ハードウェア記述言語 : HDL - Hardware Description Language; HDL - デジタル回路 特に集積回路を設計するためのコンピュータ言語 - ハードウェアの動作仕様を記述するための言語で 電子回路の経時的動作と空間的構造を表現し 構文 (syntax) や意味 (semantics) は ハードウェアの基本的属性である時間や並行性を記述 - 処理を検証するテストベンチ記述ができ シミュレーションが可能 - 論理合成が可能 - Verilog HDL と VHDL が 主要な言語 (IEEEで標準化を推進) RTL (Register Transfer Level) とは? レジスタ間の転送関係を表現したレベル 機能を 代入 if case 等で表現したもの クロックを意識した記述 論理合成 ゲートレベルとは? ゲート回路やフリップフロップ等の接続関係を表現したもの ( 素子と等電位点の列挙 ) ネットリストとも言う 33
VHDL の基本構造 1 論理合成可能 VHDL の文法 回路記述 テストベンチ シミュレーション可能 ライブラリ記述 論理合成不可 回路記述 : 論理合成に適した記述をする 回路の種類ごとに適した記述スタイルがある テストベンチ : 文法を満たしていれば どんな記述でもよい 記述のテクニックを駆使できる 34
VHDL の基本構造 2 library 複数のライブラリ use entity.1つ port architecture architecture process B process A 一つの architectureに複数のprocessを書ける architecture process C 一つの entity に複数の architecture を書ける 一つの entity に複数の architecture を書ける一つの architecture に複数の process を書ける 35
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 合成用の記述に使用するもの ( 回路の合成が可能な記述 ) シミュレーション テストベクタ記述に使用するもの ( 合成困難, 不能 ) 36
VHDL の基本構造 4 - 階層化記述 - Library Entity Architecture 動作記述構造記述 Library Entity port Architecture 動作記述構造記述 Library Entity port Architecture 動作記述構造記述 Configuration テストベンチ設計回路のトップ階層設計回路の下位階層 37
全体構造と記述例 パッケージ の指定 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 アーキテクチャ名 ; 38
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. コンパル時のエラーは しっかり読む - 必ずしも 的確な記述間違いをメッセージしてくれる訳ではない 39
半加算器の回路図と VHDL 記述 VHDL 記述 ( 図 2-7 参照 ) -- 半加算器の記述例 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; [ 図 2-9] 機能のゲート記述 回路図入力 ( 図 1-24 参照 ) O コンパイル後 ( 図 2-13 参照 [ 等価 ]) 機能の動作記述 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; 40
階層化記述例 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; 41
全加算器の回路図と VHDL 記述 [ 図 2-14] [ 図 2-15] 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; ライブラリ記述 エンティティ記述 コンポーネント宣言 アーキテクチャ コンポーネント呼び出し ( コンホ ーネント インスタンス ) 42
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 43
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; 44
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 45
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 46
テストベンチの構造 パッケージ の指定 entity エンティティ名 is end エンティティ名 ; architecture アーキテクチャ名 is bigin - DUT の宣言 - 入出力の宣言 - DUT の呼び出し - 波形記述 end アーキテクチャ名 ; configuration コンフィク レーション名 is for アーキテクチャ名 end for; end コンフィク レーション名 ; ライブラリ記述 ポートリストの無いエンティティ記述 アーキテクチャ名 of エンティティ名テストモシ ュール (DUT) のコンホ ーネント宣言 DUT の入出力信号宣言整数の定義 ( クロック周期等 ) DUT の呼び出し宣言 ( インスタンス ) 入力信号の入力波形記述 ( 期待値照合も可能 ) コンフィク レーション名を定義 コンフィク レーション名 of エンティティ名 このコンフィク レーション名でシミュレーターの実行モジュールが作られる 47
テストベンチでの入力波形記述例 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; -- シミュレーションの強制終了 end process; 48
3. 課題 2: 自分の名前を表示させよう - 第 3 日目 - M _ T O [ 各文字と各セグメントの表示は テキスト pp111 112 を参照 ] 0123456789_I_AM_TOKUYA_FUJIOKA. 自分の名前 [ 注 ] 31 文字なので 5 ビット化 (32 文字 ) が可能 49
名前表示 の開発仕様 [ 実現機能 ] 4 個の 7segLED に 1 秒毎に左に流れるように 0~9 の数字を表示させた後に 自分の名前をアルファベットで表示する [ ボタン仕様 ] Button0(stop): 押下毎に停止 / 再開の動作を繰り返す停止 : 押下時点での表示をそのまま継続する再開 : 表示状態から次の表示を再開する Button1(reset): 初期状態に戻る (0 表示から始める ) [LED 表示 ] HEX0 : 0123456789_I_am_( 各人の名前をアルファベットで表示 HEX1/2/3 : -1/-2/-3 秒遅れて HEX0を同じ内容を表示 [ モジュール構成 ] - peripheral_moji: 準備されている ボタン動作に従って 1MHz 周期 (Sim 用 ) のカウント信号 (0~31) が出力される : deco0~3[5_0] 実機用には 1Hz 周期になるように変更する - conversion_ascii: カウント信号を ascii 文字コードに変換 - moji_deco: ascii 文字コードを 7segLED 信号に変換 50
実習の進め方 第 3 日目 VHDL で設計して シミュレーションを実行して機能確認後 実機で動作を確認する [ Modelsim ] ( テキスト : 116 ~ 130 頁 ) 1 新規プロジェクト (moji_deco) を作成する 2 conversion_ascii.vhd ( 各自で記述内容が異なる ) moji_deco.vhd 3 moji_deco_top.vhd トップ回路をVHDLで設計する 4 テストベンチでシミュレーションを実行し 機能確認する ( 全員の記述内容が同じ ) を設計する [QuartusⅡ] ( テキスト : 131 ~ 137 頁 ) 5 新規プロジェクト (moji_deco_de0) を作成する 6 実機用回路に修正し ( 図 4-24) コンパイルする 修正後のデータをエラーフリーにする 7 端子割り当て後 コンパイルして実行モジュールを作成する 8 実機で動作を確認する 51
名前表示 の Sim 用モジュール構成 - 図 4-5 実習課題概要 - peripheral_moji moji_deco_top conversion_ascii decoder_7seg CLK deco0 CNV0 DEC0 S0(5) A0(7) LED0 STOP deco1 CNV1 DEC1 S1(5) A1(7) LED1 PERI RESET deco2 CNV2 DEC2 S2(5) A2(7) LED2 HEX0 HEX1 HEX2 deco3 ( 配付モシ ュール ) S3(5) CNV3 DEC3 A3(7) 今回設計する部分 LED3 HEX3 deco0 0 1 2 3 4 5 6 7 8 9 30 31 deco1 31 0 1 2 3 4 5 6 7 8 29 30 deco2 30 31 0 1 2 3 4 5 6 7 28 29 deco3 29 30 31 0 1 2 3 4 5 6 27 28 conversion_ascii (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 秒毎にカウントアップする ) moji_deco ( カウントアップした数をascii 文字と7segに変換する ) 52
名前表示 の実機用モジュール構成 - 図 4-24 実機評価用最上位回路 : moji_deco_de0 - CLK moji_deco_de0 I3: moji_deco_top HEX0 STOP RESET I1: chattering clk SW_out SW_in chat_stp I2: chattering clk SW_out SW_in chat_rst clk stop reset LED0(7..0) LED1(7..0) LED2(7..0) LED3(7..0) LED0 LED1 LED2 HEX1 HEX2 HEX3 LED3 - 入力信号の雑音を削除 チャタリング防止回路の挿入 - 表示周期を 1 秒 (=1Hz) に変更 moji_deco_top 内の peripheral_moji の一部を変更 53
名前表示 のシミュレーション 1. シミュレーション用回路の設計 1) 図 4-5 に従って conversion_ascii, decoder_7seg, moji_deco_top を設計する 2)peripheral_moji は シミュレーション用にカスタマイズする ( されている ) シミュレーションでは 雑音等は削除してよい シミュレーションの効率化を図る 出力 :deco0/1/2/3 を 1MHz(=1us) 周期に設定 3) テストベンチを記述して シミュレーションを実行する 2. シミュレーション後の確認内容 1)deco のカウント数に従って 所望の文字列が発生されているか? 2) カウント数が ascii コードに正しく変換されているか? 3)7segLED の信号が正しく生成されているか? 4)reset が正しく動作しているか? 5)stop 信号が正しく動作しているか? 1 回目押下 : カウント停止 ( 継続 ) 2 回目押下 : カウント再開 54
名前表示 のテストベンチ記述例 --Testbench for module: moji_deco_top library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; begin U0: moji_deco_top port map (clk, reset, stop, LED0, LED1, LED2, LED3 ); entity moji_deco_top_tb is end moji_deco_top_tb; architecture SIM of moji_deco_top_tb is component moji_deco_top port( CLK, STOP, RESET: in std_logic; LED0 : out std_logic_vector (7 downto 0); LED1 : out std_logic_vector (7 downto 0); LED2 : out std_logic_vector (7 downto 0); LED3 : out std_logic_vector (7 downto 0)); end component; signal CLK: std_logic := '0' ; signal STOP, RESET: std_logic := '1' ; signal LED0, LED1: std_logic_vector (7 downto 0); signal LED2, LED3: std_logic_vector (7 downto 0); constant STEP: time := 20 ns ; process begin clk <= '0'; wait for STEP/2; clk <= '1'; wait for STEP/2; end process; process begin wait for 10.3 us ; RESET <= '0'; wait for 4.5 us ; RESET <= '1'; wait for 30.7 us ; STOP <= '0'; wait for 2.0 us ; STOP <= '1'; wait for 8.2 us ; STOP <= '0'; wait for 3.8 us ; STOP <= '1'; wait for 20.5 us ; assert false severity failure; end process; end SIM; clk 生成 RESET/ STOP 生成 U0: moji_deco_top - シミュレーション用回路 configuration cfg_moji_deco_top_tb of moji_deco_top_tb is for SIM end for; end cfg_moji_deco_top_tb; 55
名前表示 のシミュレーション結果 (1) - 全体表示 - 56
名前表示 のシミュレーション結果 (2) - リセット付近 - (ascii コート は 表 4-2 参照 ) 57
名前表示 のシミュレーション結果 (3) - ストップ付近 - 58
4. 課題 3: 1 分時計 - 第 3/4 日目 - 59
[ 実現機能 ] 1/100 秒まで表示する 1 分時計を作る 60 秒でトグルする ( 表示例 ) 12.34 [ 秒桁に ドットを表示する ] [ ボタン仕様 ] Button0(reset): 初期状態に戻る (00.00 秒表示に戻る ) [LED 表示 ] HEX0 : 1/100 秒 1 分時計 の開発仕様 HEX1 : 1/10 秒 HEX2 : 1 秒 ドット を表示させる HEX3 : 10 秒 [ モジュール構成 ] - one_min_clock_top: 1 分時計の最上位回路 - Div_10ms: 50MHz(20ns) 100Hz(10ms) への分周回路 - chattering: チャタリング防止回路 ( 既設計 手法 1 2 どちらでも可 ) - CNT10: カウントアップ機能付き 10 進カウンタ - CNT06: 6 進カウンタ ( カウントアップ機能は無し ) - BCD_7segLED: BCD コードを 7segLED 信号にデコード ( 注意 ) ドット表示 をどこに組み込むかを考えること 60
実習の進め方 第 3/4 日目 シミュレーションは サブ回路で実行する 実機用回路を設計して 動作を確認する [ Modelsim ] ( テキスト : 142 ~ 146 頁 ) 1 新規プロジェクト (one_min_clock) を作成する 2 Div_10ms: Sim 用に 分周は 10us で設計する CNT10 : カウントアップ機能付き10 進カウンターを設計する 3 Parts : サブ回路のトップモジュールを設計する 4 テストベンチでシミュレーションを実行し 機能確認する [QuartusⅡ] ( テキスト : 146 ~ 1148 頁 ) 5 新規プロジェクト ( one_min_clock ) を作成する 6 実機用回路 ( 図 5-8) を設計する 分周は 10ms にする コンパイルで設計データをエラーフリーにする 7 端子割り当て後 コンパイルして実行モジュールを作成する 8 実機で動作を確認する 61
1 分時計 のトップ回路図 [ 入力 ] - CLK: 50Mhz(20ns) - 非同期 reset [ 出力 ] 1 2. 3 4 ドットを付ける 1/100 単位 60 秒で繰り返す clk reset clk clk_div [ 分周回路 ] Div_10ms chat_rst [ チャタリンク 防止回路 ] chattering - 図 5-8 1 分時計 のブロック図 - clk_10ms one_minute_top clk_sig reset clk_sig reset clk_sig reset clk_sig reset 10 進カウンタ clk_100ms 10 進カウンタ clk_1s 10 進カウンタ clk_10s 6 進カウンタ bcd up_sig bcd up_sig bcd up_sig bcd up_sig bcd0_sig bcd1_sig bcd2sig bcd3_sig BCD_7segLED bcd bcd bcd bcd seg seg seg seg LED0 LED1 LED2 LED3 HEX0 HEX1 HEX2 HEX3 ドット表示 62
シミュレーション用サブ回路 図 5-8 の回路全体をシミュレーションするのは 非効率 サブ回路で シミュレーションを実行 Div_10ms と CNT10 の動作を確認 図 5-10 のサブ回路 :Parts でシミュレーション実行 - 分周は 10ms 10us にする (1/1000 にして シミュレーション ) - 図 5-10 サブ回路 :Parts のブロック図 - システムクロック : 50MHz clk [ 分周回路 ] Div_10ms clk clk_div clk_10ms clk_sig bcd bcd(3..0) reset reset up_sig clk_100ms Parts [10 進カウンタ ] CNT10 1 9 9 1 63
1 分時計 のサブ回路のテストベンチ - 分周周波数は 10us でシミュレーションを実行 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity parts_tb is end parts_tb; architecture SIM of parts_tb is component parts port (clk, reset : in std_logic; clk_100ms : out std_logic; bcd : out std_logic_vector(3 downto 0) ); end component; signal clk, reset, clk_100ms : std_logic :='1'; signal bcd : std_logic_vector(3 downto 0); begin DUT: Parts port map (clk, reset, clk_100ms, bcd); process begin clk <= '1'; wait for 10 ns ; clk 生成 clk <= '0'; wait for 10 ns ; end process; 3215nsから2us 間 process begin wait for 3215 ns; reset <= '0'; reset 生成 wait for 2.0 us; reset <= '1'; wait for 500 us; assert false severity failure; Sim 継続時間 end process; end SIM; configuration cfg_parts_tb of parts_tb is for SIM end for; end cfg_parts_tb; reset 後 500us 実行して 強制終了 64
サブ回路 :Parts のシミュレーション結果 1 [reset 機能の確認 ] [Div_10ms の出力 :clk_10ms と CNT10 の出力 : 信号 bcd の確認 ] 65
サブ回路 :Parts のシミュレーション結果 2 [CNT10 の出力 :clk_100ms の確認 ] 66
5. 課題 4: 追加仕様版加算器 - 第 4 日目 - 67
4 ビット加算器 への追加仕様 [ 追加仕様 1] 4 ビット加算器の表示を 16 進表示 10 進表示に変更する - 1100 (=C H ) [BCD コード ] 0001_0010 (=12 10 ) [ 追加仕様 2] 追加仕様 1 の 4 ビット (0~15) を 7 ビット (0~127) へ拡張する - 入力信号 A と B: 0~99 まで入力可 99 から 0 に戻る - 加算結果は HEX0/1/2 に 10 進数で HEX/3 には = を表示する ( 表示例 ) =005 =034 =198 等 [ 追加仕様 3] 追加仕様 2 に乗算機能を追加する -99x99=9801 HEX0/1/2/3 に表示可 ) - 乗算機能は 単純に MUL <= A * B; で実現する -MUL の表示は SW1 を使う SW1= 1 の時に HEX3~0 に表示する SW0 と SW1 が同時に 1 の時は SW1 を優先する 68
実習の進め方 第 4 日目 以下の手順で設計して シミュレーションで確認後 実機用回路を設計して 動作を確認する [ Modelsim ] 1 新規プロジェクト (adder_expand) を作成する 2 プロジェクト :adder_4bit に 4 ビットカウンター : Counter_4bit.vhd BCD 化モジュール :Binary2bcd.vhd 表示信号の選択回路 : Selector.vhd を追加する 3 全体回路を整合し テストベンチでシミュレーションを実行し 機能確認する [QuartusⅡ] 4 新規プロジェクト ( adder_expand_de0 ) を作成する 5 実機用回路を設計する ( チャッタリング防止回路の追加 ) 6 端子割り当て後 コンパイルして実行モジュールを作成する 7 実機で動作を確認する 追加仕様 2/3 も同様の手順で作業する 69
システムクロック (50MHz) RESET A library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; B use ieee.std_logic_arith.all; 追加仕様版 _ 加算器 のブロック図 entity Binary2bcd is port( bin_in : in std_logic_vector(4 EQUAL downto 0); bcd1 : out std_logic_vector(3 downto 0); bcd2 : out std_logic_vector(3 downto 0)); end Binary2bcd ; 波形整形(チャタリング)図 6-1 追加仕様版 1 の加算器ブロック図 adder_expand_de0 カウンター カウンター 加算回路 BCD 化 BCD 化 BCD 化 SW0 0 1 表示信号の選択BCD_ 7segLED Hex0 Hex1 Hex2 Hex3 (Hex3) (Hex2) (Hex1) (Hex0) architecture RTL of Binary2bcd is signal Num,N1,N2: integer range 0 to 63; begin Num <= CONV_INTEGER(bin_in); N1 <= Num - (Num/10)*10; N2 <= (Num/10) mod 10; bcd1 <= CONV_std_logic_vector(N1,4); bcd2 <= CONV_std_logic_vector(N2,4); end RTL; BCD 化 : Binary2bcd.vhd の記述例 70
型の変換 の関数 関数名 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 への変換 71
参考資料 - 7segLED のデコード回路 - ( ドット表示 on/off 機能付 ) 72
7segLED のデコーダ : BCD_7seg.vhd library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity BCD_7seg is port( dot : in std_logic; led : in std_logic_vector(3 downto 0); seg : out std_logic_vector(7 downto 0)); end BCD_7seg; architecture RTL of BCD_7seg is begin process(led) begin if dot='0' then case led is when "0000" => seg<="00000011"; -- 0 when "0001" => seg<="10011111"; -- 1 when "0010" => seg<="00100101"; -- 2 when "0011" => seg<="00001101"; -- 3 when "0100" => seg<="10011001"; -- 4 when "0101" => seg<="01001001"; -- 5 when "0110" => seg<="01000001"; -- 6 when "0111" => seg<="00011011"; -- 7 when "1000" => seg<="00000001"; -- 8 when "1001" => seg<="00001001"; -- 9 when others => seg<="11111111"; end case; DUT: BCD_7seg - 7seg LED のデコーダー - 入力 : 0 ~ 9(BCD) - ドット表示の有無で場合分け else case led is when "0000" => seg<="00000010"; -- 0 when "0001" => seg<="10011110"; -- 1 when "0010" => seg<="00100100"; -- 2 when "0011" => seg<="00001100"; -- 3 when "0100" => seg<="10011000"; -- 4 when "0101" => seg<="01001000"; -- 5 when "0110" => seg<="01000000"; -- 6 when "0111" => seg<="00011010"; -- 7 when "1000" => seg<="00000000"; -- 8 when "1001" => seg<="00001000"; -- 9 when others => seg<="11111110"; end case; end if; end process; end RTL; 73
BCD_7seg のテストベンチ記述例 1 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; ライブラリ記述 entity BCD_7seg_tb is end BCD_7seg_tb; architecture SIM of BCD_7seg_tb is component BCD_7seg port( dot : in std_logic; led : in std_logic_vector(3 downto 0); seg : out std_logic_vector(7 downto 0)); end component; signal dot : std_logic; signal led : std_logic_vector(3 downto 0):="0000"; signal seg : std_logic_vector(7 downto 0); constant STEP: time := 1 us; begin DUT: BCD_7seg port map (dot, led, seg); end SIM; 波形記述 ポートリストの無いエンティティ記述 テストモシ ュール :BCD_7seg のコンホ ーネント宣言 BCD_7seg の入出力信号で定義する定数を定義する BCD_7seg を DUT としてインスタンスする 入力信号の波形を定義する (- 出力波形を記述し期待値照合を行う ) configuration cfg_bcd_7seg_tb of BCD_7seg_tb is for SIM end for; end cfg_bcd_7seg_tb; コンフィグレーションを定義する [ コンフィク レーション名 : cfg_bcd_7seg_tb ] 74
BCD_7seg のテストベンチ記述例 2 BCD_7segの入力波形の記述 ( 前頁の波形記述部分 ) constant STEP: time := 1 us; begin DUT: BCD_7seg port map (dot, led, seg); 入力信号は dot( スカラー ) と led( ヘ クトル ) process begin wait for STEP; led <= led + '1'; end process; process begin dot <= '0'; wait for STEP*16; dot <= '1'; wait for STEP*16; assert false severity failure; end process; led(3 downto 0) の入力信号を生成する - 000 ~ 1111 (0~15) を STEP(1us) 単位で生成する - 無限に繰り返す 入力信号 :dot を生成する - 0 を 16 STEP 間保持 - 1 を 16 STEP 間保持後 - assert 文で強制終了する 75
BCD_7seg_tb のシミュレーション結果 シミュレーション後の全体表示 dot= 0 のときの 7segLED の入力信号へのデコード状態 dot= 1 のときの 7segLED の入力信号へのデコード状態 76