Brent Kung Adder : 回路、動作、利点、欠点、およびその応用

問題を排除するために楽器を試してください





ブレント・クン加算器は、1982 年に Hsiang Te Kung と Richard Peirce Brent によって提案されました。これは、その柔軟性によりデジタル設計で広く使用されている並列プレフィックス加算器またはツリー加算器です。並列プレフィックス加算器は、論理レベルの数に基づいていくつかの方法で構築できます。 論理ゲート これには、すべてのゲートからのファンアウトとレベル間の配線が関係します。利用可能なさまざまなタイプのツリー加算器があり、基本的なツリー加算器は Sklanskym KoggeStone および Brent-Kung です。KSA (Kogge-Stone 加算器) と比較して、この加算器は加算器の構造に高い規則性を提供し、配線のブロックが少なくなります。これにより、パフォーマンスが向上し、必要なチップ面積が減少します。この記事では、 ブレント・クン・アダー


ブレント・クン・アダーとは何ですか?

結果を得るために最小限の回路を使用する加算器は、Brent Kung Adder として知られており、低電力加算器または並列加算器としても知られています。この加算器は、チップのサイズを節約して、これらの加算器の製造を容易にすることを目的としています。この加算器の対称性と通常の構築構造により、生産コストが大幅に削減され、パイプライン トポロジでの使用が可能になります。相補型パス トランジスタ ロジックの利用は、設計パフォーマンスの向上に役立ちます。 マルチプレクサ さまざまなセル設計にアプローチします。



ブレント・カン加算回路

brent-kung 並列プレフィックス加算器の図を以下に示します。これには、ステージ 1 (前処理ステージ)、ステージ 2 ~ 7 はキャリー生成ステージ、ステージ 8 は後処理が含まれます。これは高度なアーキテクチャであり、構築が非常に簡単で、配線の混雑が軽減されます。そのため、配線が少なくなり、アーキテクチャを実行するために必要なスペースの量が減少します。さらに、配線の交差(または重なり)が少なくなるため、配線がはるかに簡単になります。ただし、段数の増加により遅延のペナルティが増加します。この加算器のファンアウトが増加すると、遅延が増加します。

  ブレント・クン・アダー
                                                        ブレント・クン・アダー

ブレント・クン・アダーはどのように機能しますか?

Brent Kung Adder は、4 ビット グループのプレフィックスを見つけるのに役立つ 2 つのビット グループのプレフィックスを計算することによって機能します。これらのプレフィックスは、8 ビット グループのプレフィックスなどの計算に使用されます。その後、これらのプレフィックスは、特定のビット ステージのキャリーアウトの計算に使用されます。これらのキャリーは、次のステージのグループ伝播で使用され、そのステージの合計ビットを計算します。 Brent Kung Tree は 2log2N – 1 ステージを使用します。



32 ビット Brent Kung 加算器

32 ビット Brent Kung 加算器のレイアウトを以下に示します。このレイアウトの開始時に、NAND、インバーター、XOR、NOR などの基本的な論理ゲートが設計されます。その後、黒のセル、灰色のセル、バッファー、PG ロジックなどの必要なセルが論理ゲートで設計されます。

  32 ビット Brent Kung 加算器
                                  32 ビット Brent Kung 加算器

以下の 32 ビット Brent Kung 加算器では、AOI や OAI などの反転ゲートが主にグレーと黒のセルに交互に使用されます。したがって、黒とグレーのセルはグレーと黒のブロックで表され、バッファーは円で表されます。

  プリント基板ウェイ   加算器の基本セル
加算器の基本セル

A と B のような入力は、ブロック図に示されている PG ロジックに提供されます。 32 ビット加算器の場合、32 の PG ロジック ブロックが必要で、伝播 (P) 信号と生成 (G) 信号がこのブロックの出力になります。これらの信号は、Brent Kung 加算器ツリー構造に提供されます。この加算器の構造には灰色のセルと黒色のセルが含まれています。

灰色のセルには 3 つの入力と 1 つの出力が含まれます。現在のステージからの信号の伝播と生成、および前のステージからの信号の生成は入力ですが、グループ生成信号は O/P です。どのようなツリー構造でも、各ステージは灰色のセルで終了し、このセルの O/P がグループ生成信号になります。この信号は、単にそのステージのキャリーと見なされます。ブラックセルには 4 つの入力と 2 つの出力が含まれます。このセルの入力は、現在のステージの P&G 信号と前ステージからの P、G 信号です。

