Comments
Description
Transcript
卒業研究論文
卒業研究論文 (2009 年 2 月) CPLD によるミニゲーム集の制作 ソフトウェア情報学部 ソフトウェア情報学科 和島研究室 ソ 17001 相坂俊 1. 背景 ............................................................................... 4 2. 開発環境 ........................................................................... 4 2.1 ハードウェア ..................................................................... 4 2.1.1 CPLD ......................................................................... 4 2.1.2 Terasic-Blaster .............................................................. 6 2.1.3 フラットケーブル ............................................................. 6 2.2 ソフトウェア ..................................................................... 7 2.2.1 QuartusⅡ .................................................................... 7 2.2.1.1 プロジェクトの作成 ........................................................... 7 2.2.1.2 回路図エディタによる回路設計 ............................................... 9 2.2.1.3 VHDL 言語による回路設計 ................................................... 12 3. CPLD の動作テスト ................................................................. 16 3.1 テスト用回路基板の制作 .......................................................... 16 3.1.1 EAGLE による回路の設計 ...................................................... 16 3.1.1.1 ライブラリへの部品登録 .................................................... 16 CPLD ............................................................................ 17 7segLED ......................................................................... 21 3.1.1.2 回路図設計 .............................................................. 21 3.1.1.3 基板設計 ................................................................ 23 3.1.2 基板加工機による基板加工 .................................................... 23 3.1.3 ハンダ付け .................................................................. 25 3.2 回路図エディタによる並列 10 進カウンタ回路の作成 ................................. 26 3.2.1.1 仕様 ...................................................................... 26 3.2.1.2 実装 ...................................................................... 26 3.2.2 3.3 動作結果 .................................................................... 28 VHDL 言語による並列 10 進カウンタ回路の作成....................................... 29 3.3.1 仕様 ........................................................................ 29 3.3.2 プロジェクトの構成 .......................................................... 30 3.3.2.1 BCDCounter.vhd .......................................................... 31 3.3.2.2 Decode7segment.vhd ...................................................... 32 3.3.2.3 ButtonCount.vhd ......................................................... 33 3.3.2.4 ButtonCount_top.vhd ..................................................... 36 3.3.3 4. 動作結果 .................................................................... 38 ミニゲームの作成 .................................................................. 39 4.1 CPLD 基板の製作 ................................................................. 40 4.1.1 EAGLE による回路の設計 ...................................................... 40 4.1.1.1 ライブラリへの部品登録 .................................................. 40 40 ピンコネクタ ................................................................. 40 2 4.1.1.2 回路図設計 .................................................................. 41 4.1.1.3 基板設計 .................................................................... 42 4.1.2 基板加工機による基板加工 .................................................... 43 4.1.3 ハンダ付け .................................................................. 43 4.2 表示・入力用基板の製作 .......................................................... 43 4.2.1 EAGLE による回路の設計 ...................................................... 44 4.2.1.1 回路図設計 .............................................................. 44 4.2.1.2 基板設計 ................................................................ 45 4.2.2 基板加工機による基板加工 .................................................... 45 4.2.3 ハンダ付け .................................................................. 47 4.3 VHDL 言語による 8 パズル回路の作成 ............................................... 47 4.3.1 仕様 ........................................................................ 48 4.3.2 プロジェクトの構成 .......................................................... 49 4.3.2.1 8puzzle.vhd ............................................................. 50 4.3.2.2 Decode7segment.vhd ...................................................... 52 4.3.2.3 Controller.vhd .......................................................... 52 4.3.2.4 check.vhd ............................................................... 55 4.3.3 4.4 動作結果 .................................................................... 55 VHDL 言語による三目並べ回路の作成 ............................................... 57 4.4.1 仕様 ........................................................................ 57 4.4.2 プロジェクトの構成 .......................................................... 58 4.4.2.1 CircleCross.vhd ......................................................... 59 4.4.2.2 Decode7segment.vhd ...................................................... 61 4.4.2.3 Controller.vhd .......................................................... 61 4.4.3 5. 動作結果 .................................................................... 61 問題点とその解決法 ................................................................ 63 ハードウェア .................................................................... 63 5.2 ソフトウェア .................................................................... 64 6. 5.1 まとめ ............................................................................ 66 3 1. 背景 近年家電製品や携帯電話などの組み込み系の技術の需要が高まっている。組み込み技術とは、特定の システムの目的に特化して動作させるシステムであり、性能の限定されたハードウェアとそれに特化し た専用のソフトウェアで実現されている。組み込みシステムに限らず、電子回路を動作させる基板の設 計には回路 CAD(Computer Aided Design)が用いられる。これは基板上に実装される部品間の論理的な 接続を設計する回路設計と、実基板上の配線を干渉することなく行うよう部品サイズ・配線レイヤーな どを考慮して設計する基板設計に分かれる。一方、組み込みシステムの電子回路の内部の設計には、 CPLD(Complex Programmable Logic Device)や FPGA(Field Programmable Gate Array)が使われて いる。いずれも多くのロジックエレメントの集まりで、その間の接続を電気的に書き換えることのでき るもので、基板を作り直すことなく素子の論理的な接続を組み替えることができるものである。一般に 数百程度のロジックエレメントを持つものを CPLD、1000 以上のものを FPGA と呼ぶ。回路の設計に は VHDL(Very high-speed integrated circuit Hardware Description Language)や Verilog HDL が用い られる。 そこで本研究では回路設計と基板設計を統合して扱うことのできる回路 CAD EAGLE を用いて CPLD 基板と 7segLED と押しボタンスイッチを搭載した基板を設計・製作し、それにトランジスタ技 術 2006 年 4 月号[1]付録の CPLD 基板を搭載して、VHDL を用いて 8 パズルや三目並べなどの動作をす るプログラムを組み、CPLD に書き込んで動作を確認した。 2. 開発環境 2.1 ハードウェア 2.1.1 CPLD 本研究で使用した CPLD 基板の仕様を表 2-1 に記す。 図 2-1 CPLD 基板 4 10 ピンのコネクタ CN4 はプログラムの書き込みの際の PC との通信に使用する。 表 2-1 CPLD 基板の仕様 項目 仕様 基板材質 ガラス・エポキシ(FR-4) 基板層数 1 電解コンデンサ(47μF) 2層 外形寸法 70×50mm CPLD(EPM240T100C) 搭載部品 TC74VHC244FT 抵抗、コンデンサ 供給電源 3.3V(3 端子レギュレータを搭載すれば 5V 入力可能) この基板に搭載されている CPLD EPM240T100C の特性は以下の通りである。 表 2-2 CPLD EPM240T100C の特性 動作電圧 3.3V ロジックセル数 240 入出力 76 電源入力 16 通信用入出力 4 ボタンからの信号や電源、クロック入力と外部との入出力、また回路の安定動作のために CPLD 基板 に以下の部品をハンダ付けした。 表 2-3 CPLD 基板に実装した部品 部品 個数 ダブルヘッダピン(メス) 20 ピン×2、10 ピン×1、8 ピン×1 抵抗(220Ω) 1 電解コンデンサ(47μF) 2 IC ソケット 4 ピン×1 3 端子レギュレータ(LM1117T-3.3/NOPB) 1 水晶発振器(ACH-10.000MHZ-EK) 1 CPLD の動作電圧は 3 端子レギュレータを搭載したため、入力電圧には 5V のものを使用した。 5 2.1.2 Terasic-Blaster プログラムの書き込みには、USB Blaster 互換の Terasic Blaster(Terasic 社製)を使用した。これは 3.3V の電源で動作し、TCK、TDO、TMS、TDI の 4 つの入出力信号を用いて PC と CPLD の通信を行 うものである。 図 2-2 Terasic Blaster 左側の黒い端子が CPLD 基板に接続される 10 ピンのメスのコネクタで、本体の左側の端子は A-B タイプの USB ケーブルを通じて PC の USB 端子に接続される。 Terasic-Blaster を使用するために USB ケーブルで PC に接続し、ハードウェアの追加ウィザードで ドライバを自動でインストールした。図 2-1 がデバイスマネージャでの表示である。Terasic-Blaster は ALTERA 社の USB Blaster の互換品であるため、USB Blaster として認識される。 図 2-3 Terasic-Blaster の認識 2.1.3 フラットケーブル 長さはそれぞれ芯数 40 本, ピッチ 1.27mm とした。 図 2-4 基板の接続に使用する 2 本のフラットケーブル 6 2.2 ソフトウェア 2.2.1 QuartusⅡ QuartusⅡとは CPLD の回路の情報を作成し、書き込むためのソフトウェアである。CPLD への回路 の入力方法にはエディタによる入力と VHDL による入力がある。エディタによる入力では回路図エデ ィタ上に Symbol(回路記号)を配置し、それらを配線で接続し入出力を CPLD のピンに対応させて、そ れをコンパイルして書き込む。一方 VHDL による入力では、VHDL ファイルを作成し、その中で入出 力の信号を定義して入力の値によって求める動作をするようなプログラムを書き下し、それをコンパイ ルして書き込む。いずれの方法でも回路を設計・入力することができるが、VHDL を使った回路の設計 の方が、目的とする動作のための機能に応じてロジックエレメントを効率よく使うことができる。 QuartusⅡは有償だが、本研究では Web Edition という無償の評価版を使用した。 回路図エディタ で回路を入力 プロジェクト 回路の制約 の作成 条件を入力 コンパイル 書き込み VHDL を使って 回路を入力 回路図上の端子と CPLD の端子の割り当てなど 図 2-5 QuartusⅡを使ったディジタル回路開発の流れ Windows でこれを使用するために、トランジスタ技術 2006 4 月号の付録 CD の QuartusⅡインス トールファイル quartusii_51_web_edition.exe を実行してインストールした。初回起動時に「使用には ライセンスファイルが必要である」というメッセージが表示されたので、ALTERA 社[2]のサイトにアク セス・ユーザ登録し、ライセンスファイルを取得して、QuartusⅡのメニューバーの Tools の License Setup を選択してライセンスファイルを導入した。 2.2.1.1 プロジェクトの作成 書き込む回路の情報を作るには、回路図・VHDL いずれの方法を使う場合も以下の手順に従ってプロ ジェクトを作成する。 1. QuartusII のメニューバーから「File」→「New Project Wizard」を選択する。 2. 使用法の説明が表示されるので、このまま「Next」ボタンを押す。 「Don’t show me this introduction again」にチェックを入れると、次回からこのウィンドウが表示されなくなる。 3. 一番上のテキストボックスに、プロジェクトを作成するフォルダのパスを、二番目のテキストボッ クスに作成するプロジェクト名を、三番目のテキストボックスにトップレベルデザインエンティテ ィ名(回路を階層的に設計する場合に最上位の階層に置くエンティティの名前)を入力し、「Next」 ボタンを押す。 7 図 2-6 プロジェクトの情報の入力 4. 既存の設計ファイルがある場合は「File name」の右のテキストボックスにその名前を入力して、 「Add」を押すと、プロジェクトに追加することができるが、何もせずに「Next」ボタンを押す。 5. 「Family」の右のコンボボックスで、使用する CPLD のファミリ(グループ)を、「Target device」 で自動認識するかデバイスを指定するかを選択し、 「Available devices」でデバイス名を指定する。 ここでは「MAXⅡ」、「Specific device selected in ‘Available device’ list」、 「EPM240T100C5」を 選択する。 8 図 2-7 CPLD の種類の選択 6. QuartusII 評価版以外の外部ツールを追加できるが、ここでは使用しないのでそのまま「Next」ボ タンを押す。 作成するプロジェクトの内容を確認する画面が表示されるので、内容に問題がなければ「Finish」ボタ ンを押す。 2.2.1.2 回路図エディタによる回路設計 回路図エディタで回路を設計する場合は以下の手順で行う。 1. QuartusII のメニューバーから「File」→「New」→「Block Diagram/Schematic」を選択する。 9 図 2-8 シンボル部品選択 2. Symbol Tool アイコンをクリックしてライブラリから回路素子をエディタに入力する。 図 2-9 部品配置 3. Orthogonal Node Tool アイコンをクリックして、シンボル間を配線で接続する。 10 図 2-10 接続 4. 作成した回路を部品として使いたい場合は「File」→「Create/Update」→「Create Symbol Files for Current File」で図 2-9 を部品化する。このことにより上で作成した回路と同等の動作をする 部品が使えるようになる。 図 2-11 部品化したエンティティ 5. 部品化したエンティティを使う場合は、Symbol Tool アイコンをクリックしてライブラリから入力 する。さらに入力信号、出力信号のシンボルをエディタに入力し、シンボル間を配線で接続する。 6. 回路図の入出力を CPLD の端子に関連付ける(図 2-11)。 11 図 2-12 CPLD に書き込まれる回路 7. 「Processing」→「Start Compilation」でコンパイルする。 8. 「Tools」→「programmer」→「start」で CPLD への書き込みを行う。 2.2.1.3 VHDL 言語による回路設計 次に VHDL で回路を記述して CPLD に書き込む方法は以下の手順に従う。なお、デフォルトでは QuartusⅡのテキストエディタの使用フォントは英数用のものになっているので「Tools」→「Options」 →「Text Editor」の中の「Fonts」欄を MS ゴシックにし、日本語の表示を可能にしておく。 1. 「File」→「New」→「VHDL File」でソースファイルを作成する。VHDL でもエディタを使った 場合と同様に複数のコンポーネント(部品)を組み合わせて全体の動作を定義することができる。 2. 「Assignments」→「Pins」で VHDL ファイルに記述された入出力と CPLD のピンを関連付ける。 3. 「Processing」→「Start Compilation」でコンパイルする。 4. 「Tools」→「programmer」→「start」で CPLD への書き込みを行う。 VHDL の基本的な構造文と書式 VHDL で回路を記述する際は、初めに演算や CPLD を使用するために読み込むヘッダファイルを指 定し、その回路の入出力の信号とその型を書き下す。最後に内部的な信号を定義し、イベント発生時に 実行する命令を書く(参考:VHDL によるハードウェア設計入門)。 12 パッケージの指定 演算や CPLD を使用するためのヘッダファイルを読み込む library ライブラリ名; use ライブラリ名, パッケージ名; エンティティの定義 入出力の信号名とその型を定義する entity エンティティ名 is port(ポート名 : モード型 データ型); end エンティティ名; アーキテクチャの記述 内部的な信号を定義する イベント発生時に実行する命令を書く 常に実行する命令を書く Architecture アーキテクチャ名 of エンティティ名 is (信号宣言文) begin (VHDL 本体) end アーキテクチャ名; 図 2-13 VHDL の基本構文 変数の種類 通常のプログラミング言語とは異なり、VHDL では変数に相当するものを実際の回路の信号と結びつ けて考える必要がある。このうち明確に信号として扱うものを signal、内部的に処理して見かけ上独立 した変数として扱うものを variable、一定の値をとるものを constant と呼ぶ。 変数の型 通常の言語と同様に変数は型を持つ。使用できる型には以下のものがある。 表 2-4 VHDL の変数型 型名 とることのできる値 std_logic 0, 1 std_logic_vector それぞれのビットについて 0, 1 boolean 論理値 true, false integer -214783647~214783647 の整数 13 natural 0~214783647 の整数 positive 1~214783647 の整数 real -1.0E-38 から +1.0E+38 の実数 character ASCII 文字 string 文字列 time 時間の物理タイプ fs, ps, ns, us, ms, sec, min, hr severity level メッセージタイプ NOTE, WARNING, ERROR, FAILURE すべての変数は種類と型を持ち、アーキテクチャの先頭で 変数の種類 変数名 : 変数の型 の書式で宣言することで使用可能になる。特に std_logic_vector では、変数の型の後に (開始ビット to 終了ビット)または(終了ビット downto 開始ビット) をつけて使用するビットを明確に宣言する。 型の変換 VHDL では厳密に型の一致が求められ、異なる型同士の演算や代入は出来ないので、代入を行うため には代入される側の型に変換してから行う必要がある。以下に主な型変換関数の書式を挙げる。 integer から std_logic_vector への変換 conv_std_logic_vector(元の変数、ビット幅) std_logic_vector から integer への変換 conv_integer(元の変数) 他の VHDL ファイルをコンポーネントとして使用する場合は、アーキテクチャを記述する際にコン ポーネントとして使用するファイルについて PORT の情報を ARCHITECTURE 文と BEGIN 文の間に 書く。 パッケージの指定 エンティティの定義 アーキテクチャの記述 コンポーネントのポートの記述 信号の定義 コンポーネントのポートとエンティティとの対応の記述 図 2-14 階層構造を持つ VHDL の構文 値を引数として受け取り処理をした後で何らかの値を返すファンクション文、値を返さないプロシー 14 ジャ文などのあらかじめ書き下した機能をまとめたものをパッケージという。パッケージ、ファンクシ ョンの構文は図 2-13, 2-14 の様になる。 パッケージの宣言 信号宣言, 定数宣言, データタイプなどを記述する。 packege パッケージ名 is (宣言文) end パッケージ名; パッケージ文の処理の記述 packege body パッケージ名 is (本体) end パッケージ名; 図 2-15 パッケージの構文 ファンクションの宣言 引数として受け取る信号名とそのデータ型、戻り値のデータ型を記述する function ファンクション名 ( (宣言文) return データ・タイプ名 is ファンクション文の処理の記述 function ファンクション名 ( (本文) return データ・タイプ名 is begin (順次処理文) return 返却データタイプ end; 図 2-16 ファンクションの構文 別ファイルに書かれたパッケージを使用する場合は、パッケージの指定の際に NEWLIB; USE NEWLIB.ファンクション名.all; という記述を追加する。 15 3. CPLD の動作テスト CPLD 基板の動作確認のために、手頃な基板を製作する必要があった。そこで入力の信号 2 つ、出力 の信号 14 個(7segLED2 つ分)を備えた回路・基板を設計・製作し 10 進カウンタ回路を書き込んで動作 を確認した。回路の設計では回路図を用いた方法と VHDL を用いた方法の 2 通り試し、いずれも正し く動作することが確認できた。 3.1 テスト用回路基板の制作 テスト基板の製作に使用した部品を表 3-1 に示す。 表 3-1 テスト基板の製作に使用した部品 部品 個数 ダブルヘッダピン(オス) 20 ピン×2、10 ピン×1、8 ピン×1 DIP スイッチ 1 押しボタンスイッチ 2 電解コンデンサ (47μF) 1 セラミックコンデンサ(0.1μF) 2 7 セグメントLED 2 LED 1 抵抗(330Ω) 21 コード 2 メタルスペーサ 4 ナット 4 押しボタンスイッチは信号入力用、7segLED は出力表示用であり、抵抗は LED に大電流が流れない ようにするためのものである。DIP スイッチは電源の ON・OFF 用、LED はその確認のため使用した。 コードは電源入力用の 2 ピンコネクタの代用である。コンデンサは信号の変化の際に生じるノイズを打 ち消すもの (パスコン)である。メタルスペーサとナットはハンダの劣化やショートを防ぐために使用し た。 3.1.1 EAGLE による回路の設計 EAGLE(Easily Applicable Graphical Layout Editor)は回路設計と基板設計を統合して扱うことので きる回路 CAD である。使用する素子をライブラリ(回路図上のピン数と個々のピン名、入出力の情報を もつ Symbol(図 3-4,3-5)を組み合わせた Device の集合)から入力し、論理的配線を行った後、基板フ ァイルで物理的配線を行うことで回路基板の情報を設計することができる。 ここで作成した基板ファイルは、CAM ツールを使ってさまざまな形式のファイルに変換し、基板加 工機のコントロールアプリケーションで使用できる。 3.1.1.1 ライブラリへの部品登録 今回作成する基板で用いる部品のうち、CPLD と 7segLED がライブラリに無かったため、新規にこ 16 れらの Package と Symbol、Device を作成し、Device 上で Package の Pad(端子)と Symbol の Pin の 関連付けを行った。 CPLD CPLD 基板は CN1~CN5 の 5 つの入出力コネクタを持つ。このうち PC との通信に用いられる CN4 は通信用のコネクタであり、回路基板とは接続されないため省略した。 図 3-1 CPLD の Package(51×71mm) 17 図 3-2 CPLD の CN1 の Symbol 図 3-3 CPLD の CN2 の Symbol 図 3-4 CPLD の CN3 の Symbol 図 3-5 CPLD の CN5 の Symbol 18 表 3-2~3-5 に Pad(package)と Pin(Symbol)の端子の対応を示す。 表 3-2 CN1 の pin 対応 表 3-3 CN2 の pin 対応 Pad Pin Pad Pin Pad Pin Pad Pin 1 GND_1 21 USERIO83 1 VCCIO_1 21 GND_1 2 GND_2 22 USERIO84 2 VCCIO_2 22 GND_2 3 USERIO02 23 USERIO81 3 USERIO19 23 USERIO43 4 USERIO01 24 USERIO82 4 USERIO20 24 USERIO44 5 USERIO100 25 USERIO77 5 USERIO21 25 USERIO47 6 USERIO99 26 USERIO78 6 USERIO26 26 USERIO48 7 USERIO98 27 USERIO75 7 USERIO27 27 USERIO49 8 USERIO97 28 USERIO76 8 USERIO28 28 USERIO50 9 USERIO96 29 USERIO73 9 USERIO29 29 USERIO51 10 USERIO95 30 USERIO74 10 USERIO30 30 USERIO52 11 USERIO92 31 USERIO71 11 USERIO33 31 USERIO53 12 USERIO91 32 USERIO72 12 USERIO34 32 USERIO54 13 USERIO90 33 USERIO69 13 USERIO35 33 USERIO55 14 USERIO89 34 USERIO70 14 USERIO36 34 USERIO56 15 USERIO88 35 USERIO67 15 USERIO37 35 USERIO57 16 USERIO87 36 USERIO68 16 USERIO38 36 USERIO58 17 USERIO86 37 GCLK3 17 USERIO39 37 USERIO61 18 USERIO85 38 USERIO66 18 USERIO40 38 GCLK2 19 GND_3 39 VCCIO2_1 19 USERIO41 39 GND_3 20 GND_4 40 VCCIO2_2 20 USERIO42 40 GND_4 19 表 3-4 CN3 の pin 対応 表 3-5 CN5 の pin 対応 Pad Pin Pad Pin 1 3.3VCC 1 5V_1 2 VCCINT 2 3.3V_1 3 USERIO04 3 5V_2 4 USERIO03 4 3.3V_2 5 USERIO06 5 DC_1 6 USERIO05 6 DC_2 7 USERIO08 7 DC_3 8 USERIO07 8 DC_4 9 GND_1 10 GND_2 11 GCLK1 12 GCLK2 13 GND_3 14 GND_4 15 USERIO16 16 USERIO15 17 USERIO18 18 USERIO17 19 GND_5 20 GND_6 20 7segLED EAGLE の既存のライブラリにも 7segLED はあったが、ここで使用した GL9R04 の形状のものはな かったため新規に作成した。表 3-6 に Pad(package)と Pin(Symbol)の端子の対応を示す。 図 3-6 7segLED の Symbol 図 3-7 7segLED の Package(17×13mm) 表 3-6 7segLED の pin 対応 Pad Pin 1 A 2 F 3 VCC_2 4 E 5 D 6 DP 7 C 8 G 9 B 10 VCC_1 3.1.1.2 回路図設計 7segLED への出力には CPLD の USERIO81、83~88、91、92、96~100 にあたる CN1 の 5~9、 11、12、15~18、21~23 を接続し、ボタンからの入力には USERIO2、89 にあたる、CN1 の 3、14 を接続した。基板への入力電圧は 5V であるが、CPLD 基板に搭載した三端子レギュレータで降圧され た 3.3V の電源が CPLD の駆動電圧となる。 21 図 3-8 回路設計 22 3.1.1.3 基板設計 水色の部分が配線を表す。今回は片面基板として設計したため、すべての配線はハンダ面を通る。GND、 VCC(5V)、VDD(3.3V)の電源系は多くの部品に入るため、他の信号よりも配線を先に行った。基板の 4 隅の穴は基板固定穴と呼ばれ、スペーサとナットで基板を固定するのに使用される。このことによって ハンダ面と床の接触によるショートやハンダの劣化を防ぐことができる。 図 3-9 基板設計(98×78mm) 3.1.2 基板加工機による基板加工 基板加工機 RS21 とそのコントロール用アプリケーション FLASH Win を使用してテスト基板を作成 した。設計した基板データを元に EAGLE の CAM 機能で GERBER 形式のデータ drill(ドリルデータ: 穴の大きさや位置をまとめたファイル), photo(配線データ:配線部分の座標データをまとめたファイル), frame(基板外形データ:基板外形の端点の座標をまとめたファイル)を作成した。 テスト基板の材料は合成樹脂板の片面に銅箔が貼り付けられたものである。初めに drill のデータを 元に基板の厚さより長いドリルで基板を貫通する穴をあけた(A)。次に、銅箔の必要な部分のみを残して 配線とするため、FLASH Win の輪郭抽出の機能を用いて photo から輪郭データを作成し、そのデータ を元に銅箔をミリングカッタと呼ばれる先端が円錐状のドリルで削り取った(B)。最後に frame のデー タを元にフォーミングカッタと呼ばれる、先端が円柱状のドリルで基板を切り離した。 23 銅箔 合成樹脂板 ドリル (A) ミリングカッタ フォーミングカッタ (B) 図 3-10 基板加工機での基板加工過程 図 3-11 ドリルの種類 図 3-12 ドリルデータ 図 3-13 配線データ 図 3-14 輪郭データ 図 3-15 基板外形データ 24 3.1.3 ハンダ付け 出来上がった基板に抵抗など背の低いものから順にハンダ付けした。セラミックコンデンサなどの背 の高いものを先にハンダ付けしてしまうと、他の部品のハンダ付けが困難になってしまうからである。 図 3-16 テスト基板(部品面) 図 3-17 テスト基板(ハンダ面) LED1 LED2 ボタン 1 ボタン 2 電源用 スイッチ 確認用 LED 図 3-18 テスト基板の入出力素子 電源用スイッチとして 4 素子の DIP スイッチを使用したが、実際の電源の ON・OFF 用には一番右 の素子を使用した。確認用 LED は電源を ON にしたときに点灯する。LED1, 2 に使用した GL9R04 は アノードコモンなので、それぞれのセグメントに対応するピンに GND を入力すると点灯する。 25 3.2 回路図エディタによる並列 10 進カウンタ回路の作成 3.2.1.1 仕様 電源投入時の状態は 7seg LED1, 2 ともに 0 でボタン 1, 2 を押すごとに 7segLED1, 2 の数字が 1 ずつ 増えていき、9 になったとき 0 に戻るという動作をさせる。 3.2.1.2 実装 10 進カウンタの動作をさせるため、IC74160(4 ビット同期式カウンタ)、IC7447(7segDecoder)、 input(入力)、output(出力)、VCC のシンボルを回路図エディタに配置し、Orthogonal Node Tool アイ コンをクリックして、シンボル間を配線で接続する。10 進カウンタの LDN、A、B、C、D、ENT、ENP、 CLRN を VCC に、CLK を入力に接続する。これで CLK の立ち上がりで 2 進数 QDQCQBQA の値が 1 増加する様になる。1 組のボタンと LED に対しての動作をこれで実現できる。 図 3-19 1 組分の 10 進カウンタ回路 ここではこれをひとつの部品として使用するので、図 3-19 を部品化する。このことにより BUTTON という 1 つの入力と LEDA~G という 7 つの出力を持ち、図 3-19 の回路と同等の動作をする部品が 使えるようになる。 ライブラリから部品化した ButtonCount エンティティ、input(入力)、output(出力)のシンボルをエ ディタに入力し、シンボル間を配線で接続し、回路図の input, output を CPLD の端子に関連付ける(図 3-20)。これをコンパイルし、CPLD への書き込みを行う。 26 図 3-20 CPLD に書き込まれる回路 27 3.2.2 動作結果 仕様で述べた通りの動作をした。 コンパイル時のメッセージから確認した、この回路の使用ロジックエレメント数は 22 個であった。 ボタン 2 を押すたびに LED2 に表示 される値が 1 増える。 9 を超えると LED2 の値が 0 に戻る。 ボタン 1 を押すたびに LED1 に表示 される値が 1 増える。 9 を超えると LED1 の値が 0 に戻る。 図 3-21 テスト基板の動作例 28 3.3 VHDL 言語による並列 10 進カウンタ回路の作成 3.3.1 仕様 動作については回路図で設計した場合と同様である。VHDL ではそれぞれの入出力の信号名に名前を つけるが、ここではそれぞれのセグメントに対応する出力に図 3-22 のような名前をつける。 LED_G LED_A LED_B LED_F LED_E LED_C LED_D 図 3-22 LED のセグメント 29 3.3.2 プロジェクトの構成 回路図を使った設計で用いた方法に倣い、こちらでも階層構造を使って回路を設計する。すなわち、 10 進カウンタの働きをする BCDCounter、7seg デコーダの働きをする Decode7segment を作成し、両 者をエンティティとして 1 つずつ含む、1 入力 7 出力を持つ ButtonCount を作成する。最後にエンテ ィティとして 2 つの ButtonCount を含む ButtonCount_top を作成し、その入出力を CPLD のピンに 対応させる。 ButtonCount_top ButtonCount ボタン 1 から BCDCounter Decode7segment USERIO02 USERIO92 USERIO91 USERIO96 USERIO99 LED1 へ USERIO100 USERIO97 USERIO98 ButtonCount ボタン 2 から BCDCounter Decode7segment USERIO89 USERIO84 USERIO81 USERIO83 USERIO86 USERIO87 USERIO85 USERIO88 図 3-23 階層構造を使った設計 30 LED2 へ 3.3.2.1 BCDCounter.vhd 1 つの入力信号 BUTTON を受け取り、電源投入後の BUTTON の立ち上がりの回数の下 1 桁の数値 を 2 進数に変換したものに対応する信号を出力する。 LIBRARY IEEE; パッケージの指定 USE IEEE.std_logic_1164.ALL; 使用する CPLD 独自のヘッダの読み込み USE IEEE.std_logic_unsigned.ALL; logic 変数を扱うためのヘッダの読み込み USE IEEE.std_logic_arith.ALL; 算術演算のためのヘッダの読み込み ENTITY BCDCounter IS エンティティの定義 std_logic 型の入力 CLK を受け取り、 QA, QB, QC, PORT( CLK : in std_logic; QD を出力する QA : out std_logic; QB : out std_logic; QC : out std_logic; QD : out std_logic ); END BCDCounter; アーキテクチャ ARCHITECTURE rtl of BCDCounter IS signal counter : std_logic_vector(3 downto 0); 4bit の std_logic_vector 型の内 部変数 counter の定義 BEGIN PROCESS(CLK) 入力 CLK の立ち上がりのイベ BEGIN ント発生時に実行する命令 if(CLK'event and CLK='1') then if( counter = 9 ) then counter <=CONV_STD_LOGIC_VECTOR(0,4); counter が 9 なら counter を 0 に、そうでないときは counter else を 1 増加させる counter <= counter + 1; end if; end if; END PROCESS; QA <= counter(0); 出 力 QA, QB, QC, QD に QB <= counter(1); counter のそれぞれのビットの QC <= counter(2); 値を書き込む QD <= counter(3); end rtl; 31 3.3.2.2 Decode7segment.vhd 4 つの入力信号 A~D を受け取り、2 進数 DCBA を 10 進数に変換した数値の形に 7segLED を点灯さ せるための 7 つの信号 LEDA~G を出力する。2 進数 DCBA の値が 9 以下ならそれを 10 進数に変換し た数値を、10~15 なら空白を表示するための信号を出力する。 LIBRARY IEEE; パッケージの指定 USE IEEE.std_logic_1164.ALL; 使用する CPLD 独自のヘッダの読み込み USE IEEE.std_logic_unsigned.ALL; logic 変数を扱うためのヘッダの読み込み ENTITY Decode7Segment IS エンティティの定義 PORT( A, B, C, D : in std_logic; std_logic 型の入力 A, B, C, D を受け取り、 LED_A~LED_G を出力する LED_A : out std_logic; LED_B : out std_logic; LED_C : out std_logic; LED_D : out std_logic; LED_E : out std_logic; LED_F : out std_logic; LED_G : out std_logic ); END Decode7Segment; アーキテクチャ ARCHITECTURE rtl of Decode7Segment IS signal number : std_logic_vector(3 downto 0); 4bit の std_logic_vector 型の内部変 数 number の定義 BEGIN number(0) <= A; 出力 number に D, C, B, A の値を書 number(1) <= B; き込む。 number(2) <= C; number(3) <= D; 32 LED_A <= '0' when number = 0 else number の値によって LED_A の点 '1' when number = 1 else 灯・消灯を切り替える。 '0' when number = 2 else LED を点灯させる時は'0'を、消灯さ '0' when number = 3 else せる時は’1’を出力する。 '1' when number = 4 else '0' when number = 5 else LED_B~G も A と同様に記述する。 '1' when number = 6 else '0' when number = 7 else number の値が 10 から 15 の時はす '0' when number = 8 else べての LED を消灯させるため’1’を '0' when number = 9 else 出力する。 '1'; ... end rtl; 3.3.2.3 ButtonCount.vhd 1 つの入力信号 BUTTON を受け取り、電源投入後の BUTTON の立ち上がりの回数の下 1 桁の数値 の形に 7segLED を点灯させるための 7 つの信号を BC_LEDA~G に出力する。 このファイルは既出の 2 つとは異なり、他の VHDL ファイルをコンポーネントとして使用する。 ButtonCount BCDCounter Decode7segment counter1 図 3-24 decoder1 ButtonCount の階層構造 33 LIBRARY IEEE; パッケージの指定 USE IEEE.std_logic_1164.ALL; 使用する CPLD 独自のヘッダの読み込み USE IEEE.std_logic_unsigned.ALL; logic 変数を扱うためのヘッダの読み込み ENTITY ButtonCount IS エンティティの定義 std_logic 型の入力 BUTTON を受け取り、 PORT( BUTTON : in std_logic; BC_LED_A : out std_logic; BC_LED_B : out std_logic; BC_LED_C : out std_logic; BC_LED_D : out std_logic; BC_LED_E : out std_logic; BC_LED_F : out std_logic; BC_LED_G : out std_logic LED_A~LED_G を出力する ); END ButtonCount; 34 ARCHITECTURE rtl of ButtonCount IS COMPONENT BCDCounter コンポーネントの入出力の情報 PORT( CLK : in std_logic; QA : out std_logic; QB : out std_logic; QC : out std_logic; QD : out std_logic ); END COMPONENT; COMPONENT Decode7Segment PORT( A, B, C, D : in std_logic; LED_A : out std_logic; LED_B : out std_logic; LED_C : out std_logic; LED_D : out std_logic; LED_E : out std_logic; LED_F : out std_logic; LED_G : out std_logic ); END COMPONENT; signal BC_A : std_logic; コンポーネント間を接続する為の信号の signal BC_B : std_logic; 宣言 signal BC_C : std_logic; signal BC_D : std_logic; BEGIN BCDCounter のエンティティ counter1 : BCDCounter port map( CLK => BUTTON, counter1 の入出力に ButtonCount の入出 QA => BC_A, 力を接続する。 QB => BC_B, QC => BC_C, QD => BC_D ); 35 decoder1 : Decode7Segment port map( A => BC_A, Decode7segment のエンティティ decoder1 の入出力に ButtonCount の入出力 B => BC_B, を接続する。 C => BC_C, D => BC_D, LED_A => BC_LED_A, LED_B => BC_LED_B, LED_C => BC_LED_C, LED_D => BC_LED_D, LED_E => BC_LED_E, LED_F => BC_LED_F, LED_G => BC_LED_G ); END rtl; 3.3.2.4 ButtonCount_top.vhd 2 つの入力信号 BUTTON1, 2 を受け取り、2 つの 7segLED を点灯させるための信号 LED1A~G、 LED2A~G を出力する。 LED1A~G は電源投入後の BUTTON1 の立ち上がりの回数の下 1 桁の数値の形に 7segLED を点灯 させるように変化し、LED2A~G は BUTTON2 について同様に変化する。これら 2 つの組み合わせは 互いに独立に動作する。 ButtonCount_top ButtonCount bc1 ButtonCount bc1 図 3-25 ButtonCount_top の階層構造 36 LIBRARY IEEE; パッケージの指定 USE IEEE.std_logic_1164.ALL; 使用する CPLD 独自のヘッダの読み込み USE IEEE.std_logic_unsigned.ALL; logic 変数を扱うためのヘッダの読み込み ENTITY ButtonCount_top IS エンティティの定義 std_logic 型の入力 BUTTON1, 2 を受け取り、 PORT( BUTTON1 : in std_logic; LED1_A~LED1_G、LED2_A~LED2_G を出 LED1_A : out std_logic; 力する ... LED1_G : out std_logic; BUTTON2 : in std_logic; LED2_A : out std_logic; ... LED2_G : out std_logic ); END ButtonCount_top; ARCHITECTURE rtl of ButtonCount_top IS コンポーネント ButtonCount の入出力の COMPONENT ButtonCount 情報 PORT( BUTTON : in std_logic; LED_A : out std_logic; LED_B : out std_logic; LED_C : out std_logic; LED_D : out std_logic; LED_E : out std_logic; LED_F : out std_logic; LED_G : out std_logic ); END COMPONENT; 37 BEGIN ButtonCount エンティティ bc1 : ButtonCount port map( BUTTON => BUTTON1, bc1 の入出力に ButtonCount_top の入出 LED_A => LED1_A, 力を接続する。 LED_B => LED1_B, LED_C => LED1_C, LED_D => LED1_D, LED_E => LED1_E, LED_F => LED1_F, LED_G => LED1_G ); bc2 の入出力に ButtonCount_top の入出 bc2 : ButtonCount port map( 力を接続する。 BUTTON => BUTTON2, LED_A => LED2_A, LED_B => LED2_B, LED_C => LED2_C, LED_D => LED2_D, LED_E => LED2_E, LED_F => LED2_F, LED_G => LED2_G ); END rtl; 3.3.3 動作結果 このプログラムを基板に書き込み動作を確認すると、電源投入時の状態は 7seg LED1, 2 ともに 0 で ボタン 1, 2 を押すごとに 7segLED1, 2 の数字が 1 ずつ増えていき 9 になったとき 0 に戻るという動作 をする。 この回路でも 22 個のロジックエレメントを使用したことがわかった。回路図で設計したときと使用 ロジックエレメント数は同じだが、 これは回路図で設計したときに IC74160 に含まれている ENT, ENP, CLRN, RCO などの使用されていない機能がコンパイル時に再現されていないためだと思われる。 38 4. ミニゲームの作成 次に CPLD EPM240T100C の 76 の入出力をフルに活用するため、入力用に 5 つのボタン, 出力用に 10 個の 7segLED を搭載した基板を製作することにした。以降は図 4-1 の拡張情報表示部の 7segLED を「LED0」、メイン表示部のものを左上から右向きに「LED1」~「LED9」と呼ぶ。また、5 つのボ タンのうち中央のものを「ボタン C」、上下左右にあるものをそれぞれボタン U, D, L, R と呼ぶ。 ボタン 拡張情報表示部 メイン表示部 図 4-1 入出力インターフェイスの仕様 図 4-1 の入出力を使ってできるものを検討した結果、メイン表示部を使った 8 パズルと三目並べが 候補に上がり、入力と出力の仕様と動作の具体的な手段について検討した結果、実装の見通しがついた のでこれらを製作することにした。 今回設計する回路全体で、(a)入力スイッチとその周辺素子(押しボタンスイッチ、抵抗 330Ω×2、セ ラミックコンデンサ)が 5 セット、(b)出力用 LED とその周辺素子(7segLED、抵抗 330Ω×7)が 10 セッ ト、(c)電源系(トグルスイッチ、LED、抵抗 330Ω、セラミックコンデンサ)が 1 セット必要である。し かし、フリーウェア版の EAGLE で設計できる基板の最大サイズは 100×80mm であり、その中にすべ ての素子を搭載することはできないので、CPLD 用基板と表示・入力用の基板の 2 つに分けて設計し、 予備を含めた 76 個の信号と、電源の種類をフラットケーブルで接続する方法にした。そのため(a)の入 力用スイッチに関わる構成部品すべてと (b)の 7segLED を表示・入力用の基板に搭載し、残りを CPLD 用基板に実装することにした。 39 図 4-2 フラットケーブルによる 2 枚の基板の接続 4.1 CPLD 基板の製作 この基板には、主に CPLD 基板との入出力、電源入力とその ON・OFF の機能を持たせる。また、 CPLD の信号と電源を 40 ピンケーブルを通じて表示・入出力用基板に渡す。 表示・入力用の基板とつながる 2 つの 40 ピンコネクタには、7segLED への出力のために 70 個、ボ タンからの入力のために 5 個の USREIO を接続した。7segLED に流れる電流を抑えるための抵抗はこ の基板に搭載した。出力である USREIO07 は今回使用していないが、表示・入出力用基板に仕様変更 があった場合を考慮して、抵抗を経由して CN3-8 に接続した。表示・入力用基板上の 7segLED は 5V、 スイッチは 3.3V の電圧を必要とするため、40 ピンコネクタの 1 箇所ずつに 0V、5V を、2 箇所に 3.3V を接続した。 表 4-1 CPLD 用基板に使用した部品 ダブルヘッダピン(オス) 20 ピン×2、10 ピン×1、8 ピン×1 ダブルヘッダピン(メス) 20 ピン×2 LED 1 セラミックコンデンサ(0.1μF) 1 抵抗(330Ω) 72 トグルスイッチ 1 2 ピンコネクタ 1 メタルスペーサ 4 ナット 4 4.1.1 EAGLE による回路の設計 4.1.1.1 ライブラリへの部品登録 40 ピンコネクタ CPLD 用基板と表示・入力用基板の接続に 40 ピンのケーブルを使用するため、40 ピンコネクタを作 成した。40 ピンコネクタの 40 個の端子は、回路図上ではどれも等価であるため、Symbol を 1 つだけ 作成して、Device 設計時にそれを 40 個入れて Package の Pad に対応させた。 図 4-3 40 ピンコネクタの Symbol 図 4-4 40 ピンコネクタの Package(6×51mm) 40 4.1.1.2 回路図設計 図 4-5 回路設計 41 4.1.1.3 基板設計 GND や VCC が入る部品同士や、数が多い CPLD からの出力に当たる抵抗は配線のしやすさを考慮 しながら配置した。また、基板サイズの制限のため、抵抗を立てて実装することを前提として基板上の 部品を選択した。 図 4-6 基板設計(98×78mm) 42 4.1.2 基板加工機による基板加工 テスト基板の製作時と同様にして加工用のファイル drill, photo, frame を作成し基板加工機で片面基 板を加工した。 図 4-7 ドリルデータ 図 4-8 輪郭データ 4.1.3 ハンダ付け 抵抗と抵抗の幅が狭く、少しでもハンダを付けすぎてしまうと隣接する端子・配線がショートしてし まうため、ショートがないことをテスターで確認しながら、ハンダ付けを行った。 図 4-9 CPLD 基板(部品面) 4.2 図 4-10 CPLD 基板(ハンダ面) 表示・入力用基板の製作 この基板にはミニゲームをする際に必要となる 10 個の LED, 5 個のボタンとその周辺素子を搭載する。 入出力の信号は 40 ピンケーブルを通じて CPLD 用基板とやりとりする。 7segLED の各セグメントに対して必要となる抵抗は CPLD 用基板側に置いたので、7segLED と 40 ピンコネクタは直接接続する。押しボタンスイッチの端子一つを VDD(3.3V)に接続し、押したときにそ の電位を信号として CPLD 基板に渡す。 43 表 4-2 表示・入出力用基板に使用した部品 部品 個数 ダブルヘッダピン(メス) 20 ピン×2 押しボタンスイッチ 5 7 セグメント LED 10 セラミックコンデンサ 5 抵抗(330Ω) 10 メタルスペーサ(25mm) 4 ナット 4 4.2.1 EAGLE による回路の設計 4.2.1.1 回路図設計 図 4-11 回路設計 44 4.2.1.2 基板設計 素子が多く、配線が複雑になるため、部品面とハンダ面の両側を使って配線を行った。両面で配線を 行う場合、部品面とハンダ面の配線数が同程度になるようにするのが普通であるが、後述するスルーホ ールの加工が人手を要すること、素子の近くの部品面のハンダ付けが難しいことから、可能な限りハン ダ面で配線を行い、残りを部品面で配線した。図 4-12 の茶色が部品面、水色がハンダ面の配線である。 図 4-12 基板設計(98×78mm) 4.2.2 基板加工機による基板加工 こ の基 板には 部品 面にも 配線 データ があ るため 、加 工デー タと して drill, photo0(ハ ンダ面 ), photo1(部品面), frame を作成した。輪郭加工のための輪郭データは photo0, photo1 からそれぞれ抽出 した。 45 図 4-13 輪郭データ(部品面) 図 4-14 輪郭データ(ハンダ面) 加工はドリルによる穿孔、部品面の輪郭加工、基板を裏返す、ハンダ面の輪郭加工、基板外形加工の 順で行ったが、基板を裏返す際に起こる角度や位置のずれを補正するため、ドリル加工の前に基板の対 角線上に基準穴を開け、裏返した後にそれらを使い位置合わせを行った。この作業により、以降の加工 で FLASH Win が自動的に位置・角度のずれを補正して加工を行う。 基準穴 部品面の輪郭加工 ハンダ面の輪郭加工 図 4-15 位置・角度の補正 46 4.2.3 ハンダ付け この基板を作るために使用した両面基板は、絶縁体である紙フェノールの表と裏の両側に銅箔が貼り 付けられたものである。ここで設計した両面基板には基板の両面にまたがる配線があるが、基板の部品 面とハンダ面の間は紙フェノールで絶縁されているので、そのままではこのような配線はスルーホール で途切れることになる。そこでスルーホールに抵抗の足を切ったものを通して図 4-17 のように両面に ハンダ付けをした。 その際、7segLED を先にハンダ付けしてしまうとスルーホールのハンダ付けができなくなるため、 こちらを先にハンダ付けした。 ハンダ 抵抗の足 銅箔 紙フェノール 図 4-16 基板の両面にまたがる配線 図 4-17 スルーホールでのハンダ付け 図 4-18 表示・入力用基板(部品面) 4.3 図 4-19 表示・入力用基板(ハンダ面) VHDL 言語による 8 パズル回路の作成 8 パズルとは、3×3 のマスに 1~8 の数字の書かれた駒があり、1 つの空白を利用してそれらを動か して数字が順に並ぶ状態をつくることを目的としたパズルである。ここでは押しボタンと 7segLED を 47 入力・表示としたパズルができる回路を作成する。 4.3.1 仕様 メイン表示部で 8 パズルを行うために、LED1~9 に、数字の 1~8 と空白一つを表示する。 ボタン U, D, L, R で空白部分がその方向に移動し、その位置にあった数字が空白であった部分に移る ものとする。ボタン C はリセット用で、これを押すと LED1~8 に数字の 1~8 が、LED9 に空白が表 示される状態(完成状態)に戻る。LED1~9 の数字がこの状態になったときのみ LED0 には完成を意味 する 0 を表示し、そうでない場合は未完成を意味する-を表示する。 メイン表示部に空白と 1~8 の数字を表示させるため、それぞれの LED に対応する 4 ビットの std_logic_vector 型の変数 n1~n9 を定義する。また、LED0 には完成か否かの状態を表示させるため に 2 通りの状態が必要になるので、 これに対応する 4 ビットの std_logic_vector 型の変数 n0 を定義し、 0 か 11 を入れることで表示をコントロールする。 表 4-3 8 パズルの LED 表示 変数の値 用途 表示 0~9 数字の表示 ~ 10 空白の表示 11 未完成を意味する記号 12~15 未使用 空白部分の移動にはボタン U, D, L, R を用いるが、状態のチェックは CLK の立ち上がりで行う。 ボタンが押されている状態が検出されるたびに空白の移動をするという仕様にすると、クロックの立ち 上がりのたびにイベントが起こってしまう。そのため 1 つ前のクロックでのボタンの状態を変数に入れ て記憶しておき、ボタンが離された瞬間だけイベントが起こるようにした。状態を記憶するための変数 はボタン一つあたり 0 か 1 の値を格納しなければならないため、5 ビットの std_logic_vector 型とした。 48 表 4-4 入出力と変数の型 名前 型 意味 btn0~btn4 std_logic ボタンの状態 CLK std_logic クロック 出力 LEDA~G std_logic_vector(3 downto 0); LED 表示用出力 変数 status std_logic_vector(4 downto 0); 一つ前のクロックでのボタンの状態(0~4 番 入力 目のビットが btn0~btn4 に対応する) 空白と上下左右のいずれかを交換したとき、LED0 が完成の状態か否かの判定をさせるために変数 n1 ~n9 を受け取り、それらが 1~8, 10 であれば 0 を返し、そうでなければ 11 を返すファンクションを作 成した。 4.3.2 プロジェクトの構成 クロックとボタンからの入力を受け取り、ゲーム全体をコントロールする EightPuzzule、7seg デコ ーダの働きをする Decode7segment を作成し、前者を 1 つ, 後者を 10 個エンティティとして含む 6 入 力 70 出力を持つ Controller を作成し、その入出力を CPLD のピンに対応させた。 Controller ボタン Decode7segment EightPuzzle USERIO03 USERIO02 USERIO04 USERIO100 USERIO05 decoder0 USERIO06 USERIO08 USERIO98 USERIO96 LED0 へ USERIO97 USERIO01 puzzle USERIO99 ・ ・ ・ ・ ・ ・ Decode7segment USERIO51 USERIO53 decoder9 USERIO56 USERIO61 USERIO54 クロック USERIO52 USERIO62 USERIO55 図 4-20 階層構造を使った設計 49 LED9 へ 4.3.2.1 8puzzle.vhd 入力信号 btn0~4, CLK を受け取り、10 個の 4 桁の std_logic_vector 型の内部変数 n0~n9 を入力に 応じて変化させ、40 個の信号 QA0~QD9 を出力する。 ここで QDkQCkQBkQAk は nk(k は 0~9)を 2 進数に変換したものに対応する。また、btn0~4 の状 態のチェックは CLK の立ち上がりのタイミングでのみ行う。 LIBRARY IEEE, NEWLIB; パッケージの指定 USE IEEE.std_logic_1164.ALL; 使用する CPLD 独自のヘッダの読み込み USE IEEE.std_logic_unsigned.ALL; logic 変数を扱うためのヘッダの読み込み USE IEEE.std_logic_arith.ALL; 算術演算のためのヘッダの読み込み USE NEWLIB.Check.all; NEWLIB の読み込み エンティティの定義 ENTITY EightPuzzle IS std_logic 型 の 入 力 CLK, PORT( CLK, btn0,btn1, btn2, btn3, btn4 : in std_logic; btn0 ~ btn4 を 受 け 取 り 、 QA0~QD9 を出力する QA0, QB0, QC0, QD0 : out std_logic; ... QA9, QB9, QC9, QD9 : out std_logic ); END EightPuzzle; アーキテクチャ ARCHITECTURE rtl of EightPuzzle IS signal n0 : std_logic_vector(3 downto 0); 4bit の std_logic_vector 型 の内部変数 n0~n9 と 5bit ... signal n9 : std_logic_vector(3 downto 0); の std_logic_vector 型の内 signal status : std_logic_vector(4 downto 0); 部変数 status の定義 BEGIN PROCESS(CLK, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9) variable v :integer ; 空白の位置を表す変数 BEGIN if rising_edge(CLK) then if(n1=10)then v:=1; 空白の位置を v に格納す elsif(n2=10)then る。 v:=2; ・・・ else v:=9; end if; 50 if(btn4 = '1' and status(4) = '0') then status(4) <= '1'; elsif (btn4 = '0' and status(4) = '1')then status(4) <= '0'; ボタン D を離し たときの動作 v の値が 1~6 の if (v = 1) then いずれかである n1 <= n4; n4 <= CONV_STD_LOGIC_VECTOR(10, 4); end if; 場合は、その位置 の変数と一つ下 の位置の変数の ... 値を交換する。 end if; ... ボタン U, L, R に ついても同様の 処理をする。 ... if(btn0 = '1' and status(0) = '0') then status(0) <= '1'; elsif (btn0 = '0' and status(0) = '1')then status(0) <= '0'; n1 <= CONV_STD_LOGIC_VECTOR(1, 4); ボタン C を離し たときの動作 n1~n8 に 1~8, n2 <= CONV_STD_LOGIC_VECTOR(2, 4); n9 に 10 の値を n3 <= CONV_STD_LOGIC_VECTOR(3, 4); 入れる。 n4 <= CONV_STD_LOGIC_VECTOR(4, 4); n5 <= CONV_STD_LOGIC_VECTOR(5, 4); n6 <= CONV_STD_LOGIC_VECTOR(6, 4); n7 <= CONV_STD_LOGIC_VECTOR(7, 4); n8 <= CONV_STD_LOGIC_VECTOR(8, 4); n9 <= CONV_STD_LOGIC_VECTOR(10, 4); end if; n0 <= check_done(n1, n2, n3, n4, n5, n6, n7, n8, n9); end if; ファンクション 文 check_down の呼び出し END PROCESS; QA0 <= n0(0); QB0 <= n0(1); QC0 <= n0(2); QD0 <= n0(3); ... QA9 <= n9(0); QB9 <= n9(1); QC9 <= n9(2); end rtl; QD9 <= n9(3); 出力 QA0~QD9 に n0~n9 のそ れぞれを接続す る。 51 4.3.2.2 Decode7segment.vhd 4 つの入力信号 A~D を受け取り、2 進数 DCBA を 10 進数に変換した数値の形に 7segLED を点灯さ せるための 7 つの信号 LEDA~G を出力する。2 進数 DCBA の値が 9 以下ならそれを 10 進数に変換し た数値を、11 なら―を、10, 12~15 なら空白を表示するための信号を出力する。 4.3.2.3 Controller.vhd 入力信号 BUTTON0~4, CLOCK を受け取り、10 個の LED に数値や記号を表示させるための信号 LED0A~9G を出力する。 LIBRARY IEEE; パッケージの指定 USE IEEE.std_logic_1164.ALL; 使用する CPLD 独自のヘッダの読み込み USE IEEE.std_logic_unsigned.ALL; logic 変数を扱うためのヘッダの読み込み ENTITY Controller IS エンティティの定義 std_logic PORT( 型 の 入 力 CLOCK, BUTTON0 ~ CLOCK : in std_logic; BUTTON4 を受け取り、LED_A0~LED_G9 を出力 BUTTON0 : in std_logic; する ... BUTTON4 : in std_logic; LED_A0 : out std_logic; LED_B0 : out std_logic; LED_C0 : out std_logic; LED_D0 : out std_logic; LED_E0 : out std_logic; LED_F0 : out std_logic; LED_G0 : out std_logic; ... LED_G9 : out std_logic ); END Controller; 52 ARCHITECTURE rtl of Controller IS コンポーネント EightPuzzle の入出力 COMPONENT EightPuzzle の情報 PORT( CLK : in std_logic; btn0 : in std_logic; ... btn4 : in std_logic; QA0, QB0, QC0, QD0 : out std_logic; ... QA9, QB9, QC9, QD9 : out std_logic ); END COMPONENT; コンポーネント Decode7segment の COMPONENT Decode7Segment 入出力の情報 PORT( A, B, C, D : in std_logic; LED_A : out std_logic; ... LED_G : out std_logic ); END COMPONENT; コンポーネント間を接続する為の信 signal A0, B0, C0, D0 : std_logic; 号の宣言 ... signal A9, B9, C9, D9 : std_logic; BEGIN EightPuzzle のエンティティ puzzle : EightPuzzle port map( CLK => CLOCK, 出力 CLK, btn0~btn4, QA0~,QD9 btn0 => BUTTON0, に CLOCK, BUTTON , A0~D9 を接 続する。 ... btn4 => BUTTON4, QA0 => A0, QB0 => B0, QC0 => C0, QD0 => D0, ... 53 QA9 => A9, QB9 => B9, QC9 => C9, QD9 => D9 ); decoder0 : Decode7Segment port map( Decode7Segment のエンティティ A => A0, 出力 A~D, LED_A~LED_G に A0~ ... D0 を接続する。 D => D0, LED_A => LED_A0, ... LED_G => LED_G0 ); ... decoder9 : Decode7Segment port map( A => A9, ... D => D9, LED_A => LED_A9, ... LED_G => LED_G9 ); END rtl; 54 4.3.2.4 check.vhd 8puzzle から n1~n9 の値を受け取り、n1~n8 が 1~8, n9 が 10 なら 0 を std_logic_vector 型に変換 したものを、それ以外であれば 11 を変換したものを返す。 LIBRARY IEEE; パッケージの指定 USE IEEE.std_logic_1164.ALL; 使用する CPLD 独自のヘッダの読み込み USE IEEE.std_logic_unsigned.ALL; logic 変数を扱うためのヘッダの読み込み USE IEEE.std_logic_arith.ALL; 算術演算のためのヘッダの読み込み package Check is パッケージの宣言 function check_done( n1 : std_logic_vector; std_logic_vector 型の引数 n1~n9 を受け取る。 ... n9 : std_logic_vector ) return std_logic_vector; std_logic_vector 型の戻り値を返す。 end Check; package body Check is function check_done( n1 : std_logic_vector; ... n9 : std_logic_vector ) return std_logic_vector is begin if(n1 = 1 and n2 = 2 and n3 = 3 and n4 = 4 and n5 = 完成の判定 5 and n6 = 6 and n7 = 7 and n8 = 8 and n9 = 10)then n1~n8 に 1~8, n9 に 10 return CONV_STD_LOGIC_VECTOR(0, 4); があった場合は 0 を、そ れ以外は 11 を返す。 else return CONV_STD_LOGIC_VECTOR(11, 4); end if; end; end Check; 4.3.3 動作結果 これらを含んだプロジェクトをコンパイルして CPLD に書き込んだ。使用したロジックエレメントは 240 個であった。 ボタンによる U, D, L, R による空白部分の移動、ボタン C によるリセット、LED0 の完成・未完成状 態表示が確認できた。しかしかなり頻繁に誤動作がおこり、通常ではありえない数字の配置がおこるな どの問題が残った。 55 未完成状態なので拡張情報表示部 の LED0 に対応する変数 n0 の値は 11 である。 ボタン D を押すと n5 と n8 の値を交換する ボタン R を押すと n8 と n9 の値を交換する 完成したので n0 の値は 0 になる。 図 4-21 8 パズルの動作例 56 4.4 VHDL 言語による三目並べ回路の作成 三目並べとは、3×3 のマスに○と×の記号を交代で置いていき、自分の記号を縦, 横, 斜めのいずれ かに先に 3 つ揃えることを目的としたゲームである。ここでは押しボタンと 7segLED を入力・表示と したゲームができる回路を作成する。 4.4.1 仕様 メイン表示部で三目並べを行うためには、LED1~9 で○, ×, 空白と、カーソルの有無を識別できる ようにしなければならない。そこで、表 4-5 の様に 6 通りの状態を作る。また、拡張情報表示部には 現在○×どちらのターンであるかを識別するために現在のプレイヤーのターンの記号を表示する。 ボタン U, D, L, R を用いてカーソルを移動し、ボタン C を押したときにカーソルがある位置に○か×の 記号がまだ入力されていなければ、現在のターンのプレイヤーの記号を入力する。ボタン U, D を同時 に押すとすべてのマスの記号を消去し、カーソルを中央に戻す。 メイン表示部に表 4-5 の 6 通りの状態を表示させるため、それぞれの LED に対応する 3 ビットの std_logic_vector 型の変数 n1~n9 を定義する。また、LED0 においても 1, 2 の 2 通りの数値を使い表 示をコントロールする必要があるので、対応する変数 n0 にも 3 ビットの std_logic_vector 型のものを 用いる。 表 4-5 三目並べの LED 表示 変数の値 状態 0 空白 1 ○ 2 × 3 カーソル+空白 4 カーソル+○ 5 カーソル+× 6, 7 未使用 57 表示 4.4.2 プロジェクトの構成 クロックとボタンからの入力を受け取り、ゲーム全体をコントロールする CircleCross、7seg デコー ダの働きをする Decode7segment を作成し、前者を 1 つ, 後者を 10 個エンティティとして含む 6 入力 70 出力を持つ Controller を作成し、その入出力を CPLD のピンに対応させる。 Controller ボタン Decode7segment CircleCross USERIO03 USERIO02 USERIO04 USERIO100 USERIO05 decoder0 USERIO06 USERIO08 USERIO98 USERIO96 LED0 へ USERIO97 USERIO01 puzzle USERIO99 ・ ・ ・ ・ ・ ・ Decode7segment USERIO51 USERIO53 decoder9 USERIO56 USERIO61 USERIO54 クロック USERIO52 USERIO62 USERIO55 図 4-22 階層構造を使った設計 58 LED9 へ 4.4.2.1 CircleCross.vhd 入力信号 btn0~4, CLK を受け取り、3 桁の std_logic_vector 型の 10 個の内部変数 n0~n9 を入力に 応じて変化させ、40 個の信号 QA0~QC9 を出力する。ここで QCkQBkQAk は nk(k は 0~9)を 2 進数 に変換したものに対応する。 LIBRARY IEEE; パッケージの指定 USE IEEE.std_logic_1164.ALL; 使用する CPLD 独自のヘッダの読み込み USE IEEE.std_logic_unsigned.ALL; logic 変数を扱うためのヘッダの読み込み USE IEEE.std_logic_arith.ALL; 算術演算のためのヘッダの読み込み エンティティの定義 ENTITY CircleCross IS std_logic 型の入力 CLK, btn0~ PORT( CLK, btn0, btn1, btn2, btn3, btn4 : in btn4 を受け取り、QA0~QC9 を 出力する std_logic; QA0, QB0, QC0 : out std_logic; ... QA9, QB9, QC9 : out std_logic ); アーキテクチャ ARCHITECTURE rtl of CircleCross IS signal n0 : std_logic_vector(2 downto 0); 3bit の std_logic_vector 型 の内部変数 n0~n9 と 5bit ... signal n9 : std_logic_vector(2 downto 0); の std_logic_vector 型の内 signal status : std_logic_vector(4 downto 0); 部変数 status の定義 signal turn : std_logic; BEGIN PROCESS(CLK, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, status, turn) BEGIN if (CLK'event and CLK='1') then if(btn4 = '1' and status(4) = '0') then status(4) <= '1'; elsif (btn4 = '0' and status(4) = '1')then ボタン D を離したときの status(4) <= '0'; 動作 if(n1 >= 3) then n1~n6 にカーソルがあっ n1 <= n1-3; た場合、一つ下に移動す n4<= n4+3; る。 end if; ... end if; 59 ... ボタン U, L, R について も同様の処理をする。 ... if(btn0 = '1' and status(0) = '0') then status(0) <= '1'; elsif (btn0 = '0' and status(0) = '1')then status(0) <= '0'; ボタン C を離したとき の動作 カーソルが空白にある if(n1 = 3) then n1<=CONV_STD_LOGIC_VECTOR(4,3) +CONV_STD_LOGIC_VECTOR(turn, 3); turn <= not (turn); 場合は現在のターンの 記号をその位置に配置 しターンを変更する。 end if; ... end if; if(btn4 ='1' and btn3 ='0' and btn2 ='0' and btn1 ='1' and btn0 ='0') then status <= "00000"; n1 <= CONV_STD_LOGIC_VECTOR(0, 3); n2 <= CONV_STD_LOGIC_VECTOR(0, 3); n3 <= CONV_STD_LOGIC_VECTOR(0, 3); n4 <= CONV_STD_LOGIC_VECTOR(0, 3); リセット(U, D ボタン同 時押し) n1~n4, n6~n9 に 0、n5 に 3 の値を入れる。 n5 <= CONV_STD_LOGIC_VECTOR(3, 3); n6 <= CONV_STD_LOGIC_VECTOR(0, 3); n7 <= CONV_STD_LOGIC_VECTOR(0, 3); n8 <= CONV_STD_LOGIC_VECTOR(0, 3); n9 <= CONV_STD_LOGIC_VECTOR(0, 3); turn <= '0'; end if; n0<=CONV_STD_LOGIC_VECTOR(1,3)+ CONV_STD_LOGIC_VECTOR(turn, 3); n0 に turn+1 の値を入れ る end if; END PROCESS; QA0 <= n0(0); QB0 <= n0(1); QC0 <= n0(2); ... QA9 <= n9(0); QB9 <= n9(1); QC9 <= n9(2); end rtl; 60 出力 QA0~QC9 に n0~ n9 のそれぞれのビット の値を書き込む 4.4.2.2 Decode7segment.vhd 3 つの入力信号 A~C を受け取り、2 進数 CBA を 10 進数に変換した値に対応する表 4-5 の記号の 形に 7segLED を点灯させるための 7 つの信号 LEDA~G を出力する。 4.4.2.3 Controller.vhd 入力信号 BUTTON0~4, CLOCK を受け取り、10 個の LED に記号を表示させるための信号 LED0A~ 9G を出力する。 4.4.3 動作結果 これらを含んだプロジェクトをコンパイルして CPLD に書き込んだ。使用したロジックエレメントは 215 個であった。 ボタン U, D, L, R によるカーソルの移動、ボタン C による現在のプレイヤーのターンの記号の配置、 ボタン U, D 同時押しによるリセット、LED0 の現在のプレイヤーのターンの表示が確認できた。しか し、8 パズル同様かなり頻繁に誤動作がおこり、カーソルが無くなるなどの問題が残った。 61 ○ ○のターンなので拡張情報表示 部の LED0 に○を表示するため 対応する変数 n0 の値は 1 になる ボタン C を押すと、カーソルの位置に○が配置されターンが×に変わる × ×のターンなので LED0 には× が表示される LED5 では○とカーソルが重な ○ っているので、このような表示 になる。 ボタン U を押すと上に、ボタン R を押すと右にカーソルが移動する × ○ ボタン C を押すと、カーソルの位置に×が配置されターンが○に変わる ○ × LED3 は×とカーソルが重なっ ているので、このような表示に なる。 ○ ボタン L を押すとカーソルが左に移動する × ○ ○ 図 4-23 三目並べの動作例 62 5. 問題点とその解決法 5.1 ハードウェア 1. 設計段階の配線ミス 図 3-17 のテスト基板(裏側)では、回路図設計で接続すべき DIP スイッチと VCC の間の配線が抜け た状態のデータを元に基板加工機で基板を作成してしまったため、抵抗の足を利用して基板の裏側にパ イパス配線を作成した。 2. コネクタの不適合 使用したオス・メスのダブルヘッダピンはペアで購入したものではなかったため、図 5-1 の様に正 しくかみ合わず接触が悪かった。そこで、ハンダごてでメス側のコネクタの突起を熔かし正しく接触す るようにした。ハンダごてで熔かした際に、熔けたプラスチックが隣の穴を塞ぐことがあったが、その 部分をヤスリで削り穴を露出させた。 フラットケーブル 40 ピンコネクタ(オス) ピン 40 ピンコネクタ(メス) 基板 図 5-1 コネクタの加工 3. ハンダ不良 ハンダの不足による接触不良のため 7segLED に点灯しないセグメントがあった。この問題は不足部 分にハンダを追加することで一部解決した。 4. 素子の不良 ハンダの修正によっても正しい動作が得られない部分があったため、外部から抵抗を通して電流を流 しても点灯しなかったため、この不具合は素子の不良によるものであることが分かった。部品を交換す ることでこの問題は解決した。使用する素子に不良品が混入していないかのチェックを事前に行うべき であるとの教訓が得られた。 5. 高電圧による CPLD 基板の焼損 CPLD に誤って 9V の電圧をかけてしまい QuartusⅡが CPLD を認識しなくなった。そのため新たに この付録を含むトランジスタ技術を購入しなければならなくなり、研究が遅れた。今回はそのまま CPLD 基板を入れ替えて対応したが、対策としては確実に 5V の入力が保証される AC アダプタからの 入力に対応した基板を設計するという方法も考えられる。 63 5.2 ソフトウェア 1. クロックイベントの利用 CPLD 基板に搭載した水晶発信器からの信号をもう一つの入力として使用し、その立ち上がりのイベ ントでボタンの状態を調べ、変数にその値を格納して、それらを比較することでボタンが離された瞬間 に数値の交換を行う形にした。これは誤動作の問題は残るものの、一応は正しく動作した。 2. ロジックエレメントの不足 三目並べで勝敗が決定したことが確認できるように、拡張情報表示部に勝敗が決定したときは勝者側 の記号を、未定のときはと現在のターンのプレイヤーの記号を表示させるプログラムを作成した。文法 的なエラーなしに目的とした出力を出すはずのものが書けたが、回路を構成するロジックエレメント数 は 340 となり、使用した CPLD の使用可能なロジックエレメントの最大数である 240 を大きく超えて しまった。そこで拡張情報表示部の機能を現在のターンのプレイヤーの記号の表示のみに限定したとこ ろ、使用ロジックエレメント数は 215 となり、動作が確認できた。 3. 誤動作 8 パズルの動作で、ボタンを押した際に値が交換されずに同じ数が現れるという現象が起きた。表 5 -1 の方法に加えてさらに 2 通りの方法を試したがいずれも解決には至らなかった。4.3 で紹介したソ ースコードは方法 4 のものである。 表 5-1 試した方法 A B C D 方法 1 方法 3 方法 5 E 方法 2 方法 4 方法 6 A) クロックの立ち上がりが発生したときに、ボタンが押されている場合に値の交換を行う。 B) クロックの立ち上がりが発生したときにボタンが離されており、直前のクロックではボタンが押さ れていた場合に値の交換を行う。 C) ボタンを押したときに値の交換を行う。 D) LED の表示に相当する変数の値を調べ、空白にあたる数値のある位置の変数と隣接する数値を交 換する。 E) 空白の位置にあたる変数を用いて、その値の示す位置の変数と隣接する数値を交換する。 方法 1 使用ロジックエレメント数は 230 個だった。1 秒間に 100 万回起こるクロックの入力があるたびに値 の交換がされるので四隅にしか空白が行かない動作になった。 64 1 2 3 1 2 4 5 6 4 5 3 7 8 7 8 6 1 2 4 5 3 7 8 6 ボタン L ボタン U 図 5-2 方法 1 の動作 方法 2 使用ロジックエレメント数が 284 個だったため、CPLD に書き込むことができなかった。 方法 3 使用ロジックエレメント数は 222 個だった。空白の状態が二つになる、同じ数字が現れるなどの誤動 作がたびたび起こった。 方法 4 使用ロジックエレメント数は 240 個だった。方法 3 と同様の誤動作は起こるが、この方法の方が起こ る頻度が少なかった。 方法 5 使用ロジックエレメント数は 238 個だった。方向ボタンを押すと常に空白の状態が無くなり、数字が 重複して現れるという動作になった。 1 2 3 1 2 3 4 5 6 4 5 3 7 8 7 8 6 図 5-3 方法 5 の動作 方法 6 使用ロジックエレメント数が 257 個だったため、CPLD に書き込むことができなかった。 方法 7 クロックのカウント数にあたる変数 count を導入し、ボタン入力がある度に count を 0 にし count が一定値(2.5 秒)未満の時は他の入力を受け付けないようにしたが、すべてのボタンについての処理を実 装した場合はロジックエレメント不足で書き込みができなかった。また、一部だけの機能を実装した場 合も count のループ値(5 秒)を周期として、2.5 秒毎に入力を連続的に受け付ける状態とまったく受け付 けない状態が繰り返された。 65 方法 8 空白を置くべき位置に相当する変数 p を導入し、クロックの立ち上がりで方向のボタンが押されてい たら空白が移動するべき位置を p に格納し、そこの変数を空白のある位置の変数をコピーする。立ち上 がりですべてのボタンが離されていたら p の位置に相当する変数に空白の値を入れる。 1 3 6 1 3 6 1 3 4 2 8 4 2 8 4 2 7 5 7 5 8 7 5 ボタン U 押下 6 8 ボタン U 離す 図 5-4 方法 8 の動作 この方法でも一通りは動作したが、数発的に誤動作が見られた。 6. まとめ 本研究において CPLD を使用したミニゲームのための基板を設計して製作し、VHDL で制作したプ ログラムを書き込むことで、複数のミニゲームの動作をさせることができた。しかし、今回使用した CPLD 基板の最大ロジックエレメントの数は 240 と少なく、それを越えないようにするために回路を単 純化しなければならなかった。そのため無駄な変数を減らす、入力や出力の信号を必要最低限に抑える などの工夫をし、使用したロジックエレメントの数をできる限り節約した。組み込みプログラムでは限 られた数で効率よく回路を使わなければならないということを学んだ。 VHDL 言語は今回初めて使ったため、単純なプログラムを理解するのも時間がかかった。しかし使っ ていくうちに書式, 変数の種類や型を覚えたため今回のような動作プログラムを組むことができた。 CPLD 基板のロジックエレメントがもう少し多ければもっと良いものができたと思うので少し残念で はあるが VHDL 言語の知識を少しでも身につけることができたことは大きな収穫であった。 参考文献 1.トランジスタ技術 2006 年 4 月号 CQ 出版社 .....................................................................................4 2. ALTERA 社 http://www.altera.co.jp/ ..................................................................................................7 3. VHDL によるハードウェア設計入門 長谷川裕恭著 4.電気通信大学 電子工学科 5.電子工作の実験室 6.HDL 設計入門 電子工学実験 CQ 出版社 .....................................................12 http://www-lab.ee.uec.ac.jp/ http://www.picfun.com/ http://homepage3.nifty.com/hdl_design/ 66