2 |
画面の縦横の入れ替え |
画面の縦横の入れ替えの変更
過去記事において、本来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に改造後のブロック図を示します。
以下に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を切り替えることで、リアルタイムに画面の縦横変換ができるようになりました。
Leave a Comment