考虑几个方面:
1:可能是非规格化格式 形式是:8位阶码位=0,而且尾数位!=0,,,这样的数太小,必将导致精度损失。
2:因为32位补码整数能表示的范围只能是-231<=d<=231,而单精度浮点数能表示的数的范围比整数大的多,所以很多浮点数不能转换成整数,不能太小,也不能太大。
转换的方法:
先根据阶数计算出右移位数n,和根据尾数组成frac0,然后将frac0右移n位形成f_abs,截取f_abs[23:0],如果全是0 则精度没有损失,如果有则精度损失。
最后根据符号位,将f_abs[55:24]就是结果,如果是负的,将f_abs[55:24]转换成负数。
wire [8:0] shift_right_bits=9'b010011110-{1'b0,a[30:23]};/////需要右移的位数
wire [55:0] frac0={hidden_bit,a[22:0],32'h0};///////////为能检测出精度是否损失,使用了56位的数据格式,左32位为结果,右24位是被移除的位。
wire [55:0] f_abs=($signed(shift_right_bits)>9'h20)?frac0>>6'h20:frac0>>shift_right_bits;/////frac0右移后的数据
wire lost_bits=|f_abs[23:0];//判别是否精度损失
wire [31:0] int32 = (sign)? -f_abs[55:24]:f_abs[55:24];//根据符号,转换,并取出结果。
代码:
module f2i(a,d,precision_lost,denormlized,invalid,state);
input [31:0] a;
output reg [31:0] d;
output reg precision_lost;
output denormlized;
output reg invalid;
output reg [2:0] state;
wire hidden_bit=|a[30:23];
wire frac_is_not_0=|a[22:0];
assign denormlized=~hidden_bit&frac_is_not_0;
wire is_zero=~hidden_bit&~frac_is_not_0;
wire sign =a[31];
wire [8:0] shift_right_bits=9'b010011110-{1'b0,a[30:23]};
wire [55:0] frac0={hidden_bit,a[22:0],32'h0};
wire [55:0] f_abs=($signed(shift_right_bits)>9'h20)?frac0>>6'h20:frac0>>shift_right_bits;
wire lost_bits=|f_abs[23:0];
wire [31:0] int32 = (sign)? -f_abs[55:24]:f_abs[55:24];
always @* begin
if(denormlized) begin
precision_lost=1;
invalid=0;
d=32'h00000000;
state=3'b000;
end
else
begin
if(shift_right_bits[8]) begin
precision_lost=0;
invalid=1;
d=32'h80000000;
state=3'b001;
end
else
begin
if(shift_right_bits[7:0]>8'h1f) begin
if(is_zero) precision_lost=0;
else precision_lost=1;
invalid=0;
d=32'h00000000;
state=3'b010;
end
else begin
if(sign!=int32[31]) begin
precision_lost=0;
invalid=1;
d=32'h80000000;
state=3'b011;
end
else
begin
if(lost_bits) precision_lost=1;
else precision_lost=0;
invalid=0;
d=int32;
state=3'b100;
end
end
end
end
end
endmodule
文章评论(0条评论)
登录后参与讨论