2016-10-03 5 views
0

私はDE0 Nano Altera FPGAボードで簡単なブルートフォース畳み込みプロセッサを設定しようとしています。 はここに私のコードは次のようになります。VHDL:forループで、インデックス演算が機能しません

LIBRARY ieee; 
USE ieee.std_logic_1164.all; 
use ieee.numeric_bit.all; 

ENTITY Convolution IS 
    PORT( clock : IN std_logic; 
      audio_in : IN unsigned(15 downto 0); 
      audio_out : OUT unsigned(31 downto 0));  
END Convolution; 

ARCHITECTURE Convolution_Core OF Convolution IS 

    constant impulse_length : integer := 10; 

    type array16 is array(0 to impulse_length-1) of unsigned(15 downto 0); 
    type array32 is array(0 to impulse_length-1) of unsigned(31 downto 0); 

    constant impulse : array16 := (x"FFFF", x"FFFE", x"FFFD", x"FFFC", 
               x"FFFB", x"FFFA", x"FFF9", x"FFF8", 
               x"FFF7", x"FFF6"); 

    signal audio_buffer : array16 := (others=> (others=>'0')); 

    signal seq_buffer : unsigned(31 downto 0); 

BEGIN 
    process(clock) 
    begin 
     if rising_edge(clock) then 
      -- buffer the audio input in audio_buffer 
      for i in 0 to (impulse_length-2) loop 
       audio_buffer(i) <= audio_buffer(i+1); 
      end loop; 
      audio_buffer(impulse_length-1) <= audio_in; 

      for i in 0 to (impulse_length-1) loop 
       if i = 0 then 
        seq_buffer <= audio_buffer(i) * impulse(impulse_length-1-i); 
       else 
        seq_buffer <= seq_buffer + audio_buffer(i) * impulse(impulse_length-1-i); 
       end if; 
      end loop; 
     end if; 
    end process; 

    audio_out <= seq_buffer; 

END Convolution_Core; 

私の問題は、次のとおりです。インパルスのインデックス(impulse_length-1-i)は、forループの連続した時に減少していませんが、audio_bufferのインデックス(i)がありません。それは私がコードをシミュレートし、私の結果が間違っている理由を理解するのが大好きです。

ModelSimで見ることができるように信号にimpulse_length-1-iを入れようとしましたが、最大/最小32ビットの符号付き範囲(+/- 2 147 483 647)と次のサイクルはゼロにジャンプし、ゼロにとどまります。

また、変数jをプロセス内で使用しようとしました。プロセスの開始時にゼロで開始し、iの代わりに配列のインデックスとして使用し、実際の計算後にインクリメントすることができます。しかし、ModelSimは致命的なエラーを報告するようにしていたため、その理由も分かりません。

私が間違ったことを誰かに説明できますか?

Thanx事前に。

+0

も参照してくださいhttp://stackoverflow.com/questions/13954193/is-process-in-vhdl-reentrant/13956532#13956532 –

答えて

2

主な問題は、ソフトウェアを記述するのではなく、ハードウェアを記述するときに信号とループがどのように機能するかを理解できないことです。

2回目のforループの各繰り返しは、同じ信号に値を割り当てています。プロセス内では、指定されたシグナルへの最後のシグナル割り当てだけが重要であり、シグナルのすべての読み取りは、プロセスの開始前に保持していた値を使用します。つまり、2回目のforループの繰り返しは(impulse_length-1)だけです。

私は、信号や変数は、この上であなたにもう少し詳細を与えることができますVHDLプロセス内でどのように機能するかについて、数年前に答えを書いた:あなたはそのようなすべての10の追加/乗算演算することを記述する場合https://stackoverflow.com/a/19234859/1360002

seq_bufferの代わりに変数を使用して実際にseq_bufferシグナルに割り当てる値を計算するなど)、ロジックパスが非常に長くなるハードウェアについては説明していますが、クロックレート適度に高い。これはあなたのケースでは問題ではないかもしれません。

さらに、結果の幅が乗算演算子から出てくることがあるかもしれませんが、乗算単位を暗示していないのでわかりませんので、関連する演算子関数の詳細はよくわかりません。

0

Thanxは私に答えるためにたくさん!

私が正しく理解している場合、プロセス内の変数を含むforループを使用すると、いくつかの「生成」ステートメントを使用するのと同じ種類のロジック実装につながります。たぶん私は畳み込みアルゴリズムに似たようなものを試してみるとコンパイルに時間がかかりました;)

JavaやCのforループに似た何かをする唯一の方法は、入力信号を切り替えて、連続した結果をバッファリングします。

しかし、私が書き込んだ "オーディオバッファリング"プロセスがタイミングシミュレーションでも正しく動作している理由がわかりません。

敬具

+0

ループがあるときので、ループのための「オーディオのバッファリングが」作品各反復は、シグナルの異なるインデックスに値を割り当てています。これは、すべてが競合することなく並行して動作できることを意味します。 Forループは実際にはシグナル上で連続して動作しません。 Generate文はループの場合と同じように機能しますが、最終的な割り当ての問題だけでなく、実装時に複数のドライバエラーが発生します。 – QuantumRipple

+0

真のシーケンシャルロジックを実行する唯一の方法は、数学ブロックに入力を多重化する何らかの種類のステートマシンを持たせることですが、すべての10個の値の組み合わせで毎回新しい出力を得るには、変数を使用して、10回の乗算加算またはパイプラインによる計算(リソースを節約することはできませんが、ロジックパスは短くなります)を使用して、長いタイミングパスを作成する必要があります。 – QuantumRipple

+0

コンパイル時間は、デザインのタイミング効率やリソース効率がどのように重要であるのか一般的に意味がありません。これは、ターゲットFPGAにどれだけ多くのリソースが使用されているかと、どの程度のリソースが使用されているかと相関があります。実装しようとしている機能の実際に必要な数(効率)と比較して、 – QuantumRipple

関連する問題