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

Subversion Repositories plasma

[/] [plasma/] [tags/] [arelease/] [vhdl/] [mult.vhd] - Blame information for rev 2

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
-- PROJECT: MIPS CPU core
7
-- 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
---------------------------------------------------------------------
13
library ieee;
14
use ieee.std_logic_1164.all;
15
use work.mips_pack.all;
16
 
17
entity mult is
18
   port(clk       : in std_logic;
19
        a, b      : in std_logic_vector(31 downto 0);
20
        mult_func : in mult_function_type;
21
        c_mult    : out std_logic_vector(31 downto 0);
22
        pause_out : out std_logic);
23
end; --entity mult
24
 
25
architecture logic of mult is
26
--   type mult_function_type is (
27
--      mult_nothing, mult_read_lo, mult_read_hi, mult_write_lo, 
28
--      mult_write_hi, mult_mult, mult_divide, mult_signed_divide);
29
   signal do_div_reg    : std_logic;
30
   signal do_signed_reg : std_logic;
31
   signal count_reg     : std_logic_vector(5 downto 0);
32
   signal reg_a         : std_logic_vector(31 downto 0);
33
   signal reg_b         : std_logic_vector(63 downto 0);
34
   signal answer_reg    : std_logic_vector(31 downto 0);
35
begin
36
 
37
--multiplication/division unit
38
mult_proc: process(clk, a, b, mult_func,
39
                   do_div_reg, do_signed_reg, count_reg,
40
                   reg_a, reg_b, answer_reg)
41
   variable do_div_temp    : std_logic;
42
   variable do_signed_temp : std_logic;
43
   variable count_temp     : std_logic_vector(5 downto 0);
44
   variable a_temp         : std_logic_vector(31 downto 0);
45
   variable b_temp         : std_logic_vector(63 downto 0);
46
   variable answer_temp    : std_logic_vector(31 downto 0);
47
 
48
   variable sign_extension : std_logic;
49
   variable aa, bb         : std_logic_vector(32 downto 0);
50
   variable sum            : std_logic_vector(32 downto 0);
51
   variable start          : std_logic;
52
   variable do_write       : std_logic;
53
   variable do_hi          : std_logic;
54
 
55
begin
56
   do_div_temp    := do_div_reg;
57
   do_signed_temp := do_signed_reg;
58
   count_temp     := count_reg;
59
   a_temp         := reg_a;
60
   b_temp         := reg_b;
61
   answer_temp    := answer_reg;
62
 
63
   sign_extension := '0';
64
   aa             := '0' & ZERO;
65
   bb             := '0' & ZERO;
66
   sum            := '0' & ZERO;
67
   start          := '0';
68
   do_write       := '0';
69
   do_hi          := '0';
70
 
71
   case mult_func is
72
   when mult_read_lo =>
73
   when mult_read_hi =>
74
      do_hi := '1';
75
   when mult_write_lo =>
76
      do_write := '1';
77
   when mult_write_hi =>
78
      do_write := '1';
79
      do_hi := '1';
80
   when mult_mult =>
81
      start := '1';
82
      do_div_temp := '0';
83
   when mult_divide =>
84
      start := '1';
85
      do_div_temp := '1';
86
      do_signed_temp := '0';
87
   when mult_signed_divide =>
88
      start := '1';
89
      do_div_temp := '1';
90
      do_signed_temp := '1';
91
   when others =>
92
   end case;
93
 
94
   if start = '1' then
95
      count_temp := "000000";
96
      a_temp := a;
97
      answer_temp := ZERO;
98
      if do_div_temp = '1' then
99
         if do_signed_temp = '0' or b(31) = '0' then
100
            b_temp(62 downto 31) := b;
101
         else
102
            b_temp(62 downto 31) := bv_negate(b);
103
            a_temp := bv_negate(a);
104
         end if;
105
         b_temp(30 downto 0) := ZERO(30 downto 0);
106
      else --multiply
107
         b_temp := zero & b;
108
      end if;
109
   elsif do_write = '1' then
110
      if do_hi = '0' then
111
         b_temp(31 downto 0) := a;
112
      else
113
         b_temp(63 downto 32) := a;
114
      end if;
115
   end if;
116
 
117
   if do_div_reg = '1' then
118
      bb := reg_b(32 downto 0);
119
   else
120
      bb := '0' & reg_b(63 downto 32);
121
   end if;
122
   sign_extension := reg_a(31) and do_signed_reg;
123
   aa := sign_extension & reg_a;
124
   sum := bv_adder(aa, bb, do_div_reg);
125
--   sum := bv_adder_lookahead(aa, bb, do_div_reg);
126
 
127
   if count_reg(5) = '0' and start = '0' then
128
      count_temp := bv_inc6(count_reg);
129
      if do_div_reg = '1' then
130
         answer_temp(31 downto 1) := answer_reg(30 downto 0);
131
         if reg_b(63 downto 32) = ZERO and sum(32) = '0' then
132
            a_temp := sum(31 downto 0);  --aa=aa-bb;
133
            answer_temp(0) := '1';
134
         else
135
            answer_temp(0) := '0';
136
         end if;
137
         if count_reg /= "011111" then
138
            b_temp(62 downto 0) := reg_b(63 downto 1);
139
         else
140
            b_temp(63 downto 32) := a_temp;
141
            b_temp(31 downto 0) := answer_temp;
142
         end if;
143
      else  -- mult_mode
144
         if reg_b(0) = '1' then
145
            b_temp(63 downto 31) := sum;
146
         else
147
            b_temp(63 downto 31) := '0' & reg_b(63 downto 32);
148
         end if;
149
         b_temp(30 downto 0) := reg_b(31 downto 1);
150
         if count_reg = "010000" and          --early stop
151
               reg_b(15 downto 0) = zero(15 downto 0) then
152
            count_temp := "111111";
153
            b_temp(31 downto 0) := reg_b(47 downto 16);
154
         end if;
155
      end if;
156
   end if;
157
 
158
   if rising_edge(clk) then
159
      do_div_reg <= do_div_temp;
160
      do_signed_reg <= do_signed_temp;
161
      count_reg <= count_temp;
162
      reg_a <= a_temp;
163
      reg_b <= b_temp;
164
      answer_reg <= answer_temp;
165
   end if;
166
 
167
   if count_reg(5) = '0' and mult_func/= mult_nothing and start = '0' then
168
      pause_out <= '1';
169
   else
170
      pause_out <= '0';
171
   end if;
172
   if mult_func = mult_read_lo then
173
      c_mult <= reg_b(31 downto 0);
174
   elsif mult_func = mult_read_hi then
175
      c_mult <= reg_b(63 downto 32);
176
   else
177
--      c_mult <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
178
      c_mult <= ZERO;
179
   end if;
180
 
181
end process;
182
 
183
end; --architecture logic
184
 
185
 

powered by: WebSVN 2.1.0

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