O_定点原码二位乘法器的FPGA实现
原码乘法运算
原码乘法:参加运算的被乘数和乘数均用原码表示;运算时符号位单独处理,被乘数与乘数的绝对值相乘;所得的积也采用原码表示。
在定点机中,两个数的原码乘法运算包括:①乘积的符号处理 ②两数绝对值相乘。
为了便于证明,做以下设定:
被乘数:[x]原=xf.x1x2…xn
乘数: [y]原=yf.y1y2…yn
乘积: [z]原=[x]原×[y]原=[x×y]原=zf.z1z2…zn
根据“同号相乘,乘积为正;异号相乘,乘积为负”,得乘积的符号:zf=xf⊕yf
例:x=0.1101,y=0.1011 求x×y=?
解:根据二进制乘法规律,可得x×y的手算过程如下:
得:x×y=0.10001111
从例中可以看出,两个4位数相乘得8位乘积,共4个部分积需8位加法器相加。
由此可见,两个n位数相乘,得2n位乘积,共有n个部分积。
① 2n位乘积需用2n位加法器进行相加运算。
②两个n位数相乘,需n个寄存器保存n个部分积。
显然所需硬件太多,不适合用硬件去实现,为此需对算法加以改进。
一位原码乘法运算
设参加运算的被乘数为 x=0.x1x2…x4,乘数为 y=0.y1y2…y4,有:
x×y=x×0.y1y2y3y4
=x×(2-1y1+2-2y2+2-3y3+2-4y4)
=2-1xy1+2-2xy2+2-3xy3+2-4xy4
=2-1{2-3xy4+2-2xy3+2-1xy2+xy1}
=2-1{2-1[2-2xy4+2-1xy3+xy2]+xy1}
=2-1{2-1[2-1(2-1xy4+xy3)+xy2]+xy1}
=2-1{2-1[2-1(2-1(0+xy4)+xy3)+xy2]+xy1}
根据上式,可将乘法转换为一系列加法与移位操作。将递推公式推广到n位,得:
Z0=0 (初始部分积为0)
Z1=2-1(Z0+xyn)
Z2=2-1(Z1+xyn-1)
…
Zn=2-1(Zn-1+xy1)=x×y
其中,Z0、Z1、…、Zn称为部分积。
根据上述推导过程可知,可以把乘法转换为一系列加法与移位操作。
原码一位乘法的算法
① 积的符号单独按两操作数的符号模2加(异或)得到。用被乘数和乘数的数值部分进行运算。
② 以乘数的最低位作为乘法判别位,若判别位为1,则在前次部分积(初始部分积为0)上加上被乘数,然后连同乘数一起右移一位;若判别位为0,则在前次部分积上加0(或不加),然后连同乘数一起右移一位。
③ 重复第②步直到运算n次为止。(n为乘数数值部分的长度)
④ 将乘积的符号与数值部分结合,即可得到最终结果。
例:设 x=0.1101,y=-0.1011,根据原码一位乘法的算法计算x×y=?
解:[x]原=0.1101,[y]原=1.1011,乘积 [z]原=[x×y]原
① 符号位单独处理得 zf=0⊕1=1
② 将被乘数和乘数的绝对值的数值部分相乘。
[|x|]原=0.1101 [|y|]原=0.1011
数值部分为4位,共需运算4次。
得:|x×y|=0.10001111
加上符号部分得:[x×y]原=1.10001111
即:x×y=-0.10001111
原码一位乘法算法的硬件逻辑电路

A寄存器:存放部分积高位部分,初始为0
B寄存器:存放被乘数
C寄存器:存放乘数和部分积低位部分,初始为乘数
CR:计数器。用于记录乘法次数运算初始时,CR=0,每进行一次运算CR+1,当计数到CR=n时,将C<sub>T</sub>清0,结束运算。
Cj:进位位
CT:乘法控制触发器,
CT=1,允许发出移位脉冲,进行乘法运算
CT=0,不允许发出移位脉冲,停止乘法运算寄存器C通常是具有左移、右移功能的移位寄存器。寄存器A一般不具有移位功能,部分积的移位采用斜送的方法实现移位。
具有左、右斜送和直接传送的移位器
Fi:加法器的i位输出
A←2F:左移控制信号
A←1/2F:右移控制信号
A←F:直接传送控制信号
原码一位乘法的运算流程

