Posts Issued on December 2, 2022

posted by sakurai on December 2, 2022 #561

画面の縦横の入れ替えの変更

過去記事において、本来VRAMの読み出しアドレスのxとyを入れ替えるつもりが、たまたまwrite側のアドレスマルチプレクサが目につき、それを流用しました。が、動作的な欠点が目立ちました。具体的には、画面書き換えの途中で切り替えると、縦図形と横図形が混在したり、初期画面を動的に準備する負担が大きくなっていました。

これを本来のread側アドレスマルチプレクサに変更します。ただし、write側マルチプレクサに追加してread側マルチプレクサの増設が必要になります。

write側アドレスマルチプレクサは名前をWriteMuxに変更しましたが、元の単なるセレクタに戻しました。新たにReadMuxモジュールを設置し、読み出し側アドレスのxとyを入れ替えます。実際にはyはx(a[7:0])をそのまま用い、xはy(a[15:8])を256から引いたものを用います。

$$ \begin{eqnarray} \left\{ \begin{array}{l} x&\Leftarrow&256-y \\ y&\Leftarrow&x \end{array} \right. \end{eqnarray} $$

図561.1に改造後のブロック図を示します。

図%%.1
図561.1 VRAMモジュール

以下にBSVソースを示します。処理はwrite側で実施した入れ替えとほとんど同様です。

ReadMux.bsv:

// アドレス型の定義
typedef Bit#(16) Addr_t;

// マルチプレクサのインタフェース定義
interface ReadMux_ifc;
   (* prefix="" *)
   // 出力アドレスを生成するメソッド
   method Addr_t outp(Bool sel, Addr_t a);
endinterface

// マルチプレクサの実装
(* synthesize, always_ready = "outp", no_default_clock, no_default_reset *)
module mkReadMux(ReadMux_ifc);

   // 出力アドレスを生成するメソッド
   method Addr_t outp(Bool sel, Addr_t a);
      // xa: aの下位8ビット
      Bit#(8) xa = a[7:0];
      // yax: aの上位8ビットから算出
      Int#(10) yax = 256 - signExtend(unpack(a[15:8]));
      // ya: yaxを8ビットにトリミング
      Bit#(8) ya = truncate(pack(yax));

      // selがTrueなら加工したアドレスを返す
      if (sel) return {xa, ya};
      // selがFalseなら元のアドレスをそのまま返す
      else return a; 
   endmethod

endmodule

この変更により、ボード上のdip swを切り替えることで、リアルタイムに画面の縦横変換ができるようになりました。


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