diff --git a/CarryLookAhead.vhd b/CarryLookAhead.vhd
index 1d2b652..2c18cfa 100644
--- a/CarryLookAhead.vhd
+++ b/CarryLookAhead.vhd
@@ -36,8 +36,6 @@ begin
CLA : AddSub
generic map (BITCOUNT => 48)
port map (X => X, Y => Y, IS_SUB => OP, RESULT => RESULT, OVERFLOW => OVERFLOW);
-
- --OVERFLOW <= OVERFLOW_TMP xor OP;
end CarryLookAheadArch;
diff --git a/IEEE754Adder.xise b/IEEE754Adder.xise
index 621355e..208cf08 100644
--- a/IEEE754Adder.xise
+++ b/IEEE754Adder.xise
@@ -43,7 +43,7 @@
-
+
@@ -81,11 +81,11 @@
-
+
-
+
@@ -107,7 +107,7 @@
-
+
@@ -141,7 +141,7 @@
-
+
@@ -151,15 +151,15 @@
-
+
-
+
-
+
@@ -287,9 +287,9 @@
-
-
-
+
+
+
@@ -358,7 +358,7 @@
-
+
@@ -373,10 +373,10 @@
-
-
-
-
+
+
+
+
@@ -425,8 +425,8 @@
-
-
+
+
@@ -445,7 +445,7 @@
-
+
diff --git a/Normalizer.vhd b/Normalizer.vhd
index b817642..cadd6c7 100644
--- a/Normalizer.vhd
+++ b/Normalizer.vhd
@@ -7,16 +7,151 @@ entity Normalizer is
SIGN : in std_logic;
EXP : in std_logic_vector(7 downto 0);
MANT : in std_logic_vector(47 downto 0);
- OVERFLOW : in std_logic;
+ SUM_OVERFLOW : in std_logic;
IEEE_754_SUM : out std_logic_vector(31 downto 0)
);
-
+
end Normalizer;
architecture NormalizerArch of Normalizer is
+ component ZeroCounter is
+ generic(
+ BITCOUNT : integer := 8;
+ RES_BITCOUNT : integer := 3 -- MUST BE >= CEIL( LOG2( BITCOUNT ) )
+ );
+ port(
+ X : in std_logic_vector( (BITCOUNT-1) downto 0 );
+ Z_COUNT : out std_logic_vector( (RES_BITCOUNT-1) downto 0 );
+ ALL_ZEROS : out std_logic
+ );
+ end component;
+
+ component Comparator is
+ generic(
+ BITCOUNT: integer := 8
+ );
+ port(
+ X_MANT, Y_MANT : in std_logic_vector((BITCOUNT-1) downto 0);
+ NEED_SWAP : out std_logic
+ );
+ end component;
+
+ component AddSub is
+ generic(
+ BITCOUNT : integer := 8
+ );
+ port(
+ X, Y : in std_logic_vector((BITCOUNT-1) downto 0);
+ IS_SUB : in std_logic := '0';
+ RESULT : out std_logic_vector((BITCOUNT-1) downto 0);
+ OVERFLOW : out std_logic
+ );
+ end component;
+
+ component ShiftLeft48 is
+ port(
+ N : in std_logic_vector(47 downto 0);
+ PLACES : in std_logic_vector(8 downto 0);
+ RESULT : out std_logic_vector(47 downto 0)
+ );
+ end component;
+
+ signal EXP_ADD_LEFT: std_logic_vector(7 downto 0);
+ signal EXP_ADD_RIGHT: std_logic_vector(7 downto 0);
+ signal EXP_ADD_ISSUB: std_logic;
+
+ signal ZERO_COUNT: std_logic_vector(7 downto 0);
+ signal ALL_ZEROS: std_logic;
+ signal IS_FINAL_EXP_MINIMUM: std_logic;
+
+ signal EXP_ADDSUB_RES: std_logic_vector(7 downto 0);
+ signal EXP_ADDSUB_OF: std_logic;
+
+ signal FINAL_EXP: std_logic_vector(7 downto 0);
+
+ signal LEFT_SHIFT_AMOUNT: std_logic_vector(8 downto 0);
+ signal LEFT_SHIFTED_MANT: std_logic_vector(22 downto 0);
+ signal LEFT_SHIFTED_MANT_TMP: std_logic_vector(47 downto 0);
+ signal RIGHT_SHIFTED_MANT: std_logic_vector(22 downto 0);
+ signal FINAL_MANT: std_logic_vector(22 downto 0);
+
begin
+ ZC: ZeroCounter
+ generic map ( BITCOUNT => 48, RES_BITCOUNT => 8 )
+ port map ( X => MANT, Z_COUNT => ZERO_COUNT, ALL_ZEROS => ALL_ZEROS ); -- ALL_ZEROS can be ignored
+
+ C : Comparator
+ generic map ( BITCOUNT => 8 )
+ port map ( X_MANT => EXP, Y_MANT => ZERO_COUNT, NEED_SWAP => IS_FINAL_EXP_MINIMUM );
+
+
+ sum_input_process: process (SUM_OVERFLOW, IS_FINAL_EXP_MINIMUM, EXP, ZERO_COUNT)
+ begin
+ if (SUM_OVERFLOW = '1') then
+ EXP_ADD_LEFT <= EXP;
+ EXP_ADD_RIGHT <= "00000001";
+ EXP_ADD_ISSUB <= '0';
+ elsif (IS_FINAL_EXP_MINIMUM = '1') then
+ EXP_ADD_LEFT <= "01111111"; --127
+ EXP_ADD_RIGHT <= EXP;
+ EXP_ADD_ISSUB <= '1';
+ else
+ EXP_ADD_LEFT <= EXP;
+ EXP_ADD_RIGHT <= ZERO_COUNT;
+ EXP_ADD_ISSUB <= '1';
+ end if;
+ end process;
+
+ CLA : AddSub
+ generic map ( BITCOUNT => 8 )
+ port map ( X => EXP_ADD_LEFT, Y => EXP_ADD_RIGHT, IS_SUB => EXP_ADD_ISSUB, RESULT => EXP_ADDSUB_RES, OVERFLOW => EXP_ADDSUB_OF );
+
+ shift_process: process (IS_FINAL_EXP_MINIMUM, EXP_ADDSUB_RES, ZERO_COUNT)
+ begin
+ if (IS_FINAL_EXP_MINIMUM = '1') then
+ LEFT_SHIFT_AMOUNT <= '0' & EXP_ADDSUB_RES;
+ else
+ LEFT_SHIFT_AMOUNT <= '0' & ZERO_COUNT;
+ end if;
+ end process;
+
+
+ RIGHT_SHIFTED_MANT <= '1' & MANT(47 downto 26);
+ SL: ShiftLeft48
+ port map ( N => MANT, PLACES => LEFT_SHIFT_AMOUNT, RESULT => LEFT_SHIFTED_MANT_TMP );
+ LEFT_SHIFTED_MANT <= LEFT_SHIFTED_MANT_TMP(47 downto 25);
+
+ final_process: process (SUM_OVERFLOW, IS_FINAL_EXP_MINIMUM, EXP_ADDSUB_RES, EXP_ADDSUB_OF, RIGHT_SHIFTED_MANT, LEFT_SHIFTED_MANT)
+ variable IS_INF : std_logic;
+ begin
+ if (SUM_OVERFLOW = '1') then
+ IS_INF := '1';
+ for i in EXP_ADDSUB_RES'range loop
+ IS_INF := IS_INF and EXP_ADDSUB_RES(i);
+ end loop;
+ IS_INF := IS_INF or EXP_ADDSUB_OF;
+
+ if (IS_INF = '1') then
+ FINAL_EXP <= "11111111";
+ FINAL_MANT <= "00000000000000000000000";
+ else
+ FINAL_EXP <= EXP_ADDSUB_RES;
+ FINAL_MANT <= RIGHT_SHIFTED_MANT;
+ end if;
+ else
+ if (IS_FINAL_EXP_MINIMUM = '1') then
+ FINAL_EXP <= "00000000";
+ FINAL_MANT <= LEFT_SHIFTED_MANT;
+ else
+ FINAL_EXP <= EXP_ADDSUB_RES;
+ FINAL_MANT <= LEFT_SHIFTED_MANT;
+ end if;
+ end if;
+ end process;
+
+ IEEE_754_SUM <= SIGN & FINAL_EXP & FINAL_MANT;
end NormalizerArch;
diff --git a/ZeroCounter.vhd b/ZeroCounter.vhd
index 551f62f..1816552 100644
--- a/ZeroCounter.vhd
+++ b/ZeroCounter.vhd
@@ -1,6 +1,7 @@
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
+use IEEE.MATH_REAL.ALL;
entity ZeroCounter is
generic(
@@ -15,12 +16,14 @@ entity ZeroCounter is
end ZeroCounter;
architecture ZeroCounterArch of ZeroCounter is
+ signal ALLZERO_SIGNAL : std_logic;
begin
- ZEROCOUNT_PROCESS: process (X)
+ ZEROCOUNT_PROCESS: process (X, ALLZERO_SIGNAL)
variable ZC: std_logic_vector((RES_BITCOUNT-1) downto 0);
variable BIN_N: std_logic_vector((RES_BITCOUNT-1) downto 0);
variable PART_ZC: std_logic_vector((BITCOUNT-1) downto 0);
+ variable ALLZERO_PART_ZC: std_logic;
begin
ZC := ((RES_BITCOUNT-1) downto 0 => '0');
PART_ZC := ((BITCOUNT-1) downto 0 => '1');
@@ -41,6 +44,16 @@ begin
end loop;
end loop;
+ -- CHECK IF ALL_ZEROS FITS IN RESULT
+ if ( BITCOUNT < (2 ** RES_BITCOUNT) ) then
+ BIN_N := std_logic_vector(to_unsigned(BITCOUNT, BIN_N'length));
+ for res_i in (RES_BITCOUNT-1) downto 0 loop
+ if ( BIN_N(res_i) = '1' ) then
+ ZC(res_i) := ZC(res_i) or ALLZERO_SIGNAL;
+ end if;
+ end loop;
+ end if;
+
Z_COUNT <= ZC;
end process;
@@ -53,8 +66,10 @@ begin
for i in X'range loop
AZ := AZ and (not X(i));
end loop;
- ALL_ZEROS <= AZ;
+ ALLZERO_SIGNAL <= AZ;
end process;
+
+ ALL_ZEROS <= ALLZERO_SIGNAL;
end ZeroCounterArch;