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

Subversion Repositories fpu100

[/] [fpu100/] [trunk/] [pre_norm_addsub.vhd] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jidan
-------------------------------------------------------------------------------
2
--
3
-- Project:     <Floating Point Unit Core>
4
--      
5 18 jidan
-- Description: pre-normalization entity for the addition/subtraction unit
6 2 jidan
-------------------------------------------------------------------------------
7
--
8
--                              100101011010011100100
9
--                              110000111011100100000
10
--                              100000111011000101101
11
--                              100010111100101111001
12
--                              110000111011101101001
13
--                              010000001011101001010
14
--                              110100111001001100001
15
--                              110111010000001100111
16
--                              110110111110001011101
17
--                              101110110010111101000
18
--                              100000010111000000000
19
--
20
--      Author:          Jidan Al-eryani 
21
--      E-mail:          jidan@gmx.net
22
--
23
--  Copyright (C) 2006
24
--
25
--      This source file may be used and distributed without        
26
--      restriction provided that this copyright statement is not   
27
--      removed from the file and that any derivative work contains 
28
--      the original copyright notice and the associated disclaimer.
29
--                                                           
30
--              THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     
31
--      EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   
32
--      TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   
33
--      FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      
34
--      OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         
35
--      INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    
36
--      (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   
37
--      GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        
38
--      BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  
39
--      LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  
40
--      (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  
41
--      OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         
42
--      POSSIBILITY OF SUCH DAMAGE. 
43
--
44
 
45
library ieee ;
46
use ieee.std_logic_1164.all;
47
use ieee.std_logic_unsigned.all;
48
use ieee.std_logic_misc.all;
49
 
50
library work;
51
use work.fpupack.all;
52
 
53 18 jidan
entity pre_norm_addsub is
54 2 jidan
        port(
55
                        clk_i                   : in std_logic;
56 18 jidan
                        opa_i                   : in std_logic_vector(FP_WIDTH-1 downto 0);
57
                        opb_i                   : in std_logic_vector(FP_WIDTH-1 downto 0);
58
                        fracta_28_o             : out std_logic_vector(FRAC_WIDTH+4 downto 0);   -- carry(1) & hidden(1) & fraction(23) & guard(1) & round(1) & sticky(1)
59
                        fractb_28_o             : out std_logic_vector(FRAC_WIDTH+4 downto 0);
60
                        exp_o                   : out std_logic_vector(EXP_WIDTH-1 downto 0)
61 2 jidan
                );
62 18 jidan
end pre_norm_addsub;
63 2 jidan
 
64
 
65 18 jidan
architecture rtl of pre_norm_addsub is
66 2 jidan
 
67
 
68 18 jidan
        signal s_exp_o : std_logic_vector(EXP_WIDTH-1 downto 0);
69
        signal s_fracta_28_o, s_fractb_28_o : std_logic_vector(FRAC_WIDTH+4 downto 0);
70
        signal s_expa, s_expb : std_logic_vector(EXP_WIDTH-1 downto 0);
71
        signal s_fracta, s_fractb : std_logic_vector(FRAC_WIDTH-1 downto 0);
72 2 jidan
 
73 18 jidan
        signal s_fracta_28, s_fractb_28, s_fract_sm_28, s_fract_shr_28 : std_logic_vector(FRAC_WIDTH+4 downto 0);
74 2 jidan
 
75 18 jidan
        signal s_exp_diff : std_logic_vector(EXP_WIDTH-1 downto 0);
76
        signal s_rzeros : std_logic_vector(5 downto 0);
77 2 jidan
 
78 18 jidan
        signal s_expa_eq_expb : std_logic;
79
        signal s_expa_lt_expb : std_logic;
80
        signal s_fracta_1 : std_logic;
81
        signal s_fractb_1 : std_logic;
82
        signal s_op_dn,s_opa_dn, s_opb_dn : std_logic;
83
        signal s_mux_diff : std_logic_vector(1 downto 0);
84
        signal s_mux_exp : std_logic;
85
        signal s_sticky : std_logic;
86
begin
87 17 jidan
 
88 2 jidan
        -- Input Register
89
        --process(clk_i)
90
        --begin
91
        --      if rising_edge(clk_i) then      
92 18 jidan
                        s_expa <= opa_i(30 downto 23);
93
                        s_expb <= opb_i(30 downto 23);
94
                        s_fracta <= opa_i(22 downto 0);
95
                        s_fractb <= opb_i(22 downto 0);
96 2 jidan
        --      end if;
97 18 jidan
        --end process;          
98
 
99 17 jidan
        -- Output Register
100 2 jidan
        process(clk_i)
101
        begin
102 18 jidan
                if rising_edge(clk_i) then
103
                exp_o <= s_exp_o;
104
                fracta_28_o <= s_fracta_28_o;
105
                fractb_28_o <= s_fractb_28_o;
106 2 jidan
                end if;
107 18 jidan
        end process;
108 2 jidan
 
109 18 jidan
        s_expa_eq_expb <= '1' when s_expa = s_expb else '0';
110
        s_expa_lt_expb <= '1' when s_expa > s_expb else '0';
111 2 jidan
 
112 18 jidan
        -- '1' if fraction is not zero
113
        s_fracta_1 <= or_reduce(s_fracta);
114
        s_fractb_1 <= or_reduce(s_fractb);
115
 
116
        -- opa or Opb is denormalized
117
        s_op_dn <= s_opa_dn or s_opb_dn;
118
        s_opa_dn <= not or_reduce(s_expa);
119
        s_opb_dn <= not or_reduce(s_expb);
120
 
121
        -- output the larger exponent 
122
        s_mux_exp <= s_expa_lt_expb;
123 2 jidan
        process(clk_i)
124
        begin
125 18 jidan
                if rising_edge(clk_i) then
126
                        case s_mux_exp is
127
                                when '0' => s_exp_o <= s_expb;
128
                                when '1' => s_exp_o <= s_expa;
129
                                when others => s_exp_o <= "11111111";
130
                        end case;
131 2 jidan
                end if;
132
        end process;
133
 
134 18 jidan
        -- convert to an easy to handle floating-point format
135
        s_fracta_28 <= "01" & s_fracta & "000" when s_opa_dn='0' else "00" & s_fracta & "000";
136
        s_fractb_28 <= "01" & s_fractb & "000" when s_opb_dn='0' else "00" & s_fractb & "000";
137
 
138
 
139
        s_mux_diff <= s_expa_lt_expb & (s_opa_dn xor s_opb_dn);
140 2 jidan
        process(clk_i)
141
        begin
142
                if rising_edge(clk_i) then
143 18 jidan
                        -- calculate howmany postions the fraction will be shifted
144
                        case s_mux_diff is
145
                                when "00"=> s_exp_diff <= s_expb - s_expa;
146
                                when "01"=>     s_exp_diff <= s_expb - (s_expa+"00000001");
147
                                when "10"=> s_exp_diff <= s_expa - s_expb;
148
                                when "11"=> s_exp_diff <= s_expa - (s_expb+"00000001");
149
                                when others => s_exp_diff <= "11110000";
150
                        end case;
151 2 jidan
                end if;
152
        end process;
153
 
154
 
155 18 jidan
        s_fract_sm_28 <= s_fracta_28 when s_expa_lt_expb='0' else s_fractb_28;
156 2 jidan
 
157 18 jidan
        -- shift-right the fraction if necessary
158
        s_fract_shr_28 <= shr(s_fract_sm_28, s_exp_diff);
159 2 jidan
 
160 18 jidan
        -- count the zeros from right to check if result is inexact
161
        s_rzeros <= count_r_zeros(s_fract_sm_28);
162
        s_sticky <= '1' when s_exp_diff > s_rzeros and or_reduce(s_fract_sm_28)='1' else '0';
163 2 jidan
 
164 18 jidan
        s_fracta_28_o <= s_fracta_28 when s_expa_lt_expb='1' else s_fract_shr_28(27 downto 1) & (s_sticky or s_fract_shr_28(0));
165
        s_fractb_28_o <= s_fractb_28 when s_expa_lt_expb='0' else s_fract_shr_28(27 downto 1) & (s_sticky or s_fract_shr_28(0));
166 2 jidan
 
167
 
168
end rtl;

powered by: WebSVN 2.1.0

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