• 検索結果がありません。

目次 はじめに 1 第 1 章ゲームの内容 テトリス ルール 2 第 2 章設計方法 設計の概要 FPGA について VHDL について LCD SRAM 設計の流れ 5 第 3 章ゲーム

N/A
N/A
Protected

Academic year: 2021

シェア "目次 はじめに 1 第 1 章ゲームの内容 テトリス ルール 2 第 2 章設計方法 設計の概要 FPGA について VHDL について LCD SRAM 設計の流れ 5 第 3 章ゲーム"

Copied!
54
0
0

読み込み中.... (全文を見る)

全文

(1)

業 研 究 報 告

題 目

FPGA と LCD を用いたゲームマシンの設計

指 導 教 員 橘 昌良 助教授 報 告 者 笠原 拓二 提出日 平成18 年 2 月 20 日 高知工科大学 電子・光システム工学科

(2)

目次

はじめに・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・1 第1章 ゲームの内容・・・・・・・・・・・・・・・・・・・・・・・・・・・・・2 1.1 テトリス・・・・・・・・・・・・・・・・・・・・・・・・・・・2 1.2 ルール・・・・・・・・・・・・・・・・・・・・・・・・・・・・2 第2章 設計方法・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・3 2.1 設計の概要・・・・・・・・・・・・・・・・・・・・・・・・・・3 2.1.1 FPGA について・・・・・・・・・・・・・・・・・・・・・4 2.1.2 VHDL について・・・・・・・・・・・・・・・・・・・・・4 2.1.3 LCD・・・・・・・・・・・・・・・・・・・・・・・・・・4 2.1.4 SRAM・・・・・・・・・・・・・・・・・・・・・・・・・4 2.2 設計の流れ・・・・・・・・・・・・・・・・・・・・・・・・・・5 第3章 ゲームマシン仕様定義・・・・・・・・・・・・・・・・・・・・・・・・・7 3.1 仕様検討・・・・・・・・・・・・・・・・・・・・・・・・・・・7 3.1.1 テトリス本体の仕様・・・・・・・・・・・・・・・・・・・・7 3.1.2 テトリスの動作周波数・・・・・・・・・・・・・・・・・・・8 3.1.3 テトリスのアルゴリズム・・・・・・・・・・・・・・・・・・9 3.1.4 SRAM の動作・・・・・・・・・・・・・・・・・・・・・・11 3.1.5 ディスプレイの仕様・・・・・・・・・・・・・・・・・・・13 3.2 大まかな機能分割・・・・・・・・・・・・・・・・・・・・・・15 第4章 HDL設計・・・・・・・・・・・・・・・・・・・・・・・・・・・・・17 4.1 VHDL による記述・・・・・・・・・・・・・・・・・・・・・・17 4.1.1 VHDL 宣言部・・・・・・・・・・・・・・・・・・・・・・18 4.1.2 同期回路設計とリセット信号・・・・・・・・・・・・・・・19 4.2 ディスプレイ制御回路・・・・・・・・・・・・・・・・・・・・20 4.2.1 同期信号用のカウンタ設計・・・・・・・・・・・・・・・・21 4.2.2 アドレス計算・・・・・・・・・・・・・・・・・・・・・・23 4.2.3 LCD_controller の状態遷移・・・・・・・・・・・・・・・・24 4.2.4 LCD_controller のシミュレーション結果・・・・・・・・・・25 4.3 SRAM 制御部の設計・・・・・・・・・・・・・・・・・・・・・26

(3)

4.3.1 SRAM アクセスタイミング・・・・・・・・・・・・・・・・27 4.3.2 メモリーコントローラの状態遷移・・・・・・・・・・・・・29 4.3.3 Memory_controller のシミュレーション結果・・・・・・・・30 4.4 テトリス本体の設計・・・・・・・・・・・・・・・・・・・・・31 4.4.1 テトリスの状態遷移回路・・・・・・・・・・・・・・・・・31 4.4.2 データ構造・・・・・・・・・・・・・・・・・・・・・・・33 4.4.3 アルゴリズム詳細・・・・・・・・・・・・・・・・・・・・35 4.4.4 テトリスのモジュール構成・・・・・・・・・・・・・・・・39 おわりに・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・40 謝辞・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・41 参考文献・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・42

付録1

LCD_controller の VHDL 記述・・・・・・・・・・・・・・・・・・・・43

付録2

Memory_controller の VHDL 記述・・・・・・・・・・・・・・・・・・48

(4)

はじめに

携帯電話に代表される情報端末やカーエレクトロニクスなどでは、ソフトウェアとハー ドウェアから構成されている組み込みシステムとして製品化されている。このような組み 込みシステムでは、小型化、低価格化、低消費電力化への要求から、回路の高機能化とと もに複雑化が進んできた。そのため、システム LSI の設計には、大規模な回路を短期間で 設計し、さらに設計資産を再利用できるような設計方法が考えられてきた。

近年の LSI 設計・開発現場ではハードウェア記述言語(HDL:Hardware Description Language)による設計が主流になってきている。HDL は、プログラミングの構文に似て いて、回路の機能を言語レベルで記述するだけで論理合成することができ、容易に回路の 設計、シミュレーションを行うことができる。これにより、従来のゲート・レベルでの設 計よりも大幅な設計期間の短縮がかなった。[1] 本研究では、HDL による回路設計を学ぶために、プログラムによる回路の作成・書き換 えが可能なFPGA を用いて、テトリスというゲームマシンの設計を行なった。研究の概要、 経過について本論文に報告する。 本論文は全 4 章構成になっている。まず、第 1 章で設計するゲームの内容について説明 し、次の第2 章で設計の流れ、各装置の概要などを説明する。第 3 章は 2 章の内容をより 具体化したもので、第 4 章から実際の設計の内容についての解説になっている。最後に、 付録としてVHDL のソースを添付する。

(5)

1 章 ゲームの内容

この章では、今回製作するゲーム『テトリス』の概要を簡単に紹介する。 1.1 テトリス テトリス(Tetris, 露Тетрис)は、1980 年代末から 1990 年代初めにかけ、世界各国 で大流行したコンピューターゲームである。もともとは旧ソ連の科学者アレクセイ・パジ トノフ(w:Alexey Pajitnov)が教育用ソフトウェアとして開発したものであったが、その後ラ イセンス供給が様々なゲーム制作会社に対してなされ、各種のプラットフォーム上で乱立 する状態になった。なお、テトリスのもつ数学性、動的性、ならびに知名度から、テトリ スをゲームプログラミングの練習題材として用いられる例がしばしばみられた。 ゲームの内容は、1 つの画面を次々と落下してくるブロックを積み上げ、それをひたす ら消していくという単純なアルゴリズムのパズルゲームである。次に、ゲームのルールに ついて解説する。[10] 1.2 ルール フィールドは格子状のブロックを敷き詰めることが可能な領域からなる。 片面型テトロミノ状のブロックピースがフィールド上方から1 つずつ落下してくる。 プレイヤーは、落下中のブロックピースを90 度単位で回転させるか、格子単位で左右 に移動させるか、ブロックピースを高速に落下させるかのいずれかの操作をすること ができる。 ブロックピースがフィールド最下段、または他のブロックの上に着地すると、そのブ ロックピースはブロックとしてフィールドに固定される。そして新しいブロックピー スがフィールド上方に出現し、再び同じ処理が繰り返される。 格子の特定の行がすべてブロックで埋め尽くされると、その行にあるブロックが消滅 し得点となる。同時に多くの行を消去するほど高得点が得られる。(特に4 段消しを「テ トリス」と呼ぶ。)消滅した行の上にあったブロックは、消えた行数分落下する。 固定されたブロックがフィールドの最上段まで積み重なるとゲームオーバーとなる。 以上がテトリスの基本的なルールである。詳しいアルゴリズムについては第 3 章から解 説する。

(6)

2 章 設計の方法

