0

ザイリンクス ISE 14.2 を使用して、VHDL のパケット ソーティング パイプラインに取り組んできました。構造を一般的なものにするために、ソート ノードの接続方法を決定するいくつかのアルゴリズムをパッケージに記述しました。興味深いことに、関数を中心にテスト ベンチを設計すると、正しい結果が得られます。生成と関数の組み合わせを使用してプロジェクトでデザインをシミュレートすると、ハードウェアが正しく配線されます。('assert false report " & integer'image(layer);' を使用してシミュレーションで検証) しかし、RTL 回路図を生成すると、一部のノードが正しく接続されていないことがわかります。

これはバグであると 90% 確信していますが、私はこのソフトウェアのベテランではありません。関数は機能します。この段階では、使用可能なリソースの 2% が使用されている可能性があります。誰もが知っている秘密の旗や特殊性はありますか?

みんなありがとう。よろしく、スティーブ

4

3 に答える 3

1

XST はかなり信頼できます。

私が XST で見た唯一の本物の間違ったハードウェア バグは、プロセス内のプロシージャに OUT パラメータとして渡されたシグナルに関するものです... シグナルは、変数代入 (即時代入) セマンティクスを使用して代入されました!

ISE14 では、Spartan-3 以前のデバイスをターゲットにしている場合はこのバグが残っていますが、Spartan-6 以降のデバイスをターゲットにしている場合はありません。XST には 2 つの異なる VHDL パーサーがあり、新しい方が優れているようです。

そのため、他のパーサーを使用して (ターゲット ファミリを変更するか、「use_new_parser」設定またはコマンド ライン オプションを使用して) 再試行できます。詳細については、ザイリンクスのドキュメントを参照してください。

また、合成後のネットリストをテストベンチに接続して、シミュレーションでエラーを再現 (または再現しない) することもできます。(IMO では、合成後および PAR 後のシミュレーションの唯一の実用的な用途は、ツールのバグの可能性を確認または排除することです!)

そして、フィリップが言うように、小さなデモンストレーターを手に入れるか、本当の問題が何であるかを見つけるまで、デザインを分割して征服してください!

編集 :

いくつかのポイントを示すために追加されました...

l,n の正しい整数値が与えられると、この問題をより詳細に特徴付けることができます... 上記の主張から、n=8、l=3 と推測できます。

    library IEEE;
    use ieee.math_real.all;

    entity count is
    end count;

    architecture Behavioral of count is

    constant n : integer := 8;
    constant l : integer := 3;

    begin

       report "n: " & integer'image(8) severity Note;
       assert false report "r: " & real'image(8.0) severity Note;
       report "Border a: " & real'image(real(n) + ( real(n) mod 2.0)) severity Note;
       report "Border b: " & real'image(2.0**(real(l+1) - 1.0)) severity Note;
       report "Border a/b: " & real'image((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0))) severity Note;
       report "Ceil a/b: " & real'image(ceil((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0)))) severity Note;
       report "Residual a/b: " & real'image((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0)) - 1.0 ) severity Note;

    end Behavioral;

1) 「Assert False」は不要 (1993年以降)

2) 一般的な神話に反して、条件が静的に決定可能であれば、asserts は合成可能です。したがって、上記のコードでは、l,n は定数、XST 合成、レポート ...

Spartan-3 をターゲットにすると、次のようになります。

INFO:Xst:1749 - "count.vhd" line 15: note: n: 8
INFO:Xst:1749 - "count.vhd" line 16: note: r: 0

そのため、古いパーサーを使用して、合成で Math.Real を使用することは十分にサポートされていませんでした。具体的には、real'image は 0 を返しました!

Spartan-6をターゲットに、

Elaborating entity <count> (architecture <Behavioral>) from library <work>.
Note: "n: 8"
Note: "r: 8.0"
Note: "Border a: 8.0"
Note: "Border b: 8.0"
Note: "Border a/b: 1.0"
Note: "Ceil a/b: 2.0"
Note: "Residual a/b: 2.22044604925031E-16"

そのため、「エラー」を再現しました。しかし決定的に重要なのは、式の上限ではなく 1.0 を減算すると、残差 (丸めによって導入された) を確認できることです。そして、小さいながらもポジティブであることがわかります。

したがって、Ceil() は 2.0 を返す際に正しく動作しており、これは合成ツールのバグではありません。

シミュレーションで同じことを試すと、おそらく同様に小さいが負の数が見つかるため、それも正しいです...

