VGAモジュールのシミュレーション方法


VGAモジュールについては、正しくカウンタが動作しているかシミュレーション により確認しておかないと、なかなか思い通りには動作しません。

まず、VGAモジュールのカウンタ部分がテストできるように、VGAモジュールから プロセッサインタフェースを取り除きます。
そのモジュールを、vram_t モジュールと名前を変えておきます。
VRAMメモリの初期値が "0" であるとRGB出力から何も出ませんから、 適当なキャラクタコードで初期化しておきます。
--- vram_t.v ---
`define HMAX 100 // H total dots
`define HSIZ  80 // H Size
`define HSP   84 // H Sync. Pos.
`define HSL   12 // H Sync. Len.
`define HCR    8 // H dots per Char.
`define VMAX  28 // V total Line
`define VSIZ  25 // V Size
`define VSP   26 // V Sync. Pos.
`define VSL    1 // V Sync. Line
`define VCR   19 // V lines per Char.

module vram_t (CLK, RST, R, G, B, HS, VS);
   input  CLK, RST;
	output R, G, B, HS, VS;
	
	 reg   [ 6:0]  VRAM[0:2047];
	 reg   [ 7:0] CGROM[0:2047];

    initial
	 begin
			$readmemh( "VRAM初期化.ram", VRAM );
			$readmemh( "キャラクタデータ.ram", CGROM );
	 end
	 

    reg    [6:0] HCNT;  // H Counter 0-99

...



モジュール vram_t のテストフレーム vram_t_test モジュールからは、 CLK と RST のみを連続して与えます。
Verilog-XLシミュレータを用いる場合は、
initial
begin
  $shm_open("waves.shm");
  $shm_probe("as");
end
を書いておくことで、下位階層すべての信号変化をシミュレータで観測できます。


--- vram_t_test.v ---
`timescale 1ns/1ns
module vram_t_test;

reg  CLK, RST;
wire R, G, B, HS, VS;


initial
begin
  $shm_open("waves.shm");
  $shm_probe("as");
end

integer i;

initial
begin
  CLK = 0;
  for( i=0 ; i<1000000 ; i=i+1 )
     CLK = #10 ~CLK;
end

initial
begin
  RST = 0;
  RST = #5 1;
  RST = #10 0;
end

vram_t v1 (CLK, RST, R, G, B, HS, VS);

endmodule


シミュレーションの結果は以下のように観測できました。

RST が解除されたところから、分周用カウンタ CNT のカウントアップが始まっ ています。

25MHzで8回カウントしたときに、1文字分の表示終了タイミング CEP が出力され るため、これによりパイプラインレジスタとなる CADR に表示するキャラクタコー ドである 0x4B が記憶されています。

次に 0x4B に対応するドットデータを読み出すために CGADR を作成し、 CGROM メモリ内のデータである 0x42 を次の CEP タイミングを用いて シフトレジスタ SR に保存します。

この様に、文字のデータは2文字分タイミングが遅れて出力されることになりま す。



時間が進むと、水平同期クロック HS_L が出力されてくるのが分かります。



さらに時間が進むと、垂直同期クロック VS_L が出力されてくるのが分かります。




| Back |