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

Subversion Repositories rtf8088

[/] [rtf8088/] [trunk/] [rtl/] [verilog/] [divr2.v] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 robfinch
//=============================================================================
2
//      (C) 2006,2011  Robert Finch
3
//      robfinch@opencores.org
4
//
5
//      divr2.v
6
//              Radix 2 divider primitive
7
//
8
//
9
//  This source code is available for evaluation and validation purposes
10
//  only. This copyright statement and disclaimer must remain present in
11
//  the file.
12
//
13
//      NO WARRANTY.
14
//  THIS Work, IS PROVIDEDED "AS IS" WITH NO WARRANTIES OF ANY KIND, WHETHER
15
//  EXPRESS OR IMPLIED. The user must assume the entire risk of using the
16
//  Work.
17
//
18
//  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
19
//  INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES WHATSOEVER RELATING TO
20
//  THE USE OF THIS WORK, OR YOUR RELATIONSHIP WITH THE AUTHOR.
21
//
22
//  IN ADDITION, IN NO EVENT DOES THE AUTHOR AUTHORIZE YOU TO USE THE WORK
23
//  IN APPLICATIONS OR SYSTEMS WHERE THE WORK'S FAILURE TO PERFORM CAN
24
//  REASONABLY BE EXPECTED TO RESULT IN A SIGNIFICANT PHYSICAL INJURY, OR IN
25
//  LOSS OF LIFE. ANY SUCH USE BY YOU IS ENTIRELY AT YOUR OWN RISK, AND YOU
26
//  AGREE TO HOLD THE AUTHOR AND CONTRIBUTORS HARMLESS FROM ANY CLAIMS OR
27
//  LOSSES RELATING TO SUCH UNAUTHORIZED USE.
28
//
29
//
30
//      Performance
31
//      Webpack 9.2i  xc3s1000-4ft256
32
//      64 slices / 122 LUTs / 17.316 ns  (59 MHz)
33
//=============================================================================
34
 
35
module divr2(rst, clk, ce, ld, su, ri, a, b, i, q, r, divByZero, done);
36
parameter WID = 32;
37
parameter IDLE = 3'd0;
38
parameter DIV = 3'd1;
39
parameter SGN = 3'd2;
40
input rst;
41
input clk;
42
input ce;                               // clock enable
43
input ld;                               // pulse to initiate divide
44
input su;                               // 1=signed or 0=unsigned
45
input ri;                               // port: 1=register  or 0=immediate
46
input [WID-1:0] a;               // dividend
47
input [WID/2-1:0] b;     // divisor: register port input
48
input [WID/2-1:0] i;     // divisor: immediate value port input
49
output [WID-1:0] q;              // quotient
50
output [WID/2-1:0] r;    // remainder
51
output divByZero;
52
output done;                    // =1 if divide is finished
53
localparam DMSB = WID-1;
54
 
55
reg [7:0] cnt;                   // iteration count
56
 
57
reg [1:0] ad;
58
reg [WID/2-1:0] r0;
59
reg [WID-1:0] q0;
60
reg [WID-1:0] aa;
61
reg [WID/2-1:0] bb;
62
reg [WID-1:0] q;
63
reg [WID/2-1:0] r;
64
 
65
wire [WID/2:0] dif = r0 - bb;
66
reg [2:0] state;
67
reg divByZero;
68
 
69
always @(posedge clk)
70
if (rst) begin
71
        cnt <= 8'd0;
72
        state <= IDLE;
73
        divByZero <= 1'b0;
74
        q <= {WID{1'b0}};
75
        r <= {WID/2{1'b0}};
76
        r0 <= {WID/2{1'b0}};
77
        q0 <= {WID{1'b0}};
78
end
79
else if (ce) begin
80
case(state)
81
IDLE:
82
        if (ld) begin
83
                state <= DIV;
84
                cnt <= 8'd0;
85
                r0 <= {WID/2{1'b0}};
86
                if (su) begin
87
                        q0 <= a[WID-1] ? -a : a;
88
                        bb <= ri ? (b[WID/2-1] ? -b : b) : (i[WID/2-1] ? -i : i);
89
                end
90
                else begin
91
                        q0 <= a;
92
                        bb <= ri ? b : i;
93
                end
94
                divByZero <= b=={WID/2{1'b0}};
95
                if (b=={WID/2{1'b0}}) begin
96
                        q <= {WID-1{1'b1}};
97
                        state <= IDLE;
98
                end
99
        end
100
DIV:
101
        if (cnt <= WID) begin
102
                cnt <= cnt + 8'd1;
103
                q0[0] <= ~dif[WID/2-1];
104
                q0[WID-1:1] <= q0[WID-2:0];
105
                r0[0] <= q0[WID-1];
106
                if (~dif[WID/2-1])
107
                        r0[WID/2-1:1] <= dif[WID/2-1:0];
108
                else
109
                        r0[WID/2-1:1] <= r0  [WID/2-2:0];
110
        end
111
        else
112
                state <= SGN;
113
SGN:
114
        begin
115
                if (a[WID-1]^b[WID/2-1] && su)
116
                        q <= -q0;
117
                else
118
                        q <= q0;
119
                if (a[WID-1] & su)
120
                        r <= -r0[WID/2-1:1];
121
                else
122
                        r <= r0[WID/2-1:1];
123
                state <= IDLE;
124
        end
125
default:
126
        state <= IDLE;
127
endcase
128
end
129
 
130
assign done = state==IDLE;
131
 
132
endmodule
133
 
134
 
135
module divr2_tb();
136
 
137
reg rst;
138
reg clk;
139
reg ld;
140
reg [6:0] cnt;
141
 
142
wire ce = 1'b1;
143
wire [31:0] a = -32'd1283;
144
wire [31:0] b = -32'd14;
145
wire [31:0] q;
146
wire [31:0] r;
147
wire done;
148
 
149
initial begin
150
        clk = 1;
151
        rst = 0;
152
        #100 rst = 1;
153
        #100 rst = 0;
154
end
155
 
156
always #10 clk = ~clk;  //  50 MHz
157
 
158
always @(posedge clk)
159
        if (rst)
160
                cnt <= 0;
161
        else begin
162
                ld <= 0;
163
                cnt <= cnt + 1;
164
                if (cnt == 3)
165
                        ld <= 1;
166
                $display("ld=%b q=%h r=%h done=%b", ld, q, r, done);
167
        end
168
 
169
 
170
divr2 divu0(.rst(rst), .clk(clk), .ce(ce), .ld(ld), .su(1'b1), .ri(1'b0), .a(a), .b(b), .i(b), .q(q), .r(r), .divByZero(), .done(done) );
171
 
172
endmodule
173
 
174
 
175
 

powered by: WebSVN 2.1.0

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