浮動小数点に関するKahan 教授によるこの論文およびその他の論文を参照してください。これはツールの問題でも VHDL の問題でもありませんが、はるかに大きなワームの缶詰です...

したがって、最後の言葉は次のとおりです。整数演算で同じタスクを達成する方法を見つけることができれば、それがより良い解決策になります。

于 2012-12-28T21:36:19.117 に答える
0

生成された RTL 回路図を正しく理解していない可能性があります。FPGA 用の最新の合成ツールは、フリップフロップの境界を越えてロジックをプッシュしたり、ロジックを複製したり、コンパイルされたロジックの速度を向上させたりサイズを縮小したりするためのさまざまなトリックを含む、多くの最適化を行いますこの最適化ロジックにバグがある可能性はありますが、あなたのデザインがまったく自明ではない場合は、合成ツールが物事を「改善」するために行ったマングリングを完全に理解していないだけだと思います。動作に違いがある場合は、ツールにバグがあるか、コードが曖昧で、シンセサイザーとシミュレーターが異なることを行っている可能性があります。これを解決するには、コードを投稿する必要があります。

于 2012-12-28T20:17:17.090 に答える
0

あなたの時間と考えをありがとう。最終的には、IEEE.MATH_REAL の CEIL 関数の動作がシミュレーションと合成で異なるため、「グリッチ」に行き着きました。

コードに ASSERT ステートメントを貼り付けることでこれを解決しました (注: これらは SIMULATION でのみ機能します)。どこで問題が発生する可能性があるかを考えたので、以下に示すように、そのような ASSERT ステートメントを使用して関数の 1 つを分析しました。したがって、このデバッグ アプローチの目的は、合成前の関数の出力と合成後の出力を比較することです。通常のビヘイビア シミュレーションを使用してから、「合成後のシミュレーションを生成」アサート ステートメントを使用すると、シミュレーション中に値がコンソール ウィンドウに出力されます。初期化期間。

アサート コードの例: (注: integer'image は数値を文字列に変換します。assert false force to print ステートメント (以前の VHDL バージョンで必要))

assert false report "Border Value: " & integer'image(Border(l+1, n));
assert false report "Border a: " & real'image(real(n) + ( real(n) mod 2.0));
assert false report "Border b: " & real'image(2.0**(real(l+1) - 1.0));
assert false report "Border a/b: " & real'image((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0)));
assert false report "Ceil a/b: " & real'image(ceil((real(n) + ( real(n) mod 2.0))/(2.00 ** (real(l+1) - 1.0))));

結果:

これが合成前の出力です。ceil 関数を見てください。

Error: ""
Error: "(3,8)"
Error: "Node Port-ID (In.Port 0 then 1): 46 - 47"
Error: "Next Node (Out.Port 0 then 1): 4 - 8"
Error: "Dst Port: 1"
Error: "Border Value: 4"
Error: "Border a: 8.0"
Error: "Border b: 8.0"
Error: "Border a/b: 1.0"
Error: "Ceil a/b: 1.0"
Error: "Next Node Port-ID(Out.Port 0 then 1): 55 - 63"
Error: ""

これが合成後の出力です。ceil 関数をもう一度見てください。

Error: "(3,8)"
Error: "Node Port-ID (In.Port 0 then 1): 46 - 47"
Error: "Next Node (Out.Port 0 then 1): 8 - 12"
Error: "Dst Port: 0"
Error: "Border Value: 12"
Error: "Border a: 8.0"
Error: "Border b: 8.0"
Error: "Border a/b: 1.0"
Error: "Ceil a/b: 2.0"
Error: "Next Node Port-ID(Out.Port 0 then 1): 62 - 70"
Error: ""

結論:

シミュレーションでは、1.0 などの整数が CEIL に入力されると、1.0 が返されます。ただし、合成中に 1.0 は次の整数 (2.0) に丸められ、非整数部分が取り除かれ、1 が追加されます (例: 0.75 -> 0 -> 1)。解決策 (少なくとも私の場合) は、値から 0.01 を減算することです。 ceil にフィード (eg 1 -> 0.99 -> 1) これは、私が遭遇したドキュメントのいずれにも記載されておらず、これが意図されているとは思いません。Verilog は $display コマンドをサポートしており、これはこの場合に非常に役立ちました。

追加するものがない場合は、ザイリンクス サポート チームに報告します。

再度、感謝します。スティーブ

于 2012-12-28T22:59:31.673 に答える