1

一度にたくさんのものを合計する Virtex6 のコード ブロックがあります。私はコードを継承しましたが、想像していたよりも少し難しいように思えますが、これが物事をすばやく合計するための最良の方法であると言われました.

基本的に、追加する必要がある一連の値 (たとえば 16 個) がある場合、現在それらを複数のレベルで追加しています (summedOutput と additionalOverflow は、符号付き加算を行い、オーバーフローを検出するための 2 つの関数です)。

    tmpSig_0_0 <= summedOutput(inSig_0, inSig_1);
    tmpSig_0_1 <= summedOutput(inSig_2, inSig_3);
    tmpSig_0_2 <= summedOutput(inSig_4, inSig_5);
    tmpSig_0_3 <= summedOutput(inSig_6, inSig_7);
    tmpSig_0_4 <= summedOutput(inSig_8, inSig_9);
    tmpSig_0_5 <= summedOutput(inSig_10, inSig_11);
    tmpSig_0_6 <= summedOutput(inSig_12, inSig_13);
    tmpSig_0_7 <= summedOutput(inSig_14, inSig_15);
    overflow_stage0 <= (| {overflow_input,additionOverflow(inSig_0,inSig_1,inSig_0+inSig_1),additionOverflow(inSig_2,inSig_3,inSig_2+inSig_3),additionOverflow(inSig_4,inSig_5,inSig_4+inSig_5),additionOverflow(inSig_6,inSig_7,inSig_6+inSig_7),additionOverflow(inSig_8,inSig_9,inSig_8+inSig_9),additionOverflow(inSig_10,inSig_11,inSig_10+inSig_11),additionOverflow(inSig_12,inSig_13,inSig_12+inSig_13),additionOverflow(inSig_14,inSig_15,inSig_14+inSig_15)});    

    tmpSig_1_0 <= summedOutput(tmpSig_0_0, tmpSig_0_1);
    tmpSig_1_1 <= summedOutput(tmpSig_0_2, tmpSig_0_3);
    tmpSig_1_2 <= summedOutput(tmpSig_0_4, tmpSig_0_5);
    tmpSig_1_3 <= summedOutput(tmpSig_0_6, tmpSig_0_7);
    overflow_stage1 <= (| {overflow_stage0, additionOverflow(tmpSig_0_0,tmpSig_0_1,tmpSig_0_0+tmpSig_0_1), additionOverflow(tmpSig_0_2,tmpSig_0_3,tmpSig_0_2+tmpSig_0_3), additionOverflow(tmpSig_0_4,tmpSig_0_5,tmpSig_0_4+tmpSig_0_5), additionOverflow(tmpSig_0_6,tmpSig_0_7,tmpSig_0_6+tmpSig_0_7)});

    tmpSig_2_0 <= summedOutput(tmpSig_1_0, tmpSig_1_1);
    tmpSig_2_1 <= summedOutput(tmpSig_1_2, tmpSig_1_3);
    overflow_stage2 <= (| {overflow_stage1, additionOverflow(tmpSig_1_0,tmpSig_1_1,tmpSig_1_0+tmpSig_1_1), additionOverflow(tmpSig_1_2,tmpSig_1_3,tmpSig_1_2+tmpSig_1_3)});

    outSig <= summedOutput(tmpSig_2_0, tmpSig_2_1);
    overflow <= (| {overflow_stage2, additionOverflow(tmpSig_2_0, tmpSig_2_1, tmpSig_2_0+tmpSig_2_1)});

これにより 4 レベルの追加が行われ (これは理にかなっています)、16 レベルよりもはるかに優れていると言われました。

outSig <= inSig_0 + inSig_1 + inSig_2 + inSig_3 .... inSig_14 + inSig_15;

私の問題は、物事を拡張したい場合、それは非常に手作業のプロセスであり、あまり適応性がないことです. 私がやっているよりもこれを行う賢い方法はありますか?パラメータのサイズに基づいて何かを追加する一連の for ループが最適ですが、基本的には上記の 2 番目の例になり、かなり深いものになる可能性があります。

4

2 に答える 2

2

既存のコード (長いコード) と 1 行のソリューションの主な違いは、既存のコードは結果を計算するために 4 クロック サイクルにパイプライン処理され、1 行のソリューションはすべての数値を 1 クロック サイクルで加算することを目的としていることです。 .

これらの s の幅によってinSigは、それらを一度に合計しようとするとタイミングが合わない場合があります。確かに試してみて、そのコードをあなたの提案に置き換えることはできますが、合成と P&R を試して、タイミング レポートがどのようになるかを確認する必要があります。目的のタイミング周波数を満たしている場合は、先に進んで安全にソリューションに置き換えることができます。

または、よりクリーンな浅いパイプラインを作成することもできます (1 クロック サイクルに 2 つではなく 4 つの信号を追加できますか?)

tmpSig_0 <= insig_0 + insig_1 + insig_2 + insig_3;
tmpSig_1 <= insig_4 + insig_5 + insig_6 + insig_7;
tmpSig_2 <= insig_8 + insig_9 + insig_10 + insig_11;
tmpSig_3 <= insig_12 + insig_13 + insig_14 + insig_15;

outSig   <= tmpSig_0 + tmpSig_1 + tmpSig_2 + tmpSig_3;

これは、はるかに複雑なコードではなく、5 行の 2 段階のパイプラインになりますが、タイミング要件を満たしているかどうかを確認する必要があります。

于 2013-09-19T15:47:59.783 に答える