この章では、設計に関する概要や使用したデバイスについて説明する。 2.1 設計の概要 本研究では、近年、デジタル回路設計手法として一般的になってきたハードウェア記述 言語の1 つである VHDL を用いて回路の機能設計を行う。設計した回路の実装には、源発 振30MHz ほどで動作する FPGA を用いる。また、ゲーム画面表示用として LCD、フレー ムバッファ用としてSRAM を使用する。(図 2.1 参照) 図2.1 全体の構成イメージ

FPGA

SRAM

Controller

LCD

テトリスの動作 全体の制御 VHDL で記述

(7)

2.1.1 FPGA について

FPGA(Field Programmable Gate Array)とは PLC(Programmable Logic Device)の 一種で、その名前のとおり内部の倫理を回路設計者がプログラムできる LSI である。 プログラムによって容易に内部倫理を再構成できるため、回路実装後の動作シミュレ ーションをした後でも機能の変更、追加を行うことができる。[1]

2.1.2 VHDL について

VHDL(Very high speed integrated circuit Hardware Description Language)とは アルゴリズム・レベルからゲート・レベルまでの抽象度の広い範囲においてデジタル システムをモデル化することができるハードウェア記述言語である。言語レベルでの 記述から、自動設計(Design Automation : DA)ツールにより論理合成、配置配線を自動 化できるため、従来の回路図入力に比べ大幅に設計期間を短縮することができる。ま た、大きな特徴として C 言語のようにプログラムを先頭から順に処理するソフトウェ ア記述と違い、ハードウェアを設計する上で欠かすことのできないデジタル回路での 並列動作を、正確にモデリングすることができる。詳しい記述方法については第 4 章 で解説する。[1][2]

2.1.3 LCD(Liquid Crystal Display)

液晶を利用した表示装置。2 枚の偏光板と液晶分子を利用して光の透過率を調整する ことにより、画像を表示する。液晶分子自体は発光しないため光源となるバックライ トが必要となる。 CRT ディスプレイや PDP など他の表示装置に比べて薄くて軽いので、携帯用コンピ ュータや省スペースデスクトップパソコン等によく使われている。以前までLCD を代 表とする表示デバイスはコストが高く、自動車や民生機器などの組み込み機器で使わ れることはあまりなかったが、携帯電話や薄型テレビなどの普及によりLCD のコスト がかなり下がった。そのため、最近では組み込み機器向けに必要十分な機能に絞り込 んだグラフィックスLSI も生産されている。

2.1.4 SRAM(Static Random Access Memory)

プログラムやデータを記録保持する装置の一種。記憶素子としてフリップフロップ 回路を用いるもので、アクセス速度が速く消費電力が小さいという特徴があるが、回路 が複雑になり集積度を上げにくいという欠点を持つ。電源を切ると記憶内容は失われる。 非同期 SRAM、シンクロナス(同期)SRAM、デュアル・ポート SRAM などいろいろ なバリエーションがあるが、本研究ではもっとも一般的な非同期SRAM を使用する。

(8)

2.2 設計の流れ 工 程 設計データ 図2.1 FPGA 開発フロー 図2.1 は FPGA 設計の基本的な流れである。上位レベルの工程から順に設計を行ってい くが、下位レベルで問題がでたら上位レベルに戻って検討しなおす必要がある。次に、順 を追いながら各工程について簡単に解説していく。[6] 1. 仕様検討 これから作成する回路の機能を決める。実際の設計では要求仕様が提示されるので、 制約事項を踏まえて設計に着手できるレベルまで仕様を詳細に決めていく。この段階 で、どの機能をどのように実現するかのイメージがあれば、後の工程がスムーズに進 められる。 RLT シミュレーション 仕様検討 ブロック分割 HDL コーディング コンパイル 論理合成・配置配線 FPGA ダウンロード 実機検証 仕様書 ブロック図 ソースコード テストベンチ ネットリスト 回路情報 概念設計 動作設計 データパス設計 論理設計 物理設計 製造

(9)

2. ブロック分割

仕様が決定してもいきなりHDL で記述するのは困難なので、機能別にいくつかのブ ロックに分割する。機能の切り分けが終わったら、それぞれの機能ブロック間でどの ようにデータ、制御信号が流れているのかブロック図を書いて明らかにする。 3. HDL コーディング

分割した機能モジュールごとに、HDL を用いて RTL(Register Transfer Level ; レ ジスタ転送レベル)で記述する。 4. コンパイル FPGA 化できない HDL コードをシミュレーションしても意味がないので、まずは記 述したコードに問題がないかどうかをFPGA 開発ツールでチェックする。 5. RTL シミュレーション テストベンチを作成して、シミュレーションでHDL コードの論理検証を行う。 6. 論理合成・配置配線 論理合成ツールを使用してRTL の HDL コードをゲート・レベルのネットリストに 変換する。生成されたネットリストに従って、FPGA 開発ツールで部品を配置し、配 線する。必要に応じてバック・アノテーション(配置配線後の遅延情報を反映したシ ミュレーション)を実施する。 7. FPGA ダウンロード FPGA 開発ツールで FPGA へ渡す回路情報(ビットストリーム)を生成し、ダウン ロード・ケーブルを介して回路情報をFPGA へ転送する。 8. 実機検証 FPGA を実際に動作させて検証する。 以上の手順で、次章から実際にテトリスを製作した流れにそって解説していく。また、 本論文では工程1∼2 が第 3 章、工程 2∼5 が第 4 章、工程 6∼8 が第 5 章にそれぞれ対応 する。

(10)

3 章 ゲームマシン仕様定義

この章では、本研究で使用したデバイスの動作の仕組み、制約条件や、テトリスの動作 仕様について大まかに説明する。 3.1 仕様検討 初めに、ゲームのルールや動作、各デバイスの仕様を解説する。 3.1.1 テトリス本体の仕様 まず、ユーザーインターフェースの部分について下図に示す。 図3.1 テトリス画面 図 3.3 使用するブロック 左 右 回転 下 図3.2 入力インターフェース Start Reset

(11)

図3.1 は実行中のゲーム画面である。ゲームフィールド内は 10*24 段で構成され、画面 の右上に次のブロック、右下に各データを表示する。データの意味はそれぞれ次のとおり である。 SCORE : ゲームの得点。ブロックを消すと加算される。一度に消す段数に比例して 多くの点数が加算される。 Lines : 消去した段数をカウントする。一定値に達すると Level を加算する。 Level : ブロックピースの自動落下速度に影響する。 図3.2 はゲームコントローラーである。以下に説明する5つのキーで、回路全体を制御す る。 Right_key : ゲーム実行中において、ブロックピースの右方向移動を入力する。 Left_key : ゲーム実行中において、ブロックピースの左方向移動を入力する。 Down_key : ゲーム実行中において、ブロックピースの下方向移動を入力する。 Turn_key : ゲーム実行中において、ブロックピースの回転を入力する。 Start/Stop_key : ゲーム待機状態の時、ゲーム開始信号 Start を入力する。また、ゲーム 実行中の場合、ゲーム内容を保持したままゲーム待機状態へ遷移する。 その間ディスプレイの表示はオフになる。 Reset_key : ゲームを初期状態にもどす。 図3.3 はゲーム内で使用するブロックである。基本となる各色 7 種に回転後のブロックも 含め、計 19 個のブロックが登場する。回転後のブロックデータもそれぞれ SRAM に記憶 しておく。 3.1.2 テトリスの動作タイミング ブロックの自動落下速度を100ms∼500ms くらいとして回路設計を考えた場合、内部 クロック(30MHz=33.3ns)に比べて極端に遅い。また、キー入力による操作を考えても、あ まり高速で動作する回路だと設計しづらくなる。よって、テトリス本体の回路には内部ク ロックを分周した1KHz 程度(1ms)で設計する。

(12)

