L'additionneur Brent – Kung a été proposé en 1982 par Hsiang Te Kung et Richard Peirce Brent. Il s'agit d'un additionneur de préfixe parallèle ou d'un additionneur d'arbre qui est largement utilisé dans la conception numérique en raison de sa flexibilité. Les additionneurs de préfixes parallèles peuvent être construits de plusieurs manières en fonction du nombre de niveaux logiques, des portes logiques impliqués, la diffusion de chaque porte et le câblage entre les niveaux. Il existe différents types d'additionneurs d'arbres disponibles, les additionneurs d'arbres fondamentaux sont Sklanskym KoggeStone et Brent-Kung. Par rapport au KSA (additionneur Kogge-Stone), cet additionneur offre une grande régularité à la structure de l'additionneur et il a moins de blocage de câblage. ce qui conduit à de meilleures performances et à une surface de puce réduite. Cet article fournit de brèves informations sur un Brent Kung Adder .
Qu’est-ce que Brent Kung Adder ?
Un additionneur qui utilise un minimum de circuits pour obtenir le résultat est connu sous le nom de Brent Kung Adder et il est également connu sous le nom d'additionneur de faible puissance ou d'additionneur parallèle. Cet additionneur est destiné à économiser la taille de la puce afin que la fabrication de ces additionneurs devienne plus facile. La symétrie et la structure de construction habituelle de cet additionneur réduiront considérablement les coûts de production et pourront être utilisées dans des topologies pipeline. L'utilisation d'une logique de transistor passe-passe complémentaire contribue à améliorer les performances de conception avec le multiplexeur approche dans diverses conceptions de cellules.
Circuit Brent Kung Adder
Le diagramme de l'additionneur de préfixes parallèle Brent-Kung est présenté ci-dessous et comprend l'étape 1 (étape de pré-traitement), les étapes 2 à 7 sont des étapes de génération de report et l'étape 8 est le post-traitement. Il s’agit d’une architecture avancée très simple à construire et offrant moins d’encombrement de câblage. Ainsi, moins de câblage réduira la quantité d’espace requis pour exécuter l’architecture. De plus, le routage devient beaucoup plus facile grâce au croisement (ou) au chevauchement de moins de fils. Cependant, la pénalité augmentera en termes de retard en raison de l'augmentation du nombre d'étages. La répartition de cet additionneur est augmentée, puis le retard sera augmenté.

Comment fonctionne le Brent Kung Adder ?
Brent Kung Adder fonctionne en calculant les préfixes de deux groupes de bits qui sont utiles pour trouver les préfixes de groupe de 4 bits. Ces préfixes sont utilisés pour calculer les préfixes du groupe de 8 bits, etc. Après cela, ces préfixes seront utilisés pour calculer l'exécution de l'étape binaire spécifique. Ces retenues sont utilisées avec la propagation de groupe de l’étape suivante pour calculer le bit Somme de cette étape. Brent Kung Tree utilise 2log2N – 1 étape.
Additionneur Brent Kung 32 bits
La disposition de l'additionneur Brent Kung 32 bits est illustrée ci-dessous. Au début de cette disposition, les portes logiques de base sont conçues comme NAND, inverseur, XOR, NOR, etc. Après cela, les cellules nécessaires comme les cellules noires, les cellules grises, les tampons et la logique PG sont conçues avec les portes logiques.

Dans l'additionneur Brent Kung 32 bits ci-dessous, les portes inverseuses comme AOI et OAI sont alternativement utilisées pour les cellules principalement grises et noires. Ainsi les cellules noires et grises sont représentées par des blocs gris et noirs tandis que les tampons sont représentés par des cercles.


