OpenCores
URL https://opencores.org/ocsvn/openfpu64/openfpu64/trunk

Subversion Repositories openfpu64

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/openfpu64/trunk/fpu_mul_single.vhd
0,0 → 1,309
-------------------------------------------------------------------------------
-- Project : openFPU64 Multiplier Component
-------------------------------------------------------------------------------
-- File : fpu_mul.vhd
-- Author : Peter Huewe <peterhuewe@gmx.de>
-- Created : 2010-04-19
-- Last update: 2010-04-19
-- Standard : VHDL'87
-- Status : ALPHA! - Bugs exists!
-------------------------------------------------------------------------------
-- Description: double precision floating point multiplier component
-- for openFPU64, includes rounding and normalization
-- Uses only one embedded 18x18 multiplier
-- Note : Last few bits are wrong, perhaps related to stickybit /rounding
-- issues
-------------------------------------------------------------------------------
-- Copyright (c) 2010
-------------------------------------------------------------------------------
-- License: gplv3, see licence.txt
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.helpers.all;
use work.fpu_package.all;
-------------------------------------------------------------------------------
 
entity fpu_mul is
port (
clk, reset_n : in std_logic; -- reset = standard active low
cs : in std_logic; -- mode: 0 = add , 1= sub
sign_a, sign_b : in std_logic; -- sign bits
exponent_a, exponent_b : in std_logic_vector (11 downto 0); -- exponents of the operands
mantissa_a, mantissa_b : in std_logic_vector (57 downto 0); -- mantissa of operands
--enable : in std_logic; -- enable this submodule
sign_res : out std_logic;
exponent_res : out std_logic_vector(11 downto 0);
mantissa_res : out std_logic_vector (57 downto 0);
rounding_needed : out std_logic;
-- result : out std_logic_vector (63 downto 0);
-- ready : out std_logic; -- entspricht waitrequest_n
valid : out std_logic
);
 
end fpu_mul;
 
-------------------------------------------------------------------------------
 
architecture rtl of fpu_mul is
 
-----------------------------------------------------------------------------
-- Internal signal declarations
-----------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--signal mul_a, mul_b : std_logic_vector(53 downto 0); -- inputs for multiplier
--signal mul_result: std_logic_vector(57 downto 0); -- result of multiplier
signal add_result, add_op_a : unsigned (39 downto 0);
signal add_op_b : unsigned (35 downto 0);
signal mul_result : unsigned(35 downto 0);
signal mul_op_a, mul_op_b : unsigned(17 downto 0);
type t_state is (s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s12a, s12b,s12c,s12d); -- possible states
signal state : t_state; -- current state
 
signal exponent_out : std_logic_vector(11 downto 0);
signal tmp_result : std_logic_vector (57 downto 0);
 
 
alias a : std_logic_vector(17 downto 0) is mantissa_a(56 downto 39);
alias b : std_logic_vector(17 downto 0) is mantissa_a(38 downto 21);
alias c : std_logic_vector(17 downto 0) is mantissa_a(20 downto 3);
alias d : std_logic_vector(17 downto 0) is mantissa_b(56 downto 39);
alias e : std_logic_vector(17 downto 0) is mantissa_b(38 downto 21);
alias f : std_logic_vector(17 downto 0) is mantissa_b(20 downto 3);
 
 
signal a_is_normal, b_is_normal : std_logic;
signal sticky_bit : std_logic;
signal sticky_bit_enabled : std_logic;
-----------------------------------------------------------------------------
-- Component declarations
-----------------------------------------------------------------------------
begin
----------------------------------------------------------------
-- Component instantiations
-----------------------------------------------------------------------------
 
-- purpose: calculates the result of a multiplication
-- type : combinational
-- inputs : sign_a, sign_b, exponent_a, exponent_b, mantissa_a, mantissa_b
-- outputs: result
 
add_result <= add_op_a + add_op_b;
mul_result <= unsigned(mul_op_a) * unsigned(mul_op_b);
a_is_normal <= '0' when unsigned(exponent_a(10 downto 0)) = ALL_ZEROS else '1';
b_is_normal <= '0' when unsigned(exponent_b(10 downto 0)) = ALL_ZEROS else '1';
sticky_bit <= sticky_bit_enabled when add_result(18 downto 0) /= ZEROS(18 downto 0) else '0';
 