3.1.3 テトリスのアルゴリズム ここでは、テトリスの動作について解説する。テトリスのアルゴリズムについては、す でにWeb で C 言語によるソースコードが紹介されているので、それを参考にアルゴリズム 確認、動作検証をおこなった。[9] まず、テトリスの主な処理として、以下のようにまとめられる。 ○ メイン…トップモジュールとして、各処理の呼び出しとゲーム実行中か否かの判定 を行う。 ○ 初期化処理…ゲーム内の各データを初期化する。 ○ ブロック生成処理…新しいブロックをランダムに生成する。 ○ ブロック落下処理…ブロックの自動落下の処理。 ○ ブロック操作処理…キー入力に応じた制御を行う。 ○ ブロック移動処理…ブロックを移動させる処理。 ○ ブロック回転処理…ブロックを回転させる処理。 ○ 重なり検査処理…移動、回転後のブロックが壁と重なってないか判定する。 ○ 画面描画処理…画面の表示を更新する。 ○ ブロック固定処理…壁と接触したブロックを固定する。 ○ 消去判定・消去処理…フィールド全段において消去判定を行い、ブロックの横1 列 揃ったラインを消去し、得点を加える。 図3.4 はテトリスのプログラム構造を大まかにまとめた関係図である。SPD(Structured Programming Diagrams)という表記法を使用している。基本的な処理の流れとしては、各 ブロックを結んだ線上を上>右>下の優先順位で進んでいき、枝の端まできたら最初の枝 の下方向へ進んでいく。[3]

(13)

図3.4 テトリスプログラム SPD 前 処 理 後処理 回転 下 左 右 else then (IF : キー入力検出) 時間をカウント カウントの初期化 ゲーム終了 テトリス (IF : カウント一定未満) (WHILE : 否ゲームオーバー) 各初期値の設定 入力キー判定 (SWITCH : 入力キー) (IF : 重なり検査) (IF : 重なり検査) (IF : 重なり検査) 移動処理 (IF : 重なり検査) 移動処理 ブロック固定処理 画面更新処理 移動処理 回転処理 ブロック座標初期化 乱数発生 ブロックデータ再配置 ブロック座標更新 画面更新処理 (IF : 消去判定) 回転後ブロックロード 回転前ブロックに戻す 画面更新処理 消去処理 得点計算 画面更新処理 ゲームオーバー処理 ゲーム初期化処理 ブロック操作処理 ブロック落下処理 画面更新処理 (IF : 重なり検査) (IF : 重なり検査) 移動処理 ブロック作成処理 ブロック作成処理 レベル1 レベル2 レベル3

(14)

3.1.4 SRAM の動作 メモリとして、512k×8 ビット構成の非同期 SRAM を使用した。アドレスバス幅 19 ビ ット、データバス幅8 ビットで、CS(チップセレクト)、OE(アウトプット・イネーブル)、 WE(ライト・イネーブル)の 3 つの制御信号により動作を決定する。各制御入力と動作状態 の関係は表3.1 のようになっている。[8] 表3.1 FUNCTIONAL DESCRIPTION(データシートより)

CS OE WE I/O Pin Mode Power H X X High-Z Deselected Standby

L H H High-Z Output disabled Active

L L H Dout Read Active

L X L Din Write Active

CS はデバイスの選択状態をあらわす。制御信号は負極性であるので“L”のとき信号が オンとなり、デバイスが選択状態になる。選択状態でないとき、ほかの入力ピンはすべて 無視される。OE はデータ出力バッファを開く信号を意味し、WE は SRAM への書き込み 信号を意味する。ただし、WE と OE の両方を“L”にした場合 WE が優先されるため、リ ード動作を行うときはWE を“H”にしておかなくてはならない。 非同期SRAM はその名のとおり、特定のクロック信号に同期して動くようなことはなく、 入力信号の状態に対応して動作する。また、リード時に有効なデータが確定したことや、 ライト時にデータを受け取ったということを示す信号はないので、データシートのタイミ ング図から読み取りながら設計する必要がある。リード・ライトサイクルについて、それ ぞれ2 パターン計 4 種類のアクセス方法を解説していく。

(15)

○OE コントロールド・リード アドレスを制定させて、CS=”L”、WE=”H”とした状態で OE をアサート(L レベル)するこ とによりデータをI/O ピンに出力する。また、CS、WE、OE がリード状態の条件を満たさ なくなると、SRAM は I/O ピンのドライブをやめ、ハイ・インピーダンスになる。(図 3.8 参照) ○アドレスコントロールド・リード 上記の CS=”L”、WE=”H”、OE=”L”の状態のままアドレスを変化させることにより、新 しいアドレスのデータをI/O ピンに出力させる。つまり、アクセス状態のままアドレスだけ を変えて違うアドレスのデータを読み込む。ただし、高速SRAM の一部にはデバイスが選 択状態でアドレス変化をさせると誤動作するような物もあるので、この使い方が許される か否かは事前の確認が必要である。 ○WE コントロールド・ライト アドレスを制定させて、CS=”L”の状態で WE をアサート(L レベル)すると、I/O ピンはハ イ・インピーダンス状態になり、その後ホストがデータを確定させる。データの書き込み 動作はWE の立ち上がりエッジで行われる。 ○CS コントロールド・ライト WE をあらかじめアサートした状態で、CS を利用してデータを書き込む。WE が先にア サートされているので、デバイスが選択状態になるのと同時にライト状態になる。

(16)

3.1.5 ディスプレイの仕様 本研究では、SHARP 製 5.5 インチ パッシブカラー液晶モジュール LM32C041 を使用し た。LCD の外形は 150mm(W)×116mm(H)×25mm(D)。表示画素は 320(縦)×240(横)× RGB。間引き式階調コントロール回路を内蔵しており、垂直同期信号、水平同期信号、ド ットクロック、RGB 各ビットの表示データ入力により RGB 各 8 階調 512 色を表示する。 表 3.2 はタイミングの定格値、図 3.5、3.6 はそれぞれ同期信号に対するデータ入力のタイ ミングを示している。[7] 表3.2 インターフェースタイミング定格表 定 格 値 項 目

MIN TYP MAX

フレーム周期 12.5ms - 20ms クロック周期 100ns - - HSYNC”H”レベル幅 376DCK - - HSYNC”H”レベル幅 248HSYNC - - ”L”レベル HSYNC 幅 3DCK - - ”L”レベル VSYNC 幅 3HSYNC - - (a) 水平方向のタイミング (b) 垂直方向のタイミング 図3.5 データ入力タイミング図 X=320 X=1 +8DCK 48DCK 320DCK 3DCK RGB data DCK Y=240 Y=1 240H +4H Line data HSYNC VSYNC 4H 3H HSYNC

(17)

(a)通常の配置画面 (b)ゲームでの配置 図3.6 画面上での動作

○タイミング図の動作の説明

