VHDL Description

In this page, a floating-point adder subtractor supporting normal as well as subnormal numbers is simulated and described in VHDL. It is recommended to print the accompanying lectures notes. The addition/subtraction takes four steps and is suitable for pipelining


entity FloatAdd is
port ( A, B : in Std_Logic_Vector ( 31 downto 0 ) ; -- A,B: addends
SO : out Std_Logic_Vector (31 downto 0 ) ) ; -- Summ
end FloatAdd;

architecture TEST of FloatAdd is

component AbsDiff is
port ( A, B : in Std_Logic_Vector ( 7 downto 0 ) ; -- A, B: diffend
D : out Std_Logic_Vector ( 4 downto 0 ) ) ; -- D: Distance
end component ;

component Compar is
port ( A, B : in Std_Logic_Vector ( 30 downto 0 ) ; -- A,B: diffend
AeqB : out Std_Logic ; -- A equals B
AgtB : out Std_Logic ) ; -- A greater than B
end component ;

component Decod is
port ( D : in Std_Logic_Vector ( 7 downto 0 ) ; -- D
S : out Std_Logic_Vector ( 23 downto 0 ) ) ; -- D decoded
end component ;

component ShiftR is
port ( E : in Std_Logic_Vector (23 downto 0 ) ; -- E : input
D : in Std_Logic_Vector (4 downto 0 ) ; -- D : positions
Z : out Std_Logic_Vector (23 downto 0 ) ; -- Z : E shifted D positions
g : out Std_Logic ; -- g : guard
r : out Std_Logic ; -- r : round
s : out Std_Logic ) ; -- s : sticky
end component ;

component ZLPC is
port ( A, B : in Std_Logic_Vector (23 downto 0 ) ; -- A : addend, B : subend
M : in Std_Logic_Vector (23 downto 0 ) ; -- M : mask
o : in Std_Logic ; -- o : inhibit ZLPC if add
Z : out Std_Logic_Vector (4 downto 0 ) ; -- Z : number of predicted leading zeroes
n : out Std_Logic ) ; -- n : result not normalisable
end component ;

component compoundadder is
port ( A, B : in Std_Logic_Vector (23 downto 0) ; -- A addend, B addend/subend
o : in Std_Logic ; -- o : operation 0=>add, 1=>sub
g : in Std_Logic ; -- g : guard
r : in Std_Logic ; -- r : round
s : in Std_Logic ; -- s : sticky
S0 : out Std_Logic_Vector (24 downto 0) ) ;
end component ;

component AddEx is
port ( E : in Std_Logic_Vector (7 downto 0 ) ; -- E : addend
o : in Std_Logic ; -- o : o : operation 0=>add, 1=>sub
u : in Std_Logic ; -- u : error in prediction, this input late
Z : in Std_Logic_Vector (4 downto 0 ) ; -- Z : subend, number of leading '0'
S : out Std_Logic_Vector (7 downto 0 ) ; -- S : if o then S = E - Z - u + u else S <= E - u
l : out std_Logic ) ; -- S : is nul
end component ;

component ShiftL is
port ( E : in Std_Logic_Vector (24 downto 0 ) ; -- E : input to be shifted
Z : in Std_Logic_Vector (4 downto 0 ) ; -- D : positions (subtract from exponent)
n : in Std_Logic ; -- n : inhibit prediction correction
S : out Std_Logic_Vector (23 downto 0 ) ; -- S : E shifted D positions
u : out Std_logic ) ; -- u : prediction was false (add 1 to exponent)
end component ;

