VHDL上のテキストVGAモジュール

この記事では、VHDLで記述されたVGAテキストモジュールを紹介します。 このモジュールは、ボードのデバッグ時に役立ち、比較的小さなスペースしか占有しません。

一般的な特徴


モジュールは、50 MHzのクロック周波数で動作します。
60Hzの周波数で640x480の解像度の画像を生成します。
文字サイズは8x16ピクセルです。 画面には80x25文字があります。
32色のパレット。

FPGAで占有されるリソース:



実装



モジュールのインターフェイスには、クロックジェネレーターの入力(clk)、VGAコネクターへの出力(r、g、b、vsync、hsync)およびプロセッサーバスへの出力(addr、data、iowr、dout)が含まれます。 私が使用したボードには、3色(各色に1つ)の8ビットDACがあるため、モジュールからの8ビットラインは色付きです。 最も重要な色を使用して、DACのないボード用の作業バージョンを取得します。

エンティティ vga_text
ポート clk STD_LOGIC ;
iowr STD_LOGIC ;
addr STD_LOGIC_VECTOR 31 downto 0 ;
データ STD_LOGIC_VECTOR 31 downto 0 ;
dout out std_logic_vector 31 downto 0 ;
r STD_LOGIC_VECTOR 7 downto 0 ;
g STD_LOGIC_VECTOR 7 downto 0 ;
b STD_LOGIC_VECTOR 7 downto 0 ;
vga_blank STD_LOGIC ;
vsync STD_LOGIC ;
hsync out STD_LOGIC ;
vga_textを終了します


モニターには3つの同期信号と3つのカラー信号が必要です。 同期信号を生成するには、VCounterおよびHCounterカウンターが使用されます。 同期信号は、図に示されている瞬間に発行されます。

カウンターコード:
アーキテクチャ vga_textの動作

シグナル VCounter 整数 範囲 0 から 520 := 0 ;
シグナル HCounter 整数 範囲 0 から 800 := 0 ;
signal div std_logic := ' 0 ' ;

始める

プロセス clk
始める
rising_edge clk )の 場合
div <= not div ;
div = ' 1 'の場合
HCounter = 799の 場合
HCounter <= 0 ;
VCounter = 520の 場合
VCounter <= 0 ;
他に
VCounter <= VCounter + 1 ;
終了する 場合 ;
他に
HCounter <= HCounter + 1 ;
終了する 場合 ;
終了する 場合 ;
終了する 場合 ;
終了 プロセス ;

ビヘイビア;

同期信号の生成:
VSync <= ' 0 ' VCounter < 2 else ' 1 'の場合;
hsync <= ' 0 ' HCounter < 96 else ' 1 'の場合;
vga_blank <= ' 1 ' when HCounter > 143 and HCounter < 784 and
VCounter > 30 および VCounter < 511 else ' 0 ' ;

1文字のサイズは8x16ピクセルです。 文字配列には、それぞれ128ビットの256個のセルがあります。 各ビットは、現在の位置にポイントがあるかどうかを担当します。 メモリセル内のポイントの位置:


FPGAには、1024x18ビット(18432ビット)のブロックメモリ構成があり、これに焦点を合わせます。 CADは、このようなメモリブロックを使用して、選択したほぼすべての構成を自動的に実装します。 したがって、文字メモリには256x128ビット= 32768ビットのメモリが必要です。これには2つのメモリブロック(BRAM)が必要です。
シンボルメモリは設計中に初期化され、動作中に変更できます。

もう1つの必要なメモリは、画面(可視領域)メモリです。 このメモリでは、シンボル番号、シンボルの色、および背景色をエンコードします。 カラーメモリを保存するには、パレットで数値をエンコードします。 18ビットのセルを持つメモリの構成に基づいて、シンボル番号に8ビット、シンボル色に5ビット、背景色に5ビットを割り当てます。 パレットの下では、32個のセルにそれぞれ24ビットが割り当てられています(色ごとに8ビット)。


文字の解像度とサイズに基づいて、80x30文字が画面に収まります。 ただし、これにはメモリ内で2,400セル(3メモリブロック)が必要です。 最初から、このモジュールの最小サイズのタスクが設定されていたため、5つのボトムラインがカットされました。 その結果、表示される文字は80x25になり、2000個のメモリセル(2個のメモリブロック)を占有します。

