CMP设计分享 http://blog.sciencenet.cn/u/accsys 没有逆向思维就没有科技原创。 不自信是科技创新的大敌。

博文

可精确计算的浮点加减法运算器硬件设计程序

已有 5184 次阅读 2010-9-26 08:56 |个人分类:计算机核|系统分类:科研笔记| EDA, CPU设计

姜咏江
 
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

上一篇:好想有一个真正的计算机核心科技讨论会
下一篇:电子工程设计又进入了个人化时代
收藏 IP: .*| 热度|

0

发表评论 评论 (0 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-5 06:49

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部