signal Am0, Bm0, Am1, Bm1, Bm2 : Std_Logic_Vector (23 downto 0) ;
signal Sm0 : Std_Logic_Vector (24 downto 0) ;
signal Sm1 : Std_Logic_Vector (23 downto 0) ;
signal Sm2 : Std_Logic_Vector (22 downto 0 ) ;
signal Mask : Std_Logic_Vector (23 downto 0) ;
signal Se0, Se1, SeZ : Std_Logic_Vector (7 downto 0) ;
signal D : Std_Logic_Vector (4 downto 0) ; -- distance : abs( Ae - Be)
signal Z : Std_Logic_Vector (4 downto 0) ; -- zeros leading, must be subtracted from the exponent
signal ha, hb : Std_Logic ; -- hidden bits of A and B ( A or B subnormal)
signal o : Std_Logic ; -- operation, 0 : addition, 1 : subtraction
signal v : Std_Logic ; -- abs(A) and abs(B) are equal
signal w : Std_Logic ; -- A and B must be swapped around
signal g : Std_Logic ; -- guard bit from alignment
signal r : Std_Logic ; -- round bit from alignment
signal s : Std_Logic ; -- sticky bit from alignment
signal u : Std_Logic ; -- extra shift, must be added to the exponent
signal n : Std_Logic ; -- inhibit correction
signal l : Std_Logic ; -- Sm1 = 0 (S0 subnormal)

begin
-- step 1
ha <= A(30) or A(29) or A(28) or A(27) or A(26) or A(25) or A(24) or A(23) ; -- reveal A's hidden bit
hb <= B(30) or B(29) or B(28) or B(27) or B(26) or B(25) or B(24) or B(23) ; -- reveal B's hidden bit
with ha select Am0 <= '1' & A(22 downto 0) when '1' , A(22 downto 0) & '0' when others ;
with hb select Bm0 <= '1' & B(22 downto 0) when '1' , B(22 downto 0) & '0' when others ;
distance : AbsDiff port map (A(30 downto 23), B(30 downto 23), D ) ; -- exponents distance
sort : Compar port map (A(30 downto 0), B(30 downto 0), v, w) ; -- comparison
SeZ <= not ( (o and v) & (o and v) & (o and v) & (o and v) & "0000" ) ;
with w select Se0 <= A(30 downto 23) when '1', B(30 downto 23) and SeZ when others ; -- larger exponent
with w select Bm1 <= Bm0 when '1', Am0 when others ; -- smaller's mantissa
with w select Am1 <= Am0 when '1', Bm0 when others ; -- larger's mantissa
o <= A(31) xor B(31) ; -- 0 => addition, 1 => subtraction
-- step 2
alignment : ShiftR port map (Bm1, D, Bm2, g, r, s) ; -- mantissas alignment
maskgen : Decod port map (Se0, Mask) ;
-- step 3
count_0 : ZLPC port map (Am1 , Bm2, Mask, o, Z, n) ; -- prediction of the leading-one position
add_mant : compoundadder port map (Am1, Bm2, o, g, r, s, Sm0) ;
-- step 4
normalise : ShiftL port map (Sm0, Z, n, Sm1, u) ; -- mantissa normalisation
adjustExp : AddEx port map (Se0, o, u, Z, Se1, l) ; -- exponent adjust, u is late
with l select Sm2 <= Sm1(22 downto 0) when '0', Sm1(23 downto 1) when others ;
SO <= ((A(31) and w) or (B(31) and not w)) & Se1 & Sm2(22 downto 0) ;
end TEST;


Step 1

The block "AbsDiff"

bloc AbsDiff
The output D (5-bit) of the block "AbsDiff" is the absolute value of the difference of the exponents A(30,23) and B(30,23) respectively of A and of B, saturated to 31. The carry scheme is a "Kooge and Stone".

