原码乘法运算

  原码乘法:参加运算的被乘数和乘数均用原码表示;运算时符号位单独处理,被乘数与乘数的绝对值相乘;所得的积也采用原码表示。
  在定点机中,两个数的原码乘法运算包括:①乘积的符号处理 ②两数绝对值相乘。
  为了便于证明,做以下设定:
    被乘数:[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
endmodule

17位

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
endmodule

33位

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
//*/

评论已关闭

Loading...
Fullscreen Image