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

Subversion Repositories rtf65002

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

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
`define MUL             4'd8
27
`define MULS    4'd9
28
`define DIV             4'd10
29
`define DIVS    4'd11
30
`define MOD             4'd12
31
`define MODS    4'd13
32
 
33
module mult_div(rst, clk, ld, op, a, b, p, q, r, done);
34
parameter IDLE=3'd0;
35
parameter MULT=3'd1;
36
parameter FIX_SIGN=3'd2;
37
parameter DIV=3'd3;
38
input rst;
39
input clk;
40
input ld;
41
input [3:0] op;
42
input [31:0] a;
43
input [31:0] b;
44
output reg [63:0] p;
45
output reg [31:0] q;
46
output reg [31:0] r;
47
output done;
48
 
49
reg [31:0] aa, bb;
50
reg res_sgn;
51
 
52
reg [2:0] state;
53
 
54
assign done = state==IDLE;
55
wire [31:0] diff = r - bb;
56
wire [31:0] pa = a[31] ? -a : a;
57
reg [5:0] cnt;
58
 
59
always @(posedge clk)
60
if (rst)
61
state <= IDLE;
62
else begin
63
case(state)
64
IDLE:
65
        if (ld) begin
66
                cnt <= 6'd32;
67
                case(op)
68
                `MUL:
69
                        begin
70
                                aa <= a;
71
                                bb <= b;
72
                                res_sgn <= 1'b0;
73
                                state <= MULT;
74
                        end
75
                `MULS:
76
                        begin
77
                                aa <= a[31] ? -a : a;
78
                                bb <= b[31] ? -b : b;
79
                                res_sgn <= a[31] ^ b[31];
80
                                state <= MULT;
81
                        end
82
                `DIV,`MOD:
83
                        begin
84
                                aa <= a;
85
                                bb <= b;
86
                                q <= a[30:0];
87
                                r <= a[31];
88
                                res_sgn <= 1'b0;
89
                                state <= DIV;
90
                        end
91
                `DIVS,`MODS:
92
                        begin
93
                                aa <= a[31] ? -a : a;
94
                                bb <= b[31] ? -b : b;
95
                                q <= pa[30:0];
96
                                r <= pa[31];
97
                                res_sgn <= a[31] ^ b[31];
98
                                state <= DIV;
99
                        end
100
                default:
101
                        state <= IDLE;
102
                endcase
103
        end
104
MULT:
105
        begin
106
                state <= res_sgn ? FIX_SIGN : IDLE;
107
                p <= aa * bb;
108
        end
109
DIV:
110
        begin
111
                q <= {q[30:0],~diff[31]};
112
                if (cnt==6'd0) begin
113
                        state <= res_sgn ? FIX_SIGN : IDLE;
114
                        if (diff[31])
115
                                r <= r[30:0];
116
                        else
117
                                r <= diff[30:0];
118
                end
119
                else begin
120
                        if (diff[31])
121
                                r <= {r[30:0],q[31]};
122
                        else
123
                                r <= {diff[30:0],q[31]};
124
                end
125
                cnt <= cnt - 6'd1;
126
        end
127
 
128
FIX_SIGN:
129
        begin
130
                state <= IDLE;
131
                if (res_sgn) begin
132
                        p <= -p;
133
                        q <= -q;
134
                        r <= -r;
135
                end
136
        end
137
default:        state <= IDLE;
138
endcase
139
end
140
 
141
endmodule
142
 
143
module multdiv_tb();
144
reg rst;
145
reg clk;
146
reg ld;
147
 
148
initial begin
149
        #0 clk = 1'b0;
150
        #0 rst = 1'b0;
151
        #10 rst = 1'b1;
152
        #10 rst = 1'b0;
153
        #10 ld = 1'b1;
154
        #20 ld = 1'b0;
155
end
156
 
157
always #10 clk = ~clk;
158
 
159
mult_div umd1 (
160
        .rst(rst),
161
        .clk(clk),
162
        .ld(ld),
163
        .op(`DIV),
164
        .a(32'h12345678),
165
        .b(32'd10),
166
        .p(),
167
        .q(),
168
        .r(),
169
        .done()
170
);
171
 
172
endmodule

powered by: WebSVN 2.1.0

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