add core
[shakti-core.git] / src / core / fpu / fpu_int_to_sp.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_sp;
10
11 import defined_types ::*;
12 import UniqueWrappers::*;
13 `include "defined_parameters.bsv"
14 interface Ifc_fpu_int_to_sp;
15 method ActionValue#(Floating_output#(32)) _start(Bit#(64) inp_int, Bit#(1) unsigned_bit, Bit#(1) long, Bit#(3) rounding_mode);
16 endinterface
17
18
19 function Bit#(37) roundFunc(Bit#(n) unrounded, Bit#(8) expo, Bit#(3) rounding_mode)
20 provisos(
21 Add#(a__,32,n)
22 );
23 let nInd = valueOf(n);
24 bit guard = unrounded[nInd-25];
25 bit round = unrounded[nInd-26];
26 bit sticky = 0;
27 bit sign = unrounded[nInd-1];
28 Bit#(8) local_expo = expo;
29 Bit#(TSub#(n,26)) sticky_check = unrounded[nInd-27:0];
30 if(sticky_check != '0)
31 sticky = 1;
32 bit inexact = (guard | round | sticky);
33 bit lv_roundup = 0;
34 Bit#(25) lv_man = {2'b0,unrounded[nInd-2:nInd-24]};
35 if(rounding_mode == 'b000)
36 lv_roundup = guard & (unrounded[nInd-24] | round | sticky);
37 else if (rounding_mode == 'b100)
38 lv_roundup = guard; //& (round | sticky | ~sign);
39 else if (rounding_mode == 'b011)
40 lv_roundup = (guard | round | sticky) & (~sign);
41 else if (rounding_mode == 'b010)
42 lv_roundup = (guard | round | sticky) & (sign);
43 if(lv_roundup == 1)
44 lv_man = lv_man + 1;
45 if(lv_man[23] == 1) begin
46 local_expo = local_expo + 1;
47 end
48 let fflags = {1'b0,1'b0,1'b0,1'b0,inexact};
49 return {fflags,sign,local_expo,lv_man[22:0]};
50 endfunction
51
52 function Bit#(37) fcvt_s_w_l (Bit#(n) inp, Bit#(1) unsigned_bit, Bit#(3) rounding_mode)
53 provisos(
54 Add#(a__,32,n),
55 Log#(n,logN),
56 Add#(b__,logN,8),
57 Add#(c__, logN, TLog#(TAdd#(1, n)))
58 );
59 let nInd = valueOf(n);
60 Bool ubit = (unsigned_bit == 1);
61 Bit#(1) lv_sign = ubit? 0 : inp[nInd-1];
62 Bool sbit = (lv_sign == 1);
63 Bit#(7) bias = '1;
64 Bit#(8) expo = zeroExtend(bias) + fromInteger(nInd-1);
65 if(sbit)
66 inp = ~inp + 1;
67 Bit#(logN) lv_zeros = truncate(pack(countZerosMSB(inp)));
68 inp = inp << lv_zeros;
69 expo = expo - zeroExtend(pack(lv_zeros));
70 Bit#(TSub#(n,1)) inpS = inp[nInd-2:0];
71 Bit#(n) inp_temp = {lv_sign,inpS};
72 Bit#(37) res = roundFunc(inp_temp, expo, rounding_mode);
73 return res;
74 endfunction
75
76
77 `ifdef fpu_hierarchical
78 (*synthesize*)
79 `endif
80 module mkfpu_int_to_sp(Ifc_fpu_int_to_sp);
81
82
83 Wrapper3#(Bit#(32), Bit#(1), Bit#(3),Bit#(37)) fcvt_s_wwu <- mkUniqueWrapper3(fcvt_s_w_l);
84 Wrapper3#(Bit#(64), Bit#(1), Bit#(3),Bit#(37)) fcvt_s_llu <- mkUniqueWrapper3(fcvt_s_w_l);
85
86 method ActionValue#(Floating_output#(32)) _start(Bit#(64) inp_int, Bit#(1) unsigned_bit, Bit#(1) long, Bit#(3) rounding_mode);
87 `ifdef verbose $display($time,"\tGiving inputs: %h unsigned %b long %b rounding %b", inp_int, unsigned_bit, long, rounding_mode); `endif
88 Floating_output#(32) wr_final_out=?;
89 if((inp_int == 0 && long==1) || (inp_int[31:0] == 0 && long == 0))
90 wr_final_out = Floating_output{ final_result : 32'b0,
91 fflags : 5'b0
92 } ;
93 else if(long == 0) begin
94 Bit#(32) inp32 = truncate(inp_int);
95 `ifdef verbose $display("inp_int : %b",inp32); `endif
96 Bit#(1) lv_sign = inp32[31];
97 if(unsigned_bit == 0) begin
98 if((inp32 & 'h7fffffff) == 0) begin
99 Bit#(32) res = lv_sign==1? {1'b1,8'h9e,'0} : '0;
100 wr_final_out = Floating_output{
101 final_result : res,
102 fflags : 0
103 };
104 end
105 else begin
106 Bit#(37) ressw <- fcvt_s_wwu.func(inp32,unsigned_bit,rounding_mode);
107 wr_final_out = Floating_output{
108 final_result : (ressw[31:0]),
109 fflags : ressw[36:32]
110 };
111 end
112 end
113 else begin
114 Bit#(37) res <- fcvt_s_wwu.func(inp32,unsigned_bit,rounding_mode);
115 wr_final_out = Floating_output{
116 final_result : (res[31:0]),
117 fflags : res[36:32]
118 };
119 end
120 end
121 else begin
122 Bit#(37) res <- fcvt_s_llu.func(inp_int,unsigned_bit,rounding_mode);
123 wr_final_out = Floating_output {
124 final_result : res[31:0],
125 fflags : res[36:32]
126 };
127
128 end
129 return wr_final_out;
130 endmethod
131 endmodule
132
133 module mkTb(Empty);
134 Reg#(Bit#(64)) rg_operand1<-mkReg(64'h039e781bab642be4);
135 //Reg#(Bit#(64)) rg_operand1<-mkReg(~(64'hfffffffffffff812)+1);
136 Reg#(Bit#(32)) rg_clock<-mkReg(0);
137 Ifc_fpu_int_to_sp itof <- mkfpu_int_to_sp();
138 Reg#(Bit#(32)) rg_arbit <-mkReg(0);
139
140 rule rl_clk_count;
141 rg_clock<=rg_clock+1;
142 endrule
143
144 rule rl_start_1(rg_clock=='d0);
145 `ifdef verbose $display("Giving inputs rg_operand 1 : %h through testbench",rg_operand1,$time); `endif
146 let abc<-itof._start(zeroExtend(rg_operand1),1'b1,1'b0,3'b000);
147 `ifdef verbose $display("Final result= %h fflags= %h", abc.final_result, abc.fflags, $time); `endif
148 $finish(0);
149 endrule
150
151 endmodule
152 endpackage