VGAモジュールの作成


KITEプロセッサのに接続するVGAモジュールを作成します。

VGAモジュールの仕様

画面構成、文字構成、KITEにおけるメモリマップの対応を以下に示す。



VGAモジュールのブロック図

VGAモジュールは、主に以下のブロックからなる。

VGA画像表示の考え方

VGAモニタへの画像表示は、通常のテレビと同様にラスタスキャンで表示を行っ ている。 これらのカウンタ等を実現するために、以下のような定義をしておくと良いであ ろう。
`define HMAX 100 // H total Char.
`define HSIZ  80 // H Size
`define HSP   87 // H Sync. Pos.
`define HSL    2 // H Sync. Len.
`define HCR   16 // H dots per Char.
`define VMAX  47 // V total Char.
`define VSIZ  45 // V Size
`define VSP   46 // V Sync. Pos.
`define VSL    1 // V Sync. Len.
`define VCR   16 // V lines per Char.

module vram ( CLK, DCLK, RST, ADDR, DATAI, DATAO, MREQ, RW, ACK, R, G, B, HS, VS, DE );
  input  ...;
  output ...;

  ...
endmodule
また、カウンタの宣言は以下のとおりとなる。
reg    [3:0] CNT;
reg    [7:0] HCNT;  // H Counter 0-99
reg    [6:0] VCNT;  // V Counter 0-45
reg    [3:0] RCNT;  // R Counter 0-15


VideoRAMとChar.ROMのアクセス方法

VGAモニタへの画像表示は、通常のテレビと同様にラスタスキャンで表示を行っている。





出力信号

DVIビデオのR, G, Bの各出力は8ビットで256階調である。
しかし、今回の設計は単色であるので、光らせる場合はR,G,Bともに(FF)、
光らせない場合は(00)を出力する。

HS, VSの同期信号は負論理であるので注意する。

DEは文字を表示させる期間に1とする。
なお、パイプライン動作しているため、
HCNTの値が0~79のときにDEを1にするのではないことに注意する。

サンプルソース

※以下のソースは、第1テーマのビデオコントローラにおいて、プロセッサと のインタフェース部分以外はほぼ同じ動作をするので、 ここのコードを参考にして構わない。
`define HMAX 100 // H total Char.
`define HSIZ  80 // H Size
`define HSP   87 // H Sync. Pos.
`define HSL    2 // H Sync. Len.
`define HCR   16 // H dots per Char.
`define VMAX  47 // V total Char.
`define VSIZ  45 // V Size
`define VSP   46 // V Sync. Pos.
`define VSL    1 // V Sync. Len.
`define VCR   16 // V lines per Char.

