首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

25位定点小数补码加减交替法

25位定点小数补码加减交替法

在补码一位除法中必须比较被除数(余数)和除数的大小,并根据比较的结果上商。另外,未了避免溢出,商的绝对值不能大于1,即被除数的绝对值一定要小于除数的绝对值。
补码加减交替法的算法规则如下:

1
求第一位商要被除数和除数数符号的同异,被除数x与除数y同号,被除数x加[-y]补;被除数x与除数y异号,被除数x加[y]补,得z。

2)余数z左移一位,上商,余数z与除数y同号,商q[0]=1,z=z+[-y]补。余数z与除数y异号,商q[0]=0,z=z+[y]补.q左移一位.转(3)

3)重复步骤(2),包括符号位在内,共做n+1步。转(4)
(4)一般情况采用未位恒置1的方式进行舍入。


如果需要进一步以高精度,可以不用未位恒置1的方式舍入,而按上述法则多求一位后,再采用如下修正方法对商进行处理:

(1)
刚好能除尽时,如果除数为正,商不必修正;如果除数为负,则商加2-n.

(2)
不能除尽时,如果商为正,则不必修正,如果商为负,则商加2-n.


module div25(
done,
c,
a,
b,
start,
clk
);
parameter N=25;
output done;
output [N-1:0]c;
input [N-1:0]a;
input [N-1:0]b;
input start;
input clk;

reg [4:0]index;
reg [N:0]z;
reg [N:0]x;
reg [N:0]y;
reg [N:0]y_c;
reg finished;

reg [1:0]current_state,next_state;
parameter Init=0,Load=1,Acc=2,Done=3;

always @(posedge clk or negedge start)
if (!start)
  current_state<=Init;
else
  current_state<=next_state;
always @(current_state or index or over)
case (current_state )
Init :
  begin
   next_state=Load;
  end
Load:
  begin
   if (over)
    next_state=Done;
   else
    next_state=Acc;
  end
Acc :
  begin
   if(index==5'h18)
    begin
     next_state=Done;
    end
  end
endcase
always @(current_state or index)
case (current_state)
Init:
  begin
   finished=0;
  end
Load:
  begin
   y={b[N-1],b[N-1:0]};
   y_c=~{b[N-1],b[N-1:0]}+1;
   x=0;
   if(a[N-1]==b[N-1])
    z[N:0]={a[N-1],a[N-1:0]}+y_c;
   else
    z[N:0]={a[N-1],a[N-1:0]}+y;
   $display("z=%b,x=%b,y=%b,y_c=%b",z,x,y,y_c);
  end
Acc:
  begin   
   if(z[N]==y[N])
    begin
     z={z[N-1:0],1'b0}+y_c;
     x[0]=1;
     $display("Same-After adding :z=%b,x=%b",z,x);
    end
   else
    begin
     z={z[N-1:0],1'b0}+y;
     x[0]=0;
     $display("Different-After adding y:z=%b,x=%b",z,x);
    end
    x={x[N-1:0],1'b0};
  end
default:
  begin
   finished=1;
   x[0]=1;
   $display("c=%b",c);
  end
endcase
always @(posedge clk)
if (current_state==Acc)
  index<=index+1;
else
  index<=0;
assign done=finished;
assign c[N-1:0]=x[N:1];
endmodule
module test_div25_v;

        // Inputs
        reg [24:0] a;
        reg [24:0] b;
        reg start;
        reg clk;

        // Outputs
        wire done;
        wire [24:0] c;

        // Instantiate the Unit Under Test (UUT)
        div25 uut (
                .done(done),
                .c(c),
                .a(a),
                .b(b),
                .start(start),
                .clk(clk)
        );

        initial begin
                // Initialize Inputs
                a = 0;
                b = 0;
                start = 0;
                clk = 0;

                // Wait 100 ns for global reset to finish
                #100;
                start=1;
                // Add stimulus here
                a=25'h0_80_00_00;
                b=25'h1_60_00_00;
               
                a=25'h0_90_00_00;
                b=25'h0_b0_00_00;
        end
       
        always #10 clk=~clk;
      
endmodule
返回列表