代码如下
module cordicDiv
(
input CLOCK,RESET,
input iCall,
input [31:0]dividend,
input [31:0]divisor,
output [31:0]quotient
);
reg signed [7:0]e;
reg signed [31:0]f,rp,dd,x0,x1;
reg signed [63:0]q;
reg [7:0]i;
reg isDone,isSign,isE;
always @ ( posedge CLOCK or negedge RESET )
if( !RESET )
begin
e <= 8'd0;
{ f,rp,dd,x0,x1 } <= { 32'd0,32'd0,32'd0,32'd0,32'd0 };
q <= 64'd0;
i <= 8'd0;
{ isDone,isSign,isE } <= { 1'b0,1'b0,1'b0 };
end
else if( iCall )
case( i )
0:
begin
isSign <= dividend[31] ^ divisor[31];
dd <= dividend[31] ? -(dividend) : dividend;
f <= divisor[31]? -(divisor):divisor;
e <= 8'd0;
i <= i + 1'b1;
end
1:
begin
if( f >= 65536 ) begin f = f >>> 1; e = e + 1'b1; end
else if( f < 32768 ) begin f = f <<< 1; e = e - 1'b1; end
if( f < 32768 | f >= 65536 ) i <= i;
else i <= i + 1'b1;
end
2:
begin
isE <= e[7];
e <= e[7] ? -e : e;
x0 <= { 16'd0,f[19:4] };
i <= i + 1'b1;
end
3,4,5,6,7,8,9,10:
begin
x1 = 8192 - ((f[19:4]*x0) >>> 12);
x0 <= (x0 * x1) >>> 12;
i <= i + 1'b1;
end
11:
begin
x0 = x0 <<< 4;
rp = isE ? x0 <<< e : x0 >>> e; // x0 * 2-e
q <= (dd * rp) >>> 16;
i <= i + 1'b1;
end
endcase
assign quotient = isSign ? -q : q;
endmodule
模块的功能如下:
- 当RESET信号为低电平时,重置模块的内部状态和变量。
- 当iCall信号为高电平时,开始执行除法运算。
- 根据i的值,执行不同的操作:
- 当i为0时,初始化一些变量,确定被除数和除数的符号。
- 当i为1时,进行除数归一化的计算,将除数调整到特定范围内。
- 当i为2时,判断除数的符号,计算初始值x0。
- 当i为3到10时,使用CORDIC算法迭代计算x0和x1的值。
- 当i为11时,根据计算得到的x0和e,计算商的值q。
- 最后,根据商的符号位isSign,确定最终的商的值。