You are on page 1of 3

-----------------------------------------------------------------------------

-----
-- Company: Instituto Superior Tcnico
-- Prof: Paulo Alexandre Crisstomo Lopes
-- paulo.lopes@inesc-id.pt
--
-- Create Date: 14:01:57 12/27/2011
-- Design Name:
-- Module Name: multiplier - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description: VHDL implementation of a 32 bit floating multiplier.
-- Float format: sign | 8 bits exponent + 127 | 23 bits
normalized mantissa.
-- Uses IEEE 754-1985, with the following exceptions.
-- NaN is not implemented. Operations that would result in
NaN
-- have a non definied result.
-- An exponent of all zeros will always mean zero, and an
-- exponent of all ones will always mean infinity.
-- Rounding is round nearest ties away from zero.
-- Non normalized numbers are not implemented.
--
-- Dependencies:
--
-- Revision:
-- Revision 1.02
-- - Removal of comparators to test undeflow and overflow.
-- - Adding of test for 0*x and inf*x.
-- - Added rounding.
--
-- Additional Comments:
--
-----------------------------------------------------------------------------
-----
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

entity multiplier is
Port ( x : in STD_LOGIC_VECTOR (31 downto 0);
y : in STD_LOGIC_VECTOR (31 downto 0);
z : out STD_LOGIC_VECTOR (31 downto 0));
end multiplier;

architecture Behavioral of multiplier is

begin
process(x,y)
variable x_mantissa : STD_LOGIC_VECTOR (22 downto 0);
variable x_exponent : STD_LOGIC_VECTOR (7 downto 0);
variable x_sign : STD_LOGIC;
variable y_mantissa : STD_LOGIC_VECTOR (22 downto 0);
variable y_exponent : STD_LOGIC_VECTOR (7 downto 0);
variable y_sign : STD_LOGIC;
variable z_mantissa : STD_LOGIC_VECTOR (22 downto 0);
variable z_exponent : STD_LOGIC_VECTOR (7 downto 0);
variable z_sign : STD_LOGIC;
variable aux : STD_LOGIC;
variable aux2 : STD_LOGIC_VECTOR (47 downto 0);
variable exponent_sum : STD_LOGIC_VECTOR (8 downto 0);
begin
x_mantissa := x(22 downto 0);
x_exponent := x(30 downto 23);
x_sign := x(31);
y_mantissa := y(22 downto 0);
y_exponent := y(30 downto 23);
y_sign := y(31);

-- inf*0 is not tested (result would be NaN)
if (x_exponent=255 or y_exponent=255) then
-- inf*x or x*inf
z_exponent := "11111111";
z_mantissa := (others => '0');
z_sign := x_sign xor y_sign;

elsif (x_exponent=0 or y_exponent=0) then
-- 0*x or x*0
z_exponent := (others => '0');
z_mantissa := (others => '0');
z_sign := '0';
else

aux2 := ('1' & x_mantissa) * ('1' & y_mantissa);
-- args in Q23 result in Q46
if (aux2(47)='1') then
-- >=2, shift left and add one to exponent
z_mantissa := aux2(46 downto 24) + aux2(23); --
with rounding
aux := '1';
else
z_mantissa := aux2(45 downto 23) + aux2(22); --
with rounding
aux := '0';
end if;

-- calculate exponent
exponent_sum := ('0' & x_exponent) + ('0' & y_exponent)
+ aux - 127;

if (exponent_sum(8)='1') then
if (exponent_sum(7)='0') then -- overflow
z_exponent := "11111111";
z_mantissa := (others => '0');
z_sign := x_sign xor y_sign;
else -- underflow
z_exponent := (others => '0');
z_mantissa := (others => '0');
z_sign := '0';
end if;
else -- Ok
z_exponent := exponent_sum(7 downto 0);
z_sign := x_sign xor y_sign;
end if;
end if;


z(22 downto 0) <= z_mantissa;
z(30 downto 23) <= z_exponent;
z(31) <= z_sign;

end process;
end Behavioral;

You might also like