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

Subversion Repositories thor

[/] [thor/] [trunk/] [rtl/] [verilog/] [fpUnit/] [i2f.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 robfinch
/* ===============================================================
2
        (C) 2006  Robert Finch
3
        All rights reserved.
4
        rob@birdcomputer.ca
5
 
6
        i2f.v
7
                - convert integer to floating point
8
                - parameterized width
9
                - IEEE 754 representation
10
 
11
        This source code is free for use and modification for
12
        non-commercial or evaluation purposes, provided this
13
        copyright statement and disclaimer remains present in
14
        the file.
15
 
16
        If the code is modified, please state the origin and
17
        note that the code has been modified.
18
 
19
        NO WARRANTY.
20
        THIS Work, IS PROVIDEDED "AS IS" WITH NO WARRANTIES OF
21
        ANY KIND, WHETHER EXPRESS OR IMPLIED. The user must assume
22
        the entire risk of using the Work.
23
 
24
        IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
25
        ANY INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES
26
        WHATSOEVER RELATING TO THE USE OF THIS WORK, OR YOUR
27
        RELATIONSHIP WITH THE AUTHOR.
28
 
29
        IN ADDITION, IN NO EVENT DOES THE AUTHOR AUTHORIZE YOU
30
        TO USE THE WORK IN APPLICATIONS OR SYSTEMS WHERE THE
31
        WORK'S FAILURE TO PERFORM CAN REASONABLY BE EXPECTED
32
        TO RESULT IN A SIGNIFICANT PHYSICAL INJURY, OR IN LOSS
33
        OF LIFE. ANY SUCH USE BY YOU IS ENTIRELY AT YOUR OWN RISK,
34
        AND YOU AGREE TO HOLD THE AUTHOR AND CONTRIBUTORS HARMLESS
35
        FROM ANY CLAIMS OR LOSSES RELATING TO SUCH UNAUTHORIZED
36
        USE.
37
 
38
        - pipelinable
39
        - single stage latency
40
 
41
        Ref: Spartan3-4
42
        267 LUTs / 167 slices / 20? ns  (32 bits)
43
=============================================================== */
44
 
45
module i2f
46
#(      parameter WID = 32)
47
(
48
        input clk,
49
        input ce,
50
        input [1:0] rm,                  // rounding mode
51
        input [WID-1:0] i,               // integer input
52
        output [WID-1:0] o               // float output
53
);
54
localparam MSB = WID-1;
55
localparam EMSB = WID==80 ? 14 :
56
                  WID==64 ? 10 :
57
                                  WID==52 ? 10 :
58
                                  WID==48 ? 10 :
59
                                  WID==44 ? 10 :
60
                                  WID==42 ? 10 :
61
                                  WID==40 ?  9 :
62
                                  WID==32 ?  7 :
63
                                  WID==24 ?  6 : 4;
64
localparam FMSB = WID==80 ? 63 :
65
                  WID==64 ? 51 :
66
                                  WID==52 ? 39 :
67
                                  WID==48 ? 35 :
68
                                  WID==44 ? 31 :
69
                                  WID==42 ? 29 :
70
                                  WID==40 ? 28 :
71
                                  WID==32 ? 22 :
72
                                  WID==24 ? 15 : 9;
73
 
74
wire [EMSB:0] zeroXp = {EMSB{1'b1}};
75
 
76
wire iz;                        // zero input ?
77
wire [MSB:0] imag;       // get magnitude of i
78
wire [MSB:0] imag1 = i[MSB] ? -i : i;
79
wire [6:0] lz;           // count the leading zeros in the number
80
wire [EMSB:0] wd;        // compute number of whole digits
81
wire so;                        // copy the sign of the input (easy)
82
wire [1:0] rmd;
83
 
84
delay1 #(2)   u0 (.clk(clk), .ce(ce), .i(rm),     .o(rmd) );
85
delay1 #(1)   u1 (.clk(clk), .ce(ce), .i(i==0),   .o(iz) );
86
delay1 #(WID) u2 (.clk(clk), .ce(ce), .i(imag1),  .o(imag) );
87
delay1 #(1)   u3 (.clk(clk), .ce(ce), .i(i[MSB]), .o(so) );
88
generate
89
if (WID==64) begin
90
cntlz64Reg    u4 (.clk(clk), .ce(ce), .i(imag1), .o(lz) );
91
end else begin
92
cntlz32Reg    u4 (.clk(clk), .ce(ce), .i(imag1), .o(lz) );
93
assign lz[6]=1'b0;
94
end
95
endgenerate
96
 
97
assign wd = zeroXp - 1 + WID - lz;      // constant except for lz
98
 
99
wire [EMSB:0] xo = iz ? 0 : wd;
100
wire [MSB:0] simag = imag << lz;         // left align number
101
 
102
wire g =  simag[EMSB+2];        // guard bit (lsb)
103
wire r =  simag[EMSB+1];        // rounding bit
104
wire s = |simag[EMSB:0]; // "sticky" bit
105
reg rnd;
106
 
107
// Compute the round bit
108
always @(rmd,g,r,s,so)
109
        case (rmd)
110
        2'd0:   rnd = (g & r) | (r & s);        // round to nearest even
111
        2'd1:   rnd = 0;                                 // round to zero (truncate)
112
        2'd2:   rnd = (r | s) & !so;            // round towards +infinity
113
        2'd3:   rnd = (r | s) & so;                     // round towards -infinity
114
        endcase
115
 
116
// "hide" the leading one bit = MSB-1
117
// round the result
118
wire [FMSB:0] mo = simag[MSB-1:EMSB+1]+rnd;
119
 
120
assign o = {so,xo,mo};
121
 
122
endmodule
123
 
124
 
125
module i2f_tb();
126
 
127
reg clk;
128
reg [7:0] cnt;
129
wire [31:0] fo;
130
reg [31:0] i;
131
initial begin
132
clk = 1'b0;
133
cnt = 0;
134
end
135
always #10 clk=!clk;
136
 
137
always @(posedge clk)
138
        cnt = cnt + 1;
139
 
140
always @(cnt)
141
case(cnt)
142
8'd0:   i <= 32'd0;
143
8'd1:   i <= 32'd16777226;
144
endcase
145
 
146
i2f #(32) u1 (.clk(clk), .ce(1), .rm(2'd0), .i(i), .o(fo) );
147
 
148
endmodule

powered by: WebSVN 2.1.0

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