2012-01-18 4 views
0

現在、VGA経由でビデオデータを送信するデバイスの場合、VHDLで画面バッファを作成しようとしています。私はザイリンクスISE 13.1を使用しています。私はVHDLの初心者です。合成中にクラッシュするvhdlの画面バッファ

私の考えは、各ピクセル(8ビット)のRGB値を含む大きな二次元配列を作成することでした。

私は問題なく配列に書き込むことができますが、読んでみるとさらに複雑になります。合成が非常に長くなり、コンピュータがシャットダウンするまでメモリが完全に飽和します。ここで

はちょうど赤45度線を引くしようとしている、私のコードの簡易版である:

entity Pilotage_ecran is 
port(clk25 : in std_logic; --25MHz clock 
    red_out : out std_logic; --Untill the problem is solved, i use only 1 bit to set colors 
    green_out : out std_logic; 
    blue_out : out std_logic; 
    hs_out : out std_logic; 
    vs_out : out std_logic); 
end Pilotage_ecran; 

architecture Behavioral of Pilotage_ecran is 


signal horizontal_counter : std_logic_vector (9 downto 0); 
signal vertical_counter : std_logic_vector (9 downto 0); 
signal drawing : std_logic; --Signal that is set to 1 when the active video area is reached 
signal busy : std_logic; --Signal to avoid launching the drawing process twice in parallel 


--The array (actually containing single bits instead of vectors untill I solve the problem) 
type TAB_BUFFER is array(0 to 1023, 0 to 1023) of std_logic; 

signal Ecran : TAB_BUFFER := (others=>'0'); 


begin 

メインプロセス:

process (clk25) 

variable coordX : integer; 
variable coordY : integer; 

begin 
    if clk25'event and clk25 = '1' then 


    if (horizontal_counter >= "0010010000") -- 144 : limits of active video area 
    and (horizontal_counter < "1100010000") -- 784 
    and (vertical_counter >= "0000100111") -- 39 
    and (vertical_counter < "1100010000") -- 519 
    then 

     drawing <= '1'; 

    coordX := conv_integer (horizontal_counter); 
    coordY := conv_integer (vertical_counter); 


     if Ecran(coordX,coordY) = '1' then --Here is the problem 
      red_out <= '1'; 
        green_out <= '0'; 
      blue_out <= '0'; 
     else 
      red_out <= '0'; 
        green_out <= '0'; 
      blue_out <= '0'; 
     end if; 



    else 
     drawing <= '0'; 

    end if; 




    --Hsync and Vsync come after, but the code is safe and tested 

end if; 
end process; 

描画処理(実際には醜いで線を引きます私はちょうどバッファに何かを得たいと思っていた)。その後、

Ecran(coordX、coordY)= '1' の場合

draw : 
process (drawing, clk25, busy) 


--Coordinates of the starting point (actually random values...) 

variable i : integer; 
variable j : integer; 

begin 

    if (drawing = '1') and clk25 = '1' and busy = '0' then 

     busy <= '1'; 

     i :=300; 
     j :=300; 

     --The loop setting the coordinates of the line to '1' 

     loopx : while (i<=350) loop 
      Ecran(i,j) <= '1'; 
      i := i+1; 
      j := j+1; 

     end loop loopx; 

     busy <='0'; 
    end if; 


end process draw; 



end Behavioral; 

私にトラブルを起こしラインiがバッファ内にいくつかの座標に値にアクセスしようとするものです

私はまた、このように実行しようとしました:< = Ecran(coordX、coordY)red_out

iは整数値でcoordXまたはcoordYのいずれかを交換する場合、それは(表示doesntのは、バッファに一致するが、それは動作します)正常に動作しますが、私はそれらの両方のための変数を使用する場合には、合成時にクラッシュします。私はかなりいくつかの作業コードに一致するように見えても、私は配列(私はちょうどそれらを使用する方法を学んだ)に何か間違っていたと確信しています。私はまた、(おそらく)大きすぎる配列を使用している可能性があります。

誰かが私が何をやったのか、またはvhdlでスクリーンバッファを作成する方法についてもっと良い方法があれば、どんな助けでも大歓迎です。

ありがとうございます。

答えて

2

VGAがどのように動作するのかわかりませんが、あなたのコードを見ています私はあなたの "描画プロセス"に根本的に間違いがあると信じています。ハードウェア開発者ではなく、ソフトウェア開発者として何かをしようとしています。

if (drawing = '1') and clk25 = '1' and busy = '0' then 

文の場合には、この下のプロセスのほとんどをネスト要するに