PG ロジックには AND ゲートと XOR ゲートが含まれており、AND ロジック ゲートは G 信号の生成に使用され、XOR ロジック ゲートは P 信号を提供します。無駄なインバーターを排除するため、グレーセルとブラックセルの2種類を採用。グレー セルの 1 つの行で使用される反転ゲートは AOI または AND-OR-Inverter であり、次の行内の黒セルの反転ゲートは OAI または OR-AND-Inverter を使用します。 AOI セルは通常の入力を使用して反転出力を提供しますが、OAI は反転入力を使用して通常の出力を提供します。

ブレント クン加算器の操作

Brent Kung 加算器は、高性能加算演算に使用される並列プレフィックス加算器です。この加算器は算術演算を実行するツリー構造のように見えます。この加算器には黒のセルと灰色のセルが含まれます。すべての黒いセルには 2 つの AND ゲートと 1 つの OR ゲートがあり、すべての灰色のセルには 1 つの AND ゲートのみがあります。

Brent-kung 加算器には 2 つのステージが含まれています。前処理段階と生成段階。最初の段階では、入力のすべてのペアから生成と伝播が行われます。ここで、伝播は入力ビットに対して「XOR」演算を提供するのに対し、生成は入力ビットに対して「AND」演算を提供します。 「Pi」と「Gi」のような伝播と生成を以下に示します。

Pi = Ai XOR Bi および Gi = Ai AND Bi。

第 2 ステージでは、キャリー生成「Cg」として知られるビットごとにキャリーが生成され、キャリー生成「Cp」として知られるビットごとにキャリーが伝播されます。以降の操作では、キャリー伝播とキャリー生成が生成されます。すべてのビット操作内で利用可能な最後のセルはキャリーを提供します。したがって、最後のビットのキャリーは、最後のビットまで同時に次のビットの合計を支援します。キャリーの生成と伝播は次のように与えられます。

Cp = P1 AND P0 および Cg=G1 OR (P1 AND G0)

これは主に 2 32 ビットの加算演算に使用され、すべてのビットが前処理段階と生成段階を経て、最終的な合計が得られます。

プライマリ入力ビットは前処理ステージの下に進み、伝播と生成を生成します。したがって、これらの伝播と生成は、生成ステージを経て、キャリーの生成とキャリーの伝播を経て、最終的な合計を提供します。 Brent-kung 加算器の段階的なプロセスを以下に示します。

  効率的なブロック図
効率的なブロック図

Brent-kung 加算器の配置はツリー構造のように見え、ゲート レベルのロジックを対象とした高速加算器です。この加算器は、論理ゲートの数を減らして設計することができる。したがって、このアーキテクチャ内で使用される遅延とメモリが削減されます。

Brent Kung Adder Verilog コード

Brent Kung 加算器の Verilog コードを以下に示します。

`define INPUTSIZE 64 //入力サイズnを設定します

`define GROUPSIZE 8 //グループサイズを1、2、4、または8に設定します

 

モジュール Brent_Kung_Adder(A, B, S);

入力 [`INPUTSIZE – 1:0] A;

入力 [`INPUTSIZE – 1:0] B;

出力 [`INPUTSIZE:0] S;

ワイヤー [`INPUTSIZE / `GROUPSIZE * 2 – 1:0] r_temp;

ワイヤー [`INPUTSIZE / `GROUPSIZE * 2 – 1:0] r;

ワイヤー [`INPUTSIZE / `GROUPSIZE:0] cin;

ワイヤー [`INPUTSIZE / `GROUPSIZE * 2 – 1:0] q;

cin[0] = 1’b0を割り当てます。

生成する

どこで;

for (i = 0; i < `INPUTSIZE / `GROUPSIZE; i = i + 1) begin:Parallel_FA_CLA_prefix

    group_q_世代 #(.Groupsize(`GROUPSIZE))

    f(

        .a(A[`GROUPSIZE * (i + 1) – 1:`GROUPSIZE * i]),

        .b(B[`GROUPSIZE * (i + 1) – 1:`GROUPSIZE * i]),

        .cin(cin[i])、

        .s(S[`GROUPSIZE * (i + 1) – 1:`GROUPSIZE * i]),

        .qg(q[i * 2 + 1:i * 2])

    );

