数字电路之乘法器 (一)

目录

十进制乘法

初级二进制乘法

无符号数乘法

有符号数乘法


十进制乘法

[3:0] a-multiplicand

[3:0] x-multiplier

x= 10^3 * x3 + 10^2 * x2 +10^1 * x1 +10^0 * x0

a * x = 10^3 * x3 * a + 10^2 * x2 * a +10^1 * x1 * a+10^0 * x0 * a

这种做法就是小学学习的阵列乘法

初级二进制乘法

无符号数乘法

类似于无符号十进制乘法。在计算x_j*a*2^j时,我们不需要用一个乘法器。x的每一位要么是0,要么是1,如果是1,那么在计算加法的时候,就加上这一项,如果是0,则舍弃这一项。a*2^j,可以用移位来实现。

用Verilog实现以上过程,我们需要一个8bit的寄存器存储product的结果,和一个8bit位宽的加法器。

module basic_multi_u #(
    parameter DW0 = 10,
              DW1 = 10
)(

    input   wire clk,
    input   wire rst_n,

    input   wire           start,
    input   wire [DW0-1:0] din0,
    input   wire [DW1-1:0] din1,

    output  reg               prod_end,
    output  reg  [DW0+DW1-1:0] prod
);

localparam CNTW= $clog2(DW1);

reg [CNTW-1:0] mult_cnt;
wire busy;
wire [DW0+DW1-1:0] din0_lsft; // din1 left shift

assign busy = start || (mult_cnt != 0);

always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        mult_cnt <= 0;
    else if (mult_cnt == (DW1-1))
        mult_cnt <= 0;
    else if(busy)
        mult_cnt <= mult_cnt + 1'b1;
end

assign din0_lsft = din1[mult_cnt] ? din0 << mult_cnt : 0;

always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        prod <= 0;
    else if(prod_end)
        prod <= 0;
    else if (busy) begin
        prod <= prod + din0_lsft;
    end
end

always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        prod_end <= 1'b0;
    else if(mult_cnt == (DW1-1))
        prod_end <= 1'b1;
    else 
        prod_end <= 1'b0;
end


endmodule

有符号数乘法

乘数和被乘数最高位为符号位。

与无符号数乘法的区别有两个地方,一是x0a2^0等的每一项是有符号数,在做加法时需要手动扩符号位,或者转成signed类型。二是在计算x3a2^3时,由于x3是符号位,因此,权重是-3,这一项修改成x3a2^(-3)。

为了便于计算,x3a2^(-3)->x3(-a)2^3。-a是a的补码,由a取反加1得到。

下图是一个(-5)*(-3)的例子

用Verilog实现以上过程,同样需要一个8bit的寄存器存储product的结果,和一个8bit位宽的加法器。

module basic_multi_s #(
    parameter DW0 = 10,
              DW1 = 10
) (
    input   wire           clk,
    input   wire           rst_n,

    input   wire           start,
    input   wire [DW0-1:0] din0,
    input   wire [DW1-1:0] din1,

    output  reg                prod_end,
    output  reg  [DW0+DW1-1:0] prod
);

localparam CNTW= $clog2(DW1);

reg [CNTW-1:0] mult_cnt;
wire busy;
wire [DW0:0] din0_temp; // din0  
wire [DW0-1:0] din0_c;
wire [DW0+DW1-1:0] din0_lsft; // din0 left shift

assign busy = start || (mult_cnt != 0);

always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        mult_cnt <= 0;
    else if (mult_cnt == (DW1-1))
        mult_cnt <= 0;
    else if(busy)
        mult_cnt <= mult_cnt + 1'b1;
end

// if MSB, din0_temp = -din0; else, din0_temp = din0;
assign din0_c = ~din0 + 1'b1;
assign din0_temp = (mult_cnt == (DW1-1)) ? {1'b0,din0_c} : {din0[DW0-1],din0};
assign din0_lsft = din1[mult_cnt] ? {{(DW1-1){din0_temp[DW0-1]}},din0_temp} << mult_cnt : 0; //din0 is a signed number

always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        prod <= 0;
    else if(prod_end)
        prod <= 0;
    else if (busy) begin
        prod <= prod + din0_lsft;
    end
end

always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        prod_end <= 1'b0;
    else if(mult_cnt == (DW1-1))
        prod_end <= 1'b1;
    else 
        prod_end <= 1'b0;
end
    
endmodule

注意:该两个Verilog示意仅用于理解基本乘法器实现原理,并非实际电路中乘法器的实现方式。

  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
乘法器是一种常见的电子元件,其基本含义是将两个数字相乘,并输出其乘积。在数字电路系统中有着广泛的应用。数字集成电路是指将多个晶体管、二极管、电阻等电子元件集成在一起,形成一个完整的电路系统。数字集成电路中的乘法器是一种重要的电子元件,它可以实现精确的数字乘法运算,并且可以进一步优化数字电路系统的性能,使其具有更高的效率和可靠性。 数字集成电路中的乘法器可以分为以下几类: 1. 串行乘法器:串行乘法器是一种基本的乘法器,它通过将两个数字逐位相乘,并将结果相加得到最终的乘积。串行乘法器的优点是结构简单,但是速度较慢。 2. 并行乘法器:并行乘法器是一种高速的乘法器,它可以同时处理多个数字的乘法运算。并行乘法器的优点是速度快,但是结构较为复杂。 3. Booth乘法器:Booth乘法器是一种基于串行乘法器的改进型乘法器,它通过对乘数进行编码,从而减少了乘法器的运算次数,提高了乘法器的运算速度。 4. Wallace树乘法器:Wallace树乘法器是一种基于并行乘法器的改进型乘法器,它通过将多个部分积相加得到最终的乘积,从而提高了乘法器的运算速度。 在数字集成电路中,乘法器的设计和实现是一个复杂的过程,需要考虑多个因素,例如乘法器的精度、速度、功耗等。因此,乘法器的设计和实现需要有专业的知识和技能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值