定点补码整数加减交替法:
1.操作数的预置:除数装入Y寄存器,被除数装入Z,X寄存器,被除数须以2n位补码形式表示
2.
Z,X左移1位
3.
若Z与Y同号,则计算Z=Z+[-Y]补;否则计算Z=Z+[-Y]补;根据计算结果,按以下规则确定商值X[0]:
若Z,X=0或Z操作前后符号未变,则X[0]置1,转下一步;
若A操作前后符号已变,则X[0]置0,恢复Z值,转下一步;
4.重复(2),(3)两步,直到取得n位商为止。
5.余数在Z中。若被除数与除数同号,则商在X中;否则,[-X]补是真正的商。
module div32(
done,
c,
d,
a,
b,
start,
clk
);
parameter N=32;
output done;
output [N-1:0]c;
output [N-1:0]d;
input [2*N-1:0]a;
input [N-1:0]b;
input start;
input clk;
reg [5:0]index;
reg [N-1:0]z;
reg [N-1:0]temp_z;
reg [N-1:0]x;
reg [N-1:0]y;
reg [N-1: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)
case (current_state )
Init :
begin
next_state=Load;
end
Load:
begin
next_state=Acc;
end
Acc :
begin
if(index==6'h1f)
begin
next_state=Done;
end
end
endcase
always @(current_state or index)
case (current_state)
Init:
begin
finished=0;
end
Load:
begin
{z[N-1:0],x[N-1:0]}=a;
y=b;
y_c=~b+1;
$display("z=%b,x=%b,y=%b,y_c=%b",z,x,y,y_c);
end
Acc:
begin
$display("Before left shift:z=%b,x=%b",z,x);
{z[N-1:0],x[N-1:0]}={z[N-2:0],x[N-1:0],1'b0};
temp_z=z;
$display("After left shift:z=%b,x=%b",z,x);
if(z[N-1]==y[N-1])
begin
z=z+y_c;
$display("Same-After adding :z=%b,x=%b",z,x);
end
else
begin
z=z+y;
$display("Different-After adding y:z=%b,x=%b",z,x);
end
if(temp_z[N-1]==z[N-1])
begin
x[0]=1;
$display("After get a bit 1 :z=%b,x=%b",z,x);
end
else
begin
x[0]=0;
z=temp_z;
$display("After get a bit 0 :z=%b,x=%b",z,x);
end
end
default:
begin
finished=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]=(a[N-1]==b[N-1])?x[N-1:0]~x[N-1:0]+1);
assign d=z;
endmodule |