は、あなたの問題です。私が見ることができる2つの理由。最初に、ループ内のカウンタを、クロックに完全に非同期で(clock = '1'と言う場合)、無限期間高い間にインクリメントします。そのインクリメンタの更新はカウンタを通る予測遅延によってのみ制限されます。すべてのカウンタは同期(rising_edge(clk)の場合)または(clock = 1およびclk'eventの場合)同期する必要があります。

他のエラーは、現在のコンビナトリアルセットアップ(asynch)と関連しています。これは同期プロセスにすると消えてしまいます。ビジーを行うことにより、コンビナトリアルロジックのif文の直後に '1'が表示されます。このブロックをハードウェアで本質的に無効にしています。同期ソリューションをどのようにコード化するかによって、これは問題になる場合もあります。

最後に、ハードウェアではなくソフトウェアをプログラミングすることを考えているため、最初に< = '1'、if文の最後に「< = '0」とビジー状態です。同期または非同期の設計の場合、これはビジー状態になります。< =「0」。代わりに、(同期すると)ビジー状態になりました< = ifステートメントの外側では '0'、ifステートメント内では< = '1'です。ステートメントがビジーを実行するたびに、クロック信号全体が1になります。

VHDLをプログラムするときは、連続して(非同期に)実行するか、定期的に(クロックと同期して)実行するすべてのコマンドについて考える必要があります。 if文のイベントが真でない場合でも、if文のすべてのイベントが実行されます。 ifステートメントは単に「有効」として機能します。これのすべてを言って、次のコードはあなたが望むことをしているかもしれません。

draw : process (clk25) 
    --Coordinates of the starting point (actually random values...) 
    variable i : integer := 300; 
    variable j : integer := 300; 

begin 

    if (rising_edge(clk)) then 
     busy <= '0'; 
     if (i<=350) then 
      busy <= '1'; 
      Ecran(i,j) <= '1'; 
      i := i+1; 
      j := j+1; 
     end if; 
    end if; 
end process draw; 

私はあなたの「引き出し」が実際には、事前に大きな配列をロードし、色を設定しているあなたの他のプロセスが実際にあなたの作家であるとされていることと思いますか?あなたは赤い/緑色/青色のビットを画面に書いているときに、行全体を通してインクリメントしていて、列を下ろしているという印象を受けましたか?再び私は、(ディスプレイがバッファと一致していませんが、それは動作します)私は整数値でcoordXまたはcoordYのいずれかを交換する場合、それは 罰金を作品VGA

+0

ありがとうございます。これは私の最初の問題を解決しませんでしたが、それは私のプロセスとvhdlの理解を向上させるのに多大な助けとなりました。最後のパラグラフでは、描画プロセスは各ピクセルの値をバッファに保存しますが、メインプロセスはバッファ内の各ピクセルのRGB値を読み込み、VGAケーブルに送信してから次のピクセルに移動します。 –

+0

最初の問題は、このコードを合成できないということですか?私はあなたが完全に無駄な箱にいない限り、配列のサイズは問題であるとは思わない。あなたの配列は128kbのメモリに相当します。これはいくつかのFPGAでは不可能かもしれませんが、あなたが1つを使用しているような音ではありません。あなたはそれが本当に合成不可能なものではないと確信していますか?物事が停止する前にエラーメッセージが出ますか? –

+0

私はFPGA(スパルタン開発ボード)を使用して、入来データをビデオ信号に変換するので、メモリが問題になります。エラー/警告は表示されず、このログの後に合成がHDL分析に貼り付けられます。 ライブラリのエンティティの解析(アーキテクチャ)。 –

1

について何も知らないが、私が使用している場合 両方の変数が合成中にクラッシュします。私はかなり 私は配列(私はちょうどそれがいくつかの作業コードに一致すると思われる場合でも それらを使用する方法を学んだ)何か間違っていたことを確認しています。私も(おそらく )大きすぎる配列を使用している可能性があります。

RAMの小さなブロックで構成された大容量メモリ用の読み出しマルチプレクサを作成しようとしています。十分なブロックと問題は、特定のビルドプラットフォームでは難しくなります。

この場合、TAB_BUFFERを小さく(0〜639,0〜479)定義でき、メモリの2/3を節約できます(307,200対1 Mピクセル) 。問題を合成するのに十分なほど小さなものにスケールすることは明らかではなく、そうであれば、それが十分に速いかどうかは分かりません。

別の表示アドレスカウンタを使用するか、ディスプレイの最初の表示可能なピクセルとしてゼロを通過させるかのいずれかで、現在の水平カウンタと垂直カウンタからフレームバッファアドレスを切り離したい場合もあります。これにより、書き込み中にアドレス変換を行う必要がなくなります。

メモリデザインを定義して、合成できないことを克服できます。これは、配置を行うのと同じくらい単純でも、階層を作成するほど複雑なものでもあります。アイデアは、あなたが行う仕事を少なくすることによって、合成から離れた仕事の一部を取ることです。

+0

まずはお返事ありがとうございます。後で解像度を後で上げなければならないので、サイズを1024 * 1024に設定しました。私は2 640 * 240(画面の上半分と下半分を管理する)に画面サイズを分割しようとしましたが、これ以上のクラッシュの問題はありませんが、合成はまだ終了しません。いくつかの "ゾーン"でバッファを分割すると、合成ツールの作業が簡単になり、メモリ管理が改善されるのですか、別のソリューションを見つける必要がありますか? –

+0

@Mathieu C. ISE 13.1でBlock Memory Generator v6.1を使用できます。 [v6.1データシート](http://www.xilinx.co.jp/support/documentation/ipmeminterfacestorelement_ramrom_blockmemgenerator.htm)(PDF)を参照してください。ここでのトレードオフは機能性と移植性です。メモリジェネレータは、生成されたメモリのビヘイビアVHDLモデルと構造VHDLモデルの両方を生成できます。メモリのサイズとパフォーマンスは、ファミリとデバイスによって異なります。このツールは、階層と配置を管理します。 FPGAのコスト/性能に合わない機能を捨てる、あるいは戻って大きなボートを得るということです。 – user1155120

関連する問題