entity AbsDiff is
port ( A, B : in Std_Logic_Vector ( 7 downto 0 ) ; -- A,B: addends
D : out Std_Logic_Vector ( 4 downto 0 ) ) ; -- D: Distance
end AbsDiff ;
architecture structural of AbsDiff is
signal P0, G0, K0, G1, K1, G2, K2, G3, K3, S : Std_Logic_Vector ( 7 downto 0 ) ; -- prop, gen, not kill
begin
-- row 0
G0 <= A and not B ; -- generate
K0 <= A or not B ; -- spare (not kill)
P0 <= not G0 and K0 ; -- propagate
-- "BK" cells row 1 (distance 1)
G1 <= (K0(7 downto 1) and ( G0(7 downto 1) or G0(6 downto 0))) & G0(0) ;
K1 <= (K0(7 downto 1) and ( G0(7 downto 1) or K0(6 downto 0))) & K0(0) ;
-- "BK" cells row 2 (distance 2)
G2 <= (K1(7 downto 2) and ( G1(7 downto 2) or G1(5 downto 0))) & G1(1 downto 0) ;
K2 <= (K1(7 downto 2) and ( G1(7 downto 2) or K1(5 downto 0))) & K1(1 downto 0) ;
-- "BK" cells row 3 (distance 4)
G3 <= (K2(7 downto 4) and ( G2(7 downto 4) or G2(3 downto 0))) & G2(3 downto 0) ;
K3 <= (K2(7 downto 4) and ( G2(7 downto 4) or K2(3 downto 0))) & K2(3 downto 0) ;
-- feed-back row
with K3(7) select S <= P0 xor (not G3(6 downto 0) & '1') when '0', P0 xor (K3(6 downto 0) & '1') when others ;
-- reduction from 8 bits downto 5 bits with saturation
with S(7) or S(6) or S(5) select D <= S(4 downto 0) when '0', "11111" when others ;
end structural
The block "Compar"

bloc Compar
In parallel with the block "AbsDif", the block "Compar" compare the absolute values (the sign is ignored) of A and B by computing the carry out c31 of the subtraction.

entity Compar is
port ( A, B : in Std_Logic_Vector ( 30 downto 0 ) ; -- A,B: addends
C31 : out Std_Logic ) ; -- A greater than B
end Compar ;
architecture structural of Compar is
signal G, P : Std_Logic_Vector (59 downto 0) ;
begin
-- "HA" cells row
G(30 downto 0) <= A and not B ; -- generate
P(30 downto 0) <= A xor not B ; -- propagate
-- "BK" cells row 1 (distance 1)
G(45) <= G(29) or (P(29) and G(28)) ; P(45) <= P(29) and P(28) ;
G(44) <= G(27) or (P(27) and G(26)) ; P(44) <= P(27) and P(26) ;
G(43) <= G(25) or (P(25) and G(24)) ; P(43) <= P(25) and P(24) ;
G(42) <= G(23) or (P(23) and G(22)) ; P(42) <= P(23) and P(22) ;
G(41) <= G(21) or (P(21) and G(20)) ; P(41) <= P(21) and P(20) ;
G(40) <= G(19) or (P(19) and G(18)) ; P(40) <= P(19) and P(18) ;
G(39) <= G(17) or (P(17) and G(16)) ; P(39) <= P(17) and P(16) ;
G(38) <= G(15) or (P(15) and G(14)) ; P(38) <= P(15) and P(14) ;
G(37) <= G(13) or (P(13) and G(12)) ; P(37) <= P(13) and P(12) ;
G(36) <= G(11) or (P(11) and G(10)) ; P(36) <= P(11) and P(10) ;
G(35) <= G(9) or (P(9) and G(8)) ; P(35) <= P(9) and P(8) ;
G(34) <= G(7) or (P(7) and G(6)) ; P(34) <= P(7) and P(6) ;
G(33) <= G(5) or (P(5) and G(4)) ; P(33) <= P(5) and P(4) ;
G(32) <= G(3) or (P(3) and G(2)) ; P(32) <= P(3) and P(2) ;
G(31) <= G(1) or (P(1) and G(0)) ;
-- "BK" cells row 2 (distance 2)
G(53) <= G(30) or (P(30) and G(45)) ; P(53) <= P(30) and P(45) ;
G(52) <= G(44) or (P(44) and G(43)) ; P(52) <= P(44) and P(43) ;
G(51) <= G(42) or (P(42) and G(41)) ; P(51) <= P(42) and P(41) ;
G(50) <= G(40) or (P(40) and G(39)) ; P(50) <= P(40) and P(39) ;
G(49) <= G(38) or (P(38) and G(37)) ; P(49) <= P(38) and P(37) ;
G(48) <= G(36) or (P(36) and G(35)) ; P(48) <= P(36) and P(35) ;
G(47) <= G(34) or (P(34) and G(33)) ; P(47) <= P(34) and P(33) ;
G(46) <= G(32) or (P(32) and G(31)) ;
-- "BK" cells row 3 (distance 4)
G(57) <= G(53) or (P(53) and G(52)) ; P(57) <= P(53) and P(52) ;
G(56) <= G(51) or (P(51) and G(50)) ; P(56) <= P(51) and P(50) ;
G(55) <= G(49) or (P(49) and G(48)) ; P(55) <= P(49) and P(48) ;
G(54) <= G(47) or (P(47) and G(46)) ;
-- "BK" cells row 4 (distance 8)
G(59) <= G(57) or (P(57) and G(56)) ; P(59) <= P(57) and P(56) ;
G(58) <= G(55) or (P(55) and G(54)) ;
-- "BK" cells row 5 (distance 16)
C31 <= G(59) or (P(59) and G(58)) ;
end structural;