終わり

Parallel_prefix_tree_first_half #(.Treesize(`INPUTSIZE / `GROUPSIZE))

t1(

    .q(q[`INPUTSIZE / `GROUPSIZE * 2 – 1:0]),

    .r(r_temp[`INPUTSIZE / `GROUPSIZE * 2 – 1:0])

);

パラレルプレフィックスツリー_セカンドハーフ #(.Treesize(`INPUTSIZE / `GROUPSIZE))

t2(

    .q(r_temp[`INPUTSIZE / `GROUPSIZE * 2 – 1:0]),

    .r(r[`INPUTSIZE / `GROUPSIZE * 2 – 1:0])

);

for (i = 0; i < `INPUTSIZE / `GROUPSIZE; i = i + 1) begin: cin_generation

    cin_generation_logic f(

        .r(r[2 * i + 1:2 * i]),

        .c0(1'b0)、

        .cin(cin[i + 1])

    );

終わり

assign S[`INPUTSIZE] = cin[`INPUTSIZE / `GROUPSIZE];

終了する

エンドモジュール

// 並列プレフィックス ツリーの前半

モジュールParallel_prefix_tree_first_half #(parameter Treesize = `INPUTSIZE / `GROUPSIZE)(q, r);

入力 [ツリーサイズ * 2 – 1:0] q;

出力 [ツリーサイズ * 2 – 1:0] r;

生成する

どこで;

if (ツリーサイズ == 2) 開始: trivial_case

    r[1:0] = q[1:0] を割り当てます。

    プレフィックスロジック f(

        .ql(q[1:0])、

        .qh(q[3:2])、

        .r(r[3:2])

    );

end else begin: recursive_case

    ワイヤー [ツリーサイズ * 2 – 1:0] r_temp;

    Parallel_prefix_tree_first_half #(.Treesize(Treesize / 2))

    recursion_lsbh(

        .q(q[ツリーサイズ – 1:0]),

        .r(r_temp[ツリーサイズ – 1:0])

    );

    Parallel_prefix_tree_first_half #(.Treesize(Treesize / 2))

    recursion_msbh(

        .q(q[ツリーサイズ * 2 – 1:ツリーサイズ]),

        .r(r_temp[ツリーサイズ * 2 – 1:ツリーサイズ])

    );

    for (i = 0; i < Treesize * 2; i = i + 2) 開始:Parallel_stitch_up

        if (i != Treesize * 2 – 2) begin:Parallel_stitch_up_pass

            割り当て r[i + 1:i] = r_temp[i + 1:i];

        end else begin:Parallel_stitch_up_Produce

            プレフィックスロジック f(

                .ql(r_temp[ツリーサイズ – 1:ツリーサイズ – 2]),

                .qh(r_temp[ツリーサイズ * 2 – 1:ツリーサイズ * 2 – 2]),

                .r(r[ツリーサイズ * 2 – 1:ツリーサイズ * 2 – 2])

            );

        終わり

    終わり

終わり

終了する

エンドモジュール

// 並列プレフィックス ツリーの後半

モジュールParallel_prefix_tree_Second_half #(parameter Treesize = `INPUTSIZE / `GROUPSIZE)(q, r);

入力 [ツリーサイズ * 2 – 1:0] q;

出力 [ツリーサイズ * 2 – 1:0] r;

ワイヤー [ツリーサイズ * 2 * ($clog2(ツリーサイズ) – 1) – 1:0] r_temp;

assign r_temp[ツリーサイズ * 2 – 1:0] = q[ツリーサイズ * 2 – 1:0];

生成する

ゲンバー i、j;

for (i = 0; i < $clog2(Treesize) – 2; i = i + 1) begin: Second_half_level

    assign r_temp[Treesize * 2 * (i + 1) + ((Treesize / (2 ** i)) – 1 – 2 ** ($clog2(Treesize / 4) – i)) * 2 – 1:Treesize * 2 * (i + 1)] = r_temp[ツリーサイズ * 2 * i + ((ツリーサイズ / (2 ** i)) – 1 – 2 ** ($clog2(ツリーサイズ / 4) – i)) * 2 – 1:ツリーサイズ * 2 * i];

    for (j = (ツリーサイズ / (2 ** i)) – 1 – 2 ** ($clog2(ツリーサイズ / 4) – i); j < ツリーサイズ; j = j + 2 ** ($clog2(ツリーサイズ / 2) ) – i)) 開始: Second_half_level_logic

        プレフィックスロジック f(

            .ql(r_temp[Treesize * 2 * i + (j – 2 ** ($clog2(Treesize / 4) – i)) * 2 + 1:Treesize * 2 * i + (j – 2 ** ($clog2(ツリーサイズ / 4) – i)) * 2])、

            .qh(r_temp[ツリーサイズ * 2 * i + j * 2 + 1:ツリーサイズ * 2 * i + j * 2]),

            .r(r_temp[ツリーサイズ * 2 * (i + 1) + j * 2 + 1:ツリーサイズ * 2 * (i + 1) + j * 2])

        );

        if (j != Treesize – 1 – 2 ** ($clog2(Treesize / 4) – i)) begin: Second_half_level_direct_connect

            assign r_temp[Treesize * 2 * (i + 1) + (j + 2 ** ($clog2(Treesize / 2) – i)) * 2 – 1:Treesize * 2 * (i + 1) + j * 2 + 2] = r_temp[ツリーサイズ * 2 * i + (j + 2 ** ($clog2(ツリーサイズ / 2) – i)) * 2 – 1:ツリーサイズ * 2 * i + j * 2 + 2];

        終わり

    終わり

    assign r_temp[Treesize * 2 * (i + 2) – 1:Treesize * 2 * (i + 2) – (2 ** ($clog2(Treesize / 4) – i)) * 2] = r_temp[Treesize * 2 * (i + 1) – 1:ツリーサイズ * 2 * (i + 1) – (2 ** ($clog2(Treesize / 4) – i)) * 2];

終わり

assign r[1:0] = r_temp[Treesize * 2 * ($clog2(Treesize) – 2) + 1:Treesize * 2 * ($clog2(Treesize) – 2)];

for (i = 1; i < Treesize; i = i + 2) begin:final_r_odd

    assign r[i * 2 + 1:i * 2] = r_temp[Treesize * 2 * ($clog2(Treesize) – 2) + i * 2 + 1:Treesize * 2 * ($clog2(Treesize) – 2) + i * 2];

終わり

for (i = 2; i < Treesize; i = i + 2) 開始:final_r_even

    プレフィックスロジック f(

        .ql(r_temp[ツリーサイズ * 2 * ($clog2(ツリーサイズ) – 2) + i * 2 – 1:ツリーサイズ * 2 * ($clog2(ツリーサイズ) – 2) + i * 2 – 2]),

        .qh(r_temp[ツリーサイズ * 2 * ($clog2(ツリーサイズ) – 2) + i * 2 + 1:ツリーサイズ * 2 * ($clog2(ツリーサイズ) – 2) + i * 2]),

        .r(r[i * 2 + 1:i * 2])

    );

終わり

終了する

エンドモジュール

モジュールグループ_q_世代 #(パラメータグループサイズ = `GROUPSIZE)(a, b, cin, s, qg);

入力 [グループサイズ – 1:0] a;

入力 [グループサイズ – 1:0] b;

cinを入力します。

[グループサイズ – 1:0] を出力します。

出力 [1:0] qg;

ワイヤ [2 * グループサイズ – 1:0] q;

ワイヤ [グループサイズ – 1:0] c;

c[0] = cin を割り当てます。

生成する

どこで;

for (i = 0; i < グループサイズ; i = i + 1) 開始:Parallel_FA_CLA_prefix

    FA_CLA_プレフィックス f(

        .a(a[i])、

        .b(b[i])、

        .cin(c[i])、

        .s(s[i])、

        .q(q[i * 2 + 1:i * 2])

    );

    if (i != グループサイズ – 1) begin:special_case

        割り当て c[i + 1] = q[i * 2 + 1] | (q[i * 2] & c[i]);

    終わり

終わり

//グループサイズに基づいてグループ q を生成する

if (グループサイズ == 1) 開始: case_gs1

    qg[1] = q[1] を割り当てます。

    qg[0] = q[0] を割り当てます。

end else if (Groupsize == 2) begin: case_gs2

    qg[1] = q[3] | を割り当てる(q[1] & q[2]);

    assign qg[0] = q[2] & q[0];

end else if (Groupsize == 4) begin: case_gs4

    qg[1] = q[7] を割り当てる | (q[5] & q[6]) | (q[3] & q[6] & q[4]) | (q[1] & q[6] & q[4] & q[2]);

    assign qg[0] = q[6] & q[4] & q[2] & q[0];

end else if (Groupsize == 8) begin: case_gs8

    qg[1] = q[15] | を割り当てる(q[13] & q[14]) | (q[11] & q[14] & q[12]) | (q[9] & q[14] & q[12] & q[10]) | (q[7] & q[14] & q[12] & q[10] & q[8]) | (q[5] & q[14] & q[12] & q[10] & q[8] & q[6]) | (q[3] & q[14] & q[12] & q[10] & q[8] & q[6] & q[4]) | (q[1] & q[14] & q[12] & q[10] & q[8] & q[6] & q[4] & q[2]);

    assign qg[0] = q[14] & q[12] & q[10] & q[8] & q[6] & q[4] & q[2] & q[0];

終わり

終了する

エンドモジュール

// Cin 生成ロジック

モジュール cin_generation_logic(r, c0, cin);

入力 [1:0] r;

c0を入力します。

出力cin;

割り当て cin = (r[0] & c0) | r[1];

エンドモジュール

// プレフィックス操作の基本ロジック

モジュール prefix_logic(ql, qh, r);

[1:0] ql を入力します。

入力 [1:0] qh;

出力 [1:0] r;

assign r[0] = qh[0] & ql[0];

assign r[1] = (qh[0] & ql[1]) | qh[1];

エンドモジュール

// 桁上げ先読みを備えた全加算器セル

モジュール FA_CLA_prefix(a, b, cin, s, q);

aを入力します。

入力 b;

cinを入力します。

出力 s;

出力 [1:0] q;

q[0] = a ^ b を割り当てます。

代入 s = q[0] ^ cin;

q[1] = a & b を割り当てます。

エンドモジュール

利点

Brent Kung Adder の利点は次のとおりです。

  • これは、結果を得るために最小限の回路を使用するため、低電力加算器です。
  • 非常に人気があり、広く使用されている加算器です。
  • この種の加算器は、Kogge-Stone 加算器と比較してより少ないモジュールを使用して実装できます。
  • Brent-Kung 加算器の設計は非常に簡単です。
  • この加算器は他のモジュールとの接続が少なくなります。
  • これらの加算器は、主に Kogge-Stone 加算器の欠点を解決するために提案されました。

短所

ブレント・クン・アデのデメリット rには以下が含まれます。

  • これらの加算器は遅延が大きく、すべてのキャリー ビットを計算するには 2 log2 n − 2 論理レベルが必要です。
  • この加算器の主な欠点はファンアウトで、加算器全体の電流の伝播が分割されて弱くなる可能性があります。

Brent Kung 加算器のアプリケーション

Brent Kung Adder のアプリケーションには次のようなものがあります。

  • Brent-Kung 加算器はパイプライン方式で使用され、組み合わせロジックの深さとグリッチの安定化を減らすことで電力消費を削減します。
  • Brent-Kung 加算器は、i/p からすべての o/ps まで卓越した数のステージを提供しますが、非対称な中間ステージのロードを備えています。
  • この加算器は、乗算器内および他のデータ パス要素内で使用できます。

したがって、これは ブレント クン アダーの概要 、その仕組み、利点、欠点、およびその用途について説明します。これは非常に効率的な加算器であり、その構造は主に高性能の算術演算に使用されるツリー構造のように見えます。このタイプの加算器は非常に高速で、主にゲート レベルのロジックに重点を置いています。この加算器は、より少ない数の論理ゲートを使用して設計されています。したがって、このアーキテクチャ内で使用されるメモリと遅延が削減されます。ここであなたに質問があります。ブレント クン アダーとしても知られています。