4

だから、私はベリログで加算器ツリーを書き込もうとしています。その一般的な部分は、追加する要素の構成可能な数と構成可能なワードサイズがあることです。しかし、私は問題を次々と抱えており、これが私の問題を解決する正しい方法であると疑問を呈し始めています。(私はより大きなプロジェクトでそれを使用します。)加算器ツリーをハードコーディングすることは間違いなく可能ですが、それは多くのテキストを必要とします。

だから、私はあなたとあなたがそれについてどう思うかについてスタックオーバーフローをチェックしたいと思います。これは「それを行う方法」ですか?さまざまなアプローチについての提案も受け付けています。

また、私はVerilogを初めて使用することもできます。

誰かが興味を持っている場合のために、これが私の現在の機能していないコードです:(私はあなたが問題を解決することを期待していません;私は便宜のためにそれを示しています。)

module adderTree(
    input clk,
    input [`WORDSIZE * `BANKSIZE - 1 : 0] terms_flat,
    output [`WORDSIZE - 1 : 0] sum
);

genvar i, j;

reg [`WORDSIZE - 1 : 0] pipeline [2 * `BANKSIZE - 1 : 0];   // Pipeline array
reg clkPl = 0;                                              // Pipeline clock

assign sum = pipeline[0];

// Pack flat terms
generate
    for (i = `BANKSIZE; i < 2 * `BANKSIZE; i = i + 1) begin
        always @ (posedge clk) begin
            pipeline[i] <= terms_flat[i * `WORDSIZE +: `WORDSIZE];
            clkPl = 1;
        end
    end
endgenerate

// Add terms logarithmically
generate
    for (i = 0; i < $clog2(`BANKSIZE); i = i + 1) begin
        for (j = 0; j < 2 ** i; j = j + 1) begin
            always @ (posedge clkPl) begin
                pipeline[i * (2 ** i) + j] <= pipeline[i * 2 * (2 ** i) + 2 * j] + pipeline[i * 2 * (2 ** i) + 2 * j + 1];
            end
        end
    end
endgenerate

endmodule
4

1 に答える 1

7

以下に、役に立つと思われるコメントをいくつか示します。

クロッキング

一般に、デザイン内のクロックはできるだけ少なくすることをお勧めします (できれば 1 つだけにすることをお勧めします)。

この特定のケースでは、新しいクロックclkPlを生成しようとしているように見えますが、これは 0 に戻らないため機能しません。 "clkPl = 1;" で永続的に 1 になります。)

これを置き換えるだけで修正できます

always @ (posedge clkPl)

always @ (posedge clk)

課題

組み合わせブロックではブロック割り当てのみを使用し、クロック付きブロックでは非ブロック割り当てを使用することをお勧めします。「Pack flat terms」セクションで、ブロッキング割り当てと非ブロッキング割り当ての両方を混在させています。

clkPlは必要ないので、ブロッキング割り当て ("clkPl = 1;") を含む行を削除するだけです。

ツリー構造

あなたのダブル for ループ:

for (i = 0; i < $clog2(`BANKSIZE); i = i + 1) begin
    for (j = 0; j < 2 ** i; j = j + 1) begin
        always @ (posedge clkPl) begin
            pipeline[i * (2 ** i) + j] <= pipeline[i * 2 * (2 ** i) + 2 * j] + pipeline[i * 2 * (2 ** i) + 2 * j + 1];
        end
    end
end

間違った要素にアクセスするようです。

たとえば、BANKSIZE = 2 8 の場合、**iは 7 までカウントされ、その時点で "pipeline[i * (2 ** i) + j]"="pipeline[7*2**7+j]"="配列の範囲外になるパイプライン[896+j] (配列には 2*BANKSIZE=512 要素が含まれます)。

私はあなたが実際にこの構造を望んでいると思います:

assign sum = pipeline[1];
for (i = 1; i < `BANKSIZE; i = i + 1) begin
    always @ (posedge clk) begin
        pipeline[i] <= pipeline[i*2] + pipeline[i*2 + 1];
        end
    end

低レイテンシー

ほとんどの Verilog ツールは、複数の要素の加算を合成するのに非常に優れているため、階層の各レベルでより多くの項を結合することを検討する必要がある場合があることに注意してください。

(ツールはキャリー セーブ アダーなどの最適化を使用してゲート遅延を削減できるため、項を追加しても予想よりもコストがかかりません。)

于 2013-01-22T21:43:32.100 に答える