verilog有符号数的乘法

news2025/4/13 1:42:06

无符号整数的乘法

1、单周期乘法器( 无符号整数 )

        对于低速要求的乘法器,可以简单的使用 * 实现。

module    Mult
            (
                input    wire [7:0]    multiplicand    ,
                input    wire [7:0]    multipliter     ,

                output   wire [7:0]    product
            );

    assign    product = multiplicand    *    multipliter     ;

endmodule

        下面例子为按照 加性分解 的思路( 无符号整数 )

module    Mul
            (
                input    wire [7:0]    multiplicand    ,
                input    wire [7:0]    multiplier      ,

                output   wire [7:0]    product
            );

    wire [15:0]    adder0 , adder1 , adder2 ,adder3 , adder4 , adder5 , adder6 , adder7 ;

    assign    adder0    =    ( multiplier[0] == 1'b1 )?{8'd0,multiplicand }:15'b0    ;    
    assign    adder1    =    ( multiplier[1] == 1'b1 )?{7'd0,multiplicand,1'b0}:15'b0   ;  
    assign    adder2    =    ( multiplier[2] == 1'b1 )?{6'd0,multiplicand,2'b0}:15'b0    ;  
    assign    adder3    =    ( multiplier[3] == 1'b1 )?{5'd0,multiplicand,3'b0}:15'b0    ;  
    assign    adder4    =    ( multiplier[4] == 1'b1 )?{4'd0,multiplicand,4'b0}:15'b0    ;  
    assign    adder5    =    ( multiplier[5] == 1'b1 )?{3'd0,multiplicand,5'b0}:15'b0    ;  
    assign    adder6    =    ( multiplier[6] == 1'b1 )?{2'd0,multiplicand,6'b0}:15'b0    ;  
    assign    adder7    =    ( multiplier[7] == 1'b1 )?{1'd0,multiplicand,7'b0}:15'b0    ;     

    assign    product    =    adder0 + adder1 + adder2 + adder3 + adder4 + adder5 + adder6 + adder7    ;

endmodule

        高吞吐改进型( 无符号整数 )

        经常会出现高吞吐的数据处理类型,组合逻辑实现延迟较大,需要用流水线思路.

        采样流水线的乘法器,虽然不能一个clk计算完成,但是可以提高运算吞吐量

`timescale 1ns / 1ps



module mult
    (
        input   wire        clk             ,
        
        input   wire [7:0]  multiplicand    ,
        input   wire [7:0]  multiplier      ,
        
        output  wire [15:0] product
        
    );
    
    reg [15:0]      model_product   ;
    
    reg [15:0]      adder0 , adder1 , adder2 , adder3 , adder4 , adder5 , adder6 , adder7   ;
    reg [15:0]      t1a ,t1b , t1c , t1d ;
    reg [15:0]      t2a , t2b   ;
    
    always@( posedge clk )
    begin
    
        if( multiplier[0] == 1'b1 )
        begin
            adder0  <=  { 8'b0,multiplicand }   ;
        end
        else
        begin
            adder0  <=  15'b0   ;
        end
        
        if( multiplier[1] == 1'b1 )
        begin
            adder1  <=  { 7'b0,multiplicand,1'b0 }   ;
        end
        else
        begin
            adder1  <=  15'b0   ;
        end
        
        if( multiplier[2] == 1'b1 )
        begin
            adder2  <=  { 6'b0,multiplicand,2'b0 }   ;
        end
        else
        begin
            adder2  <=  15'b0   ;
        end
        
        if( multiplier[3] == 1'b1 )
        begin
            adder3  <=  { 5'b0,multiplicand,3'b0 }   ;
        end
        else
        begin
            adder3  <=  15'b0   ;
        end
        
        if( multiplier[4] == 1'b1 )
        begin
            adder4  <=  { 4'b0,multiplicand,4'b0 }   ;
        end
        else
        begin
            adder4  <=  15'b0   ;
        end
        
        if( multiplier[5] == 1'b1 )
        begin
            adder5  <=  { 3'b0,multiplicand,5'b0 }   ;
        end
        else
        begin
            adder5  <=  15'b0   ;
        end
        
        if( multiplier[6] == 1'b1 )
        begin
            adder6  <=  { 2'b0,multiplicand,6'b0 }   ;
        end
        else
        begin
            adder6  <=  15'b0   ;
        end
        
        if( multiplier[7] == 1'b1 )
        begin
            adder7  <=  { 1'b0,multiplicand,7'b0 }   ;
        end
        else
        begin
            adder7  <=  15'b0   ;
        end
        
        t1a =   adder0  +   adder1  ;
        t1b =   adder2  +   adder3  ;
        t1c =   adder4  +   adder5  ;
        t1d =   adder6  +   adder7  ;
        
        t2a =   t1a +   t1b ;
        t2b =   t1c +   t1d ;
        
        model_product   =   t2a +   t2b ;
        
    end
    
    assign product  =   model_product   ;
    
endmodule

`timescale 1ns / 1ps


module tb_mult();

    reg         clk ;
    
    reg [7:0]   multiplicand    ;
    reg [7:0]   multiplier      ;
    
    wire [15:0]     product     ;
    
    initial
    begin
        clk =   1'b0    ;
        #100
        multiplicand    =   8'd50   ;
        multiplier      =   8'd20   ;
        #100
        multiplicand    =   8'd100   ;
        multiplier      =   8'd5     ;       
        
        $finish ;
    end

    
    always #2.5 clk = ~clk  ;

    mult        mult_inst
    (
        .clk                    (clk),
                                
        .multiplicand           (multiplicand),
        .multiplier             (multiplier),
        
        .product                (product)
        
    );

endmodule

         可变系数乘法实现方式-----基于减性分解( 无符号整数 )

        实现乘法器的另一种思路是按照减性分解( 无符号整数 )

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/03/28 16:02:59
// Design Name: 
// Module Name: mult_3
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module mult_3
    (
        input   wire        clk             ,
        input   wire        rst_n           ,
        
        input   wire        enIn            ,
        input   wire [7:0]  multiplicand    ,
        input   wire [7:0]  multiplier      ,
        
        output  wire        busy            ,
        output  wire        enOut           ,
        output  wire [15:0] product
        
        
    );
    
    reg [15:0]      out_product ;
    reg             out_busy    ;
    reg             out_enOut   ;
    
    parameter   IDLE    =   0   ;
    parameter   S_CALE  =   1   ;
    
    reg         state,next_state    ;
    reg         lockMuls            ;
    reg  [15:0] mulA                ;
    reg  [9:0]  mulB                ;
    wire [1:0]  oriBits             ;
    reg         adding , shifting , subbing , ending ;
    reg [15:0]  calculator ;
    reg         out_busy    ;
    
    assign  busy    =   out_busy    ;
    assign  enOut   =   out_enOut   ;
    assign  product =   out_product ;
    
    always@( posedge clk )
    begin
        if( rst_n == 1'b0 )
        begin
            state   <=  IDLE    ;
            mulA    <=  15'd0   ;
            mulB    <=  10'd0   ;
            calculator  <=  16'd0   ;
            out_enOut   <=  1'b0    ;
            out_product <=  16'd0   ;
        end
        else
        begin
            state   <=  next_state  ;
            //mulA mulB
            if( lockMuls == 1'b1 )
            begin
                mulA    <=  { 8'b0,multiplicand }   ;
                mulB    <=  { 1'b0,multiplier,1'b0 }    ;  
            end
            else if( shifting == 1'b1 )
            begin
                mulA    <=  { mulA[14:0],1'b0 } ;
                mulB    <=  { 1'b0,mulB[9:1] }  ;
            end
            //calculator
            if( lockMuls == 1'b1 )
            begin
                calculator <=  16'b0   ;
            end
            else if( adding == 1'b1 )
            begin
                calculator  <=  calculator + mulA   ;
            end
            else if( subbing == 1'b1 )
            begin
                calculator  <=  calculator - mulA   ;               
            end
            //out_enOut
            out_enOut   <=  ending  ;
            //out_product
            if( ending == 1'b1 )
            begin
                out_product <=  calculator  ;
            end
        end
    end
    
    assign  oriBits =   mulB[1:0]   ;
    
    always@( state,enIn,oriBits,mulB )
    begin
        out_busy <=  1'b0    ;
        lockMuls <=  1'b0    ;
        adding   <=  1'b0    ;
        shifting <=  1'b0    ;
        subbing  <=  1'b0    ;
        ending   <=  1'b0    ;  
        
        case( state )
            IDLE    :
                begin
                    if( enIn == 1'b1 )
                    begin
                        next_state  <=  S_CALE  ;
                        lockMuls    <=  1'b1    ;
                    end
                    else
                    begin
                        next_state  <=  IDLE  ;                    
                    end
                end
            S_CALE  :
                begin
                    out_busy    <=  1'b1    ;
                    shifting    <=  1'b1    ;
                    
                    case( oriBits )
                        2'b01   :
                            begin
                                adding  <= 1'b1  ;
                            end
                        2'b10   :
                            begin
                                subbing <= 1'b1  ;
                            end
                    endcase
                    if( mulB == 10'b0 )
                    begin
                        ending  <=   1'b1    ;
                        next_state  <=  IDLE   ; 
                    end
                    else
                    begin
                        next_state  <=   S_CALE  ;
                    end  
                end
            default :
                begin
                    next_state  <=  IDLE    ;
                end
        endcase
    end  
endmodule
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/03/28 15:37:12
// Design Name: 
// Module Name: tb_mult
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_mult();

    reg         clk ;
    reg         rst_n   ;
    reg         enIn    ;
    reg [7:0]   multiplicand    ;
    reg [7:0]   multiplier      ;
    wire        busy            ;
    wire        enOut           ;
    wire [15:0]     product     ;
    
    initial
    begin
      clk   =   1'b0    ;
      rst_n =   1'b0    ;
      enIn  =   1'b0    ;
      
      multiplicand  =   8'd1000    ;
      multiplier    =   8'd20      ;
      
      #50
      rst_n =   1'b1    ;
      enIn  =   1'b1    ;      
      
      
    end

    
    always #2.5 clk = ~clk  ;

    mult_3  mult_3_inst
    (
        .clk                        (clk)      ,
        .rst_n                      (rst_n)      ,
                                          
        .enIn                       (enIn)      ,
        .multiplicand               (multiplicand)      ,
        .multiplier                 (multiplier)      ,
                                         
        .busy                       (busy)      ,
        .enOut                      (enOut)      ,
        .product                    (product)
    );

endmodule

  按照减性分解的改进( 无符号整数 )

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/04/08 17:13:19
// Design Name: 
// Module Name: mult_3B
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module mult_3B
    (
    // clk and rst_
        input   wire        sys_clk         ,
        input   wire        sys_rst_n       ,
    // input multipilicand and multipliter
        input   wire [7:0]  multiplicand   ,
        input   wire [7:0]  multipliter     ,
        input   wire        enIn            ,
    // output product
        output  wire        busy            ,
        output  wire        enOut           ,
        output  wire [15:0] product  
    );
    
    localparam  IDLE    =   1'b0    ;
    localparam  S_CALE  =   1'b1    ;
    
    reg         current_state       ;
    reg         next_state          ;
    
    reg         lockMuls            ;
    reg  [15:0] mulA                ;
    reg  [10:0] mulB                ;
    
    wire [2:0]  oriBits             ;
    
    reg         adding1 , adding2 ,shifting , subbing1 , subbing2 , ending ;
    reg [15:0]  calculator          ;
    
    reg         out_busy             ;
    reg         out_enOut            ;
    reg [15:0]  out_product          ;
    
    always@( posedge sys_clk )
    begin
        if( sys_rst_n == 1'b0 )
        begin
            current_state   <=  IDLE    ;
            mulA            <=  16'b0   ;
            mulB            <=  11'b0   ;
            calculator      <=  16'b0   ;
            out_enOut       <=  1'b0    ;
            out_product     <=  16'd0   ;
        end
        else
        begin
            current_state   <=  next_state  ;
            // mulA mulB
            if( lockMuls == 1'b1 )
            begin
                mulA    <=  { 8'b0,multiplicand }       ;
                mulB    <=  { 2'b0,multiplicand,1'b0 }  ;
            end
            else if( shifting == 1'b1 )
            begin
                mulA    <=  { mulA[13:0],2'b0 } ;
                mulB    <=  { 2'b0,mulB[10:2] } ;
            end
            // calculator
            if( lockMuls == 1'b1 )
            begin
                calculator  <=  16'd0   ;
            end
            else if( adding1 == 1'b1 )
            begin
                calculator  <=  calculator + mulA   ;
            end
            else if( adding2 == 1'b1 )
            begin
               calculator  <=  calculator + (mulA<<1)   ; 
            end
            else if( subbing1 == 1'b1 )
            begin
                calculator  <=  calculator - mulA   ;
            end
            else if( subbing2 == 1'b1 )
            begin
                calculator  <=  calculator - (mulA<<1)   ;
            end
            
            out_enOut   <=  ending  ;
            // out_product
            if( ending == 1'b1 )
            begin
                out_product <=  calculator  ;
            end   
        end
    end   
    // oriBits
    assign  oriBits = mulB[2:0] ;
    
    always@( current_state,enIn,oriBits,mulB )
    begin
        out_busy    <=  1'b0    ;
        lockMuls    <=  1'b0    ;
        adding1     <=  1'b0    ;
        adding2     <=  1'b0    ;
        shifting    <=  1'b0    ;
        subbing1    <=  1'b0    ;
        subbing2    <=  1'b0    ;
        ending      <=  1'b0    ;
        
        case( current_state )
            IDLE    :
                begin
                    if( enIn == 1'b1 )
                    begin
                        next_state  <=  S_CALE  ;
                        lockMuls    <=  1'b1    ;
                    end
                    else
                    begin
                        next_state  <=  IDLE  ;
                    end
                end
            S_CALE  :
                begin
                    out_busy    <=  1'b1    ;
                    shifting    <=  1'b1    ;
                    // adding1 adding2 subbing1 subbing2 
                    case( oriBits )
                        3'b001,3'b010   :
                            begin
                                adding1 <=  1'b1    ;
                            end
                        3'b101,3'b110   :
                            begin
                                subbing1 <=  1'b1    ;
                            end
                        3'b011          :
                            begin
                                adding2 <=  1'b1    ;
                            end
                        3'b100          :
                            begin
                                subbing2 <=  1'b1    ;
                            end
                        default         :
                            begin
                            end
                    endcase
                    
                    if( mulB == 11'b0 )
                    begin
                        ending  <=  1'b1    ;
                        next_state  <=  IDLE    ;
                    end
                    else
                    begin
                        next_state  <=  S_CALE  ;
                    end
                    
                end
            default :
                begin
                    next_state  <=  IDLE    ;
                end
        endcase
        
    end
    
    assign  busy    =   out_busy    ;
    assign  enOut   =   out_enOut   ;
    assign  product =   out_product ;
    
    
endmodule
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/04/08 17:59:30
// Design Name: 
// Module Name: tb_mult_3B
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_mult_3B(

    );
 
     // clk and rst_
        reg             sys_clk     ;
        reg             sys_rst_n   ;
        reg [7:0]       multiplicand;
        reg [7:0]       multipliter ;
        reg             enIn        ;
        wire            busy        ;
        wire            enOut       ;
        wire [15:0]     product     ;
        
        initial
        begin
            sys_clk         =   1'b0    ;
            sys_rst_n       =   1'b0    ;
            
            multiplicand    =   8'd0    ;
            multipliter     =   8'd0    ;
            enIn            =   1'b0    ;
            
            #100 
            sys_rst_n       =   1'b1      ;
            multiplicand    =   8'd100    ;
            multipliter     =   8'd200    ;
            enIn            =   1'b1      ;
            #10
            enIn            =   1'b0      ;  
            
            #100
            multiplicand    =   8'd10    ;
            multipliter     =   8'd20    ;
            enIn            =   1'b1      ;
            #10
            enIn            =   1'b0      ;  
            
            $finish ;         
        
        end
        
        // sys_clk
        always #5
        begin
            sys_clk = ~sys_clk  ;
        end
    
    mult_3B     mult_3B_inst
    (
        .sys_clk                (sys_clk),
        .sys_rst_n              (sys_rst_n),
        .multiplicand           (multiplicand),
        .multipliter            (multipliter),
        .enIn                   (enIn),
        .busy                   (busy),
        .enOut                  (enOut),
        .product                (product)
    );
    
endmodule

 

有符号整数的乘法

        现实中运算常常涉及到符号位(有符号整数)

1、积的宽度讨论

        宽度为 M 和 N 的两个数相乘,结果为 M+N-1 位。

2、基于无符号乘法器的原码乘法器

        原码乘法器

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/04/09 14:59:08
// Design Name: 
// Module Name: mults_4A
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module mults_4A
    (
    //clk and rst_n
        input   wire        sys_clk         ,
        input   wire        sys_rst_n       ,
    //mulu figure
        input   wire [7:0]  multiplicand    ,
        input   wire [7:0]  multiplier      ,
    //product
        output  wire [14:0] product
    );
    
    wire        signOfMulA , signOfMulB ;
    wire [6:0]  absMulA , absMulB   ;
    wire        signOfPro           ;
    wire [13:0] absPro              ;

    
    assign  signOfMulA  =   multiplicand[7] ;
    assign  signOfMulB  =   multiplier[7]   ;
    
    assign  absMulA     =   multiplicand[6:0]   ;
    assign  absMulB     =   multiplier[6:0]     ;
    
    assign  signOfPro   =   signOfMulA ^ signOfMulB ;
    assign  absPro      =   absMulA * absMulB   ;
    

    assign  product     =   { signOfPro,absPro }    ;
    
endmodule
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/04/09 15:08:25
// Design Name: 
// Module Name: tb_mults_4A
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_mults_4A();

        reg                     sys_clk         ;
        reg                     sys_rst_n       ;
        reg  [7:0]              multiplicand    ;
        reg  [7:0]              multiplier      ;
        wire [14:0]             product         ;

    initial
    begin
        sys_clk         =   1'b0            ;
        sys_rst_n       =   1'b0            ;   
        multiplicand    =   8'b0000_0000    ;
        multiplier      =   8'b0000_0000    ;
        

        sys_rst_n       =   1'b1            ;
        multiplicand    =   8'b0000_0011    ;
        multiplier      =   8'b0000_0100    ;
        #1000
        multiplicand    =   8'b1000_0011    ;
        multiplier      =   8'b0000_0100    ;
        #1000
        $finish;
        
    end
    always #5 sys_clk = ~sys_clk    ;

    mults_4A        mults_4A_inst
    (
        .sys_clk                (sys_clk),
        .sys_rst_n              (sys_rst_n),
        .multiplicand           (multiplicand),
        .multiplier             (multiplier),
        .product                (product)
    );

endmodule

 

3、基于无符号乘法器的补码乘法器

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/04/09 16:19:46
// Design Name: 
// Module Name: mults_4B
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module mults_4B
    (
        input   wire [7:0]  multiplicand        ,
        input   wire [7:0]  multiplier          ,
        
        output  wire [14:0] product
    );
    
    wire [1:0]      signs               ;
    wire [15:0]     modifyA , modifyB   ;
    wire [15:0]     unsignedProduct     ;
    reg  [15:0]     finalProduct        ;
    
    
    assign  signs   =   { multiplicand[7],multiplier[7] }   ;
    assign  modifyA =   { multiplicand,8'b0 }   ;
    assign  modifyB =   { multiplier,8'b0 } ;
    assign  unsignedProduct =   multiplicand * multiplier   ;
    assign  product =  finalProduct[14:0] ; 
    
    always@( signs , modifyA , modifyB , unsignedProduct )
    begin
        case( signs )
            2'b00   :
                begin
                    finalProduct    =   unsignedProduct ;
                end
            2'b01   :
                begin
                    finalProduct    =   unsignedProduct - modifyA ;
                end
            2'b10   :
                begin
                    finalProduct    =   unsignedProduct - modifyB ;
                end
            2'b11   :
                begin
                    finalProduct    =   unsignedProduct - modifyA - modifyB ;
                end
            default :
                begin
                    finalProduct    <=  16'b0   ;
                end
        endcase
    end
    
endmodule
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/04/09 16:37:34
// Design Name: 
// Module Name: tb_mults_4B
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_mults_4B();

        reg  [7:0]  multiplicand       ; 
        reg  [7:0]  multiplier         ;
        wire [14:0] product            ;
        
    initial
    begin
        multiplicand    =   8'd0    ;
        multiplier      =   8'd0    ;    
        #10
        $display(" simulink start: ")   ;
        multiplicand    =   8'd2    ;
        multiplier      =   8'd40   ;
        #1000
        multiplicand    =   -8'd2   ;
        multiplier      =   8'd40   ;
        #1000
        $display(" simulink end ")   ;       
        $finish ;
        
    end

    mults_4B       mults_4B_inst     
    (
        .multiplicand               (multiplicand)  ,
        .multiplier                 (multiplier)  ,
        .product                    (product)
    );
    
endmodule

 

4、补码乘法之加性分解乘法器

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/04/09 17:05:44
// Design Name: 
// Module Name: mults_5
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module mults_5
    (
    // clk and rst_n
        input   wire        sys_clk         ,
        input   wire        sys_rst_n       ,
    // multiplicand multiplier
        input   wire [7:0]  multiplicand    ,
        input   wire [7:0]  multiplier      ,
        input   wire        enIn            ,
    // product enOut
        output  wire        enOut           ,
        output  wire        busy            ,
        output  wire [15:0] product     
    );
    
    reg [15:0]      out_product ;
    reg             out_busy    ;
    reg             out_enOut   ;
    
    localparam  IDLE    =   1'b0    ;
    localparam  S_CALC  =   1'b1    ;
    
    reg         current_state , next_state  ;
    reg         lockMuls    ;
    reg [15:0]  mulA    ;
    reg         signOfMulB  ;
    reg [7:0]   mulB    ;
    reg         adding , shifting , ending ;
    reg [15:0]  accumulator ;
    
    always@( posedge sys_clk )
    begin
        if( sys_rst_n == 1'b0 )
        begin
            current_state   <=  IDLE    ;
            mulA            <=  16'b0   ;
            signOfMulB      <=  1'b0    ;
            mulB            <=  8'b0    ;
            accumulator     <=  16'b0   ;
            out_enOut       <=  1'b0    ;
            out_product     <=  16'b0   ;
        end
        else
        begin
            current_state  <=  next_state  ;
            // mulA mulB
            if( lockMuls == 1'b1 )
            begin
                mulA        <=  { {8{multiplicand[7]}},multiplicand }   ;
                signOfMulB  <=  multiplicand[7] ;
                mulB        <=  { 1'b1,multiplier[6:0] }    ;
            end
            else if( shifting == 1'b1 )
            begin
                mulA    <=  { mulA[14:0],1'b0 } ;
                mulB    <=  { 1'b0,mulB[7:1] }  ;
            end
            // accumulator
            if( lockMuls == 1'b1 )
            begin
                accumulator <=  16'b0   ;
            end
            else if( adding == 1'b1 )
            begin
                accumulator <=  accumulator + mulA  ;
            end
            //out_enOut
            out_enOut   <=  ending  ;
            //out_product
            if( ending == 1'b1 )
            begin
                if( signOfMulB == 1'b0 )
                begin
                    out_product <=  accumulator ;
                end
                else
                begin
                    out_product <=  accumulator - mulA  ;
                end
            end 
        end
    end
    
    always@( current_state , enIn , mulB )
    begin
        out_busy    <=  1'b0    ;
        lockMuls    <=  1'b0    ;
        adding      <=  1'b0    ;
        shifting    <=  1'b0    ;
        ending      <=  1'b0    ;
        
        case( current_state )
            IDLE    :
                begin
                    if( enIn == 1'b1 )
                    begin
                        next_state  <=  S_CALC  ;
                        lockMuls    <=  1'b1    ;
                    end
                    else
                    begin
                        next_state  <=  IDLE    ;
                    end
                end
            S_CALC  :
                begin
                    out_busy    <=  1'b1    ;
                    shifting    <=  1'b1    ;
                    adding      <=  mulB[0] ;
                    if( mulB == 8'b1 )
                    begin
                        ending      <=  1'b1    ;
                        next_state  <=  IDLE    ;
                    end
                    else
                    begin
                        next_state  <=  S_CALC  ;
                    end
                end
            default :
                begin
                    next_state  <=  IDLE    ;
                end
        endcase
        
    end
       
    assign  product =   out_product ;
    assign  busy    =   out_busy    ;
    assign  enOut   =   out_enOut   ;
    
endmodule
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/04/09 17:40:06
// Design Name: 
// Module Name: tb_mults_5
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_mults_5();

        reg         sys_clk         ;
        reg         sys_rst_n       ;
        reg  [7:0]  multiplicand    ;
        reg  [7:0]  multiplier      ;
        reg         enIn            ;
        wire        enOut           ;
        wire        busy            ;
        wire [15:0] product         ;
    
    initial
    begin
        sys_clk         =   1'b0    ;
        sys_rst_n       =   1'b0    ;
        multiplicand    =   8'b0    ;
        multiplier      =   8'b0    ;
        enIn            =   1'b0    ;
        #100
        sys_rst_n       =   1'b1    ;
        
        multiplicand    =   8'd20   ;    
        multiplier      =   8'd40   ;
        enIn            =   1'b1    ;
        #10
        enIn            =   1'b0    ;
        #1000
        
        multiplicand    =   8'd40   ;    
        multiplier      =   8'd80   ;
        enIn            =   1'b1    ;
        #10
        enIn            =   1'b0    ;
        #1000
        
        multiplicand    =   -8'd20  ;    
        multiplier      =   8'd40   ;
        enIn            =   1'b1    ;
        #10
        enIn            =   1'b0    ;
        #1000
        
        multiplicand    =   -8'd40  ;    
        multiplier      =   8'd80   ;
        enIn            =   1'b1    ;
        #10
        enIn            =   1'b0    ;
        #1000
        
        $finish ;
        
    end    
        
    always #5 sys_clk = ~sys_clk    ;

    mults_5     mults_5_inst
    (
        .sys_clk                (sys_clk),
        .sys_rst_n              (sys_rst_n),
        .multiplicand           (multiplicand),
        .multiplier             (multiplier),
        .enIn                   (enIn),
        .enOut                  (enOut),
        .busy                   (busy),
        .product                (product)
    );

endmodule

 测试发现,只能用于无符号乘,负数乘法错误,正数乘法正确

9、补码乘法之BOOTH乘法器

10、利用特殊资源实现整数乘法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2333489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DevDocs:抓取并整理技术文档的MCP服务

GitHub&#xff1a;https://github.com/cyberagiinc/DevDocs 更多AI开源软件&#xff1a;发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI DevDocs 是一个完全免费的开源工具&#xff0c;由 CyberAGI 团队开发&#xff0c;托管在 GitHub 上。它专为程序员和软件开发…

第十四届蓝桥杯大赛软件赛国赛Python大学B组题解

文章目录 弹珠堆放划分偶串交易账本背包问题翻转最大阶梯最长回文前后缀贸易航线困局 弹珠堆放 递推式 a i a i − 1 i a_ia_{i-1}i ai​ai−1​i&#xff0c; n 20230610 n20230610 n20230610非常小&#xff0c;直接模拟 答案等于 494 494 494 划分 因为总和为 1 e 6 1e6…

折叠屏手机:技术进步了,柔性OLED面板测试技术需求跟上了吗?

全球智能手机市场陷入创新焦虑&#xff0c;折叠屏手机被寄予厚望&#xff0c;2023 年出货量同比增长 62%。但在供应链技术狂欢背后&#xff0c;存在诸多问题。消费端数据显示&#xff0c;用户使用频率低&#xff0c;定价策略反常。产业链重构虽让部分企业获利&#xff0c;却推高…

30天学Java第九天——线程

并行与并发的区别 并行是多核 CPU 上的多任务处理&#xff0c;多个任务在同一时间真正的同时执行并发是单核 CPU 上的多任务处理&#xff0c;多个任务在同一时间段内交替执行&#xff0c;通过时间片轮转实现交替执行&#xff0c;用于解决 IO 密集型任务的瓶颈 线程的创建方式…

自行搭建一个Git仓库托管平台

1.安装Git sudo apt install git 2.Git本地仓库创建&#xff08;自己选择一个文件夹&#xff09; git init 这里我在 /home/test 下面初始化了代码仓库 1. 首先在仓库中新建一个txt文件&#xff0c;并输入一些内容 2. 将文件添加到仓库 git add test.txt 执行之后没有任何输…

LeeCode 409.最长回文串

给定一个包含大写字母和小写字母的字符串 s &#xff0c;返回 通过这些字母构造成的 最长的 回文串 的长度。 在构造过程中&#xff0c;请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串。 示例 1: 输入:s "abccccdd" 输出:7 解释: 我们可以构造的…

【前端分享】JavaScript异步编程详解!

JavaScript 的异步编程是其核心特性之一&#xff0c;主要用于处理非阻塞操作&#xff08;如网络请求、文件读写、定时任务等&#xff09;。由于 JavaScript 是单线程的&#xff0c;异步机制可以避免代码阻塞&#xff0c;提高性能和用户体验。以下是 JavaScript 异步编程的核心概…

工厂模式(简单工厂,工厂方法,抽象工厂)

工厂模式 工厂模式是java中最常用的设计模式&#xff0c;主要是用来完成对象的创建&#xff0c;使得对象创建过程和对象使用过程分离。 简单来说是取消对象创建者和使用者的耦合&#xff0c;简化new 对象的创建。 优势 &#xff1a;对象的属性创建完整。 缺点&#xff1a; 创建…

Axure RP9教程 【数据传输】(页面值传递)| 作用域 :全局变量、局部变量

文章目录 引言作用域:全局变量作用域>局部变量作用域I 基于全局变量实现一个简单的登陆操作设置变量值的交互动作打开链接的交互动作接收并显示变量值注意点see also共享原型引言 全局变量在交互效果作用是页面值传递 作用域:全局变量作用域>局部变量作用域 全局变量…

IBM Rational Software Architect安装感受及使用初体验

1 安装感受 最近准备用UML 2.0绘制模型图。在读UML创始人之一Grady Booch写的书《Object-Oriented Analysis and Design with Applications》&#xff08;第3版&#xff09;1时&#xff0c;发现书中用的UML工具之一为IBM Rational Software Architect&#xff08;RSA&#xff…

VRRP学习

虚拟路由器冗余技术【三层技术】&#xff1a;网关冗余VRRP设计了VRRP组的概念&#xff0c;在一个 VRRP 组中&#xff0c;多台路由器共同构成一个虚拟路由器。这个虚拟路由器拥有一个虚拟 IP 地址【VRRP-ID默认是8位二进制&#xff0c;范围是0~255&#xff0c;用以标识和区别不同…

GPT-5、o3和o4-mini即将到来

原计划有所变更: 关于我们应有何期待的一些零散想法。 深度研究(Deep Research)确实强大但成本高昂且速度较慢(当前使用o3模型)。即将推出的o4-mini在性能上可能与o3相近,但将突破这些限制,让全球用户——甚至免费用户(尽管会有速率限制)——都能用上世界顶级AI研究助…

C#MVC项目引用Swagger的详细步骤

目录 一、安装Swagger依赖包二、配置Swagger服务三、启用XML注释四、调整启动配置五、验证与访问常见问题解决 以下是基于ASP.NET Core项目集成Swagger的详细步骤&#xff08;已适配当前项目结构&#xff09;&#xff1a; 一、安装Swagger依赖包 通过NuGet安装 右键点击项目…

golang 对象池sync.Pool

Golang中的sync.Pool是什么&#xff1f; sync.Pool 是 Go 标准库中提供的一个对象池&#xff08;Object Pool&#xff09;实现&#xff0c;用于缓存和复用临时对象&#xff0c;以减少内存分配和垃圾回收&#xff08;GC&#xff09;的压力。它的主要特点是&#xff1a; 临时对…

聚焦AI与大模型创新,紫光云如何引领云计算行业快速演进?

【全球云观察 &#xff5c; 科技热点关注】 随着近年来AI与大模型的兴起&#xff0c;云计算行业正在发生着一场大变局。 “在2025年春节期间&#xff0c;DeepSeek两周火爆全球&#xff0c;如何进行私域部署成了企业关心的问题。”紫光云公司总裁王燕平强调指出&#xff0c;AI与…

解决前后端时区不一致问题

前后端时区不一致导致&#xff1a; 》数据不显示在前端 》页面显示时间有误 》一些对时间有要求的方法&#xff0c;无法正确执行&#xff0c;出现null值&#xff0c;加上我们对null值有判断/注解&#xff0c;程序就会报错中断&#xff0c;以为是业务逻辑问题&#xff0c;其实…

STL之序列式容器(Vector/Deque/List)

序列式容器 序列式容器包括&#xff1a;静态数组 array 、动态数组 vector 、双端队列 deque 、单链表 forward_ list 、双链表 list 。这五个容器中&#xff0c;我们需要讲解三个 vector 、 deque 、 list 的使 用&#xff0c;包括&#xff1a;初始化、遍历、尾部插入与删除、…

小试牛刀-抽奖程序

编写抽奖程序 需求&#xff1a;设计一个抽奖程序&#xff0c;点击抽奖按钮随机抽取一个名字作为中奖者 目标&#xff1a;了解项目结构&#xff0c;简单UI布局&#xff0c;属性方法、事件方法&#xff0c;程序运行及调试 界面原型 ​ 待抽奖&#xff1a; 点击抽奖按钮&#x…

从 MySQL 切换到国产 YashanDB 数据库时,需要在数据库字段和应用连接方面进行适配 ,使用总结

YashanDB | 崖山数据库系统 - 崖山科技官网崖山数据库系统YashanDB是深圳计算科学研究院完全自主研发设计的新型数据库系统&#xff0c;融入原创理论&#xff0c;支持单机/主备、共享集群、分布式等多种部署方式&#xff0c;覆盖OLTP/HTAP/OLAP交易和分析混合负载场景&#xff…

【学习笔记】头文件中定义函数出现重复定义报错

目录 错误复现原因解决方案inlinestatic 扩展参考 错误复现 现在有一个头文件 duplicate_define.h 和两个源文件 duplicate_define_1.cpp 和 duplicate_define_2.cpp。 两个源文件都引入了头文件 duplicate_define.h&#xff0c;且在各自的函数中调用了定义在头文件中的全局函…