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

Subversion Repositories rf68000

[/] [rf68000/] [trunk/] [rtl/] [cpu/] [rf68000_divider.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2013-2022  Robert Finch, Waterloo
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch<remove>@finitron.ca
7
//       ||
8
//
9
// BSD 3-Clause License
10
// Redistribution and use in source and binary forms, with or without
11
// modification, are permitted provided that the following conditions are met:
12
//
13
// 1. Redistributions of source code must retain the above copyright notice, this
14
//    list of conditions and the following disclaimer.
15
//
16
// 2. Redistributions in binary form must reproduce the above copyright notice,
17
//    this list of conditions and the following disclaimer in the documentation
18
//    and/or other materials provided with the distribution.
19
//
20
// 3. Neither the name of the copyright holder nor the names of its
21
//    contributors may be used to endorse or promote products derived from
22
//    this software without specific prior written permission.
23
//
24
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
//                                                                          
35
// ============================================================================
36
//
37
// rf68000_divider.v
38
//  - 32 bit divider
39
//
40
// ============================================================================
41
//
42
module rf68000_divider(rst, clk, ld, abort, sgn, sgnus, a, b, qo, ro, dvByZr, ovf, done, idle);
43
parameter WID=32;
44
parameter DIV=3'd3;
45
parameter IDLE=3'd4;
46
parameter DONE=3'd5;
47
input clk;
48
input rst;
49
input ld;
50
input abort;
51
input sgn;
52
input sgnus;
53
input [WID-1:0] a;
54
input [WID-1:0] b;
55
output [WID-1:0] qo;
56
reg [WID-1:0] qo;
57
output [WID-1:0] ro;
58
reg [WID-1:0] ro;
59
output done;
60
output idle;
61
output dvByZr;
62
output ovf;
63
reg dvByZr;
64
reg ovf;
65
 
66
reg [WID-1:0] aa,bb;
67
reg so, rs;
68
reg [2:0] state;
69
reg [7:0] cnt;
70
wire cnt_done = cnt==8'd0;
71
assign done = state==DONE||(state==IDLE && !ld);
72
assign idle = state==IDLE;
73
reg ce1;
74
reg [WID-1:0] q;
75
reg [WID:0] r;
76
wire b0 = bb <= r;
77
wire [WID-1:0] r1 = b0 ? r - bb : r;
78
 
79
initial begin
80
  q = 32'd0;
81
  r = 32'd0;
82
  qo = 32'd0;
83
  ro = 32'd0;
84
end
85
 
86
always @(posedge clk)
87
if (rst) begin
88
        aa <= {WID{1'b0}};
89
        bb <= {WID{1'b0}};
90
        q <= {WID{1'b0}};
91
        r <= {WID{1'b0}};
92
        qo <= {WID{1'b0}};
93
        ro <= {WID{1'b0}};
94
        cnt <= 8'd0;
95
        dvByZr <= 1'b0;
96
        ovf <= 1'b0;
97
        so <= 1'b0;
98
        rs <= 1'b0;
99
        state <= IDLE;
100
end
101
else
102
begin
103
if (abort)
104
    cnt <= 8'd00;
105
else if (!cnt_done)
106
        cnt <= cnt - 8'd1;
107
 
108
case(state)
109
IDLE:
110
        if (ld) begin
111
                ovf <= 1'b0;
112
                if (sgn) begin
113
                        q <= a[WID-1] ? -a : a;
114
                        bb <= b[WID-1] ? -b : b;
115
                        so <= a[WID-1] ^ b[WID-1];
116
                        rs <= a[WID-1];
117
                end
118
                else if (sgnus) begin
119
                        q <= a[WID-1] ? -a : a;
120
            bb <= b;
121
            so <= a[WID-1];
122
                end
123
                else begin
124
                        q <= a;
125
                        bb <= b;
126
                        so <= 1'b0;
127
                        $display("bb=%d", b);
128
                end
129
                dvByZr <= b=={WID{1'b0}};
130
                r <= {WID{1'b0}};
131
                cnt <= WID+1;
132
                state <= DIV;
133
        end
134
DIV:
135
        if (!cnt_done) begin
136
                $display("cnt:%d r1=%h q[31:0]=%h", cnt,r1,q);
137
                q <= {q[WID-2:0],b0};
138
                r <= {r1,q[WID-1]};
139
                if (q[31:16] >= bb[15:0] && cnt==WID+1) begin
140
                        ovf <= 1'b1;
141
                        state <= DONE;
142
                end
143
        end
144
        else begin
145
                $display("cnt:%d r1=%h q[63:0]=%h", cnt,r1,q);
146
                if (sgn|sgnus) begin
147
                        if (so)
148
                                qo <= -q;
149
                        else
150
                                qo <= q;
151
                        // The sign of the remainder is the same as the dividend.
152
                        if (rs != r[WID])
153
                                ro <= -r[WID:1];
154
                        else
155
                                ro <= r[WID:1];
156
                end
157
                else begin
158
                        qo <= q;
159
                        ro <= r[WID:1];
160
                end
161
                state <= DONE;
162
        end
163
DONE:
164
        begin
165
                /*
166
                if (so) begin
167
                        if (qo[WID-1:WID/2] != {WID/2{qo[WID/2-1]}})
168
                                ovf <= 1'b1;
169
                end
170
                else begin
171
                        if (qo[WID-1:WID/2] != 'd0)
172
                                ovf <= 1'b1;
173
                end
174
                */
175
                if (!ld)
176
                        state <= IDLE;
177
        end
178
default: state <= IDLE;
179
endcase
180
end
181
 
182
endmodule
183
 
184
module rf68000_divider_tb();
185
parameter WID=32;
186
reg rst;
187
reg clk;
188
reg ld;
189
wire done;
190
wire [WID-1:0] qo,ro;
191
 
192
initial begin
193
        clk = 1;
194
        rst = 0;
195
        #100 rst = 1;
196
        #100 rst = 0;
197
        #100 ld = 1;
198
        #150 ld = 0;
199
end
200
 
201
always #10 clk = ~clk;  //  50 MHz
202
 
203
 
204
rf68000_divider #(WID) u1
205
(
206
        .rst(rst),
207
        .clk(clk),
208
        .ld(ld),
209
        .abort(1'b0),
210
        .sgn(1'b0),
211
        .sgnus(1'b0),
212
        .a(32'h10000000),
213
        .b(32'h5a5a),
214
        .qo(qo),
215
        .ro(ro),
216
        .dvByZr(),
217
        .ovf(),
218
        .done(done),
219
        .idle()
220
);
221
 
222
endmodule
223
 

powered by: WebSVN 2.1.0

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