文字メモリはコアジェネレータで生成されます。 モジュールへのメモリ接続は次のとおりです。
シグナル SAddrA std_logic_vector 7 downto 0 ;
signal SAddrRead、SAddrWrite 0 から 255の 整数 範囲
信号 SDataA、SDinA std_logic_vector 127 downto 0 ;
信号 SWeA std_logic ;
-...
コンポーネント vga640_symbols
ポート
addr IN std_logic_VECTOR 7 downto 0 ;
clk std_logicで ;
din IN std_logic_VECTOR 127 downto 0 ;
dout OUT std_logic_VECTOR 127 downto 0 ;
we IN std_logic ;
終了 コンポーネント
-...
始める
-...
vga640_symbols_0 vga640_symbols
ポート マップ
addr => SAddrA、
clk => clk、
din => NewSymbol、
dout => SDataA、
we => SWeA
;
SWeA <= ' 1 ' when isLowLevel = ' 1 ' and conv_integer addr = 337 and iowr = ' 1 ' else ' 0 ' ;
SAddrA <= conv_std_logic_vector SAddrWrite、 8 when isLowLevel = ' 1 ' および conv_integer addr = 337 and iowr = ' 1 ' else conv_std_logic_vector SAddrRead、 8 ;


画面メモリは、定型コードを記述することで作成されます(ただし、文字メモリの場合と同じことができます)。
タイプ TScreen std_logic_vector 17 downto 0 )の配列 0〜1999 です。
シグナル画面 TScreen ;
信号 scrAddrA、scrAddrB 0 から 1999の 整数 範囲 ;
シグナル scrDataA、scrDataB、scrDinB std_logic_vector 17 downto 0 ;
信号 scrWeB std_logic ;
-...
始める
-...
プロセス clk
始める
rising_edge clk )の 場合
scrWeB = ' 1 'の場合
スクリーン scrAddrB <= scrDinB ;
終了する 場合 ;
scrDataA <= Screen scrAddrA ;
scrDataB <= Screen scrAddrB ;
終了する 場合 ;
終了 プロセス ;

scrDinB <= scrDinBLowLevel isLowLevel = ' 1 'の場合else scrDinBNormal ;
scrWeb <= scrWeBLowLevel isLowLevel = ' 1 'の場合、またはscrWebNormal ;
isrLevel = ' 1 'の場合は scrAddrB <= scrAddrBLowLevel そうでない場合は scrAddrBNormal

scrDinBLowLevel <= data 17 downto 0 ;
scrWeBLowLevel <= ' 1 ' when conv_integer addr = 300 または conv_integer addr = 309 および iowr = ' 1 ' else ' 0 ' ;

scrAddrBNormal <= GotoY * 80 + GotoX ;
scrDiNBNormal <= BgColor&Color&data 7 downto 0 ;
scrWebNormal <= ' 1 ' conv_integer addr = 306 および iowr = ' 1 ' else ' 0 'の場合;


また、パレットのカラーテーブルを設定する必要があります。これは次のとおりです。
タイプ TColor std_logic_vector 23 downto 0 )の配列 0〜31 です。
信号 PalleteColor TColor :=

0 => x "000000"
1 => x "0000FF"
2 => x "00FF00"
3 => x "00FFFF"
4 => x "FF0000"
5 => x "FF00FF"
6 => x "FFFF00"
7 => x "FFFFFF"
その他 => x "FFFFFF"
;
シグナル PalleteAddr 整数 範囲 0〜31


必要なすべてのメモリが形成され、画面に表示するピクセルの準備の実装を開始できます。
現在のFPGAデザインの傾向は、完全同期デザインを意味します。 これらのトレンドから逸脱することはなく、次のピクセルを準備するためのパイプラインを実装します。 入力には、画面上の現在の位置を決定するHCountカウンターとVCountカウンターがあり、出力には、表示されるピクセルの色があります。

コンベアステージ:
  1. 画面の表示部分の位置を決定するscrX、scrY信号の計算。
  2. 必要なシンボルを使用して画面メモリ内のセルを定義する信号の計算
    textX = scrX / 8
    textY = scrY / 16
    文字に必要なピクセルを決定する信号の計算
    SymbolX = scrX mod 8-1
    SymbolY = scrY mod 16
    modは除算の残りです。
  3. 信号X、Yのアドレスの計算。
  4. 現在のキャラクターを取得します。
  5. 現在のピクセルと色の構成を取得します。