Step 2
The block "Decod"
bloc Decod
The block "Decod" transcode the value of "Se0" (8 bits) into a "thermometer code" (24 bits). The output "Mask" has as many '0' at the left as the value of "Se0", the other bits are '1'.

entity Decod is
port ( D : in Std_Logic_Vector ( 7 downto 0 ) ; -- D
Mask : out Std_Logic_Vector ( 23 downto 0 ) ) ; -- D decoded
end Decod;
architecture structural of Decod is
signal P : Std_Logic_Vector (53 downto 0) ;
begin
with D(7) or D(6) or D(5) select Mask <= "000000000000000000000000" when '1',
P(23 downto 0) when others ;
with D(4) select P(23 downto 0) <= "00000000" & P(39 downto 24) when '1' ,
P(39 downto 24) & "11111111" when others ;
with D(3) select P(39 downto 24) <= "00000000" & P(47 downto 40) when '1' ,
P(47 downto 40) & "11111111" when others ;
with D(2) select P(47 downto 40) <= "0000" & P(51 downto 48) when '1' ,
P(51 downto 48) & "1111" when others ;
with D(1) select P(51 downto 48) <= "00" & P(53 downto 52) when '1' ,
P(53 downto 52) & "11" when others ;
P(53 downto 52) <= not D(0) & '1' ;
end ;
The block "ShiftR"

bloc ShiftR
The block "ShiftR" shifts "Bm1" to the Right of "D" positions to give "Bm2". This block computes in parallel the bits g, r and s.

