若以f[31:0]表示一个单精度32位浮点数,f[31]是符号位,其为‘0’表示正数、为‘1’表示负数;f[30:23]这8位为指数位,为了能表示负指数,将在实际指数的基础上加上127得到的结果存入f[30:23];f[22:0]表示小数位(尾数),类似科学计数法,不过采用了省略整数位(2进制的科学计数法整数位必定是1)1,将小数位从高到低依次存入f[22:0]的从高到低的位数,不足23位则在末尾补0,例如小数位只有“10011001”则f[22:0]="10011001000000000000000",这样就可以用23位存储空间表示24位的数据,变相增加了精度。另外还有一些特殊编码,如无穷大、0、NAN和非正规数,这里没有考虑,待以后用到再细究吧。
我用verilog语言写的定点数转浮点数模块,实现25位有符号定点整数转化成32位单精度浮点数,并不完全符合标准(例如未考虑特殊编码等),第一步实现补码到原码的转换,第二步计算指数和尾数。
代码如下:
module fix2float(clk,rst_n,ifix,ofloat);
input clk,rst_n;
input [24:0] ifix;
//reg [24:0] ifix;
output [31:0] ofloat;
reg [24:0] ifix_r;
reg [31:0] ofloat_r;
reg [23:0] ustd_tail;
reg [22:0] std_tail;
reg [7:0] exp;
reg s1,s2;
assign ofloat=ofloat_r;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
//ifix<=25'd100;
ofloat_r<=32'd0;
ustd_tail<=23'd0;
exp<=8'd0;
end
else
begin
ustd_tail<=ifix_r[23:0];
s1<=ifix[24];
s2<=s1;
if(ifix[24]==1'b1)
begin
ifix_r<=~ifix+24'd1;
end
else
begin
ifix_r<=ifix;
end
if(ustd_tail[23]==1'b1)
begin
exp<=8'd127+8'd23;
std_tail<=ustd_tail[22:0];
end
else if(ustd_tail[22]==1'b1)
begin
exp<=8'd127+8'd22;
std_tail<={ustd_tail[21:0],1'd0};
end
else if(ustd_tail[21]==1'b1)
begin
exp<=8'd127+8'd21;
std_tail<={ustd_tail[20:0],2'd0};
end
else if(ustd_tail[20]==1'b1)
begin
exp<=8'd127+8'd20;
std_tail<={ustd_tail[19:0],3'd0};
end
else if(ustd_tail[19]==1'b1)
begin
exp<=8'd127+8'd19;
std_tail<={ustd_tail[18:0],4'd0};
end
else if(ustd_tail[18]==1'b1)
begin
exp<=8'd127+8'd18;
std_tail<={ustd_tail[17:0],5'd0};
end
else if(ustd_tail[17]==1'b1)
begin
exp<=8'd127+8'd17;
std_tail<={ustd_tail[16:0],6'd0};
end
else if(ustd_tail[16]==1'b1)
begin
exp<=8'd127+8'd16;
std_tail<={ustd_tail[15:0],7'd0};
end
else if(ustd_tail[15]==1'b1)
begin
exp<=8'd127+8'd15;
std_tail<={ustd_tail[14:0],8'd0};
end
else if(ustd_tail[14]==1'b1)
begin
exp<=8'd127+8'd14;
std_tail<={ustd_tail[13:0],9'd0};
end
else if(ustd_tail[13]==1'b1)
begin
exp<=8'd127+8'd13;
std_tail<={ustd_tail[12:0],10'd0};
end
else if(ustd_tail[12]==1'b1)
begin
exp<=8'd127+8'd12;
std_tail<={ustd_tail[11:0],11'd0};
end
else if(ustd_tail[11]==1'b1)
begin
exp<=8'd127+8'd11;
std_tail<={ustd_tail[10:0],12'd0};
end
else if(ustd_tail[10]==1'b1)
begin
exp<=8'd127+8'd10;
std_tail<={ustd_tail[9:0],13'd0};
end
else if(ustd_tail[9]==1'b1)
begin
exp<=8'd127+8'd9;
std_tail<={ustd_tail[8:0],14'd0};
end
else if(ustd_tail[8]==1'b1)
begin
exp<=8'd127+8'd8;
std_tail<={ustd_tail[7:0],15'd0};
end
else if(ustd_tail[7]==1'b1)
begin
exp<=8'd127+8'd7;
std_tail<={ustd_tail[6:0],16'd0};
end
else if(ustd_tail[6]==1'b1)
begin
exp<=8'd127+8'd6;
std_tail<={ustd_tail[5:0],17'd0};
end
else if(ustd_tail[5]==1'b1)
begin
exp<=8'd127+8'd5;
std_tail<={ustd_tail[4:0],18'd0};
end
else if(ustd_tail[4]==1'b1)
begin
exp<=8'd127+8'd4;
std_tail<={ustd_tail[3:0],19'd0};
end
else if(ustd_tail[3]==1'b1)
begin
exp<=8'd127+8'd3;
std_tail<={ustd_tail[2:0],20'd0};
end
else if(ustd_tail[2]==1'b1)
begin
exp<=8'd127+8'd2;
std_tail<={ustd_tail[1:0],21'd0};
end
else if(ustd_tail[1]==1'b1)
begin
exp<=8'd127+8'd1;
std_tail<={ustd_tail[0],22'd0};
end
else
begin
exp<=8'd127+8'd24;
std_tail<=23'd0;
end
ofloat_r<={s2,exp,std_tail};
end
end
endmodule