state_trans : process (clk, reset_n, cs)
variable tmp : unsigned(57 downto 0);
begin -- process state_trans
rounding_needed <= '1';
if reset_n = '0' or cs = '0' then
state <= s1;
sign_res <= '0';
valid <= '0';
sticky_bit_enabled <= '0';
-- result <= (others => '0');
exponent_res <= (others => '0');
mantissa_res <= (others => '0');
-- tmp := (others => '0');
tmp_result <= (others => '0');
elsif rising_edge(clk) then
sign_res <= sign_a xor sign_b;
valid <= '0';
-- result <= (others => '0');
exponent_res <= exponent_out;
mantissa_res <= (others => '0');
mantissa_res <= tmp_result;
tmp_result <= tmp_result;
add_op_a <= (others => '0');
add_op_b <= (others => '0');
mul_op_a <= (others => '0');
mul_op_b <= (others => '0');
sticky_bit_enabled <= sticky_bit_enabled;
 
case state is
when s1 =>
add_op_a <= (others => '0');
add_op_b <= (others => '0');
add_op_a(10 downto 0) <= unsigned(exponent_a(10 downto 0));
add_op_b(10 downto 0) <= unsigned(exponent_b(10 downto 0));
 
mul_op_a <= unsigned(c);
mul_op_b <= unsigned(f);
state <= s2;
when s2 =>
--assert false report "Test" & to_string(std_logic_vector(add_result(13 downto 0))) severity warning;
add_op_a (11 downto 0) <= add_result(11 downto 0);
add_op_b (11 downto 0) <= DOUBLE_BIAS_2COMPLEMENT(11 downto 0);
tmp_result(35 downto 0) <= std_logic_vector(mul_result);
 
mul_op_a <= unsigned(b);
mul_op_b <= unsigned(f);
 
 
state <= s3;
when s3 =>
-- assert false report "Test" & to_string(std_logic_vector(add_result(13 downto 0))) severity warning;
-- assert false report "ea" & to_string(exponent_a) & "eb" & to_string(exponent_b) &"xx"& to_string(std_logic_vector(DOUBLE_BIAS_2COMPLEMENT)) severity warning;
-- if either the result is a subnormal/zero or both operands are zero
-- set exponent to zero
if (add_result(12) = '1' and (a_is_normal = '0' or b_is_normal = '0'))
or (a_is_normal = '0' and b_is_normal = '0')
then
exponent_out <= (others => '0');
else
exponent_out <= std_logic_vector(add_result(11 downto 0));
end if;
sticky_bit_enabled <= '1'; -- since we start adding up values,
-- sticky bit has to be calculated
assert sticky_bit = '0' report "sticky3"&to_string(std_logic_vector(add_result))severity note;
 
if unsigned(tmp_result(18 downto 0)) = (ZEROS(18 downto 0))then
add_op_a <= unsigned(tmp_result(57 downto 19))&'0';
 
else
add_op_a <= unsigned(tmp_result(57 downto 18));
end if;
 
add_op_b <= mul_result;
 
mul_op_a <= unsigned(c);
mul_op_b <= unsigned(e);
 
state <= s4;
when s4 =>
assert sticky_bit = '0' report "sticky4"&to_string(std_logic_vector(add_result))severity note;
add_op_a <= add_result;
add_op_b <= mul_result;
 
mul_op_a <= unsigned(a);
mul_op_b <= unsigned(f);
 
state <= s5;
when s5 =>
assert sticky_bit = '0' report "sticky5"&to_string(std_logic_vector(add_result))severity note;
add_op_a <= "00"&x"0000"& add_result(39 downto 19)&sticky_bit;
add_op_b <= mul_result;
 
mul_op_a <= unsigned(b);
mul_op_b <= unsigned(e);
 
state <= s6;
when s6 =>
assert sticky_bit = '0' report "sticky6"&to_string(std_logic_vector(add_result))severity note;
add_op_a <= add_result;
add_op_b <= mul_result;
 