Les entrées comme A et B sont fournies à la logique PG qui est illustrée dans le schéma fonctionnel. Pour un additionneur 32 bits, 32 blocs logiques PG sont nécessaires et les signaux de propagation (P) et de génération (G) sont les sorties de ce bloc. Ces signaux sont fournis à la structure arborescente de l'additionneur Brent Kung. La structure de cet additionneur comprend des cellules grises et des cellules noires.
Une cellule grise comprend trois entrées et une seule sortie. Les signaux propagés et générés à partir de l'étape actuelle et générés par l'étape précédente sont des entrées tandis que le groupe génère des signaux est l'o/p. Dans toute structure arborescente, chaque étape se terminera par une cellule grise et l'o/p de cette cellule est le signal généré par le groupe. Ce signal est considéré simplement comme le report de cet étage. La cellule noire comprend quatre entrées et deux sorties. Les entrées de cette cellule sont les signaux P & G de l'étage actuel et les signaux P, G de l'étage précédent.
Une logique PG comprend des portes ET et XOR où la porte logique ET est utilisée pour générer le signal G et la porte logique XOR fournit le signal P. Pour éliminer les onduleurs inutiles, deux types de cellules grises et de cellules noires sont utilisés. Les portes inverseuses utilisées dans une rangée pour la cellule grise sont AOI ou AND-OR-Inverter et les portes inverseuses pour la cellule noire dans la rangée suivante utilisent OAI ou OR-AND-Inverter. La cellule AOI utilise les entrées normales pour fournir des sorties inversées tandis que OAI utilise des entrées inversées pour fournir des sorties normales.
Opération Brent Kung Adder
L'additionneur Brent Kung est un additionneur de préfixes parallèle utilisé pour l'opération d'addition haute performance. Cet additionneur ressemble à une structure arborescente qui effectue l'opération arithmétique. Cet additionneur comprend des cellules noires et des cellules grises. Chaque cellule noire a deux portes ET et une seule porte OU et chaque cellule grise n'a qu'une seule porte ET.
L'additionneur Brent-kung comprend deux étages ; l'étape de prétraitement et l'étape de génération. Dans la première étape, la génération et la propagation se feront à partir de chaque paire d'entrées. Ici, la propagation fournit une opération « XOR » pour les bits d'entrée tandis que la génération fournit une opération « ET » pour les bits d'entrée. Les propagations et générations comme « Pi » et « Gi » sont indiquées ci-dessous.
Pi = Ai XOR Bi et Gi = Ai ET Bi.
Dans la deuxième étape, la retenue sera générée pour chaque bit connu sous le nom de génération de retenue « Cg » et la retenue se propagera pour chaque bit est connue sous le nom de génération de retenue « Cp ». Pour la suite de l'opération, carry propate et carry generate seront générés. La dernière cellule disponible dans chaque fonction bit fournit le report. Ainsi, le report de bit final aidera à faire la somme du bit suivant simultanément jusqu'au dernier bit. Le report, la génération et la propagation sont donnés comme suit :
Cp = P1 ET P0 et Cg=G1 OU (P1 ET G0)
Il est utilisé principalement pour l'opération d'addition de deux trente-deux bits et chaque bit subit l'étape de prétraitement et l'étape de génération, puis il fournit la somme finale.
Les bits d'entrée principaux passent en dessous de l'étape de prétraitement et produisent, propagent et génèrent. Ainsi, ceux-ci se propagent et génèrent, subissent une étape de génération, génèrent un report, génèrent et se propagent et fournissent la somme finale. Le processus étape par étape de l’additionneur Brent-kung est présenté ci-dessous.

