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

Subversion Repositories openfpu64

[/] [openfpu64/] [trunk/] [fpu_mul_single.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 bro
-------------------------------------------------------------------------------
2
-- Project    : openFPU64 Multiplier Component
3
-------------------------------------------------------------------------------
4
-- File       : fpu_mul.vhd
5
-- Author     : Peter Huewe  <peterhuewe@gmx.de>
6
-- Created    : 2010-04-19
7
-- Last update: 2010-04-19
8
-- Standard   : VHDL'87
9
-- Status     : ALPHA! - Bugs exists!
10
-------------------------------------------------------------------------------
11
-- Description: double precision floating point multiplier component
12
--                     for openFPU64, includes rounding and normalization
13
--              Uses only one embedded 18x18 multiplier
14
-- Note       : Last few bits are wrong, perhaps related to stickybit /rounding
15
--                      issues
16
-------------------------------------------------------------------------------
17
-- Copyright (c) 2010 
18
-------------------------------------------------------------------------------
19
-- License: gplv3, see licence.txt
20
-------------------------------------------------------------------------------
21
library ieee;
22
use ieee.std_logic_1164.all;
23
use ieee.numeric_std.all;
24
use work.helpers.all;
25
use work.fpu_package.all;
26
-------------------------------------------------------------------------------
27
 
28
entity fpu_mul is
29
  port (
30
    clk, reset_n           : in  std_logic;  -- reset = standard active low
31
    cs                     : in  std_logic;  --  mode: 0 = add , 1= sub
32
    sign_a, sign_b         : in  std_logic;  -- sign bits
33
    exponent_a, exponent_b : in  std_logic_vector (11 downto 0);  -- exponents of the operands
34
    mantissa_a, mantissa_b : in  std_logic_vector (57 downto 0);  -- mantissa of operands
35
    --enable       : in  std_logic;       -- enable this submodule
36
    sign_res               : out std_logic;
37
    exponent_res           : out std_logic_vector(11 downto 0);
38
    mantissa_res           : out std_logic_vector (57 downto 0);
39
    rounding_needed        : out std_logic;
40
    -- result                 : out std_logic_vector (63 downto 0);
41
    -- ready        : out std_logic;       -- entspricht waitrequest_n
42
    valid                  : out std_logic
43
    );
44
 
45
end fpu_mul;
46
 
47
-------------------------------------------------------------------------------
48
 
49
architecture rtl of fpu_mul is
50
 
51
  -----------------------------------------------------------------------------
52
  -- Internal signal declarations
53
  -----------------------------------------------------------------------------
54
-------------------------------------------------------------------------------
55
-------------------------------------------------------------------------------
56
  --signal mul_a, mul_b         : std_logic_vector(53 downto 0);  -- inputs for multiplier
57
--signal mul_result: std_logic_vector(57 downto 0);  -- result of multiplier
58
  signal add_result, add_op_a : unsigned (39 downto 0);
59
  signal add_op_b             : unsigned (35 downto 0);
60
  signal mul_result           : unsigned(35 downto 0);
61
  signal mul_op_a, mul_op_b   : unsigned(17 downto 0);
62
  type t_state is (s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s12a, s12b,s12c,s12d);  -- possible states
63
  signal state                : t_state;  -- current state
64
 
65
  signal exponent_out : std_logic_vector(11 downto 0);
66
  signal tmp_result   : std_logic_vector (57 downto 0);
67
 
68
 
69
  alias a : std_logic_vector(17 downto 0) is mantissa_a(56 downto 39);
70
  alias b : std_logic_vector(17 downto 0) is mantissa_a(38 downto 21);
71
  alias c : std_logic_vector(17 downto 0) is mantissa_a(20 downto 3);
72
  alias d : std_logic_vector(17 downto 0) is mantissa_b(56 downto 39);
73
  alias e : std_logic_vector(17 downto 0) is mantissa_b(38 downto 21);
74
  alias f : std_logic_vector(17 downto 0) is mantissa_b(20 downto 3);
75
 
76
 
77
  signal a_is_normal, b_is_normal : std_logic;
78
  signal sticky_bit               : std_logic;
79
  signal sticky_bit_enabled       : std_logic;
80
-----------------------------------------------------------------------------
81
-- Component declarations
82
-----------------------------------------------------------------------------
83
begin
84
----------------------------------------------------------------
85
  -- Component instantiations
86
  -----------------------------------------------------------------------------
87
 
88
  -- purpose: calculates the result of a multiplication
89
  -- type   : combinational
90
  -- inputs : sign_a, sign_b, exponent_a, exponent_b, mantissa_a, mantissa_b
91
  -- outputs: result
92
 
93
  add_result  <= add_op_a + add_op_b;
94
  mul_result  <= unsigned(mul_op_a) * unsigned(mul_op_b);
95
  a_is_normal <= '0'                when unsigned(exponent_a(10 downto 0)) = ALL_ZEROS else '1';
96
  b_is_normal <= '0'                when unsigned(exponent_b(10 downto 0)) = ALL_ZEROS else '1';
97
  sticky_bit  <= sticky_bit_enabled when add_result(18 downto 0) /= ZEROS(18 downto 0) else '0';
98
 
99
  state_trans : process (clk, reset_n, cs)
100
    variable tmp : unsigned(57 downto 0);
101
  begin  -- process state_trans
102
    rounding_needed <= '1';
103
    if reset_n = '0' or cs = '0' then
104
      state              <= s1;
105
      sign_res           <= '0';
106
      valid              <= '0';
107
      sticky_bit_enabled <= '0';
108
      --     result       <= (others => '0');
109
      exponent_res       <= (others => '0');
110
      mantissa_res       <= (others => '0');
111
      -- tmp          := (others => '0');
112
      tmp_result         <= (others => '0');
113
    elsif rising_edge(clk) then
114
      sign_res           <= sign_a xor sign_b;
115
      valid              <= '0';
116
      --    result       <= (others => '0');
117
      exponent_res       <= exponent_out;
118
      mantissa_res       <= (others => '0');
119
      mantissa_res       <= tmp_result;
120
      tmp_result         <= tmp_result;
121
      add_op_a           <= (others => '0');
122
      add_op_b           <= (others => '0');
123
      mul_op_a           <= (others => '0');
124
      mul_op_b           <= (others => '0');
125
      sticky_bit_enabled <= sticky_bit_enabled;
126
 
127
      case state is
128
        when s1 =>
129
          add_op_a              <= (others => '0');
130
          add_op_b              <= (others => '0');
131
          add_op_a(10 downto 0) <= unsigned(exponent_a(10 downto 0));
132
          add_op_b(10 downto 0) <= unsigned(exponent_b(10 downto 0));
133
 
134
          mul_op_a <= unsigned(c);
135
          mul_op_b <= unsigned(f);
136
          state    <= s2;
137
        when s2 =>
138
          --assert false report "Test" & to_string(std_logic_vector(add_result(13 downto 0))) severity warning;
139
          add_op_a (11 downto 0)  <= add_result(11 downto 0);
140
          add_op_b (11 downto 0)  <= DOUBLE_BIAS_2COMPLEMENT(11 downto 0);
141
          tmp_result(35 downto 0) <= std_logic_vector(mul_result);
142
 
143
          mul_op_a <= unsigned(b);
144
          mul_op_b <= unsigned(f);
145
 
146
 
147
          state <= s3;
148
        when s3 =>
149
          --  assert false report "Test" & to_string(std_logic_vector(add_result(13 downto 0))) severity warning;
150
          --  assert false report "ea" & to_string(exponent_a) & "eb" & to_string(exponent_b) &"xx"& to_string(std_logic_vector(DOUBLE_BIAS_2COMPLEMENT)) severity warning;
151
          -- if either the result is a subnormal/zero or both operands are zero
152
          -- set exponent to zero
153
          if (add_result(12) = '1' and (a_is_normal = '0' or b_is_normal = '0'))
154
            or (a_is_normal = '0' and b_is_normal = '0')
155
          then
156
            exponent_out <= (others => '0');
157
          else
158
            exponent_out <= std_logic_vector(add_result(11 downto 0));
159
          end if;
160
          sticky_bit_enabled <= '1';    -- since we start adding up values,
161
                                        -- sticky bit has to be calculated
162
          assert sticky_bit = '0' report "sticky3"&to_string(std_logic_vector(add_result))severity note;
163
 
164
          if unsigned(tmp_result(18 downto 0)) = (ZEROS(18 downto 0))then
165
            add_op_a <= unsigned(tmp_result(57 downto 19))&'0';
166
 
167
          else
168
            add_op_a <= unsigned(tmp_result(57 downto 18));
169
          end if;
170
 
171
          add_op_b <= mul_result;
172
 
173
          mul_op_a <= unsigned(c);
174
          mul_op_b <= unsigned(e);
175
 
176
          state <= s4;
177
        when s4 =>
178
          assert sticky_bit = '0' report "sticky4"&to_string(std_logic_vector(add_result))severity note;
179
          add_op_a <= add_result;
180
          add_op_b <= mul_result;
181
 
182
          mul_op_a <= unsigned(a);
183
          mul_op_b <= unsigned(f);
184
 
185
          state <= s5;
186
        when s5 =>
187
          assert sticky_bit = '0' report "sticky5"&to_string(std_logic_vector(add_result))severity note;
188
          add_op_a <= "00"&x"0000"& add_result(39 downto 19)&sticky_bit;
189
          add_op_b <= mul_result;
190
 
191
          mul_op_a <= unsigned(b);
192
          mul_op_b <= unsigned(e);
193
 
194
          state <= s6;
195
        when s6 =>
196
          assert sticky_bit = '0' report "sticky6"&to_string(std_logic_vector(add_result))severity note;
197
          add_op_a <= add_result;
198
          add_op_b <= mul_result;
199
 
200
          mul_op_a <= unsigned(c);
201
          mul_op_b <= unsigned(d);
202
 
203
 
204
 
205
          state <= s7;
206
        when s7 =>
207
          assert sticky_bit = '0' report "sticky7"&to_string(std_logic_vector(add_result))severity note;
208
          add_op_a <= add_result;
209
          add_op_b <= mul_result;
210
          mul_op_a <= unsigned(a);
211
          mul_op_b <= unsigned(e);
212
 
213
          state <= s8;
214
        when s8 =>
215
          assert sticky_bit = '0' report "sticky8"&to_string(std_logic_vector(add_result))severity note;
216
          add_op_a <= "00"&x"0000"& add_result(39 downto 18);--&sticky_bit;
217
          add_op_b <= mul_result;
218
 
219
          mul_op_a <= unsigned(b);
220
          mul_op_b <= unsigned(d);
221
 
222
 
223
          state <= s9;
224
        when s9 =>
225
          assert sticky_bit = '0' report "sticky9"&to_string(std_logic_vector(add_result))severity note;
226
          add_op_a                <= add_result;
227
          add_op_b                <= mul_result;
228
          mul_op_a                <= unsigned(a);
229
          mul_op_b                <= unsigned(d);
230
          tmp_result              <= (others => '0');
231
          assert false report "bla" & to_string(std_logic_vector(add_result)) severity warning;
232
          assert false report "bla" & to_string(std_logic_vector(add_result(39 downto 30))) severity warning;
233
          tmp_result (4 downto 0) <= std_logic_vector(add_result(39 downto 36))&sticky_bit;  --
234
          -- driving me crazy!
235
 
236
          state <= s10;
237
        when s10 =>
238
          assert sticky_bit = '0' report "sticky10"&to_string(std_logic_vector(add_result))severity note;
239
          assert false report "bla1" & to_string(std_logic_vector(add_result)) severity warning;
240
          add_op_a <= "00"&x"0000"& add_result(39 downto 18);
241
          add_op_b <= mul_result;
242
 
243
          tmp_result(22 downto 5) <= std_logic_vector(add_result(17 downto 0));
244
 
245
 
246
          state <= s11;
247
        when s11 =>
248
          assert false report "bla2" & to_string(std_logic_vector(add_result)) severity warning;
249
          tmp_result (57 downto 23) <= std_logic_vector(add_result(34 downto 0));
250
          state                     <= s12b;
251
          if add_result (33) = '1' then
252
            state <= s12a;
253
          end if;
254
          --     VALID                     <= '1';
255
 
256
        when s12a=>
257
          assert false report "shift"&to_string(tmp_result) severity note;
258
          assert false report "ungleich" severity note;
259
          tmp_result(57 downto 1) <= '0'&tmp_result(57 downto 2);
260
          tmp_result(0)           <= tmp_result(1) or tmp_result(0);
261
          exponent_out            <= std_logic_vector(unsigned(exponent_out)+"1");
262
          state                   <= s12b;
263
 
264
        when s12b=>
265
          assert false report "vorrund"&to_string(tmp_result) severity note;
266
          case tmp_result(3 downto 0) is
267
            when "0101" => tmp_result(3) <= '1';
268
            when "0110" => tmp_result(3) <= '1';
269
            when "0111" => tmp_result(3) <= '1';
270
 
271
            when "1100" => tmp_result(57 downto 3) <= std_logic_vector(unsigned(tmp_result(57 downto 3))+"1");
272
            when "1101" => tmp_result(57 downto 3) <= std_logic_vector(unsigned(tmp_result(57 downto 3))+"1");
273
            when "1110" => tmp_result(57 downto 3) <= std_logic_vector(unsigned(tmp_result(57 downto 3))+"1");
274
            when "1111" => tmp_result(57 downto 3) <= std_logic_vector(unsigned(tmp_result (57 downto 3))+"1");
275
 
276
 
277
            when others => null;        -- others remain unchanged
278
          end case;
279
 
280
                  state <= s12c;
281
        when s12c=>
282
                  state <= s12;
283
                  if tmp_result(56) ='1' then
284
                    state <= s12d;
285
 
286
                  end if;
287
 
288
        when s12d=>
289
          assert false report "ungleich" severity note;
290
          tmp_result(57 downto 1) <= '0'&tmp_result(57 downto 2);
291
          tmp_result(0)           <= tmp_result(1) or tmp_result(0);
292
          exponent_out            <= std_logic_vector(unsigned(exponent_out)+"1");
293
          state                   <= s12;
294
 
295
 
296
        when s12 =>
297
          assert false report "ttt"&to_string(tmp_result) severity note;
298
          state <= s12;
299
          valid <= '1';
300
 
301
        when others => null;
302
      end case;
303
    end if;
304
 
305
  end process state_trans;
306
 
307
end rtl;
308
 
309
-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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