mul_op_a <= unsigned(c);
mul_op_b <= unsigned(d);
 
 
 
state <= s7;
when s7 =>
assert sticky_bit = '0' report "sticky7"&to_string(std_logic_vector(add_result))severity note;
add_op_a <= add_result;
add_op_b <= mul_result;
mul_op_a <= unsigned(a);
mul_op_b <= unsigned(e);
 
state <= s8;
when s8 =>
assert sticky_bit = '0' report "sticky8"&to_string(std_logic_vector(add_result))severity note;
add_op_a <= "00"&x"0000"& add_result(39 downto 18);--&sticky_bit;
add_op_b <= mul_result;
 
mul_op_a <= unsigned(b);
mul_op_b <= unsigned(d);
 
 
state <= s9;
when s9 =>
assert sticky_bit = '0' report "sticky9"&to_string(std_logic_vector(add_result))severity note;
add_op_a <= add_result;
add_op_b <= mul_result;
mul_op_a <= unsigned(a);
mul_op_b <= unsigned(d);
tmp_result <= (others => '0');
assert false report "bla" & to_string(std_logic_vector(add_result)) severity warning;
assert false report "bla" & to_string(std_logic_vector(add_result(39 downto 30))) severity warning;
tmp_result (4 downto 0) <= std_logic_vector(add_result(39 downto 36))&sticky_bit; --
-- driving me crazy!
 
state <= s10;
when s10 =>
assert sticky_bit = '0' report "sticky10"&to_string(std_logic_vector(add_result))severity note;
assert false report "bla1" & to_string(std_logic_vector(add_result)) severity warning;
add_op_a <= "00"&x"0000"& add_result(39 downto 18);
add_op_b <= mul_result;
 
tmp_result(22 downto 5) <= std_logic_vector(add_result(17 downto 0));
 
 
state <= s11;
when s11 =>
assert false report "bla2" & to_string(std_logic_vector(add_result)) severity warning;
tmp_result (57 downto 23) <= std_logic_vector(add_result(34 downto 0));
state <= s12b;
if add_result (33) = '1' then
state <= s12a;
end if;
-- VALID <= '1';
 
when s12a=>
assert false report "shift"&to_string(tmp_result) severity note;
assert false report "ungleich" severity note;
tmp_result(57 downto 1) <= '0'&tmp_result(57 downto 2);
tmp_result(0) <= tmp_result(1) or tmp_result(0);
exponent_out <= std_logic_vector(unsigned(exponent_out)+"1");
state <= s12b;
 
when s12b=>
assert false report "vorrund"&to_string(tmp_result) severity note;
case tmp_result(3 downto 0) is
when "0101" => tmp_result(3) <= '1';
when "0110" => tmp_result(3) <= '1';
when "0111" => tmp_result(3) <= '1';
 
when "1100" => tmp_result(57 downto 3) <= std_logic_vector(unsigned(tmp_result(57 downto 3))+"1");
when "1101" => tmp_result(57 downto 3) <= std_logic_vector(unsigned(tmp_result(57 downto 3))+"1");
when "1110" => tmp_result(57 downto 3) <= std_logic_vector(unsigned(tmp_result(57 downto 3))+"1");
when "1111" => tmp_result(57 downto 3) <= std_logic_vector(unsigned(tmp_result (57 downto 3))+"1");
 
 
when others => null; -- others remain unchanged
end case;
state <= s12c;
when s12c=>
state <= s12;
if tmp_result(56) ='1' then
state <= s12d;
end if;
 
when s12d=>
assert false report "ungleich" severity note;
tmp_result(57 downto 1) <= '0'&tmp_result(57 downto 2);
tmp_result(0) <= tmp_result(1) or tmp_result(0);
exponent_out <= std_logic_vector(unsigned(exponent_out)+"1");
state <= s12;
 
 
when s12 =>
assert false report "ttt"&to_string(tmp_result) severity note;
state <= s12;
valid <= '1';
 
when others => null;
end case;
end if;
end process state_trans;
end rtl;
 
-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.