プロセス clk
始める
rising_edge clk )の 場合
div = ' 1 'の場合
-1
scrX <= conv_std_logic_vector HCounter-139、10 ;
scrY <= conv_std_logic_vector VCounter-70、10 ;

-2
textX <= conv_integer scrX 9 downto 3 ;
textY <= conv_integer scrY 9 downto 4 ;
SymbolX <= scrX 2 downto 0 -1 ;
SymbolY <= scrY 3 downto 0 ;

-3
scrAddrA <= textY * 80 + textX ;
SymbolPoint <= conv_integer SymbolY * 8 + 7 -conv_integer SymbolX ;

-4
SAddrRead <= conv_integer scrDataA 7 downto 0 ;
scrData <= scrDataA ;

-5
VCounter > 69 および VCounter < 470 )の 場合
SDataA SymbolPoint = ' 1 'の場合
curColor <= PalleteColor conv_integer scrData 12 downto 8 ;
他に
curColor <= PalleteColor conv_integer scrData 17 downto 13 )) ;
終了する 場合 ;
他に
curColor <= x "000000" ;
終了する 場合 ;
終了する 場合 ;
終了する 場合 ;
終了 プロセス

b <= curColor 23 downto 16 when vga_blank = ' 1 ' else "00000000" ;
g <= curColor 15 downto 8 when vga_blank = ' 1 ' else "00000000" ;
r <= curColor 7 downto 0 when vga_blank = ' 1 ' else "00000000" ;


インターフェイスを備えたバスを介してモジュールを操作します


バスは、同じFPGAに実装されたフォートプロセッサによって制御されます。 OUTPORTコマンドで、Addr、Data行が設定され、Iowr行が「1」行に上昇します。 INPORTコマンドで、プロセッサはAddr行を設定し、Dout行からデータを収集します。
バスの使用例:
プロセス clk
始める
rising_edge clk )の 場合
-カーソルを位置Xに設定(GOTOX)
conv_integer addr = 302 および iowr = ' 1 'の場合
conv_integer data > 79の 場合
GotoX <= 0 ;
他に
GotoX <= conv_integer データ ;
終了する 場合 ;
終了する 場合 ;

-カーソルを位置Yに設定(GOTOY)
conv_integer addr = 303 および iowr = ' 1 'の場合
conv_integer data > 24の 場合
GotoY <= 0 ;
他に
GotoY <= conv_integer データ ;
終了する 場合 ;
終了する 場合 ;
終了する 場合 ;
終了 プロセス


同様に、モジュールを操作するためのコマンドのほとんどが実装されています。

モジュールの完全なリストはこちらから入手できます。
モジュールリスト
文字メモリを初期化するには

UPD:
基本機能
300-画面メモリへの書き込み/読み取り
301-画面メモリに書き込むためのアドレス

302-キャリッジのX座標を設定します(GotoX)
303-キャリッジ座標の設定(GotoY)
304-文字色の設定(SetColor)
305-背景色の設定(SetBgColor)
306-文字出力とキャリッジ移動(EMIT)
307-切り替えモード
1-低レベルモード。 ダイレクトメモリ操作に使用可能な300、301の機能
0-通常モード。 機能306は、特定の色の文字を特定の位置に設定し、キャリッジを移動するために使用できます。
308-CR
309-VGA_SetData(A ++)

カーソルオプション
310-カーソルパラメータを設定します。
0ビット-カーソルの下のバー
1ビット-黒い四角
2ビット-フリッカー
3ビット-垂直ストリップ
311-カーソルパラメータのビット番号0の設定
...
314-カーソルパラメータのビット番号3の設定

320-カーソルの色の設定
321-カーソルの点滅時間の設定
322-カーソルの書き込み時間の設定

パレットを操作する
330-カラーパレットのアドレスの設定
331-設定されたアドレスでの記録色

シンボルテーブルを使用する
335-文字テーブルでのアドレスの設定
337-指定されたアドレスでNewSymbolを記録する
340-NewSymbol信号の下位32ビットの設定(NewSymbol(31:0))
341-NewSymbolの次の32ビットの設定(63:32)
342-NewSymbol(95:64)
343-NewSymbol(127:96)

ご清聴ありがとうございました。

Source: https://habr.com/ru/post/J129746/


All Articles