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

Subversion Repositories v65c816

[/] [v65c816/] [trunk/] [multiplier.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 Valerio63
library IEEE;
2
use IEEE.std_logic_1164.all;  -- defines std_logic types
3
use IEEE.STD_LOGIC_unsigned.all;
4
use IEEE.STD_LOGIC_arith.all;
5
 
6
-- 16X16->32 bit multiplier signed/unsigned
7
entity multiplier is
8
  port(       clk:   in STD_LOGIC;
9
              clr:   in STD_LOGIC;
10
             init:   in STD_LOGIC;
11
          start_u:   in STD_LOGIC;
12
                    start_s:   in STD_LOGIC;
13
           mpcand:   in STD_LOGIC_VECTOR(15 downto 0);
14
                          mplier:   in STD_LOGIC_VECTOR(15 downto 0);
15
                            busy:  out STD_LOGIC;
16
          res_lsb:  out STD_LOGIC_VECTOR(15 downto 0);
17
          res_msb:  out STD_LOGIC_VECTOR(15 downto 0);
18
                           z_flg:  out STD_LOGIC;
19
                                n_flg:  out STD_LOGIC
20
      );
21
end multiplier;
22
 
23
architecture rtl of multiplier is
24
type state_type is (s0, s1, s2, s3, s4);
25
signal state: state_type;
26
signal s:          STD_LOGIC;
27
signal a:          STD_LOGIC_VECTOR(31 downto 0);
28
signal b:          STD_LOGIC_VECTOR(15 downto 0);
29
signal accum:      STD_LOGIC_VECTOR(31 downto 0);
30
signal sign_a:     STD_LOGIC;
31
signal sign_b:     STD_LOGIC;
32
signal mpy:        STD_LOGIC_VECTOR(1 downto 0);
33
 
34
begin
35
  mpy <= start_s & start_u;
36
  process(clk,clr)
37
  begin
38
        if (clr = '1') THEN
39
           state <= s0;
40
   elsif rising_edge(clk) then
41
    case state is
42
      -- wait for init
43
      when s0 =>
44
        if clr = '1' or init = '1' then
45
                s <= '0';
46
           a <= "0000000000000000" & mpcand;
47
                          b <= mplier;
48
                          accum <= (others => '0');
49
           state <= s0;
50
                  else
51
                          a <= a;
52
                          b <= b;
53
                accum <= accum;
54
                          sign_a <= sign_a;
55
                          sign_b <= sign_a;
56
                          case mpy is
57
                                  when "01" =>   s <= '1';                                     -- start multiply unsigned
58
                                                                          state <= s1;
59
                                  when "10" =>   s <= '1';                                     -- start multiply signed
60
                                                                          state <= s2;
61
                                  when others => s <= '0';
62
                                                 state <= s0;
63
                          end case;
64
             end if;
65
 
66
           -- multiply unsigned
67
           when s1 =>
68
                          sign_a <= sign_a;
69
                          sign_b <= sign_b;
70
                          if b = 0 then                                                   -- if finished
71
                        accum <= accum;
72
                        s <= '0';
73
                        state <= s0;
74
                          else
75
                                  if b(0) = '1' then                                           -- if bit #0 = 1 sum the (left) shifted multiplicand to the accumulator
76
                                          accum <= accum + a;
77
                                  else
78
                                accum <= accum;
79
                                  end if;
80
                             s <= '1';
81
                                  a <= a(30 downto 0) & '0';                                   -- shift left moltiplicand
82
                                  b <= '0' & b(15 downto 1);                                   -- shift right multiplier
83
                                  state <= s1;
84
                          end if;
85
 
86
           -- multiply signed
87
                when s2 =>
88
                          sign_a <= a(15);                                                -- save sign of factors
89
                          sign_b <= b(15);
90
           a <= "00000000000000000" & mpcand(14 downto 0);                 -- reload factors without sign bits
91
                          b <= '0' & mplier(14 downto 0);
92
           state <= s3;
93
 
94
                when s3 =>
95
                          sign_a <= sign_a;
96
                          sign_b <= sign_b;
97
                          if b = 0 then                                                   -- if finished
98
                        accum <= accum;
99
                                  if (sign_a = '1' and sign_b = '0') or (sign_a = '0' and sign_b = '1') then  -- if two's complement is needed
100
                           s <= '1';
101
                           state <= s4;
102
                                  else
103
                           s <= '0';
104
                           state <= s0;
105
                                  end if;
106
                          else
107
                                  if b(0) = '1' then                                           -- if bit #0 = 1 sum the (left) shifted multiplicand to the accumulator
108
                                          accum <= accum + a;
109
                                  else
110
                                accum <= accum;
111
                                  end if;
112
                             s <= '1';
113
                                  a <= a(30 downto 0) & '0';                                   -- shift left moltiplicand
114
                                  b <= '0' & b(15 downto 1);                                   -- shift right multiplier
115
                                  state <= s3;
116
                          end if;
117
 
118
                when s4 =>
119
                accum <= 0 - accum;                                                -- two's complement
120
                s <= '0';
121
                state <= s0;
122
 
123
      -- illegal state covering
124
      when others =>
125
                                  a <= a;
126
                                  b <= b;
127
                             sign_a <= sign_a;
128
                             sign_b <= sign_b;
129
                        accum <= accum;
130
                        s <= '0';
131
              state <= s0;
132
 
133
           end case;
134
         end if;
135
  end process;
136
  res_lsb <= accum(15 downto 0);
137
  res_msb <= accum(31 downto 16);
138
  z_flg <= '1' when accum = "00000000000000000000000000000000" else '0';
139
  n_flg <= accum(31);
140
  busy <= s;
141
end rtl;
142
 
143
 

powered by: WebSVN 2.1.0

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