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

Subversion Repositories plasma

[/] [plasma/] [tags/] [V3_0/] [vhdl/] [mult.vhd] - Blame information for rev 45

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rhoads
---------------------------------------------------------------------
2
-- TITLE: Multiplication and Division Unit
3
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
-- DATE CREATED: 1/31/01
5
-- FILENAME: mult.vhd
6 43 rhoads
-- PROJECT: Plasma CPU core
7 2 rhoads
-- COPYRIGHT: Software placed into the public domain by the author.
8
--    Software 'as is' without warranty.  Author liable for nothing.
9
-- DESCRIPTION:
10
--    Implements the multiplication and division unit.
11
--    Normally takes 32 clock cycles.
12 7 rhoads
--    if b(31 downto 16) = ZERO(31 downto 16) then mult in 16 cycles. 
13
--    if b(31 downto 8) = ZERO(31 downto 8) then mult in 8 cycles. 
14 2 rhoads
---------------------------------------------------------------------
15
library ieee;
16
use ieee.std_logic_1164.all;
17 39 rhoads
use work.mlite_pack.all;
18 2 rhoads
 
19
entity mult is
20
   port(clk       : in std_logic;
21
        a, b      : in std_logic_vector(31 downto 0);
22
        mult_func : in mult_function_type;
23
        c_mult    : out std_logic_vector(31 downto 0);
24
        pause_out : out std_logic);
25
end; --entity mult
26
 
27
architecture logic of mult is
28
--   type mult_function_type is (
29
--      mult_nothing, mult_read_lo, mult_read_hi, mult_write_lo, 
30
--      mult_write_hi, mult_mult, mult_divide, mult_signed_divide);
31
   signal do_div_reg    : std_logic;
32
   signal do_signed_reg : std_logic;
33
   signal count_reg     : std_logic_vector(5 downto 0);
34
   signal reg_a         : std_logic_vector(31 downto 0);
35
   signal reg_b         : std_logic_vector(63 downto 0);
36
   signal answer_reg    : std_logic_vector(31 downto 0);
37
begin
38
 
39
--multiplication/division unit
40
mult_proc: process(clk, a, b, mult_func,
41
                   do_div_reg, do_signed_reg, count_reg,
42
                   reg_a, reg_b, answer_reg)
43
   variable do_div_temp    : std_logic;
44
   variable do_signed_temp : std_logic;
45
   variable count_temp     : std_logic_vector(5 downto 0);
46
   variable a_temp         : std_logic_vector(31 downto 0);
47
   variable b_temp         : std_logic_vector(63 downto 0);
48
   variable answer_temp    : std_logic_vector(31 downto 0);
49
 
50
   variable aa, bb         : std_logic_vector(32 downto 0);
51
   variable sum            : std_logic_vector(32 downto 0);
52
   variable start          : std_logic;
53
   variable do_write       : std_logic;
54
   variable do_hi          : std_logic;
55 45 rhoads
   variable sign_extend    : std_logic;
56 2 rhoads
 
57
begin
58
   do_div_temp    := do_div_reg;
59
   do_signed_temp := do_signed_reg;
60
   count_temp     := count_reg;
61
   a_temp         := reg_a;
62
   b_temp         := reg_b;
63
   answer_temp    := answer_reg;
64 45 rhoads
   sign_extend    := do_signed_reg and not do_div_reg;
65 2 rhoads
 
66
   aa             := '0' & ZERO;
67
   bb             := '0' & ZERO;
68
   sum            := '0' & ZERO;
69
   start          := '0';
70
   do_write       := '0';
71
   do_hi          := '0';
72
 
73
   case mult_func is
74
   when mult_read_lo =>
75
   when mult_read_hi =>
76
      do_hi := '1';
77
   when mult_write_lo =>
78
      do_write := '1';
79
   when mult_write_hi =>
80
      do_write := '1';
81
      do_hi := '1';
82
   when mult_mult =>
83
      start := '1';
84
      do_div_temp := '0';
85 45 rhoads
      do_signed_temp := '0';
86
   when mult_signed_mult =>
87
      start := '1';
88
      do_div_temp := '0';
89
      do_signed_temp := a(31) xor b(31);
90 2 rhoads
   when mult_divide =>
91
      start := '1';
92
      do_div_temp := '1';
93
      do_signed_temp := '0';
94
   when mult_signed_divide =>
95
      start := '1';
96
      do_div_temp := '1';
97 23 rhoads
      do_signed_temp := a(31) xor b(31);
98 2 rhoads
   when others =>
99
   end case;
100
 
101
   if start = '1' then
102
      count_temp := "000000";
103
      answer_temp := ZERO;
