Estoy diseñando un sumador / multiplicador segmentado y sintetizable de punto flotante de 32 bits como parte de un grupo para una clase en la escuela. Me pusieron a cargo de la re-normalización. Parte de esto es la izquierda o la derecha desplazando un bus 48 que representa la salida de la mantisa. El código que tengo hasta ahora es este
library ieee;
use ieee.std_logic_1164.all;
USE ieee.numeric_std.ALL;
entity renormalizer is
PORT(
enableIN : in std_logic;
signIN : in std_logic;
exponentIN : in std_logic_vector(7 downto 0);
mantissaIN : in std_logic_vector(47 downto 0);
zOUT : out std_logic_vector(31 downto 0)
);
end renormalizer;
architecture behave of renormalizer IS
begin
process(enableIN,signIN,exponentIN,mantissaIN)
variable mantissaHEAD : std_logic_vector(1 downto 0);
variable exponentNORM : std_logic_vector(7 downto 0);
variable exponentONE : std_logic_vector(7 downto 0) := "00000001";
variable exponentNEGONE : std_logic_vector(7 downto 0) := "11111110";
variable exponentCARRY : std_logic_vector(7 downto 0);
begin
mantissaHEAD := mantissaIN(47 downto 46); --First bits of mantissa
case enableIN is
when '0' =>
--Pass things through
zOUT <= signIN & exponentIN & mantissaIN(45 downto 23);
when '1' =>
--Do the normalization
case mantissaHEAD is
--DONT KNOW HOW TO IMPLEMENT THIS
when "00" =>
zOUT <= (others => 'Z')
;
--NUMBER IS RENORMALIZED PASS IT THROUGH
when "01" =>
zOUT <= signIN & exponentIN & mantissaIN(45 downto 23)
;
--THESE BOTTOM TWO DO THE SAME THING
when "10" =>
--SUBTRACT ONE FROM THE EXPONENT AND OUTPUT SHIFTED MANTISSA
exponentNORM(0) := exponentIN(0) xor exponentNEGONE(0) xor '1';
exponentCARRY(0) := (exponentIN(0) and exponentNEGONE(0)) or ('1' and (exponentIN(0) xor exponentNEGONE(0)));
for i in 1 to 7 loop
exponentNORM(i) := exponentIN(i) xor exponentNEGONE(i) xor exponentCARRY(i-1);
exponentCARRY(i) := (exponentIN(i) and exponentNEGONE(i)) or (exponentCARRY(i-1) and (exponentIN(i) xor exponentNEGONE(i)));
end loop;
zOUT <= signIN & exponentNORM & mantissaIN(46 downto 24); --46 downto 24 instead of 45 downto 23
when "11" =>
exponentNORM(0) := exponentIN(0) xor exponentNEGONE(0) xor '1';
exponentCARRY(0) := (exponentIN(0) and exponentNEGONE(0)) or ('1' and (exponentIN(0) xor exponentNEGONE(0)));
for i in 1 to 7 loop
exponentNORM(i) := exponentIN(i) xor exponentNEGONE(i) xor exponentCARRY(i-1);
exponentCARRY(i) := (exponentIN(i) and exponentNEGONE(i)) or (exponentCARRY(i-1) and (exponentIN(i) xor exponentNEGONE(i)));
end loop;
zOUT <= signIN & exponentNORM & mantissaIN(46 downto 24);
when others => zOUT <= (others => 'Z');
end case;
when others => zOUT <= (others => 'Z');
end case;
end process;
end behave;
El código anterior verifica que la mantisa ingresada esté en el formulario 01.xxxxxxxxx ... (de 47 a 0) antes de configurarlo en la salida. Si no es así, cambia la mantisa respectivamente y agrega o resta al exponente de cada cambio. Para un cambio a la derecha, esto es trivial, pero para el desplazamiento a la izquierda un número N de veces no sé cómo implementarlo de manera combinada como parte de una etapa de oleoducto. Realmente estoy perdido, si lo estuviera haciendo problemáticamente, continuaría moviéndome a la izquierda y revisando los dos primeros bits de la mantisa después de cada turno, pero no creo que esto sea posible sintetizarlo. ¿Podría alguien darme un punto en la dirección correcta y alguna orientación para resolver este problema?