VSYNC は画面縦方向の同期信号、HSYNC は横方向の同期信号を表している。データ入 力の流れとしては、図3.5(a)に示すように、まず VSYNC の立ち上がりから HSYNC4 周期 (379DCK)をカウントし、その後 HSYNC1 周期ごとに 1 行分のデータ入力が開始される。 1 行分のデータ入力に関しては、図 3.5(b)に示すように HSYNC の立ち上がりから DCK(dot clock)48 周期をカウントし、その後 DCK(に同期して 1 画素のデータが LCD に入力される。 この流れを繰り返しながら、図3.6(a)に示すように画面左上隅から掃引を開始し、右下隅で 1 画面分の掃引を完了する。 ○本研究での使い方 テトリスのゲーム画面は縦長であるので、LCD を 90 度 時計回りに回転した配置で使用 し、よって、x,y 座標の進み方は図 3.6(b)のようになる。 また、デジタル入力の液晶の場合、アナログ入力の液晶と違い画像データを送り続けな くても画面を保持し続けることができる。図3.4 を見てもわかるとおり、テトリスの場合、 画面更新処理はそう多くない。したがって、通常時LCD の同期信号を止めておき、テトリ ス本体回路からの画面描画要求があった時のみ1フレーム分動作するよう設計する。画面 を連続して描画し続ける場合、DCK の 1 周期を LCD からの SRAM アクセスとテトリス本 体からのSRAM アクセスに二分して割り当てなくてはならないため、連続描画よりかなり 設計を簡素化できる。LCD のフレーム周期 12.5ms∼20ms と、テトリス本体の動作周波数 (1KHz=1ms)を考えると、ゲーム動作への影響も少ないと思われる。

V シンク(VSYNC:vertical synchronous)、 H シンク(HSYNC : horizontal synchronous)

x 座 標 24 0H 320DCK HSYNC V S Y N C (1.1) (1.320) (2.1) (239.320) (240.1) (240.320) (240.1) (1.1) (240.320) (320,1) y 座標

(18)

3.2 大まかな機能分割 前節で得られた要求仕様をもとに、大まかな機能分割を行い、入出力を明確にする。 1 つのモジュールだけで記述することもできるが、大規模で複雑な機能だと機能記述が散乱 し、不具合が発生しやすくなりデバッグも大変になってしまう。設計データの再利用性を 高めるという意味でも、見通しのよい機能ブロックへ分割していく。 まず、最上位ブロックの入出力を明らかにする。(図 3.7 参照) 図3.7 のブラックボックスを、いくつか機能ブロックに分割したものが図 3.8 である。内部 の主な回路はほとんど順序回路であるので、複数の有限状態機械(finite state machine : FSM)で構成される。

図3.7 最上位ブロックの入出力仕様

図3.8 大まかな機能ブロック図

SRAM data bus(8bit)

address bus(19bit) CS LCD data bus(9bit) h_sync v_sync DCK OE WE

FPGA

Right key Left key Down key Turn key Start/Stop Reset key Clock LCD SRAM スイッチ パルス制御部 テトリス メイン回路部 LCD・メモリ 制御部 LCD SRAM

(19)

図3.8 全体の機能ブロック図 図3.8 について、右のモジュールから順に簡単に説明する。 ○LCD 制御 FSM テトリス本体からの制御信号によりLCD 同期信号を発生し、画面を描画したり非表示に したりする。L_con(LCD_controller)というモジュール名で設計する。 ○メモリ制御 FSM テトリス本体からの SRAM アクセスと、LCD からのアクセスに対しバス調停を行い、 SRAM アクセス用の制御信号を操作する。Mem_con(Memory_controller)というモジュー ル名で設計する。 ○tetris FSM テトリスの動作を記述します。図3.4 のアルゴリズムを参考に、さらにいくつかのステー トマシンで構成される。Tetris_main というトップモジュールから設計していく。 ○DFF・T_CLK コントローラーからの入力信号のチャタリングを防止するとともに、入力パルスを DFF によって保持する。T_CLK では、源発振からのクロックを分周してテトリス本体用のクロ ック(1kHz 程度)を生成する。 LCD 制御 FSM Memory 制御 FSM DFF DFF DFF DFF DFF DFF T_CLK

C

on

tr

ol

le

r

GEN tetris FSM

L

C

D

S

R

A

M

(20)

4 章 HDL設計

この章では、まずVHDL の基本的な記述のしかたについて説明する。その後、各機能ブ ロックについてRTL で記述できるところまで詳細に設計する。[1][2][4] 4.1 VHDL による記述 VHDL の基本構造は図 4.1 に示すように、ライブラリ宣言とパッケージ宣言で始まり、 エンティティ宣言で入出力ポートを定義し、アーキテクチャ宣言に動作を記述していく。 図4.1 VHDL の言語構造 library ライブラリ名; ライブラリ宣言 use ライブラリ.パッケージ名.all; entity エンティティ名 is port( 信号1 : in std_logic; 信号2 : out std_logic); end エンティティ名; architecture インプリメンテーション名 of エンティティ名 is signal node1 : std_logic;

begin 動作記述部 end インプリメンテーション名; エンティティ宣言 内部信号宣言部 アーキテクチャ宣言

(21)

4.1.1 VHDL 宣言部 ○ライブラリ宣言 ライブラリは、あらかじめ定義されたデータの集まりである。このライブラリを使用す るための宣言を行う。IEEE ライブラリは、VHDL 記述において必須であり最初に必ず library IEEE; と記述する。 ○パッケージ呼び出し パッケージは、データ・タイプなどをまとめたものである。とりあえず基本的な型が定 義されているstd_logic_1164 は必須。また、最後の all はパッケージ中のすべてを使うとい う意味である。 ○エンティティ宣言 エンティティは、回路の入出力ポートを定義する。 entity エンティティ名 is と end エンティティ名; の間に信号の方向と属性を列挙する。 信号の方向は、入力(in)、出力(out)、双方向(inout)の 3 種類、属性はビット(std_logic)と バス(std_logic_vector)を主に使用する。std_logic_vector ではデータ幅を指定する。このと き、downto で定義すると最上位ビットが番号の大きい信号に割り当てられる。to で定義し た場合逆になる。 ○アーキテクチャ宣言 アーキテクチャ宣言は、 architecture インプリメンテーション名 of エンティティ名 is で記述する。本体は、ノード宣言部と動作記述部からなる。ノード宣言部では、動作記述 部で用いるノード名(モジュール内部でのみ使い、外部には出力しない内部信号名)を宣 言する。 signal ノード名 : 属性; 動作記述部は、回路の動作について記述していく部分である。begin と end で囲み、この間 に記述する。

(22)

4.1.2 同期回路設計とリセット信号 ○同期回路 大規模な回路を確実に動作させるためには、すべてを同期回路で設計する必要がある。 同期回路とは、一定周波数の信号(クロック)に従ってすべてのフリップフロップが同じ タイミングで動作する回路を意味する。よって、一定の順序で処理していく回路やフリッ プフロップを使うような回路では、プロセス文のセンシティビティリストにclk を記述する。 プロセス文については下記に説明している。[1][2] ○リセット回路 回路の電源投入時の過度状態では回路の内部状態がどう定まるかが全く不明である。ま た、プログラムが暴走して制御不能になった場合、回路を再び初期状態にしてリスタート する必要がある。このような目的で回路を初期化するのがリセット信号である。上記のclk と同じくセンシティビティリストに加えて記述する。 ○同期信号と非同期信号 D フリップフロップの一般的な記述を下に示す。

動作記述部のbegin から end の間は全て同時に実行されるが、process 文で囲まれた部分 は上から順に実行され、下のprocess 文で最初に戻る。1 行目の()内はセンシティビティ リストと呼ばれ、()内に記述された信号の値が変化した時のみprocess 文が実行される。 5 行目の識別子 event は遅延属性というもので、信号 CLK が変化しているとき真(TRUE) を返す。すなわち、5 行目によりクロックの立ち上がりを検出し、クロックに同期して入力 を出力に伝盤させている。一方reset 信号はクロックに同期した信号ではないため、if 文の 最初に記述している。 なお、同期信号によるデータ入力では、入力信号を保持・確定するための時間(セット アップ・タイム)と(ホールド・タイム)が必要であるため、クロックの周波数とデータ の入力タイミングに注意しなければならない。[1] 1 process( CLK, reset ) 2 begin 3 if ( reset = ‘0’ ) then 4 Q <= ‘0’;

5 elsif ( CLK ’event and CLK = ‘1’ ) then 6 Q <= D;

7 end if; 8 end process;

(23)

4.2 ディスプレイ制御回路の設計 第3 章で分割した機能のうち、画面表示を制御するモジュール(LCD_controller)について 解説する。図4.2 は信号入出力を表したブロック図であり、信号の内容については表 4.1 に 示している。 LCD T_main SRAM 図4.2 LCD_controller のエンティティ図 表4.1 LCD_controller の入出力仕様 信号 意味 clk システム内部クロック(30MHz) reset リセット入力 LCDRD_en テトリス本体からの画面更新要求 DISP_en テトリス本体からの画面表示off 要求 SD SRAM 直結のデータ入力(8bit)

A_count_N 表示画素アドレスのSRAM 出力(17bit) LCDRD_en_off テトリス本体への画面更新終了出力 v_sync LCD の垂直同期信号 h_sync LCD の水平同期信号 DCK LCD の画素同期信号 DISP ディスプレイ表示オフ出力 LCD_red 赤色画素データ(3bit) LCD_green 緑色画素データ(3bit) LCD_blue 青色画素データ(3bit) SD(8bit) reset LCDRD_en DISP_en clk v_sync h_sync DCK DISP RGBdata(9bit) LCDRD_en_off A_count(17bit)_N

LCD_controller

T_main Mem_con

(24)

33.3ns

内部の動作は、テトリス本体の制御信号によるステートマシンと、v_sync1 周期分のカウ ンタで構成される。SRAM へのデータアクセスについては、SRAM をリード状態にしたま まアドレスの値を変更することで1 フレーム分のデータを連続で読み出す構成としている。

また、LCD へ出力するデータ幅は 9bit であるが、SRAM のデータ幅が 8bit であるため 青色出力3bit のうち B1 と B2 に同じ値を出力するようにしている。[5] 4.2.1 同期信号用のカウンタ設計 LCD の画面表示は VSYNC、HSYNC、DCK の 3 つの同期信号により動作しているため、 それぞれの同期信号用の 3 つのカウンタが必要になる。また、表示させる画素を選ぶため の、SRAM のフレームバッファ対するアドレスカウンタも必要である。そのため、モジュ ールの内部に次のような4 つのカウンタを設計した。 ○S_count(2bit) DCK を発振させるためのシステム内部クロックの 2bit カウンタ。clk の立ち上がりに同 期して1ずつ加算されていき、0~3 の範囲を遷移していく。S_count0~1 の間 DCK=0、 S_count2~3 の間 DCK=1 という条件付信号代入により、DCK を発生させる。システムク ロックが30MHz なので DCK は 7.5MHz となる。 0 1 2 3 0 1 2 3 図4.3 DCK 発振タイミング図 133.3ns DCK S_count(3bit) System clock(30MHz)

(25)

… 562, 0, 1, 2, 3, … 50, 51, … 370,371 … H_count 0, 1, 2,3,4, 5,6, 7, 8 … 246 ○D_count(10bit) HSYNC 用の DCK カウンタ。563 個のドットクロックをカウントする。D_count0~2 の 時のみHSYNC=0 として HSYNC を発生させる。 D_count 図4.4 HSYNC 発生タイミング図 ○H_count(8bit)

VSYNC 用の HSYNC246 進カウンタ。DCK カウンタ 562→0 により HSYNC をインク リメントする。247 カウントで 1 画面の表示終了であるので、ここで全てのカウンタを初期 化状態にしてVSYNC と HSYNC を 1 に固定する。 図4.5 VSYNC 発生タイミング図 ○A_count(17bit) 読み込む画素データのアドレスを計算する。LCD の画素数が 320×240 であるため 320 ×240 のカウンタを作ればよいが、テトリス本体から SRAM にアクセスする時のアドレス 計算を簡潔にするため、512×240 までカウントする。画像データの表示は VSYNC、HSYNC の立ち上がりからそれぞれ4H、48DCK 後となるため、図 4.4、4.5 のカウンタのタイミン グ図を参照にD_count=51,H_count=7 からカウントを開始する。 HSYNC 3H 4H DCK 3DCK HSYNC 48DCK 320DCK 192DCK VSYNC 240H

(26)

4.2.2 アドレス計算 SRAM のアドレス幅は 19bit であり 0~524288 番地までデータを格納することができる。 本研究ではx 座標に下位 9 ビットを割り当て、上位 10 ビットを y 座標に割り当てて使用す る。すなわち横方向512 画素、縦方向 1024 画素のメモリ空間が作成される。(図 4.6 参照) こうすることにより、アクセスしたいアドレスの計算はy座標の値を左に 9 ビットシフ トした値とx座標の値のor をとるだけで、アクセスしたいアドレスを生成することができ る。(図 4.7 参照) 図4.6 メモリ領域 図 4.7 アドレス計算例 上記のアドレス計算を満たすため、アドレスのカウント(A_count)は、x 座標 9bit512 分までカウントしている。 図4.8 フレームバッファのアドレス空間 y 座 標 8b it x座標9bit 512 512*240-1 320 511 0 1 2 (x,y) (0,0) (1,0) (2,0) (320,0) (551,0) (0,1) (511,239) (0,0) (319,9) 表示領域 (511,0) 非表示領域 深さ 表示領域 非表示領域 (320,0) (511,0) (511,0) 他画像 格納用、その他 (0,1023) (511,1023) (0.0) (319,0) 1 フレーム (0,239) アクセスしたいアドレス(10,1) x 座標 ”000001010” or y 座標 “0000000001000000000” = “0000000001000001010” アドレスの深さ 10 進数 512+8+2=522 番地 y× 512 + x = アドレス

(27)

4.2.3 LCD_controller の状態遷移 LCD_controller の状態遷移図を下に示す。通常 LCD には同期信号をとめた Idle 状態で あり、画面には前の画面更新処理で表示された画像が保持されている。 テトリス本体からの画面更新要求(LCDRD_en=1)が入ると活性化状態となり、各種カウ ンタにより同期信号を発生し、1 画面表示処理をおこなう。1 画面の処理が終わるとテトリ ス本体へ終了信号(LCDRD_en_off=1)を返し、(LCDRD_en=0)の入力により Idle 状態へ遷 移する。 また、ユーザーインターフェース部のコントローラーのstop 信号入力により、ディスプ レイ表示オフ要求(DISP_en)が入力されると DISP_off 状態へ遷移する。テトリスの実行が 停止している間、画面の表示がオフになる。 図4.9 LCD コントローラーの状態遷移図

Idle

待機

LCD_act 画面描画 実行

DISP_off

画面表示 オフ DISP_en=1 DISP_en=0 LCDRD_en=0 LCDRD_en=1

(28)

4.2.4 LCD_controller のシミュレーション結果 VHDL コーディング、論理合成、シミュレーションには ALTERA 社の PLD 総合開発ツ ールQuartusⅡ WebEdition(v5.1)を使用した。LCD_controller のシミュレーション結果を 以下に示す。なお、VHDL コードについては論文末の付録 1 に示している。 (A) 0~1μs のシミュレーション結果 (B) 0~2ms のシミュレーション結果 図4.10 LCD_controller のシミュレーション結果

(29)

4.3 SRAM 制御部の設計 SRAM アクセスに関する制御信号の発生、テトリス本体とLCDコントロール部からの SRAM アクセスの際のバス調停を行う回路を設計する。この回路の入出力は以下のように なる。 図4.11 メモリコントローラーブロック図 表4.2 メモリコントローラーの入出力仕様 信号 意味 clk システム内部クロック(30MHz) reset リセット入力 LCDRD_en テトリス本体からの画面更新要求 TR_en テトリス本体からSRAM へのデータ要求 TW_en テトリス本体からSRAM への書き込み要求 TD テトリス本体とのデータバス(8bit) TA テトリス本体とのアドレスバス(19bit)

A_count_N LCD_cont からのフレームバッファアドレス(17bit)

CS チップセレクト(非極性) OE アウトプットイネーブル(非極性) WE ライトイネーブル(非極性) SD SRAM とのデータバス(8bit) SA SRAM とのアドレスバス(19bit) SD(8bit) SA(19bit)

Memory

contoroller

LCDRD_en TR_en TW_en TD(8bit) Reset Clock CS OE WE TA(19bit) A_count_N(17bit) SRAM Tetris LCD_controller

(30)

4.3.1 SRAM アクセスタイミング SRAM へのアクセスタイミングとして、データシートのタイミング定格値を参考に次の ようなアクセスサイクルを設計した。[8] リードサイクル、ライトサイクル共に3ステートでクロックに同期した制御信号の操作 を行い、全4クロックサイクルでのSRAM アクセスとなっている。また、LCD によるリー ドサイクルにはアドレスコントロールドリードで行っているため、テトリス本体からのリ ードアクセスとは別のステートにより操作する。 図4.12(a) テトリス本体からのリードサイクル 33.3ns Data Valid clk CS OE Data out Address R0 R1 R2 Idle R0 R1 R2 Idle trc=70ns~ taa=~70ns

(31)

図4.12(b) テトリス本体からのライトサイクル 図4.12(c) LCD からのリードサイクル

4.12 SRAM アクセスタイミング図

Data Valid Data Valid CS WE Data in clk Address W0 W1 W2 Idle W0 W1 W2 Idle clk Address Data out DCK CS OE

(32)

4.3.2 メモリコントローラーの状態遷移 図4.12 を参考に状態遷移図でまとめたものが図 4.13 である。 図4.13 メモリーコントローラーの状態遷移図 LCDRD_en=0 LCDRD_en=1 TR_en=1 TW_en=1

Idle

CS=H

OE=H

WE=H

W0

CS=L WE=L

R0

CS=L OE=L

W1

R1

W2

CS=H WE=H

R2

OE=H

LCD_act

CS=L OE=L

(33)

4.3.3 Memory_controller のシミュレーション結果

Memory_controller のシミュレーション結果を以下に示す。なお、VHDL コードについ ては論文末の付録2 に示している。

(34)

4.4 テトリス本体の設計 第3 章でまとめたテトリスの仕様、大まかなアルゴリズムをもとに、HDL で記述できる までに詳細に分析していく。 4.4.1 テトリスの状態遷移回路 第 3 章では処理の内容、順序についてまとめてプログラム構造図(図 3.4)を作成した。 しかし、逐次実行のソフトウェアプログラムから作成したものであり、すべての回路が同 時に動作するように記述する HDL でそのまま構成を設計するのは困難である。そのため、 HDL では外部信号によって内部の状態が遷移する、状態遷移回路によって構成を考えてい く。 本状態遷移回路は、以下のような11 種類の状態とする。状態遷移図を図 4.15 に示す。 ① Init – 各信号、レジスタの値を初期化する。 ② Idle – ゲーム開始の待機状態。画面表示はオフになっている。 ③ Run – ゲーム実行状態。各種入力信号により複数のステートに分岐する。 ④ R_shift – Right_key の入力により、ブロックを右に移動させる。 ⑤ L_shift – Left_key の入力により、ブロックを左に移動させる。 ⑥ Rot – Turn_key の入力により、ブロックを回転させる。 ⑦ Drop – Down_key 入力、もしくは一定時間経過により、ブロックを下移動する。 ⑧ Check_L – ブロックが横一列揃ったラインがないか調査する。 ⑨ Delet_L – 横一列揃ったラインを消去し、上のブロックを 1 段ずらす。 ⑩ Create_B – 新しいブロックを作成し、画面初期位置へ配置する。 ⑪ End – ゲームオーバー画面を表示し、初期化の実行を待つ。 各状態の詳しい処理については、4.4.3 節より順番に解説していく。

(35)

図4.15 テトリスの状態遷移図 移動完了 Down_key 時間経過 or Turn_key Left_key Right_key start_key 初期化完了 start_key ブロック 配置完了 ブロック 配置error ゲーム準備中サイクル ゲーム実行中サイクル Init 初期化 Idle 実行待機 End 再開待機

Run

実行状態 Create_B ブロック生成 R_shift 右移動 L_shift 左移動 Rot 回転 Drop 下移動 Check_L line 調査 Delete_L line 消去 消去列なし 消去完了 消去列 発見 移動error

(36)

4.4.2 データ構造 各状態についての解説の前に、まず、テトリスの画像データの扱い方について解説する。 ゲーム画面の構成を図4.16、ブロックの構成について図 4.17 に示す。 ○画面構成 ゲーム画面は LCD を時計周りに 90°回転させた配置であるから、ブロックの落下方向 はx 座標系で考える事になる。すなわち、ブロックの下移動=x加算、右移動=yの減算、 左移動=yの加算、という具合になる。また、ブロックの移動範囲は(40,100)~(279,199)の 格子内とする。ゲーム画面の右上は、次に出現するブロックを表示する。(図 4.16 参照) 図4.16 ゲーム画面の構成 y 座 標 2 40 d ot x 座標 320 dot (0,0) (319,0) (0,239) (319,239) (40,100) (279,100) (40,199) (279,199)

(37)

○ブロックデータの構成 ブロックの取り扱いに関しては、図4.17 左上のように 10×10 ドットを 1 セルとし、こ のセルを 4 つ組み合わせたものとして考える。各セルごとにそれぞれ位置情報を示すアド レスを持ち、ブロックの移動・回転はこのセル単位ごとに管理する。ブロックデータをフ レームバッファに書き込む際も、1 セル分の処理を 4 回繰り返すことによりデータを書き込 んでいく。 また、ブロックには 7 つの種類があり、さらにそれぞれ対応する回転後のデータがある ため、ブロックの種類ごとに 7 つの識別子を用意する。この識別子は、ブロックの回転動 作だけでなくブロックの色分けの判定にも使用する。 図4.17 ブロックの構成 保 持 す る 座標 画素構成 1 セル 1 8 ドット 1 (0,0) (10,0) (0,10) (10,10) 灰データ 黄データ 白データ

(38)

4.4.3 アルゴリズム詳細 図4.15 に示した状態遷移をもとに、各状態での処理内容について順に解説していく。 ① Init 回路起動時、リセット信号入力時、または End 状態から start 入力があった時に実行す る回路初期化状態。リセット信号のトグルにより各内部信号の値を初期化し、SRAM のフ レームバッファに対し初期画面データを書き込む。各レジスタに初期値を与え初期ブロッ クの作成が終わると、次のIdle 状態へと遷移する。 ② Idle

Init による初期化の終了、もしくは Run 状態から start 入力があった時の状態。LCD に 対して画面表示オフ信号(DISP_en)を出力する以外には特に何も処理をしない。start 入力 が入るまでゲームの実行を待機する。 ③ Run ゲーム実行中のメインとなる状態。start 入力でゲーム一時停止状態へ、各ブロック操作 キー入力、および一定時間経過で、それぞれ④∼⑦のブロック制御状態へ遷移する。なお、 時間経過による状態遷移にはカウンタを用いるが、時間のカウントはRun 状態時だけでな く移動・回転処理状態にもカウントしていくことにする。こうすることで、移動信号を入 力し続けることによるブロックの落下停止を防ぐことができる。各状態への遷移の制御と 時間のカウントを許可するだけで、メインとはいえ特に複雑な処理はしない。 ④ R_shift Run 状態から Right_key の入力により、 ブロックを1 セル右方向へ移動させる。 すなわち、レジスタに保持してある4 つの アドレスに対し、y座標−10の演算を行う。 しかし、移動後の位置に壁や他のブロックが あった場合、移動を中止しなければならない。 そのため、右図4.14 に示すような流れで処理 を行う。 図4.18 ブロック移動処理の流れ 背景色 否背景色 ブロック消去 座標更新 ブロック書き込み 座標戻し 画素検査 LCD 出力

(39)

まず、制御中ブロックに対して重なり判定が起こらないように、R_shift に状態遷移した 時点で保持している 4 つのセルアドレスを参照して、ブロックを消去する。そして 4 つの アドレスに対しy座標+10 の演算を行う。演算後のアドレスが移動後のブロックの座標に なるので、SRAM からこの 4 つのアドレスの画素データをリードしてくる。その画素デー タが 4 つとも背景データ(黒)だった場合、移動先にブロックはないと判断できるので、 このアドレスに対し画像データを書き込み、LCD への出力を実行する。4 つの内どれか 1 つでも背景以外のデータが検出された場合、制御中ブロックと他のブロック・壁との重な りがおきてしまうので、4 つのアドレスに対しy座標−10 の演算を行い、もとの座標にも どす。その後、再びブロック画像データを書き込み、Run 状態へと遷移する。 ⑤ L_shift R_shift と移動方向が逆なだけで処理の内容は同じであるので、セルアドレスy座標に対 する演算を+−逆転させるだけでよい。 ⑥ Rot Run 状態から turn_key の入力により、ブロックの回転を実行する。処理の流れは図 4.14 とほぼ同じであるが、R/L_shift より座標の更新が少しだけ複雑になる。 A B D C A B D C block No=1 address register A (0,0) + (50,150) → (50,150) B (10,0) + (50,150) → (60,150) C (20,0) + (50,150) → (70,150) D (0,10) + (50,150) → (50,160) 回転前アドレス if (block No=1) then address register A (50,150) + (0,0) → (50,150) B (60,150) + (0,0) → (60,150) C (70,150) + (−10,10) → (60,160) D (50,160) + (10,10) → (60,170) 回転動作の座標の計算方法につい て、左のようなブロックを例に説明す る。 前節で解説したとおり、制御中のブ ロックに対し 4 つのアドレスを各セル ごとに持っている。ブロックのAセル の位置座標が(50,150)の時、それを基準 に各セルのアドレスが計算される。各 セルの位置はブロックの種類により異 なっているため、全19 種のブロック識 別子を参照に計算を行う。 移動処理ではこのアドレスに対し同 じ数値の加算になるが、回転動作では セルごとの位置が変更されるため、も う一度ブロック識別子を参照してブロ ックごとの演算を行う。 その後、移動処理と同じように重な り判定を行い、ブロックのデータを書

(40)

⑦ Drop Run 状態から Down_key 入力、もしくはゲーム実行サイクルにおける時間(テトリス用の クロック)のカウントが一定数になった時、ブロックを下方向へ移動させる。これもアドレ スのx軸に対する加算になるだけで、あとの処理はR_shift と同じ流れである。ただし、ブ ロックの移動エラーが起きた場合、座標を移動前に戻してブロックの再描画を行った後、 Run 状態ではなく Check_L 状態へと遷移する。 ⑧ Check_L この状態へ遷移したときに保持している4 つのアドレスの x 座標に消える可能性のある ラインが含まれているので、x 座標アドレスを別のレジスタへ格納しておき、このアドレス をもとにそれぞれ1∼4 のラインに対し消去判定を行う。 消去ラインの判定にはカウンタを用いる。ゲームフィールド内のセルの y 軸に取りうる 値の範囲は(100,110,120,130,140,150,160,170,180,190)だけであるので、この y 座標と上記 で格納したx座標のアドレスをもとに、SRAM からそれぞれ画素データをリードしてくる。 このときの画素データが背景色データでない時(ブロックのセルデータが存在する場合)、 消去カウンタをカウントアップし、カウンタの値が10 の時、Delete_L へと遷移する。 格納したx座標の走査が終わるとCreate_B へと遷移する。 図 4.19 消去判定フロー else y=190 count≠10 y=190 count=10 (A or B,C,D)の 3 つのx座標で ライン検査 x y A B C D 背景色 否背景色 走査対象アドレスの保持 y=100 count+1 画素検査 (保持 x,y) 次のライン or Create_B へ y,count 値 y+10 Delete_L へ

(41)

⑨ Delete_L 消去判定がでたラインに対して消去を行う。まず、Check_L で消去判定がでたx座標よ り上のフィールドデータをSRAM の空き領域へコピーする。そして、コピーしたデータを 1 段ずらしたところに上書きしていき、最後にゲームフィールド最上段を消去する。 消去判定と消去処理は1 ラインずつおこなうため、Check_L で格納したx座標アドレス を1 セル分ずらして、再び Check_L へ遷移する。 ⑩ Create_B 1 度目の実行でも、すでに Init で次に生成されるブロックは決定されてるため、次の次 のブロックを乱数により決定する。その後、ブロックの位置を示す 4 つのセルアドレスを 次のブロックを表示する領域に書き換え、次の次に生成されるブロックを書き込む。そし て、ブロックのアドレスを初期位置へもどし、初期配置位置の画素を検査して重なりがな いか調べる。初期位置に他のブロックがないことが確認できれば、新しいブロックをフレ ームバッファに書き込む。ここまでで一連の処理が終わり、再びRun 状態へ遷移する。も し、初期配置位置で重なり判定が起きた場合、Game over となり End 状態へ遷移する。

⑪ End

(42)

4.4.4 テトリス内部のモジュール構成 図4.15 の状態遷移図をもとに、テトリス本体のモジュール構成を以下のようにした。 コンポーネントによっては、さらに下位レベルのステートマシン、サブコンポーネントに より構成され、階層化したステートマシンによってテトリスの動作を実現する。 図4.20 テトリス本体の機能ブロック図

メイン

FSM

アドレス REG 画素 ROM Control Block FSM Tetris Initialize FSM Delete Block FSM Create Block FSM

clk T_clk reset start turn down Left Right

DISP_en LCDRD_en TR_en TW_en TA TD address BUS

Data BUS

(43)

おわりに

本研究の目標としては、回路を実装して動作確認をするところまでであったが、結局回 路の構造や処理をまとめるだけで終わってしまった。処理の順序がわかってもゲート回路 で信号がどのタイミングでどのように伝盤していくのか、といったソフトウェアとハード ウェアの動作の違いがなかなか呑み込めなかった。しかし、そのまま強引に下位レベルの 設計へと進めようとしてしまったために、後の段階で回路の整合性がとれなくなってしま うなど、無駄が多かったように思える。HDL により抽象的な段階からロジック回路を生成 できるとはいえ、トップレベルから具体的な機能ブロックとロジック回路を作っていくに は、基礎的な知識が十分に必要であると感じた。 全工程の半分程しか進められなかったが、あきらめずできるとこまで取り組んだことに よって知識や解析力が身についただけでなく、ハードウェアの設計に関する興味も強くな った。ゲームの設計には様々な要素が含まれるので、論理設計の学習に非常に有効である と思う。今後、完成させる事はもちろん、アルゴリズムの最適化や回路規模の小型化、ゲ ーム性の向上など、時間があれば考えていきたい。

(44)

謝辞

今回の卒業研究に際して、丁寧なご助言、ご鞭撻下さりました橘 昌良助教授に心から感 謝いたします。就職活動や大学生活についてご指導下さいました杉田 彰久教育講師はじめ、 本学入学以来ご教授賜りました電子・光システム工学科の教員・職員の皆様と共に、ここ に厚くお礼申し上げます。 また、共に最後まで卒業研究に励んだ橘研究室の皆さん、同期生諸氏にお礼を申し上げ ます。 平成18 年 2 月 20 日

(45)

参考文献

[1]「VHDL によるマイクロプロセッサ設計入門」仲野 巧 著、CQ 出版 [2]「VHDL によるハードウェア設計」長谷川 裕恭 著、CQ 出版 [3]「構造化プログラム設計図法 SPD」遠藤 裕香 著、共立出版 [4]「Design Wave magazine」2002 年 5 月号、CQ 出版

[5]「Design Wave magazine」2003 年 1 月号、CQ 出版 [6]「Design Wave magazine」2005 年 4 月号、CQ 出版 [7]「5.5 インチ LCD LM32C041 仕様書」

[8]「CMOS SRAM K6T4008C1B Family 仕様書」 [9]ゲーム&その他【プログラミング研究所】

「http://www13.plala.or.jp/kymats/study/game_other.html」

[10]テトリス − Wikipedia

(46)

付録1 LCD_controller の VHDL 記述 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity LCD_controller is port ( clk : in std_logic; reset : in std_logic; LCDRD_en : in std_logic; DISP_en : in std_logic; SD : in std_logic_vector(7 downto 0); A_count_N : out std_logic_vector(16 downto 0); LCDRD_en_off : out std_logic;

v_sync : out std_logic; h_sync : out std_logic; DCK : out std_logic; DISP : out std_logic;

LCD_red : out std_logic_vector(3 downto 1); LCD_green : out std_logic_vector(3 downto 1); LCD_blue : out std_logic_vector(3 downto 1) );

end LCD_controller;

architecture Behavior of LCD_controller is type LCDstatus is ( idle, DISP_off, LCD_act);

signal state : LCDstatus; -- LCD Sequencer state signal DCK_I : std_logic; -- Internal dot clock -- clock counter

signal S_count : std_logic_vector(1 downto 0); -- system clock count(0 to 3) signal A_count : std_logic_vector(16 downto 0); --address count(0 to 512*240-1)

(47)

signal D_count : std_logic_vector(9 downto 0); -- DCK count(0 to 562) signal H_count : std_logic_vector(7 downto 0); -- HSYNC count(0 to 246)

begin

-- LCD data out

LCD_red <= SD(7 downto 5); LCD_green <= SD(4 downto 2);

LCD_blue <= SD(1 downto 0) & SD(0);

-- LCD state machine --- process(clk,reset)

begin

if( reset = '1' ) then state <= idle; DISP <= '1';

elsif( CLK'event and CLK = '1') then case state is

when idle =>

if ( LCDRD_en = '1' ) then state <= LCD_act; elsif ( DISP_en = '1' ) then

state <= DISP_off; DISP <= '0'; end if; when LCD_act => if ( LCDRD_en = '0' ) then state <= idle; end if; when DISP_off => if ( DISP_en = '0' ) then state <= idle; DISP <= '1'; end if; when others =>

(48)

null; end case; end if; end process; -- state LCD_active ====================================== -- DCK generation,S_COUNT(0~3)---

process(clk, reset, LCDRD_en) begin

if( reset = '1' or LCDRD_en = '0') then S_count <= (others => '0'); elsif( clk'event and clk='1' ) then

if( state = LCD_act ) then if( S_count = 3 ) then

S_count <= (others => '0'); else S_count <= S_count + 1; end if; end if; end if; end process; DCK_I <= S_count(1); DCK <= DCK_I; -- H_COUNT(0~246),D_COUNT(0~562),A_COUNT(0~512*240-1) ---- process(DCK_I, reset, LCDRD_en)

begin

if( reset = '1' or LCDRD_en = '0') then D_count <= (others => '0'); H_count <= (others => '0'); A_count <= (others => '0'); LCDRD_en_off <= '0';

elsif( DCK_I'event and DCK_I = '1' ) then if( state = LCD_act ) then

(49)

D_count <= (others => '0'); H_count <= H_count + 1; else D_count <= D_count + 1; end if; if ( A_count = 122690 ) then -- (512*240-190) LCDRD_en_off <= '1'; elsif ( H_count >= 7 and D_count >= 51 ) then

A_count <= A_count + 1; end if; end if; end if; end process; A_count_N <= A_count; -- HSYNC,VSYNC generation--- process (DCK_I, reset, LCDRD_en)

begin

if( reset = '1' or LCDRD_en = '0') then h_sync <= '1';

v_sync <= '1';

elsif( DCK_I'event and DCK_I ='1' ) then if( state = LCD_act ) then

if ( D_count >= 0 and D_count < 3) then h_sync <= '0';

else

h_sync <= '1'; end if;

if ( H_count >= 0 and H_count < 3) then v_sync <= '0'; else v_sync <= '1'; end if; end if; end if;

(50)

end process; end Behavior;

(51)

付録2 Memory_controller の VHDL 記述 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity Memory_controller is port ( clk : in std_logic; reset : in std_logic; LCDRD_en : in std_logic; TR_en : in std_logic; TW_en : in std_logic;

TD : inout std_logic_vector(7 downto 0); TA : in std_logic_vector(18 downto 0); A_count_N : in std_logic_vector(16 downto 0); CS : out std_logic;

WE : out std_logic; OE : out std_logic;

SD : inout std_logic_vector(7 downto 0); SA : out std_logic_vector(18 downto 0) );

end Memory_controller;

architecture Behavior of Memory_controller is

type MEMstatus is ( idle, R0, R1 ,R2, W0, W1, W2, LCD_act);

signal state : MEMstatus; -- SRAM Sequencer state signal TD_OE_I : boolean; -- Tetris data bus output enable signal SD_OE_I : boolean; -- SRAM data bus output enable

(52)

-- tri state logic

TD <= SD when TD_OE_I else (others => 'Z'); SD <= TD when SD_OE_I else (others => 'Z');

-- Mem_con state machine --- process(clk,reset)

begin

if( reset = '1' ) then

state <= idle; CS <= '1'; OE <= '1'; WE <= '1'; TD_OE_I <= false; SD_OE_I <= false; elsif( CLK'event and CLK = '1') then

case state is when idle => if ( LCDRD_en = '1' ) then state <= LCD_act; CS <= '0'; OE <= '0'; WE <= '1'; elsif ( TW_en = '1' ) then

state <= W0; CS <= '0'; OE <= '1'; WE <= '0';

elsif ( TR_en = '1' ) then state <= R0; CS <= '0'; OE <= '0'; WE <= '1'; end if; -- LCD active --- when LCD_act => if (LCDRD_en = '0') then

(53)

state <= idle; CS <= '1'; OE <= '1'; end if; -- Read cicle --- when R0 => state <= R1; when R1 => state <= R2; OE <= '1'; TD_OE_I <= true; when R2 => state <= idle; CS <= '1'; TD_OE_I <= false; -- Wright cicle --- when W0 => state <= W1; SD_OE_I <= true; when W1 => state <= W2; CS <= '1'; WE <= '1'; when W2 => state <= idle; SD_OE_I <= false; when others => null; end case; end if; end process; process(A_count_N,LCDRD_en,TA) begin if (LCDRD_en = '1') then

(54)

else

SA <= TA; end if;

end process; end Behavior;

図 3.7 最上位ブロックの入出力仕様
図 3.8 全体の機能ブロック図  図 3.8 について、右のモジュールから順に簡単に説明する。  ○LCD 制御  FSM   テトリス本体からの制御信号により LCD 同期信号を発生し、画面を描画したり非表示に したりする。L_con(LCD_controller)というモジュール名で設計する。  ○メモリ制御  FSM   テトリス本体からの SRAM アクセスと、LCD からのアクセスに対しバス調停を行い、 SRAM アクセス用の制御信号を操作する。Mem_con(Memory_controller
図 4.12(b) テトリス本体からのライトサイクル  図 4.12(c) LCD からのリードサイクル  図 4.12 SRAM アクセスタイミング図 Data Valid Data Valid CSWEData in clkAddress W0 W1 W2 Idle W0 W1  W2  Idle clkAddress Data out DCK CSOE
図 4.14   Memory_controller の単体シミュレーション結果
+2

参照

関連したドキュメント

 第1節計測法  第2節 計測成績  第3節 年齢的差異・a就テ  第4節 性的差異二就テ  第5節 小 括 第5章  纏括並二結論

12―1 法第 12 条において準用する定率法第 20 条の 3 及び令第 37 条において 準用する定率法施行令第 61 条の 2 の規定の適用については、定率法基本通達 20 の 3―1、20 の 3―2

契約約款第 18 条第 1 項に基づき設計変更するために必要な資料の作成については,契約約 款第 18 条第

まとめ資料変更箇所リスト 資料名 :設計基準対象施設について 章/項番号:第14条 全交流動力電源喪失対策設備

第1章 生物多様性とは 第2章 東京における生物多様性の現状と課題 第3章 東京の将来像 ( 案 ) 資料編第4章 将来像の実現に向けた

バーチャルパワープラント構築実証事業のうち、「B.高度制御型ディマンドリスポンス実

第1章 総論 第1節 目的 第2節 計画の位置付け.. 第1章

さらに第 4