entity ShiftR is
port ( E : in Std_Logic_Vector (23 downto 0 ) ; -- E : input
D : in Std_Logic_Vector (4 downto 0 ) ; -- D : positions
Z : out Std_Logic_Vector (23 downto 0 ) ; -- Z : E shifted right D positions
g, r, s : out Std_Logic ; -- g : guard, r : round, s : sticky
end ShiftR ;
architecture structural of ShiftR is
signal sticky : Std_Logic ;
signal P0, P1, P2, P3, P4, P5 : Std_Logic_Vector (25 downto 0) ; -- internal signals
begin
P5 <= E & "00" ; -- append room for guard and round bits
with D(4) select P4 <= P5 when '0' , "0000000000000000" & P5(25 downto 16) when others ;
with D(3) select P3 <= P4 when '0' , "00000000" & P4(25 downto 8 ) when others ;
with D(2) select P2 <= P3 when '0' , "0000" & P3(25 downto 4) when others ;
with D(1) select P1 <= P2 when '0' , "00" & P2(25 downto 2) when others ;
with D(0) select P0 <= P1 when '0' , "0" & P1(25 downto 1) when others ;
sticky <= ((P5(15) or P5(14) or P5(13) or P5(12) or P5(11) or P5(10) or P5(9) or P5(8) or
P5(7) or P5(6) or P5(5) or P5(4) or P5(3) or P5(2) or P5(1) or P5(0)) and D(4)) or
((P4(7) or P4(6) or P4(5) or P4(4) or P4(3) or P4(2) or P4(1) or P4(0)) and D(3)) or
((P3(3) or P3(2) or P3(1) or P3(0)) and D(2)) or
((P2(1) or P2(0)) and D(1)) or (P1(0) and D(0)) ;
Z <= P0(25 downto 2) ;
g <= P0(1) ; r <= P0(0) ; s <= sticky ;
end structural ;

Step 3
Thee block "ZLPC"
bloc ZLPC
The block "ZLPC" counts the number of leading '0' of a prediction of the result of a subtraction "Bm2 – Am1" (if o = '1'). In parallel the number of '0' is checked against "Se0" (translated in thermometer code "Mask"), if smaller or equal then the final result can be normalised.

entity ZLPC is
port ( A, B : in Std_Logic_Vector (23 downto 0 ) ; -- A addend, B subtraend
Mask : in Std_Logic_Vector (23 downto 0 ) ; -- Se0 leading zeroes
o : in Std_Logic ; -- enable if subtraction, disable if addition
Z : out Std_Logic_Vector (4 downto 0 ) ; -- Z : number of leading zeroes
n : out Std_Logic ) ; -- N normalised
end ZLPC ;
architecture structural of ZLPC is
signal P : Std_Logic_Vector (93 downto 0) ; -- internal signals
signal Q, R : Std_Logic_Vector (23 downto 0 ) ;
begin
Q <= (A xor B) and ((A(22 downto 0) or not B(22 downto 0)) & '1') ; -- prediction
R <= not Q or Mask ;
n <= R(23) and R(22) and R(21) and R(20) and R(19) and R(18) and R(17) and R(16)
and R(15) and R(14) and R(13) and R(12) and R(11) and R(10) and R(9) and R(8)
and R(7) and R(6) and R(5) and R(4) and R(3) and R(2) and R(1) and R(0) ;
P(93 downto 70) <= not (Q or Mask) ;
-- counter row 1 (blocks of 2)
P(69 downto 68) <= (P(93) and P(92)) & (P(93) and not P(92)) ;
P(67 downto 66) <= (P(91) and P(90)) & (P(91) and not P(90)) ;
P(65 downto 64) <= (P(89) and P(88)) & (P(89) and not P(88)) ;
P(63 downto 62) <= (P(87) and P(86)) & (P(87) and not P(86)) ;
P(61 downto 60) <= (P(85) and P(84)) & (P(85) and not P(84)) ;
P(59 downto 58) <= (P(83) and P(82)) & (P(83) and not P(82)) ;
P(57 downto 56) <= (P(81) and P(80)) & (P(81) and not P(80)) ;
P(55 downto 54) <= (P(79) and P(78)) & (P(79) and not P(78)) ;
P(53 downto 52) <= (P(77) and P(76)) & (P(77) and not P(76)) ;
P(51 downto 50) <= (P(75) and P(74)) & (P(75) and not P(74)) ;
P(49 downto 48) <= (P(73) and P(72)) & (P(73) and not P(72)) ;
P(47 downto 46) <= (P(71) and P(70)) & (P(71) and not P(70)) ;
-- counter row 2 (blocks of 4)
P(45 downto 43) <= (P(69) and P(67)) & (P(69) and not P(67)) & (P(68) or (P(69) and P(66))) ;
P(42 downto 40) <= (P(65) and P(63)) & (P(65) and not P(63)) & (P(64) or (P(65) and P(62))) ;
P(39 downto 37) <= (P(61) and P(59)) & (P(61) and not P(59)) & (P(60) or (P(61) and P(58))) ;
P(36 downto 34) <= (P(57) and P(55)) & (P(57) and not P(55)) & (P(56) or (P(57) and P(54))) ;
P(33 downto 31) <= (P(53) and P(51)) & (P(53) and not P(51)) & (P(52) or (P(53) and P(50))) ;
P(30 downto 28) <= (P(49) and P(47)) & (P(49) and not P(47)) & (P(48) or (P(49) and P(46))) ;
-- counter row 3 (blocks of 8)
P(27 downto 24) <= (P(45) and P(42)) & (P(45) and not P(42)) & (P(44) or (P(45) and P(41))) & (P(43) or (P(45) and P(40))) ;
P(23 downto 20) <= (P(39) and P(36)) & (P(39) and not P(36)) & (P(38) or (P(39) and P(35))) & (P(37) or (P(39) and P(34))) ;
P(19 downto 16) <= (P(33) and P(30)) & (P(33) and not P(30)) & (P(32) or (P(33) and P(29))) & (P(31) or (P(33) and P(28))) ;
-- counter row 4 (blocks of 16)
P(14 downto 11) <= (P(27) and not P(23)) & (P(26) or (P(27) and P(22))) & (P(25) or (P(27) and P(21))) & (P(24) or (P(27) and P(20))) ;
-- counter row 5
P(4) <= P(27) and P(23) ; P(3) <= P(14) or (P(4) and P(19)) ; P(2) <= P(13) or (P(4) and P(18)) ;
P(1) <= P(12) or (P(4) and P(17)) ; P(0) <= P(11) or (P(4) and P(16)) ;
with o select Z <= "00000" when '0' , P(4 downto 0) when others ;
end structural;
The block "CompoundAdder"


bloc CompoundAdder
The block "CompoundAdder" compute the result "Sm0" correctly rounded to the nearest but not yet normalised. The carry scheme is a "Kooge and Stone".

entity compoundadder is
port ( A, B : in Std_Logic_Vector (23 downto 0) ;
o, g, r, s : in Std_Logic ; -- operation, guard, round, sticky
S0 : out Std_Logic_Vector (24 downto 0) ) ; -- rounded, not normalised
end compoundadder ;
architecture structural of compoundadder is
signal c, m, k, i, plus1, minus0 : Std_Logic ;
signal G0, P0, K0, G1, K1, G2, K2, G3, K3, G4, K4, G5, K5 : Std_Logic_Vector (23 downto 0) ;
signal S1, S2 : Std_Logic_Vector (24 downto 0) ;
begin
with o select G0 <= A and B when '0' , A and not B when others ; -- generate
with o select K0 <= A or B when '0' , A or not B when others ; -- spare (not kill)
P0 <= not G0 and K0 ; -- propagate
k <= P0(1) xor G0(0) ; -- penultimate
i <= P0(0) ; -- least significant
-- "BK" cells row 1 (distance 1)
G1 <= (K0(23 downto 1) and ( G0(23 downto 1) or G0(22 downto 0))) & G0(0) ;
K1 <= (K0(23 downto 1) and ( G0(23 downto 1) or K0(22 downto 0))) & K0(0) ;
-- "BK" cells row 2 (distance 2)
G2 <= (K1(23 downto 2) and ( G1(23 downto 2) or G1(21 downto 0))) & G1(1 downto 0) ;
K2 <= (K1(23 downto 2) and ( G1(23 downto 2) or K1(21 downto 0))) & K1(1 downto 0) ;
-- "BK" cells row 3 (distance 4)
G3 <= (K2(23 downto 4) and ( G2(23 downto 4) or G2(19 downto 0))) & G2(3 downto 0) ;
K3 <= (K2(23 downto 4) and ( G2(23 downto 4) or K2(19 downto 0))) & K2(3 downto 0) ;
-- "BK" cells row 4 (distance 8)
G4 <= (K3(23 downto 8) and ( G3(23 downto 8) or G3(15 downto 0))) & G3(7 downto 0) ;
K4 <= (K3(23 downto 8) and ( G3(23 downto 8) or K3(15 downto 0))) & K3(7 downto 0) ;
-- "BK" cells row 5 (distance 16)
G5 <= (K4(23 downto 16) and ( G4(23 downto 16) or G4(7 downto 0))) & G4(15 downto 0) ;
K5 <= (K4(23 downto 16) and ( G4(23 downto 16) or K4(7 downto 0))) & K4(15 downto 0) ;
c <= G5(23) ; -- carry
m <= P0(23) xor G5(22) ; -- most significant
with c select plus1 <= i and ( k or g or r or s ) when '1' , g and ( i or r or s ) when others ;
with m select minus0 <= g and ( not i or r or s ) when '1' , g or ( r and s ) when others ;
with plus1 select S1 <= ('0' & P0) xor (G5 & '0') when '0', ('0' & P0) xor (K5 & '1') when others ;
with minus0 select S2 <= ('1' & P0) xor (G5 & '0') when '1', ('1' & P0) xor (K5 & '1') when others ;
with o select S0 <= S1 when '0', S2(23 downto 0) & g when others ; -- pre-shift
end structural ;

Step 4
The block "AddEx"
bloc AddEX
The block "AddEx" compute the final result exponent. In parallel the exponent is checked. If the exponent is null, then the result can not be normalised (subnormal) and the leading zero is left explicit.

entity AddEx is
port ( E : in Std_Logic_Vector (7 downto 0 ) ; -- E : positive input
o : in Std_Logic ; -- o : operation 0=>add, 1=>sub
u : in Std_Logic ; -- u : error in prediction, u is late
Z : in Std_Logic_Vector (4 downto 0 ) ; -- Z : number of leading '0'
S : out Std_Logic_Vector (7 downto 0 ) ; -- S : if o then S = E - Z - u else S <= E - u
l : out std_Logic ) ; -- S is nul
end AddEx ;
architecture structural of AddEx is
signal G0, P0, K0, G1, K1, G2, K2, G3, K3 : Std_Logic_Vector ( 7 downto 0 ) ; -- prop, gen, spare
signal L0 : Std_Logic_Vector ( 6 downto 0 ) ;
begin
-- row 0
with o select G0 <= "00000000" when '0', E(7 downto 5) & (E(4 downto 0) and not Z) when others ;
with o select K0 <= E when '0' , "111" & (E(4 downto 0) or not Z) when others ;
P0 <= not G0 and K0 ;
L0 <= not P0(7 downto 1) xor K0(6 downto 0) ; -- "111111" => S = 0
-- "BK" cells row 1 (distance 1)
G1 <= (K0(7 downto 1) and ( G0(7 downto 1) or G0(6 downto 0))) & G0(0) ;
K1 <= (K0(7 downto 1) and ( G0(7 downto 1) or K0(6 downto 0))) & K0(0) ;
-- "BK" cells row 2 (distance 2)
G2 <= (K1(7 downto 2) and ( G1(7 downto 2) or G1(5 downto 0))) & G1(1 downto 0) ;
K2 <= (K1(7 downto 2) and ( G1(7 downto 2) or K1(5 downto 0))) & K1(1 downto 0) ;
-- "BK" cells row 3 (distance 4)
G3 <= (K2(7 downto 4) and ( G2(7 downto 4) or G2(3 downto 0))) & G2(3 downto 0) ;
K3 <= (K2(7 downto 4) and ( G2(7 downto 4) or K2(3 downto 0))) & K2(3 downto 0) ;
-- last row
with u select S <= P0 xor (G3(6 downto 0) & '0') when '1', P0 xor (K3(6 downto 0) & '1') when others ;
with u select l <= L0(5) and L0(4) and L0(3) and L0(2) and L0(1) and L0(0) and not P0(0) when '1' ,
not G3(7) and K3(7) when others ;
end structural ;
The block "ShiftL"
bloc ShiftL
In parallel with "AddEx", the block "ShiftL" shifts "Sm0"to the right of Z positions. The result is not necessarily normalised since a prediction error (in case of subtraction) or an overflow (in case of addition) may have occurred. The last stage correct the error.

entity ShiftL is
port ( E : in Std_Logic_Vector (24 downto 0 ) ; -- E : input
Z : in Std_Logic_Vector (4 downto 0 ) ; -- Z : positions
n : in Std_Logic ; -- n : inhibit correction
S : out Std_Logic_Vector (23 downto 0 ) ; -- S : E shifted left Z + u positions
u : out Std_Logic ) ; -- add to exponent
end ShiftL ;
architecture structural of ShiftL is
signal P0, P1, P2, P3, P4 : Std_Logic_Vector (24 downto 0) ; -- internal signals
begin
with Z(4) select P4 <= E when '0' , E(8 downto 0) & "0000000000000000" when others ;
with Z(3) select P3 <= P4 when '0' , P4(16 downto 0) & "00000000" when others ;
with Z(2) select P2 <= P3 when '0' , P3(20 downto 0) & "0000" when others ;
with Z(1) select P1 <= P2 when '0' , P2(22 downto 0) & "00" when others ;
with Z(0) select P0 <= P1 when '0' , P1(23 downto 0) & "0" when others ;
with P0(24) or n select S <= P0(24 downto 1) when '1' , P0(23 downto 0) when others ;
u <= not ( P0(24) or n ) ;
end structural ;