一 设计思路(一)求商的符号(二)求商的数值部分(三)商的最后一位恒置1
二 verilog代码(一)程序代码变量说明(二)程序代码结构说明1. 除法器2. 根据余数和除数的符号进行加法操作和商的操作3. 移位4. 截取最终的商和余数
(三)程序代码(四)时序模拟图
一 设计思路
(一)求商的符号
若[X]补与[Y]补同号,[X]补 - [Y]补; 若[X]补与[Y]补异号(即不够减),[X]补 + [Y]补。如果所得余数与除数同号,商上1; 若余数与除数异号,商上0; 商即结果的符号位。
(二)求商的数值部分
若[Ri]补与[Y]补同号,商上“1”,下次操作为:[Ri+1]补=2[Ri]补 - [Y]补若[Ri]补与[Y]补异号,商上“0”,下次操作为:[Ri+1]补=2[Ri]补 + [Y]补 如此重复执行n-1次(设数值部分有n位,符号位1位)。
(三)商的最后一位恒置1
商的最后一位一般采用恒置1的办法,并省略了最低位+1的操作,此时最大的误差为±2-n。
二 verilog代码
(一)程序代码变量说明
parameter N = 16 // 16位
input [N-1:0] x,y, // 输入:被除数x,除数y,16位单符号位定点小数(1位符号位+15位数值位)
output [N-1:0] quotient); // 输出:商,16位单符号位定点小数(1位符号位+15位数值位)
wire [N:0] yy,_y; // 双符号位定点小数表示的[y]补、[-y]补
wire [N:0] xx; // 双符号位定点小数表示的[x]补
wire [N:0] r[0:2*(N-1)-1]; // 双符号位定点小数表示的余数,共需要2*(N-1)=30次加法、移动操作
wire [N-1:0] q[0:2*(N-1)-1]; // 双符号位定点小数表示的商
wire [N-1:0] remainder; // 最终的余数
wire [N-1:0] q_start0,q_start1; // 初始的商
wire [N:0] ry,r_y,rr; // 初始的余数
(二)程序代码结构说明
1. 除法器
module divider #(parameter N = 16)(
input [N-1:0] x,y,
output [N-1:0] quotient);
2. 根据余数和除数的符号进行加法操作和商的操作
module add #(parameter N = 16)(
input [N:0] r_in,
input [N-1:0] q_in,
input [N:0] yy,_y,
output [N:0] r_out,
output [N-1:0] q_out);
3. 移位
module move #(parameter N = 16)(
input [N:0] r_in,
input [N-1:0] q_in,
output [N:0] r_out,
output [N-1:0] q_out);
4. 截取最终的商和余数
module cut #(parameter N = 16)(
input [N-1:0] q,
input [N:0] r,
output [N-1:0] quotient,remainder);
(三)程序代码
组合逻辑,加减交替法定点补码一位除法 软件:Quartus II 9.0
module divider #(parameter N = 16)(
input [N-1:0] x,y, // 1 bit for sign and 15 bit for number(decimal)
output [N-1:0] quotient);
wire [N:0] yy,_y; // 2 bit for sign + 15 bit for number
wire [N:0] xx; // 2 bit for sign + 15 bit for number
wire [N:0] r[0:2*(N-1)-1];
wire [N-1:0] q[0:2*(N-1)-1];
wire [N-1:0] remainder;
// prepare
assign yy = {y[N-1],y};
assign _y = ~yy + 1'b1;
assign xx = {x[N-1],x};
// initialize
wire [N-1:0] q_start0,q_start1;
assign q_start0 = {N{1'b0}};
assign q_start1 = {q_start0[N-1:1],1'b1};
wire [N:0] ry,r_y,rr;
assign ry = xx + yy;
assign r_y = xx + _y;
assign r[0] = (xx[N]==yy[N]) ? r_y : ry;
assign rr = r[0];
assign q[0] = (rr[N]==yy[N]) ? q_start1 : q_start0;
move(r[0],q[0],r[1],q[1]);
// add and move
add(r[1],q[1],yy,_y,r[2],q[2]);
move(r[2],q[2],r[3],q[3]);
add(r[3],q[3],yy,_y,r[4],q[4]);
move(r[4],q[4],r[5],q[5]);
add(r[5],q[5],yy,_y,r[6],q[6]);
move(r[6],q[6],r[7],q[7]);
add(r[7],q[7],yy,_y,r[8],q[8]);
move(r[8],q[8],r[9],q[9]);
add(r[9],q[9],yy,_y,r[10],q[10]);
move(r[10],q[10],r[11],q[11]);
add(r[11],q[11],yy,_y,r[12],q[12]);
move(r[12],q[12],r[13],q[13]);
add(r[13],q[13],yy,_y,r[14],q[14]);
move(r[14],q[14],r[15],q[15]);
add(r[15],q[15],yy,_y,r[16],q[16]);
move(r[16],q[16],r[17],q[17]);
add(r[17],q[17],yy,_y,r[18],q[18]);
move(r[18],q[18],r[19],q[19]);
add(r[19],q[19],yy,_y,r[20],q[20]);
move(r[20],q[20],r[21],q[21]);
add(r[21],q[21],yy,_y,r[22],q[22]);
move(r[22],q[22],r[23],q[23]);
add(r[23],q[23],yy,_y,r[24],q[24]);
move(r[24],q[24],r[25],q[25]);
add(r[25],q[25],yy,_y,r[26],q[26]);
move(r[26],q[26],r[27],q[27]);
add(r[27],q[27],yy,_y,r[28],q[28]);
move(r[28],q[28],r[29],q[29]);
cut(q[29],r[29],quotient,remainder);
endmodule
module add #(parameter N = 16)(
input [N:0] r_in,
input [N-1:0] q_in,
input [N:0] yy,_y,
output [N:0] r_out,
output [N-1:0] q_out);
wire [N:0] ry,r_y;
assign ry = r_in + yy;
assign r_y = r_in + _y;
assign r_out = (q_in[1]==1) ? r_y : ry;
wire [N-1:0] q;
assign q = {q_in[N-1:1],1'b1};
assign q_out = (r_out[N]==yy[N]) ? q : q_in;
endmodule
module move #(parameter N = 16)(
input [N:0] r_in,
input [N-1:0] q_in,
output [N:0] r_out,
output [N-1:0] q_out);
assign r_out = {r_in[N-1:0],1'b0};
assign q_out = {q_in[N-2:0],1'b0};
endmodule
module cut#(parameter N = 16)(
input [N-1:0] q,
input [N:0] r,
output [N-1:0] quotient,remainder);
assign quotient = {q[N-1:1],1'b1};
assign remainder = r[N-1:0];
endmodule
(四)时序模拟图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210128212006983.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTE2MTI5NA==,size_16,color_FFFFFF,t_70#pic_center)
被除数x0.50.25-0.25-0.125除数y0.75-0.50.375-0.4375商q0.6666564941406250.666656494140625-0.6666564941406250.285736083984375正确答案0.666666666666666-0.5-0.6666666666666660.285714285714285误差0.0000101725260410.0000305175781250.0000101725260410.000021798270089
误差均小于最大误差=|2-n|=|2-15|=0.000030517578125
|