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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [fpdivr8.v] - Blame information for rev 9

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

Line No. Rev Author Line
1 8 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2006-2016  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
//      fpdivr8.v
9
//    Radix 8 floating point divider primitive
10
//
11
//
12
// This source file is free software: you can redistribute it and/or modify 
13
// it under the terms of the GNU Lesser General Public License as published 
14
// by the Free Software Foundation, either version 3 of the License, or     
15
// (at your option) any later version.                                      
16
//                                                                          
17
// This source file is distributed in the hope that it will be useful,      
18
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
19
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
20
// GNU General Public License for more details.                             
21
//                                                                          
22
// You should have received a copy of the GNU General Public License        
23
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
24
//                                                                          
25
// ============================================================================
26
 
27
module fpdivr8(clk, ld, a, b, q, r, done);
28
parameter WID = 112;
29
parameter RADIX = 8;
30
localparam WID1 = WID;//((WID+2)/3)*3;    // make width a multiple of three
31
localparam DMSB = WID1-1;
32
input clk;
33
input ld;
34
input [WID1-1:0] a;
35
input [WID1-1:0] b;
36
output reg [WID1*2-1:0] q;
37
output [WID1-1:0] r;
38
output done;
39
 
40
 
41
wire [DMSB:0] rx [2:0];           // remainder holds
42
reg [DMSB:0] rxx;
43
reg [8:0] cnt;                           // iteration count
44
wire [DMSB:0] sdq;
45
wire [DMSB:0] sdr;
46
wire sdval;
47
wire sddbz;
48
reg [DMSB+1:0] ri;
49
wire b0,b1,b2;
50
wire [DMSB:0] r1,r2,r3;
51
 
52
specialCaseDivider #(WID1) u1 (.a(a), .b(b), .q(sdq), .val(sdval), .dbz(sdbz) );
53
 
54
wire [7:0] maxcnt;
55
wire [2:0] n1;
56
generate
57
begin
58
if (RADIX==8) begin
59
    assign maxcnt = WID1*2/3+1;
60
    assign b0 = b < rxx;
61
    assign r1 = b0 ? rxx - b : rxx;
62
    assign b1 = b < {r1,q[WID*2-1]};
63
    assign r2 = b1 ? {r1,q[WID*2-1]} - b : {r1,q[WID*2-1]};
64
    assign b2 = b < {r2,q[WID*2-1-1]};
65
    assign r3 = b2 ? {r2,q[WID*2-1-1]} - b : {r2,q[WID*2-1-1]};
66
    assign n1 = 2;
67
        always @(posedge clk)
68
        if (ld)
69
            rxx <= 0;
70
        else if (!done)
71
            rxx <= {r3,q[WID*2-1]};
72
end
73
else if (RADIX==2) begin
74
    assign b0 = b <= ri;
75
    assign r1 = b0 ? ri - b : ri;
76
    assign maxcnt = WID1*2+1;
77
    assign n1 = 0;
78
//      assign rx[0] = rxx  [DMSB] ? {rxx  ,q[WID*2-1  ]} + b : {rxx  ,q[WID*2-1  ]} - b;
79
end
80
end
81
endgenerate
82
 
83
        always @(posedge clk)
84
                if (ld)
85
                        cnt <= sdval ? 9'h1FF : maxcnt;
86
                else if (!done)
87
                        cnt <= cnt - 1;
88
 
89
 
90
generate
91
begin
92
if (RADIX==8) begin
93
        always @(posedge clk)
94
                if (ld) begin
95
                        if (sdval)
96
                                q <= {3'b0,sdq,{WID1{1'b0}}};
97
                        else
98
                                q <= {3'b0,a,{WID1{1'b0}}};
99
                end
100
                else if (!done) begin
101
                        q[WID1-1:3] <= q[WID1-1-3:0];
102
                        q[0] <= b0;
103
                        q[1] <= b1;
104
                        q[2] <= b2;
105
                end
106
        // correct remainder
107
        assign r = sdval ? sdr : r3;
108
end
109
if (RADIX==2) begin
110
        always @(posedge clk)
111
    if (ld) begin
112
        ri <= 0;
113
        if (sdval)
114
            q <= {3'b0,sdq,{WID1{1'b0}}};
115
        else
116
            q <= {3'b0,a,{WID1{1'b0}}};
117
    end
118
    else if (!done) begin
119
        q[WID1*2-1:1] <= q[WID1*2-1-1:0];
120
        q[0] <= b0;
121
        ri <= {r1[DMSB:0],q[WID1*2-1]};
122
    end
123
        // correct remainder
124
    assign r = sdval ? sdr : ri;
125
end
126
end
127
endgenerate
128
 
129
        assign done = cnt[8];
130
 
131
endmodule
132
 
133
/*
134
module fpdiv_tb();
135
 
136
        reg rst;
137
        reg clk;
138
        reg ld;
139
        reg [6:0] cnt;
140
 
141
        wire ce = 1'b1;
142
        wire [49:0] a = 50'h0_0000_0400_0000;
143
        wire [23:0] b = 24'd101;
144
        wire [49:0] q;
145
        wire [49:0] r;
146
        wire done;
147
 
148
        initial begin
149
                clk = 1;
150
                rst = 0;
151
                #100 rst = 1;
152
                #100 rst = 0;
153
        end
154
 
155
        always #20 clk = ~clk;  //  25 MHz
156
 
157
        always @(posedge clk)
158
                if (rst)
159
                        cnt <= 0;
160
                else begin
161
                        ld <= 0;
162
                        cnt <= cnt + 1;
163
                        if (cnt == 3)
164
                                ld <= 1;
165
                        $display("ld=%b q=%h r=%h done=%b", ld, q, r, done);
166
                end
167
 
168
 
169
        fpdivr8 divu0(.clk(clk), .ce(ce), .ld(ld), .a(a), .b(b), .q(q), .r(r), .done(done) );
170
 
171
endmodule
172
 
173
*/
174
 

powered by: WebSVN 2.1.0

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