module vram (CLK, DCLK, RST, ADDR, DATAI, DATAO, MREQ, RW, ACK, pDATA, HS, VS, DE);
   input         CLK,	     // Processor Clock (75MHz)
                 DCLK,	     // Video Clock     (75MHz)
                 RST;	     // Reset
   input  [11:0] ADDR;	     // Video Memory Address
   input  [ 7:0] DATAI;	     // Data Input
   input         MREQ,	     // Memory Request
                 RW;	     // Read/Write
   output [ 7:0] DATAO;      // Data Output
   output        ACK;	     // Acknowledge
   output [23:0] pDATA;      // RGB Data
   output        HS, VS, DE; // Sync. & Data Enable

   reg    [ 7:0] DATAO;

   // Memory
   reg    [..:0] VRAM [0:....]; //  8-bit, 2048word memory
   reg    [..:0] CGROM[0:....]; // 16-bit, 4096 word ROM

   // Counter
   reg    [..:0] CNT;	 // Character Counter (16-dot)
   reg    [..:0] HCNT;   // H Counter 0-99
   reg    [..:0] VCNT;   // V Counter 0-46
   reg    [..:0] RCNT;   // R Counter 0-15

   wire          CEP;	 // Character End Pulse

   // Internal Signals
   wire   [..:0] VADR;   // VideoRAM Address (2048-word)
   wire   [..:0] CGADR;  // CG-ROM Address (4096-word)
   wire   [..:0] CGDATA; // CG-ROM Font Data Size (16-bit)

   // Pipeline Register
   reg    [..:0] CADR;	// Character Code from VRAM (8-bit)
   reg    [..:0] SR;	// Shift Register (16-bit)

  // Memory Initialize
  initial
    begin
      $readmemh( "VRAM20.mif",  VRAM );
      $readmemh( "18x18ja.mif", CGROM );
    end

   // Video-RAM Write & Read
   always @( posedge CLK )
   begin
     if( ( ADDR[...] == 1'b1 ) && MREQ && ( RW == ...  ) )
         VRAM[ ...[...:...] ] <= ...;
         ... <= VRAM[ ...[...:...]];
   end

   // Video-RAM Acknowledge for Write & Read 
   assign ACK = ( ( ADDR[...] == 1'b1 ) && ... );

   // Counter for Character End Pulse
   always @( posedge DCLK )
     if( RST ) ... <= ...     else
               ... <= .......;

   assign ...  = ...;  // Character End Pulse


   always @( posedge DCLK )
   begin
      if( ... ) begin ...<=...; ...<=...; ...<=...; end // Reset
      if( ... )
      begin
         if( ... == ... )
         begin
            ... <= ...;
            if( ... == ... )
            begin
               ... <= ...;
               if( ... == ... ) ... <= ...;
               else             ... <= ...;
            end
            else
               ... <= ......;
         end
         else
               ... <= ......;
      end
   end

   // Internal Memory Address
   // ・VCNTは文字表示用に 0〜45 まで使用するが、文字フォントは
   //   16ドットx16ラインである.16ドットx32ラインの表示にするため
   //   にはVCNTを1/2の値にしてVADDRを生成する必要がある。

   assign VADR  = ...[...:...] * 11'd... + ...;

   always @( ... )
       if( ... )
           CADR <= ...[...];

   // Generate CG-ROM address from character data in video memory and VCNT, RCNT
   // ・CGROMは表示文字コード順に16ワード毎にフォントデータ格納されて
   //   いる.CGADRは文字コードの下位に16ワード分4ビットのアドレスを付
   //   加し、対応する文字フォントの1ライン分のフォントイメージを読み出す.
   //   この4ビットのアドレスはRCNTを用いるが、表示文字を16ドットx32ラインの
   //   表示にするため2ライン分フォントのラインを重複表示させる必要がある.
   //   したがって,RCNTは1/2にして使用する必要がある.この時1ビット分の
   //   アドレスが足りなくなるが、これは次のカウンタであるVCNTの最下位ビット
   //   用いる必要がある.
   assign CGADR  = { ..., ...[...], ...[...:...] };
   assign CGDATA = ...[ ... ];

   // Shift Register
   always @( posedge DCLK )
   begin
      if ( ... ) SR <= ...; else
      if ( ... ) SR <= ...; else
                 SR <= { ..., ... };
   end

   // RGB pixel Data & Data Enable
   assign pDATA = ( ...[...]  ) ? 24'hffffff : 24'h000000;
   assign DE = ( ( 1 < ... && ... < ... + ... ) && ( ... < ... ) );

   //Sync
   assign HS = ~( HCNT >= ... && HCNT < (... + ...) );
   assign VS = ~( VCNT >= ... && VCNT < (... + ...) );

endmodule



最後に、kite_top階層からは以下の様に呼び出すことになる。
  //
  // Memory & Video RAM
  //
  vram   mem1 ( .CLK (CLK75),
                .DCLK(CLK75),
                .RST(RST),
                .ADDR(ADR),
                .DATAI(DATAO[7:0]),
                .DATAO(VRAM_DATAO),
                .MREQ(MREQ),
                .RW(RW),
                .ACK(VRAM_ACK),
                .pDATA(pDATA),
                .HS(HS),
                .VS(VS),
                .DE(DE)
              );



次は、 DVIエンコーダモジュール を追加します。
| Back |