姜咏江
1. 说明
这里给出正确的程序设计,朋友们可以与上次中秋节给出的有缺欠的设计程序对比,也许会有深刻一点的体会。下面程序的输出omov、osign只是为了设计时参考,并非必要。实际使用时,尾数加减法运算器要带上溢出标志,有兴趣的朋友将这里给出的程序稍加修改就可以做到。以下设计是在Quartus II上进行的。读者可将下面的程序直接复制到Quartus II中进行测试。
浮点乘除法运算器不用对阶,只要尾数乘除,阶码加减,因而相对设计难度不大,朋友可以自己去设计试试。
2. 设计的Verilog HDL语言描述
/*这是我65岁年初编写的程序:限位数32位浮点加减法运算器设计。阶码的变化范围是-128~127,尾数右移损失有效码由mov_f监控。这里的浮点数表数范围是 -0.16777216 *2exp127 ~+0.16777216 *2exp127 */
module fudian(f_a,f_b,clk,rst,me,f_out,sub,omov,mov_f,space,osign);
input [31:0] f_a,f_b; //输入浮点数
input clk, //时钟
me, //选择使用
rst, //复位信号
sub; //减法控制
output [31:0] f_out; //结果浮点输出
output [23:0] omov; //参考:移动后的尾数
output mov_f; //参考:甩掉有效数字尾标志
output [255:0] space; //参考:甩掉的尾数,可以提供精确计算数据
output [8:0] osign; //参考:移位数
reg [31:0] f_out; //寄存器型输出
reg [8:0] osign;
reg [7:0] exp_out;
reg [7:0] exp_a,exp_b;
reg [8:0] sign,ep_b; //保证不溢出用9位判断
reg [23:0] man_out;
reg [23:0] a_a,b_b,c_c;
reg [255:0] tru,zero,shift;
reg mov_flg;
reg one=1'b1;
assign space = shift;
assign mov_f = mov_flg;
assign omov = c_c;
always @(posedge clk or negedge rst)
begin
if (!rst)
begin
exp_a <= 8'h00;
exp_b <= 8'h00;
a_a <= 24'h000000;
b_b <= 24'h000000;
tru <= 256'hffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
zero <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
sign <= 9'b000000000;
ep_b <= 9'b000000000;
end
else if (me)
begin
exp_a = f_a[31:24];
exp_b = f_b[31:24];
a_a = f_a[23:0];
b_b = f_b[23:0];
if (exp_b[7]) ep_b={one,exp_b};
else ep_b=exp_b;
sign = exp_a - ep_b;
end
end
always @(posedge clk )
begin
if (!sign[8]) //exp_a > exp_b
begin
osign = sign;
exp_out <= f_a[31:24]; //取f_a原阶码
if (b_b[23]) //f_b的尾数为负数
{c_c,shift} <= {tru,b_b,zero} >> sign; //需要按负数扩充,然后右移
else {c_c,shift} <= {b_b,zero} >> sign;
end
else //差为负
begin
osign = -sign;
exp_out <= f_b[31:24]; //取f_b原阶码
if (a_a[23])
{c_c,shift} <= {tru,a_a,zero} >> -sign; //需要按正负数扩充
else
{c_c,shift} <= {a_a,zero} >> -sign;
end
end
always @(posedge clk )
begin
if (!sub) //加
if (!sign[8])
man_out <= a_a + c_c;
else man_out <= b_b + c_c;
else //减
if (!sign[8])
man_out <= a_a - c_c;
else man_out <= b_b - c_c;
end
always @(posedge clk )
begin
f_out <= {exp_out,man_out}; //输出
if (!shift)
mov_flg <=1'b0;
else mov_flg <=1'b1; //移位有损失,影响精度
end
endmodule
3. 仿真
下面是十六进制的浮点加减法运算器仿真。图1是阶码符号相反的运算,求的是十六进制的0.154329×208±0.734566×2FA;图2是阶码符号相同的运算,求的是十六进制的0.154329×208±0.924566×211。
图 1 阶码符号相反的运算
图 2 阶码符号相同的运算仿真
2010-9-26
https://blog.sciencenet.cn/blog-340399-367010.html
上一篇:
好想有一个真正的计算机核心科技讨论会下一篇:
电子工程设计又进入了个人化时代