L'arrangement de l'additionneur Brent-kung ressemble à une structure arborescente et c'est l'additionneur à grande vitesse qui cible la logique au niveau de la porte. Cet additionneur peut être conçu avec une diminution du nombre de portes logiques. Ainsi, cela réduit le délai et la mémoire utilisés dans cette architecture.
Code Verilog de Brent Kung Adder
Le code verilog de l'additionneur Brent Kung est indiqué ci-dessous.
`define INPUTSIZE 64 //définit la taille d'entrée n
`define GROUPSIZE 8 //définit la taille du groupe = 1, 2, 4 ou 8
module Brent_Kung_Adder(A,B,S);
entrée [`INPUTSIZE – 1:0] A ;
entrée [`INPUTSIZE – 1:0] B ;
sortie [`INPUTSIZE:0] S ;
fil [`INPUTSIZE / `GROUPSIZE * 2 – 1:0] r_temp ;
fil [`INPUTSIZE / `GROUPSIZE * 2 – 1:0] r ;
fil [`INPUTSIZE / `GROUPSIZE:0] cin;
fil [`INPUTSIZE / `GROUPSIZE * 2 – 1:0] q ;
attribuer cin[0] = 1'b0 ;
générer
où dans ;
pour (i = 0 ; i < `INPUTSIZE / `GROUPSIZE ; i = i + 1) commencer : parallel_FA_CLA_prefix
group_q_génération #(.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])
);
fin
parallel_prefix_tree_first_half #(.Treesize(`INPUTSIZE / `GROUPSIZE))
t1(
.q(q[`INPUTSIZE / `GROUPSIZE * 2 – 1:0]),
.r(r_temp[`INPUTSIZE / `GROUPSIZE * 2 – 1:0])
);
parallel_prefix_tree_second_half #(.Treesize(`INPUTSIZE / `GROUPSIZE))
t2(
.q(r_temp[`INPUTSIZE / `GROUPSIZE * 2 – 1:0]),
.r(r[`INPUTSIZE / `GROUPSIZE * 2 – 1:0])
);
pour (i = 0 ; i < `INPUTSIZE / `GROUPSIZE ; i = i + 1) commencer : cin_génération
cin_génération_logic f(
.r(r[2 * je + 1:2 * je]),
.c0(1’b0),
.cin(cin[i + 1])
);
fin
attribuer S[`INPUTSIZE] = cin[`INPUTSIZE / `GROUPSIZE] ;
générer fin
module final
// Première moitié de l'arborescence des préfixes parallèles
module parallel_prefix_tree_first_half #(paramètre Treesize = `INPUTSIZE / `GROUPSIZE)(q, r);
saisir [Treesize * 2 – 1:0] q ;
sortie [Treesize * 2 – 1:0] r ;
générer
où dans ;
si (Treesize == 2) début : trivial_case
attribuer r[1:0] = q[1:0] ;
préfixe_logique f(
.ql(q[1:0]),
.qh(q[3:2]),
.r(r[3:2])
);
fin sinon début : recursive_case
fil [Treesize * 2 – 1:0] r_temp;
parallel_prefix_tree_first_half #(.Treesize(Treesize / 2))
récursion_lsbh(
.q(q[Taille de l'arbre – 1:0]),
.r(r_temp[Taille de l'arbre – 1:0])
);
parallel_prefix_tree_first_half #(.Treesize(Treesize / 2))
récursion_msbh(
.q(q[Taille de l'arbre * 2 – 1 :Taille de l'arbre]),
.r(r_temp[Treesize * 2 – 1:Treesize])
);
pour (i = 0 ; i < Treesize * 2 ; i = i + 2) commencer : parallel_stitch_up
if (i != Treesize * 2 – 2) start: parallel_stitch_up_pass
attribuer r[i + 1:i] = r_temp[i + 1:i];
fin sinon début : parallel_stitch_up_produce
préfixe_logique f(
.ql(r_temp[Treesize – 1:Treesize – 2]),
.qh(r_temp[Treesize * 2 – 1:Treesize * 2 – 2]),
.r(r[Taille de l'arbre * 2 – 1 : Taille de l'arbre * 2 – 2])
);
fin
fin
fin
générer fin
module final
// Deuxième moitié de l'arborescence des préfixes parallèles
module parallel_prefix_tree_second_half #(paramètre Treesize = `INPUTSIZE / `GROUPSIZE)(q, r);
saisir [Treesize * 2 – 1:0] q ;
sortie [Treesize * 2 – 1:0] r ;
fil [Treesize * 2 * ($clog2(Treesize) – 1) – 1:0] r_temp;
attribuer r_temp[Treesize * 2 – 1:0] = q[Treesize * 2 – 1:0] ;
générer
genvar je, j;
pour (i = 0 ; i < $clog2(Treesize) – 2 ; i = i + 1) début : second_half_level
attribuer r_temp[Treesize * 2 * (i + 1) + ((Treesize / (2 ** i)) – 1 – 2 ** ($clog2(Treesize / 4) – i)) * 2 – 1:Treesize * 2 * (i + 1)] = r_temp[Treesize * 2 * i + ((Treesize / (2 ** i)) – 1 – 2 ** ($clog2(Treesize / 4) – i)) * 2 – 1 : Taille de l'arbre * 2 * i] ;
pour (j = (Treesize / (2 ** i)) – 1 – 2 ** ($clog2(Treesize / 4) – i); j < Treesize; j = j + 2 ** ($clog2(Treesize / 2 ) – i)) début : second_half_level_logic
préfixe_logique f(
.ql(r_temp[Treesize * 2 * i + (j – 2 ** ($clog2(Treesize / 4) – i)) * 2 + 1 : Treesize * 2 * i + (j – 2 ** ($clog2( Taille de l'arbre / 4) – i)) * 2]),
.qh(r_temp[Treesize * 2 * i + j * 2 + 1:Treesize * 2 * i + j * 2]),
.r(r_temp[Taille de l'arbre * 2 * (i + 1) + j * 2 + 1 : Taille de l'arbre * 2 * (i + 1) + j * 2])
);
if (j != Treesize – 1 – 2 ** ($clog2(Treesize / 4) – i)) commencer : second_half_level_direct_connect
attribuer r_temp[Treesize * 2 * (i + 1) + (j + 2 ** ($clog2(Treesize / 2) – i)) * 2 – 1 : Treesize * 2 * (i + 1) + j * 2 + 2] = r_temp[Treesize * 2 * i + (j + 2 ** ($clog2(Treesize / 2) – i)) * 2 – 1 : Treesize * 2 * i + j * 2 + 2];
fin
fin
attribuer r_temp[Treesize * 2 * (i + 2) – 1:Treesize * 2 * (i + 2) – (2 ** ($clog2(Treesize / 4) – i)) * 2] = r_temp[Treesize * 2 * (i + 1) – 1 : Taille de l'arbre * 2 * (i + 1) – (2 ** ($clog2(Treesize / 4) – i)) * 2] ;
fin
attribuer r[1:0] = r_temp[Treesize * 2 * ($clog2(Treesize) – 2) + 1:Treesize * 2 * ($clog2(Treesize) – 2)] ;
pour (i = 1 ; i < Treesize ; i = i + 2) commencer : final_r_odd
attribuer r[i * 2 + 1:i * 2] = r_temp[Treesize * 2 * ($clog2(Treesize) – 2) + i * 2 + 1:Treesize * 2 * ($clog2(Treesize) – 2) + je * 2];
fin
pour (i = 2 ; i < Treesize ; i = i + 2) commencer : final_r_even
préfixe_logique f(
.ql(r_temp[Treesize * 2 * ($clog2(Treesize) – 2) + i * 2 – 1:Treesize * 2 * ($clog2(Treesize) – 2) + i * 2 – 2]),
.qh(r_temp[Treesize * 2 * ($clog2(Treesize) – 2) + i * 2 + 1:Treesize * 2 * ($clog2(Treesize) – 2) + i * 2]),
.r(r[je * 2 + 1:je * 2])
);
fin
générer fin
module final
module group_q_generation #(paramètre Groupsize = `GROUPSIZE)(a, b, cin, s, qg);
entrée [Taille du groupe – 1:0] a ;
saisir [Taille du groupe – 1:0] b ;
entrée cin ;
sortie [Taille du groupe – 1:0] s ;
sortie [1:0] qg ;
fil [2 * Taille du groupe – 1:0] q ;
fil [Taille du groupe – 1:0] c ;
attribuer c[0] = cin;
générer
où dans ;
pour (i = 0 ; i < Taille du groupe ; i = i + 1) commencer : parallel_FA_CLA_prefix
FA_CLA_préfixe f(
.a(a[i]),
.b(b[i]),
.cin(c[i]),
.s(s[je]),
.q(q[i * 2 + 1:i * 2])
);
if (i != Taille du groupe – 1) début : cas_spécial
attribuer c[i + 1] = q[i * 2 + 1] | (q[je * 2] & c[je]);
fin
fin
// génération de groupe q basée sur la taille du groupe
si (Groupsize == 1) début : case_gs1
attribuer qg[1] = q[1];
attribuer qg[0] = q[0];
fin sinon si (Groupsize == 2) début : case_gs2
attribuer qg[1] = q[3] | (q[1] et q[2]);
attribuer qg[0] = q[2] & q[0] ;
fin sinon si (Groupsize == 4) début : case_gs4
attribuer qg[1] = q[7] | (q[5] et q[6]) | (q[3] & q[6] & q[4]) | (q[1] & q[6] & q[4] & q[2]) ;
attribuer qg[0] = q[6] & q[4] & q[2] & q[0] ;
fin sinon si (Groupsize == 8) début : case_gs8
attribuer 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]) ;
attribuer qg[0] = q[14] & q[12] & q[10] & q[8] & q[6] & q[4] & q[2] & q[0] ;
fin
générer fin
module final
// Logique de génération Cin
module cin_génération_logic(r, c0, cin);
entrée [1:0] r ;
entrez c0 ;
sortie cin ;
attribuer cin = (r[0] & c0) | r[1];
module final
// Logique de base pour les opérations de préfixe
module préfixe_logic(ql, qh, r);
entrée [1:0] ql ;
entrée [1:0] qh ;
sortie [1:0] r ;
attribuer r[0] = qh[0] & ql[0] ;
attribuer r[1] = (qh[0] & ql[1]) | qh[1];
module final
// Cellule additionneuse complète avec Carry Look-Ahead
module FA_CLA_prefix(a, b, cin, s, q);
saisir un ;
entrée b ;
entrée cin ;
les sorties;
sortie [1:0] q ;
attribuer q[0] = a ^ b;
attribuer s = q[0] ^ cin ;
attribuer q[1] = a & b ;
module final
Avantages
Les avantages du Brent Kung Adder sont les suivants.
- Il s'agit d'un additionneur de faible puissance car il utilise un circuit minimum pour obtenir le résultat.
- C'est un additionneur très populaire et largement utilisé.
- Ce type d'additionneur peut être implémenté en utilisant moins de modules par rapport à un additionneur Kogge-Stone.
- La conception de l'additionneur Brent-Kung est très simple.
- Cet additionneur a moins de connexions avec d'autres modules.
- Ces additionneurs ont été proposés principalement pour résoudre les inconvénients des additionneurs Kogge-Stone.
Désavantages
Le inconvénients de Brent Kung Adde r inclure ce qui suit.
- Ces additionneurs ont un plus grand retard et nécessitent 2 log2 n − 2 niveaux logiques pour calculer tous les bits de report.
- Le principal inconvénient de cet additionneur est la fanout qui peut provoquer la propagation du courant dans tout l'additionneur, la diviser et l'affaiblir.
Applications de l'additionneur Brent Kung
Les applications de Brent Kung Adder sont les suivantes.
- Un additionneur Brent – Kung est utilisé de manière pipeline pour diminuer la consommation d'énergie en diminuant la profondeur de la logique combinatoire et la stabilisation des problèmes.
- L'additionneur Brent-Kung fournit un nombre exceptionnel d'étages depuis i/p jusqu'à tous les o/ps, mais avec un chargement asymétrique des étages intermédiaires.
- Cet additionneur peut être utilisé dans le multiplicateur ainsi que dans d’autres éléments du chemin de données.
Ainsi, c'est un aperçu de l'additionneur Brent Kung , son fonctionnement, ses avantages, ses inconvénients et ses applications. Il s'agit d'un additionneur très efficace et sa structure ressemble à une structure arborescente utilisée principalement pour les opérations arithmétiques hautes performances. Ce type d'additionneur est très rapide et se concentre principalement sur la logique au niveau de la porte. Cet additionneur est conçu en utilisant moins de portes logiques. Ainsi, cela réduit la mémoire et le délai utilisés dans cette architecture. Voici une question pour vous, Brent Kung Adder également connu sous le nom de ?