104
      if do_div_temp = '1' then
105 18 rhoads
         b_temp(63) := '0';
106 23 rhoads
         if mult_func /= mult_signed_divide or b(31) = '0' then
107 2 rhoads
            b_temp(62 downto 31) := b;
108
         else
109
            b_temp(62 downto 31) := bv_negate(b);
110 23 rhoads
         end if;
111
         if mult_func /= mult_signed_divide or a(31) = '0' then
112
            a_temp := a;
113
         else
114 2 rhoads
            a_temp := bv_negate(a);
115
         end if;
116
         b_temp(30 downto 0) := ZERO(30 downto 0);
117
      else --multiply
118 23 rhoads
         a_temp := a;
119 7 rhoads
         b_temp := ZERO & b;
120 2 rhoads
      end if;
121
   elsif do_write = '1' then
122
      if do_hi = '0' then
123
         b_temp(31 downto 0) := a;
124
      else
125
         b_temp(63 downto 32) := a;
126
      end if;
127
   end if;
128
 
129
   if do_div_reg = '1' then
130
      bb := reg_b(32 downto 0);
131
   else
132 45 rhoads
--      bb := '0' & reg_b(63 downto 32);
133
      bb := (reg_b(63) and sign_extend) & reg_b(63 downto 32);
134 2 rhoads
   end if;
135 45 rhoads
--   aa := '0' & reg_a;
136
   aa := (reg_a(31) and sign_extend) & reg_a;
137 2 rhoads
   sum := bv_adder(aa, bb, do_div_reg);
138
--   sum := bv_adder_lookahead(aa, bb, do_div_reg);
139
 
140
   if count_reg(5) = '0' and start = '0' then
141
      count_temp := bv_inc6(count_reg);
142
      if do_div_reg = '1' then
143
         answer_temp(31 downto 1) := answer_reg(30 downto 0);
144 23 rhoads
         if reg_b(63 downto 32) = ZERO and sum(32) = '0' then
145 2 rhoads
            a_temp := sum(31 downto 0);  --aa=aa-bb;
146
            answer_temp(0) := '1';
147
         else
148
            answer_temp(0) := '0';
149
         end if;
150
         if count_reg /= "011111" then
151
            b_temp(62 downto 0) := reg_b(63 downto 1);
152
         else
153
            b_temp(63 downto 32) := a_temp;
154 23 rhoads
            if do_signed_reg = '0' then
155
               b_temp(31 downto 0) := answer_temp;
156
            else
157
               b_temp(31 downto 0) := bv_negate(answer_temp);
158
            end if;
159 2 rhoads
         end if;
160
      else  -- mult_mode
161
         if reg_b(0) = '1' then
162
            b_temp(63 downto 31) := sum;
163
         else
164 45 rhoads
            b_temp(63 downto 31) := sign_extend & reg_b(63 downto 32);
165
            if reg_b(63 downto 32) = ZERO then
166
               b_temp(63) := '0';
167
            end if;
168 2 rhoads
         end if;
169
         b_temp(30 downto 0) := reg_b(31 downto 1);
170 45 rhoads
         if count_reg = "010000" and sign_extend = '0' and   --early stop
171 7 rhoads
               reg_b(15 downto 0) = ZERO(15 downto 0) then
172 2 rhoads
            count_temp := "111111";
173
            b_temp(31 downto 0) := reg_b(47 downto 16);
174
         end if;
175 45 rhoads
         if count_reg = "001000" and sign_extend = '0' and   --early stop
176 7 rhoads
               reg_b(23 downto 0) = ZERO(23 downto 0) then
177
            count_temp := "111111";
178
            b_temp(31 downto 0) := reg_b(55 downto 24);
179
         end if;
180 2 rhoads
      end if;
181
   end if;
182
 
183
   if rising_edge(clk) then
184
      do_div_reg <= do_div_temp;
185
      do_signed_reg <= do_signed_temp;
186
      count_reg <= count_temp;
187
      reg_a <= a_temp;
188
      reg_b <= b_temp;
189
      answer_reg <= answer_temp;
190
   end if;
191
 
192
   if count_reg(5) = '0' and mult_func/= mult_nothing and start = '0' then
193
      pause_out <= '1';
194
   else
195
      pause_out <= '0';
196
   end if;
197
   if mult_func = mult_read_lo then
198
      c_mult <= reg_b(31 downto 0);
199
   elsif mult_func = mult_read_hi then
200
      c_mult <= reg_b(63 downto 32);
201
   else
202
      c_mult <= ZERO;
203
   end if;
204
 
205
end process;
206
 
207
end; --architecture logic
208
 

powered by: WebSVN 2.1.0

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