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

Subversion Repositories rtf65002

[/] [rtf65002/] [trunk/] [rtl/] [verilog/] [mult_div.v] - Blame information for rev 32

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

Line No. Rev Author Line
1 12 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2013  Robert Finch, Stratford
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@opencores.org
6
//       ||
7
//
8
// rtf65002.v
9
//  - 32 bit CPU multiplier/divider
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
// ============================================================================
25
//
26 32 robfinch
`include "rtf65002_defines.v"
27 30 robfinch
 
28 32 robfinch
module mult_div(rst, clk, ld, op, fn, a, b, p, q, r, done);
29 12 robfinch
parameter IDLE=3'd0;
30
parameter MULT=3'd1;
31
parameter FIX_SIGN=3'd2;
32
parameter DIV=3'd3;
33
input rst;
34
input clk;
35
input ld;
36 32 robfinch
input [8:0] op;
37
input [3:0] fn;
38 12 robfinch
input [31:0] a;
39
input [31:0] b;
40
output reg [63:0] p;
41
output reg [31:0] q;
42
output reg [31:0] r;
43
output done;
44
 
45
reg [31:0] aa, bb;
46
reg res_sgn;
47
 
48
reg [2:0] state;
49
 
50
assign done = state==IDLE;
51
wire [31:0] diff = r - bb;
52
wire [31:0] pa = a[31] ? -a : a;
53
reg [5:0] cnt;
54
 
55
always @(posedge clk)
56
if (rst)
57
state <= IDLE;
58
else begin
59
case(state)
60
IDLE:
61
        if (ld) begin
62
                cnt <= 6'd32;
63
                case(op)
64 32 robfinch
                `MUL_IMM8,`MUL_IMM16,`MUL_IMM32:
65 12 robfinch
                        begin
66
                                aa <= a;
67
                                bb <= b;
68
                                res_sgn <= 1'b0;
69
                                state <= MULT;
70
                        end
71 30 robfinch
`ifdef SUPPORT_DIVMOD
72 32 robfinch
                `DIV_IMM8,`DIV_IMM16,`DIV_IMM32,
73
                `MOD_IMM8,`MOD_IMM16,`MOD_IMM32:
74 12 robfinch
                        begin
75
                                aa <= a;
76
                                bb <= b;
77
                                q <= a[30:0];
78
                                r <= a[31];
79
                                res_sgn <= 1'b0;
80
                                state <= DIV;
81
                        end
82 30 robfinch
`endif
83 32 robfinch
                `RR:
84
                        case(fn)
85
                        `MUL_RR:
86
                                begin
87
                                        aa <= a;
88
                                        bb <= b;
89
                                        res_sgn <= 1'b0;
90
                                        state <= MULT;
91
                                end
92
                        `MULS_RR:
93
                                begin
94
                                        aa <= a[31] ? -a : a;
95
                                        bb <= b[31] ? -b : b;
96
                                        res_sgn <= a[31] ^ b[31];
97
                                        state <= MULT;
98
                                end
99
`ifdef SUPPORT_DIVMOD
100
                        `DIV_RR,`MOD_RR:
101
                                begin
102
                                        aa <= a;
103
                                        bb <= b;
104
                                        q <= a[30:0];
105
                                        r <= a[31];
106
                                        res_sgn <= 1'b0;
107
                                        state <= DIV;
108
                                end
109
                        `DIVS_RR,`MODS_RR:
110
                                begin
111
                                        aa <= a[31] ? -a : a;
112
                                        bb <= b[31] ? -b : b;
113
                                        q <= pa[30:0];
114
                                        r <= pa[31];
115
                                        res_sgn <= a[31] ^ b[31];
116
                                        state <= DIV;
117
                                end
118
`endif
119
                        default:
120
                                state <= IDLE;
121
                        endcase
122 12 robfinch
                endcase
123
        end
124
MULT:
125
        begin
126
                state <= res_sgn ? FIX_SIGN : IDLE;
127
                p <= aa * bb;
128
        end
129 30 robfinch
`ifdef SUPPORT_DIVMOD
130 12 robfinch
DIV:
131
        begin
132
                q <= {q[30:0],~diff[31]};
133
                if (cnt==6'd0) begin
134
                        state <= res_sgn ? FIX_SIGN : IDLE;
135
                        if (diff[31])
136
                                r <= r[30:0];
137
                        else
138
                                r <= diff[30:0];
139
                end
140
                else begin
141
                        if (diff[31])
142
                                r <= {r[30:0],q[31]};
143
                        else
144
                                r <= {diff[30:0],q[31]};
145
                end
146
                cnt <= cnt - 6'd1;
147
        end
148 30 robfinch
`endif
149 12 robfinch
 
150
FIX_SIGN:
151
        begin
152
                state <= IDLE;
153
                if (res_sgn) begin
154
                        p <= -p;
155
                        q <= -q;
156
                        r <= -r;
157
                end
158
        end
159
default:        state <= IDLE;
160
endcase
161
end
162
 
163
endmodule
164
 
165
module multdiv_tb();
166
reg rst;
167
reg clk;
168
reg ld;
169
 
170
initial begin
171
        #0 clk = 1'b0;
172
        #0 rst = 1'b0;
173
        #10 rst = 1'b1;
174
        #10 rst = 1'b0;
175
        #10 ld = 1'b1;
176
        #20 ld = 1'b0;
177
end
178
 
179
always #10 clk = ~clk;
180
 
181
mult_div umd1 (
182
        .rst(rst),
183
        .clk(clk),
184
        .ld(ld),
185 32 robfinch
        .op(`RR),
186
        .fn(`DIV_RR),
187 12 robfinch
        .a(32'h12345678),
188
        .b(32'd10),
189
        .p(),
190
        .q(),
191
        .r(),
192
        .done()
193
);
194
 
195
endmodule

powered by: WebSVN 2.1.0

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