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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog/] [IntToFloat.v] - Blame information for rev 89

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

Line No. Rev Author Line
1 5 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2006-2016  Robert Finch, Stratford
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// This source file is free software: you can redistribute it and/or modify 
9
// it under the terms of the GNU Lesser General Public License as published 
10
// by the Free Software Foundation, either version 3 of the License, or     
11
// (at your option) any later version.                                      
12
//                                                                          
13
// This source file is distributed in the hope that it will be useful,      
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
16
// GNU General Public License for more details.                             
17
//                                                                          
18
// You should have received a copy of the GNU General Public License        
19
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
20
//
21
// IntToFloat
22
// - Integer to floating point conversion
23
// - Can convert a number on every clock cycle, with a latency of one cycle.
24
// - parameterized width
25
// - IEEE 754 representation
26
//
27
// The WID parameter should be either 32 or 64
28
// ============================================================================
29
//
30
module IntToFloat(clk, ce, rm, i, o);
31
parameter WID = 32;
32
input clk;
33
input ce;
34
input [2:0] rm;                  // rounding mode
35
input [WID-1:0] i;               // integer input
36
output [WID-1:0] o;              // float output
37
 
38
localparam MSB = WID-1;
39
localparam EMSB = WID==64 ? 10 : 7;
40
localparam FMSB = WID==64 ? 51 : 22;
41
 
42
wire [EMSB:0] zeroXp = {EMSB{1'b1}};
43
 
44
wire iz;                        // zero input ?
45
wire [MSB:0] imag;       // get magnitude of i
46
wire [MSB:0] imag1 = i[MSB] ? -i : i;
47
wire [6:0] lz;           // count the leading zeros in the number
48
wire [EMSB:0] wd;        // compute number of whole digits
49
wire so;                        // copy the sign of the input (easy)
50
wire [1:0] rmd;
51
 
52
delay1 #(2)   u0 (.clk(clk), .ce(ce), .i(rm),     .o(rmd) );
53
delay1 #(1)   u1 (.clk(clk), .ce(ce), .i(i==0),   .o(iz) );
54
delay1 #(WID) u2 (.clk(clk), .ce(ce), .i(imag1),  .o(imag) );
55
delay1 #(1)   u3 (.clk(clk), .ce(ce), .i(i[MSB]), .o(so) );
56
generate
57
if (WID==64) begin
58
cntlz64Reg    u4 (.clk(clk), .ce(ce), .i(imag1), .o(lz) );
59
end else begin
60
cntlz32Reg    u4 (.clk(clk), .ce(ce), .i(imag1), .o(lz) );
61
assign lz[6]=1'b0;
62
end
63
endgenerate
64
 
65
assign wd = zeroXp - 1 + WID - lz;      // constant except for lz
66
 
67
wire [EMSB:0] xo = iz ? 0 : wd;
68
wire [MSB:0] simag = imag << lz;         // left align number
69
 
70
wire g =  simag[EMSB+2];        // guard bit (lsb)
71
wire r =  simag[EMSB+1];        // rounding bit
72
wire s = |simag[EMSB:0]; // "sticky" bit
73
reg rnd;
74
 
75
// Compute the round bit
76
always @(rmd,g,r,s,so)
77
        case (rmd)
78
        3'd0:   rnd = (g & r) | (r & s);        // round to nearest even
79
        3'd1:   rnd = 0;                                 // round to zero (truncate)
80
        3'd2:   rnd = (r | s) & !so;            // round towards +infinity
81
        3'd3:   rnd = (r | s) & so;                     // round towards -infinity
82
        // The following reserved for additional round mode
83
        default: rnd = 0;                                        // round to zero (truncate)
84
        endcase
85
 
86
// "hide" the leading one bit = MSB-1
87
// round the result
88
wire [FMSB:0] mo = simag[MSB-1:EMSB+1]+rnd;
89
 
90
assign o = {so,xo,mo};
91
 
92
endmodule
93
 
94
 
95
module IntToFloat_tb();
96
 
97
reg clk;
98
reg [7:0] cnt;
99
wire [31:0] fo1,fo2,fo3,fo4,fo5,fo6;
100
initial begin
101
clk = 1'b0;
102
cnt = 0;
103
end
104
always #10 clk=!clk;
105
 
106
always @(posedge clk)
107
        cnt = cnt + 1;
108
 
109
// Some test cases
110
IntToFloat #(32) u1 (.clk(clk), .ce(1), .rm(2'd0), .i(0),        .o(fo1) ); // zero should return zero (INT min)
111
IntToFloat #(32) u2 (.clk(clk), .ce(1), .rm(2'd0), .i(1),        .o(fo2) );
112
IntToFloat #(32) u3 (.clk(clk), .ce(1), .rm(2'd0), .i(-1),       .o(fo3) ); // ensure negative flows through
113
IntToFloat #(32) u4 (.clk(clk), .ce(1), .rm(2'd0), .i(16777226), .o(fo4) );
114
IntToFloat #(32) u5 (.clk(clk), .ce(1), .rm(2'd0), .i(32'h7FFFFFFF), .o(fo5) ); // INT max
115
IntToFloat #(32) u6 (.clk(clk), .ce(1), .rm(2'd0), .i(32'h80000000), .o(fo6) ); // INT max negative
116
 
117
endmodule

powered by: WebSVN 2.1.0

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