代码
7位 | 17位 | 33位 | 激励块
7位
module BFI7(output [12:0]result,
inout [6:0]x,
inout [6:0]y,
input clk);
wire [8:0]xtmp;
assign xtmp[6:0]=x;
assign xtmp[7]=x[6];
assign xtmp[8]=x[6];
wire [8:0]prtmp[3:0];
wire [5:0]ytmp[3:0];
wire ctmp[3:0];
wire [14:0]restmp;
assign x=7'b0_10_0111;
assign y=7'b0_10_0111;
assign prtmp[0]=0;
assign ytmp[0]=y[5:0];
assign ctmp[0]=0;
cho c1(prtmp[1],ytmp[1],ctmp[1],ctmp[0],prtmp[0],xtmp,ytmp[0],clk);
cho c2(prtmp[2],ytmp[2],ctmp[2],ctmp[1],prtmp[1],xtmp,ytmp[1],clk);
cho c3(prtmp[3],ytmp[3],ctmp[3],ctmp[2],prtmp[2],xtmp,ytmp[2],clk);
resch rc(result,ytmp[3],prtmp[3],ctmp[3],clk);
endmodule
module resch(output reg [12:0]result,
input [5:0]yt,
input [8:0]prt,
input ct,
input clk);
reg [14:0]restmp;
always @(posedge clk)
begin
restmp[5:0]=yt;
restmp[14:6]=prt;
result=restmp[12:0];
end
endmodule
module cho(output reg [8:0]prout,
output reg [5:0]yout,
output reg cout,
input cin,
input [8:0]prin,
input [8:0]x,
input [5:0]yin,
input clk);
reg [8:0]prtmp;
reg [14:0]pry;
reg [8:0]opx;
always @(posedge clk)
begin
opx[0]=~x[0];
opx[1]=~x[1];
opx[2]=~x[2];
opx[3]=~x[3];
opx[4]=~x[4];
opx[5]=~x[5];
opx=opx+6'b00_0001;
opx[6]=~x[6];
opx[7]=~x[6];
opx[8]=~x[6];
if(!yin[1])
begin
if(!yin[0])
begin
if(!cin)
begin
prtmp=prin; //suanfa
cout=0;
pry[5:0]=yin;
pry[14:6]=prtmp;
pry=pry>>2;
pry[14]=cout;
pry[13]=cout;
yout=pry[5:0];
prout=pry[14:6];
end
if(cin)
begin
prtmp=prin+x;
cout=0;
pry[5:0]=yin;
pry[14:6]=prtmp;
pry=pry>>2;
pry[14]=cout;
pry[13]=cout;
yout=pry[5:0];
prout=pry[14:6];
end
end
if(yin[0])
begin
if(!cin)
begin
prtmp=prin+x;
cout=0;
pry[5:0]=yin;
pry[14:6]=prtmp;
pry=pry>>2;
pry[14]=cout;
pry[13]=cout;
yout=pry[5:0];
prout=pry[14:6];
end
if(cin)
begin
prtmp=prin+(2*x);
cout=0;
pry[5:0]=yin;
pry[14:6]=prtmp;
pry=pry>>2;
pry[14]=cout;
pry[13]=cout;
yout=pry[5:0];
prout=pry[14:6];
end
end
end
if(yin[1])
begin
if(!yin[0])
begin
if(!cin)
begin
prtmp=prin+(2*x);
cout=0;
pry[5:0]=yin;
pry[14:6]=prtmp;
pry=pry>>2;
pry[14]=cout;
pry[13]=cout;
yout=pry[5:0];
prout=pry[14:6];
end
if(cin)
begin
prtmp=prin+opx;
cout=1;
pry[5:0]=yin;
pry[14:6]=prtmp;
pry=pry>>2;
pry[14]=cout;
pry[13]=cout;
yout=pry[5:0];
prout=pry[14:6];
end
end
if(yin[0])
begin
if(!cin)
begin
prtmp=prin+opx;
cout=1;
pry[5:0]=yin;
pry[14:6]=prtmp;
pry=pry>>2;
pry[14]=cout;
pry[13]=cout;
yout=pry[5:0];
prout=pry[14:6];
end
if(cin)
begin
prtmp=prin;
cout=1;
pry[5:0]=yin;
pry[14:6]=prtmp;
pry=pry>>2;
pry[14]=cout;
pry[13]=cout;
yout=pry[5:0];
prout=pry[14:6];
end
end
end
end
endmodule17位
module BFI17(output [32:0]result,
inout [16:0]x,
inout [16:0]y,
input clk);
wire [18:0]xtmp;
assign xtmp[16:0]=x;
assign xtmp[17]=x[16];
assign xtmp[18]=x[16];
wire [18:0]prtmp[8:0];
wire [15:0]ytmp[8:0];
wire ctmp[8:0];
wire [34:0]restmp;
assign x=17'b0_0010_0111_0010_0111;
assign y=17'b0_0010_0111_0010_0111;
assign prtmp[0]=0;
assign ytmp[0]=y[15:0];
assign ctmp[0]=0;
cho c1(prtmp[1],ytmp[1],ctmp[1],ctmp[0],prtmp[0],xtmp,ytmp[0],clk);
cho c2(prtmp[2],ytmp[2],ctmp[2],ctmp[1],prtmp[1],xtmp,ytmp[1],clk);
cho c3(prtmp[3],ytmp[3],ctmp[3],ctmp[2],prtmp[2],xtmp,ytmp[2],clk);
cho c4(prtmp[4],ytmp[4],ctmp[4],ctmp[3],prtmp[3],xtmp,ytmp[3],clk);
cho c5(prtmp[5],ytmp[5],ctmp[5],ctmp[4],prtmp[4],xtmp,ytmp[4],clk);
cho c6(prtmp[6],ytmp[6],ctmp[6],ctmp[5],prtmp[5],xtmp,ytmp[5],clk);
cho c7(prtmp[7],ytmp[7],ctmp[7],ctmp[6],prtmp[6],xtmp,ytmp[6],clk);
cho c8(prtmp[8],ytmp[8],ctmp[8],ctmp[7],prtmp[7],xtmp,ytmp[7],clk);
resch rc(result,ytmp[8],prtmp[8],ctmp[8],clk);
endmodule
module resch(output reg [32:0]result,
input [15:0]yt,
input [18:0]prt,
input ct,
input clk);
reg [34:0]restmp;
always @(posedge clk)
begin
restmp[15:0]=yt;
restmp[34:16]=prt;
result=restmp[32:0];
end
endmodule
module cho(output reg [18:0]prout,
output reg [15:0]yout,
output reg cout,
input cin,
input [18:0]prin,
input [18:0]x,
input [15:0]yin,
input clk);
reg [18:0]prtmp;
reg [34:0]pry;
reg [18:0]opx;
always @(posedge clk)
begin
opx[0]=~x[0];
opx[1]=~x[1];
opx[2]=~x[2];
opx[3]=~x[3];
opx[4]=~x[4];
opx[5]=~x[5];
opx[6]=~x[6];
opx[7]=~x[7];
opx[8]=~x[8];
opx[9]=~x[9];
opx[10]=~x[10];
opx[11]=~x[11];
opx[12]=~x[12];
opx[13]=~x[13];
opx[14]=~x[14];
opx[15]=~x[15];
opx=opx+16'b1;
opx[16]=~x[16];
opx[17]=~x[16];
opx[18]=~x[16];
if(!yin[1])
begin
if(!yin[0])
begin
if(!cin)
begin
prtmp=prin; //suanfa
cout=0;
pry[15:0]=yin;
pry[34:16]=prtmp;
pry=pry>>2;
pry[34]=cout;
pry[33]=cout;
yout=pry[15:0];
prout=pry[34:16];
end
if(cin)
begin
prtmp=prin+x;
cout=0;
pry[15:0]=yin;
pry[34:16]=prtmp;
pry=pry>>2;
pry[34]=cout;
pry[33]=cout;
yout=pry[15:0];
prout=pry[34:16];
end
end
if(yin[0])
begin
if(!cin)
begin
prtmp=prin+x;
cout=0;
pry[15:0]=yin;
pry[34:16]=prtmp;
pry=pry>>2;
pry[34]=cout;
pry[33]=cout;
yout=pry[15:0];
prout=pry[34:16];
end
if(cin)
begin
prtmp=prin+(2*x);
cout=0;
pry[15:0]=yin;
pry[34:16]=prtmp;
pry=pry>>2;
pry[34]=cout;
pry[33]=cout;
yout=pry[15:0];
prout=pry[34:16];
end
end
end
if(yin[1])
begin
if(!yin[0])
begin
if(!cin)
begin
prtmp=prin+(2*x);
cout=0;
pry[15:0]=yin;
pry[34:16]=prtmp;
pry=pry>>2;
pry[34]=cout;
pry[33]=cout;
yout=pry[15:0];
prout=pry[34:16];
end
if(cin)
begin
prtmp=prin+opx;
cout=1;
pry[15:0]=yin;
pry[34:16]=prtmp;
pry=pry>>2;
pry[34]=cout;
pry[33]=cout;
yout=pry[15:0];
prout=pry[34:16];
end
end
if(yin[0])
begin
if(!cin)
begin
prtmp=prin+opx;
cout=1;
pry[15:0]=yin;
pry[34:16]=prtmp;
pry=pry>>2;
pry[34]=cout;
pry[33]=cout;
yout=pry[15:0];
prout=pry[34:16];
end
if(cin)
begin
prtmp=prin;
cout=1;
pry[15:0]=yin;
pry[34:16]=prtmp;
pry=pry>>2;
pry[34]=cout;
pry[33]=cout;
yout=pry[15:0];
prout=pry[34:16];
end
end
end
end
endmodule33位
module BFI33(output [64:0]result,
inout [32:0]x,
inout [32:0]y,
input clk);
wire [34:0]xtmp;
assign xtmp[32:0]=x;
assign xtmp[33]=x[32];
assign xtmp[34]=x[32];
wire [34:0]prtmp[16:0];
wire [31:0]ytmp[16:0];
wire ctmp[16:0];
wire [66:0]restmp;
assign x=33'b0_0010_0111_0010_0111_0010_0111_0010_0111;
assign y=33'b0_0010_0111_0010_0111_0010_0111_0010_0111;
assign prtmp[0]=0;
assign ytmp[0]=y[31:0];
assign ctmp[0]=0;
cho c1(prtmp[1],ytmp[1],ctmp[1],ctmp[0],prtmp[0],xtmp,ytmp[0],clk);
cho c2(prtmp[2],ytmp[2],ctmp[2],ctmp[1],prtmp[1],xtmp,ytmp[1],clk);
cho c3(prtmp[3],ytmp[3],ctmp[3],ctmp[2],prtmp[2],xtmp,ytmp[2],clk);
cho c4(prtmp[4],ytmp[4],ctmp[4],ctmp[3],prtmp[3],xtmp,ytmp[3],clk);
cho c5(prtmp[5],ytmp[5],ctmp[5],ctmp[4],prtmp[4],xtmp,ytmp[4],clk);
cho c6(prtmp[6],ytmp[6],ctmp[6],ctmp[5],prtmp[5],xtmp,ytmp[5],clk);
cho c7(prtmp[7],ytmp[7],ctmp[7],ctmp[6],prtmp[6],xtmp,ytmp[6],clk);
cho c8(prtmp[8],ytmp[8],ctmp[8],ctmp[7],prtmp[7],xtmp,ytmp[7],clk);
cho c9(prtmp[9],ytmp[9],ctmp[9],ctmp[8],prtmp[8],xtmp,ytmp[8],clk);
cho c10(prtmp[10],ytmp[10],ctmp[10],ctmp[9],prtmp[9],xtmp,ytmp[9],clk);
cho c11(prtmp[11],ytmp[11],ctmp[11],ctmp[10],prtmp[10],xtmp,ytmp[10],clk);
cho c12(prtmp[12],ytmp[12],ctmp[12],ctmp[11],prtmp[11],xtmp,ytmp[11],clk);
cho c13(prtmp[13],ytmp[13],ctmp[13],ctmp[12],prtmp[12],xtmp,ytmp[12],clk);
cho c14(prtmp[14],ytmp[14],ctmp[14],ctmp[13],prtmp[13],xtmp,ytmp[13],clk);
cho c15(prtmp[15],ytmp[15],ctmp[15],ctmp[14],prtmp[14],xtmp,ytmp[14],clk);
cho c16(prtmp[16],ytmp[16],ctmp[16],ctmp[15],prtmp[15],xtmp,ytmp[15],clk);
resch rc(result,ytmp[16],prtmp[16],ctmp[16],clk);
endmodule
module resch(output reg [64:0]result,
input [31:0]yt,
input [34:0]prt,
input ct,
input clk);
reg [66:0]restmp;
always @(posedge clk)
begin
restmp[31:0]=yt;
restmp[66:32]=prt;
result=restmp[64:0];
end
endmodule
module cho(output reg [34:0]prout,
output reg [31:0]yout,
output reg cout,
input cin,
input [34:0]prin,
input [34:0]x,
input [31:0]yin,
input clk);
reg [34:0]prtmp;
reg [66:0]pry;
reg [34:0]opx;
always @(posedge clk)
begin
opx[0]=~x[0];
opx[1]=~x[1];
opx[2]=~x[2];
opx[3]=~x[3];
opx[4]=~x[4];
opx[5]=~x[5];
opx[6]=~x[6];
opx[7]=~x[7];
opx[8]=~x[8];
opx[9]=~x[9];
opx[10]=~x[10];
opx[11]=~x[11];
opx[12]=~x[12];
opx[13]=~x[13];
opx[14]=~x[14];
opx[15]=~x[15];
opx[16]=~x[16];
opx[17]=~x[17];
opx[18]=~x[18];
opx[19]=~x[19];
opx[20]=~x[20];
opx[21]=~x[21];
opx[22]=~x[22];
opx[23]=~x[23];
opx[24]=~x[24];
opx[25]=~x[25];
opx[26]=~x[26];
opx[27]=~x[27];
opx[28]=~x[28];
opx[29]=~x[29];
opx[30]=~x[30];
opx[31]=~x[31];
opx=opx+32'b1;
opx[32]=~x[32];
opx[33]=~x[32];
opx[34]=~x[32];
if(!yin[1])
begin
if(!yin[0])
begin
if(!cin)
begin
prtmp=prin; //suanfa
cout=0;
pry[31:0]=yin;
pry[66:32]=prtmp;
pry=pry>>2;
pry[66]=cout;
pry[65]=cout;
yout=pry[31:0];
prout=pry[66:32];
end
if(cin)
begin
prtmp=prin+x;
cout=0;
pry[31:0]=yin;
pry[66:32]=prtmp;
pry=pry>>2;
pry[66]=cout;
pry[65]=cout;
yout=pry[31:0];
prout=pry[66:32];
end
end
if(yin[0])
begin
if(!cin)
begin
prtmp=prin+x;
cout=0;
pry[31:0]=yin;
pry[66:32]=prtmp;
pry=pry>>2;
pry[66]=cout;
pry[65]=cout;
yout=pry[31:0];
prout=pry[66:32];
end
if(cin)
begin
prtmp=prin+(2*x);
cout=0;
pry[31:0]=yin;
pry[66:32]=prtmp;
pry=pry>>2;
pry[66]=cout;
pry[65]=cout;
yout=pry[31:0];
prout=pry[66:32];
end
end
end
if(yin[1])
begin
if(!yin[0])
begin
if(!cin)
begin
prtmp=prin+(2*x);
cout=0;
pry[31:0]=yin;
pry[66:32]=prtmp;
pry=pry>>2;
pry[66]=cout;
pry[65]=cout;
yout=pry[31:0];
prout=pry[66:32];
end
if(cin)
begin
prtmp=prin+opx;
cout=1;
pry[31:0]=yin;
pry[66:32]=prtmp;
pry=pry>>2;
pry[66]=cout;
pry[65]=cout;
yout=pry[31:0];
prout=pry[66:32];
end
end
if(yin[0])
begin
if(!cin)
begin
prtmp=prin+opx;
cout=1;
pry[31:0]=yin;
pry[66:32]=prtmp;
pry=pry>>2;
pry[66]=cout;
pry[65]=cout;
yout=pry[31:0];
prout=pry[66:32];
end
if(cin)
begin
prtmp=prin;
cout=1;
pry[31:0]=yin;
pry[66:32]=prtmp;
pry=pry>>2;
pry[66]=cout;
pry[65]=cout;
yout=pry[31:0];
prout=pry[66:32];
end
end
end
end
endmodule激励块
//6(7)Bit
`timescale 1ns/1ps
module BFI_tb;
reg clk;
wire [6:0]x;
wire [6:0]y;
wire [12:0]result;
BFI i1 (
.clk(clk),
.result(result),
.x(x),
.y(y)
);
always
#10 clk=~clk;
initial
begin
clk=0;
//x=7'b0_10_0111;
//y=7'b0_10_0111;
#200 $stop;
end
endmodule
/*
//16(17)Bit
`timescale 1ns/1ps
module BFI_tb;
reg clk;
wire [16:0]x;
wire [16:0]y;
wire [32:0]result;
BFI i1 (
.clk(clk),
.result(result),
.x(x),
.y(y)
);
always
#10 clk=~clk;
initial
begin
clk=0;
//x=7'b0_10_0111;
//y=7'b0_10_0111;
#200 $stop;
end
endmodule
//*/
/*
//32(33)Bit
`timescale 1ns/1ps
module BFI_tb;
reg clk;
wire [32:0]x;
wire [32:0]y;
wire [64:0]result;
BFI i1 (
.clk(clk),
.result(result),
.x(x),
.y(y)
);
always
#10 clk=~clk;
initial
begin
clk=0;
//x=7'b0_10_0111;
//y=7'b0_10_0111;
#2000 $stop;
end
endmodule
//*/
/*
//Test
`timescale 1ns/1ps
module BFI_tb;
reg clk;
reg [8:0]x;
reg cin;
reg [8:0]prin;
wire [8:0]prout;
wire [5:0]yout;
wire cout;
reg [5:0]yin;
cho i2(prout,yout, cout,cin,prin,x,yin,clk);
always
#10 clk=~clk;
initial
begin
clk=0;
prin=0;
x=9'b000_10_0111;
yin=6'b10_0111;
cin=0;
#40 $stop;
end
endmodule
//*/ 

评论已关闭