af10fc288cde3303402cce4e796cef981abe254e
[shakti-core.git] / src / core / fpu / fpu_int_to_dp.bsv
1 /*
2 Authors : Vinod.G
3 Email : g.vinod1993@gmail.com
4 Last Update : 27th November 2017
5 See LICENSE for more details
6 Description:
7 TODO
8 */
9 package fpu_int_to_dp;
10 import defined_types ::*;
11 import UniqueWrappers::*;
12 `include "defined_parameters.bsv"
13 //TODO Rework and optimize
14 function Bit#(m) zeroExtendLSB(Bit#(n) value)
15 provisos(Add#(a__, n, m));
16
17 Bit#(m) resp = 0;
18 resp[valueOf(m)-1:valueOf(m)-valueOf(n)] = value;
19 return resp;
20 endfunction
21
22 function Bit#(m) truncateLSB(Bit#(n) value);
23 return value[valueOf(n)-1:valueOf(n)-valueOf(m)];
24 endfunction
25
26 interface Ifc_fpu_int_to_dp;
27 method ActionValue#(Floating_output#(64)) _start(Bit#(64) inp_int, Bit#(1) unsigned_bit, Bit#(1) long, Bit#(3) rounding_mode);
28 endinterface
29
30
31 function Bit#(69) roundFunc(Bit#(64) unrounded, Bit#(11) expo, Bit#(3) rounding_mode);
32 bit guard = unrounded[10];
33 bit round = unrounded[9];
34 bit sticky = 0;
35 bit sign = unrounded[63];
36 Bit#(11) local_expo = expo;
37 Bit#(9) sticky_check = unrounded[8:0];
38 if(sticky_check != '0)
39 sticky = 1;
40 bit inexact = (guard | round | sticky);
41 bit lv_roundup = 0;
42 Bit#(54) lv_man = {2'b0,unrounded[62:11]};
43 if(rounding_mode == 'b000)
44 lv_roundup = guard & (unrounded[11] | round | sticky);
45 else if (rounding_mode == 'b100)
46 lv_roundup = guard; //& (round | sticky | ~sign);
47 else if (rounding_mode == 'b011)
48 lv_roundup = (guard | round | sticky) & (~sign);
49 else if (rounding_mode == 'b010)
50 lv_roundup = (guard | round | sticky) & (sign);
51 if(lv_roundup == 1)
52 lv_man = lv_man + 1;
53 if(lv_man[52] == 1) begin
54 local_expo = local_expo + 1;
55 end
56 let fflags = {1'b0,1'b0,1'b0,1'b0,inexact};
57 return {fflags,sign,local_expo,lv_man[51:0]};
58 endfunction
59
60 `ifdef fpu_hierarchical
61 (*synthesize*)
62 `endif
63 module mkfpu_int_to_dp(Ifc_fpu_int_to_dp);
64
65 //Wrapper3#(Bit#(32), Bit#(1), Bit#(3),Bit#(69)) fcvt_d_wwu <- mkUniqueWrapper3(fcvt_s_w_l);
66 //Wrapper3#(Bit#(64), Bit#(1), Bit#(3),Bit#(69)) fcvt_d_llu <- mkUniqueWrapper3(fcvt_s_w_l);
67
68 method ActionValue#(Floating_output#(64)) _start(Bit#(64) inp_int, Bit#(1) unsigned_bit, Bit#(1) long, Bit#(3) rounding_mode);
69 Floating_output#(64) wr_final_out=?;
70 `ifdef verbose $display($time,"Giving inputs: %h unsigned %b long %b rounding %b", inp_int, unsigned_bit, long, rounding_mode); `endif
71 if((inp_int == 0 && long==1) || (inp_int[31:0] == 0 && long == 0))
72 wr_final_out = Floating_output{ final_result : 64'b0,
73 fflags : 5'b0
74 } ;
75 else if(long == 0) begin
76 Bit#(32) inp32 = inp_int[31:0];
77 `ifdef verbose $display("inp_int : %b",inp32); `endif
78 Bool ubit = (unsigned_bit == 1);
79 Bit#(1) lv_sign = ubit? 0 : inp32[31];
80 Bool sbit = (lv_sign==1);
81 Bit#(10) bias = '1;
82 Bit#(11) expo = zeroExtend(bias) + 31;
83 if(sbit)
84 inp32 = ~inp32+1;
85 Bit#(5) lv_zeros = truncate(pack(countZerosMSB(inp32)));
86 inp32 = inp32 << lv_zeros;
87 expo = expo - zeroExtend(lv_zeros);
88 Bit#(52) mantissa = zeroExtendLSB(inp32[30:0]);
89 Bit#(64) res = {lv_sign,expo,mantissa};
90 wr_final_out = Floating_output {
91 final_result : res,
92 fflags : 0
93 };
94 end
95 else begin
96 `ifdef verbose $display("inp_int : %b",inp_int); `endif
97 Bool ubit = (unsigned_bit == 1);
98 Bit#(1) lv_sign = ubit? 0 : inp_int[63];
99 Bool sbit = (lv_sign==1);
100 Bit#(10) bias = '1;
101 Bit#(11) expo = zeroExtend(bias) + 63;
102 if(sbit)
103 inp_int = ~inp_int + 1;
104 Bit#(6) lv_zeros = truncate(pack(countZerosMSB(inp_int)));
105 inp_int = inp_int << lv_zeros;
106 expo = expo - zeroExtend(lv_zeros);
107 Bit#(69) res = roundFunc({lv_sign,inp_int[62:0]},expo,rounding_mode);
108 wr_final_out = Floating_output {
109 final_result : res[63:0],
110 fflags : res[68:64]
111 };
112
113 end
114 return wr_final_out;
115 endmethod
116 endmodule
117
118 //module mkTb(Empty);
119 // Reg#(Bit#(64)) rg_operand1<-mkReg(64'hffffffffe945c730);
120 // //Reg#(Bit#(64)) rg_operand1<-mkReg(~(64'hfffffffffffff812)+1);
121 // Reg#(Bit#(32)) rg_clock<-mkReg(0);
122 // Ifc_fpu_int_to_dp itod <- mkfpu_int_to_dp();
123 // Reg#(Bit#(32)) rg_arbit <-mkReg(0);
124 //
125 // rule rl_clk_count;
126 // rg_clock<=rg_clock+1;
127 // endrule
128 //
129 // rule rl_start_1(rg_clock=='d0);
130 // `ifdef verbose $display("Giving inputs rg_operand 1 : %h through testbench",rg_operand1,$time); `endif
131 // itod._start(zeroExtend(rg_operand1),1'b0,1'b0,3'b000);
132 // endrule
133 //
134 // rule rl_display_result;
135 // let abc = itod.result_();
136 // `ifdef verbose $display("Final result= %h", abc.final_result,$time); `endif
137 // $finish(0);
138 // endrule
139 //endmodule
140 endpackage