Posts Issued on September 15, 2022

posted by sakurai on September 15, 2022 #509

Graphic Controlerの再設計

引き続き、従来設計ではVerilogで設計していたものを勉強の目的からBSVに置き換えます。Graphic ControllerはVRAMへアドレスを出力し、VRAMデータを読み出し、また水平同期、垂直同期、表示期間等のタイミング信号を作成するモジュールです。

Verilogによる設計(過去記事)では、水平カウンタ、垂直カウンタを別々に設け、水平のタイミングデコーダと垂直のタイミングデコーダにより同期信号等を作成していました。また、自機が破壊された場合に全画面を赤色表示にするモジュールを図414.2のように、後段に接続していました。また、VRAMデータ4bitのうちRGBを表す3bitを取り出すために、xisliceモジュールを用いていました。

図414.2
図414.2 従来のグラフィックコントローラ階層図

今回BSVで再設計するにあたり、3個に分かれていたモジュール構成を1個にまとめます。

アルゴリズム説明

Graphics.bsvの中心部分:

         y <= 0;
         while (y < `VL) seq
//       for (y <= 0; y < `VL; y <= y+1) seq
            x <= 0;
//          for (x <= 0; x < `HL; x <= x+1) action  --- for consumes two cycles, then we like to use while
            while (x < `HL) action
               if (((`HD+`HFP)<x)&&(x<=(`HD+`HFP+`HSP))) in_xhs <= False;
               else in_xhs <= True;
               if ((ehoff<x)&&(x<=ehoff+`EHD)) in_hdt <= True;
               else in_hdt <= False;
               x <= x + 1;
               if (((`VD+`VFP)<y)&&(y<=(`VD+`VFP+`VSP))) in_xvs <= False;
               else in_xvs <= True;
               if ((evoff<y)&&(y<=evoff+`EVD)) in_vdt <= True;
               else in_vdt <= False;
            endaction // for -> while
            y <= y + 1;
         endseq // for -> while

このように、y方向とx方向の2次元方向にドットクロックを数えます。コメントされている行のように、本来for文を2重で回したいのですが、資料事例で学ぶ BSVからの引用の図509.1に示すように、Stmt文内のfor文は2サイクルかかることに注意します。

図%%.1
図509.1 for文とwhile文

一方、while文は初期化に1サイクルかかるものの、インナーループでのチェックとアクションを1サイクルで実行できます。

for文のインナーループが2サイクルになるということは、2倍の周波数でFSMを駆動しなければならないことになります。現行では49.5MHzなので2倍では99MHzとなり、FPGAの上限に近くなってしまいます。

念のため99MHzで動作するfor文を用いたケースを合成し、正常動作を確認しましたが、タイミングクロージャや発熱等を考えると、回路はなるべく低速で回した方が望ましいです。

一方whileループであればインナーループが1サイクルで良いため、一旦for文で書いてから等価なwhile文に書き換えます


左矢前のブログ 次のブログ右矢