verilog有符号数的乘法
无符号整数的乘法
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 / 1psmodule 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 )beginif( multiplier[0] == 1'b1 )beginadder0 <= { 8'b0,multiplicand } ;endelsebeginadder0 <= 15'b0 ;endif( multiplier[1] == 1'b1 )beginadder1 <= { 7'b0,multiplicand,1'b0 } ;endelsebeginadder1 <= 15'b0 ;endif( multiplier[2] == 1'b1 )beginadder2 <= { 6'b0,multiplicand,2'b0 } ;endelsebeginadder2 <= 15'b0 ;endif( multiplier[3] == 1'b1 )beginadder3 <= { 5'b0,multiplicand,3'b0 } ;endelsebeginadder3 <= 15'b0 ;endif( multiplier[4] == 1'b1 )beginadder4 <= { 4'b0,multiplicand,4'b0 } ;endelsebeginadder4 <= 15'b0 ;endif( multiplier[5] == 1'b1 )beginadder5 <= { 3'b0,multiplicand,5'b0 } ;endelsebeginadder5 <= 15'b0 ;endif( multiplier[6] == 1'b1 )beginadder6 <= { 2'b0,multiplicand,6'b0 } ;endelsebeginadder6 <= 15'b0 ;endif( multiplier[7] == 1'b1 )beginadder7 <= { 1'b0,multiplicand,7'b0 } ;endelsebeginadder7 <= 15'b0 ;endt1a = adder0 + adder1 ;t1b = adder2 + adder3 ;t1c = adder4 + adder5 ;t1d = adder6 + adder7 ;t2a = t1a + t1b ;t2b = t1c + t1d ;model_product = t2a + t2b ;endassign product = model_product ;endmodule
`timescale 1ns / 1psmodule tb_mult();reg clk ;reg [7:0] multiplicand ;reg [7:0] multiplier ;wire [15:0] product ;initialbeginclk = 1'b0 ;#100multiplicand = 8'd50 ;multiplier = 8'd20 ;#100multiplicand = 8'd100 ;multiplier = 8'd5 ; $finish ;endalways #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 )beginif( rst_n == 1'b0 )beginstate <= IDLE ;mulA <= 15'd0 ;mulB <= 10'd0 ;calculator <= 16'd0 ;out_enOut <= 1'b0 ;out_product <= 16'd0 ;endelsebeginstate <= next_state ;//mulA mulBif( lockMuls == 1'b1 )beginmulA <= { 8'b0,multiplicand } ;mulB <= { 1'b0,multiplier,1'b0 } ; endelse if( shifting == 1'b1 )beginmulA <= { mulA[14:0],1'b0 } ;mulB <= { 1'b0,mulB[9:1] } ;end//calculatorif( lockMuls == 1'b1 )begincalculator <= 16'b0 ;endelse if( adding == 1'b1 )begincalculator <= calculator + mulA ;endelse if( subbing == 1'b1 )begincalculator <= calculator - mulA ; end//out_enOutout_enOut <= ending ;//out_productif( ending == 1'b1 )beginout_product <= calculator ;endendendassign oriBits = mulB[1:0] ;always@( state,enIn,oriBits,mulB )beginout_busy <= 1'b0 ;lockMuls <= 1'b0 ;adding <= 1'b0 ;shifting <= 1'b0 ;subbing <= 1'b0 ;ending <= 1'b0 ; case( state )IDLE :beginif( enIn == 1'b1 )beginnext_state <= S_CALE ;lockMuls <= 1'b1 ;endelsebeginnext_state <= IDLE ; endendS_CALE :beginout_busy <= 1'b1 ;shifting <= 1'b1 ;case( oriBits )2'b01 :beginadding <= 1'b1 ;end2'b10 :beginsubbing <= 1'b1 ;endendcaseif( mulB == 10'b0 )beginending <= 1'b1 ;next_state <= IDLE ; endelsebeginnext_state <= S_CALE ;end enddefault :beginnext_state <= IDLE ;endendcaseend
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 ;initialbeginclk = 1'b0 ;rst_n = 1'b0 ;enIn = 1'b0 ;multiplicand = 8'd1000 ;multiplier = 8'd20 ;#50rst_n = 1'b1 ;enIn = 1'b1 ; endalways #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 multipliterinput wire [7:0] multiplicand ,input wire [7:0] multipliter ,input wire enIn ,// output productoutput 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 )beginif( sys_rst_n == 1'b0 )begincurrent_state <= IDLE ;mulA <= 16'b0 ;mulB <= 11'b0 ;calculator <= 16'b0 ;out_enOut <= 1'b0 ;out_product <= 16'd0 ;endelsebegincurrent_state <= next_state ;// mulA mulBif( lockMuls == 1'b1 )beginmulA <= { 8'b0,multiplicand } ;mulB <= { 2'b0,multiplicand,1'b0 } ;endelse if( shifting == 1'b1 )beginmulA <= { mulA[13:0],2'b0 } ;mulB <= { 2'b0,mulB[10:2] } ;end// calculatorif( lockMuls == 1'b1 )begincalculator <= 16'd0 ;endelse if( adding1 == 1'b1 )begincalculator <= calculator + mulA ;endelse if( adding2 == 1'b1 )begincalculator <= calculator + (mulA<<1) ; endelse if( subbing1 == 1'b1 )begincalculator <= calculator - mulA ;endelse if( subbing2 == 1'b1 )begincalculator <= calculator - (mulA<<1) ;endout_enOut <= ending ;// out_productif( ending == 1'b1 )beginout_product <= calculator ;end endend // oriBitsassign oriBits = mulB[2:0] ;always@( current_state,enIn,oriBits,mulB )beginout_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 :beginif( enIn == 1'b1 )beginnext_state <= S_CALE ;lockMuls <= 1'b1 ;endelsebeginnext_state <= IDLE ;endendS_CALE :beginout_busy <= 1'b1 ;shifting <= 1'b1 ;// adding1 adding2 subbing1 subbing2 case( oriBits )3'b001,3'b010 :beginadding1 <= 1'b1 ;end3'b101,3'b110 :beginsubbing1 <= 1'b1 ;end3'b011 :beginadding2 <= 1'b1 ;end3'b100 :beginsubbing2 <= 1'b1 ;enddefault :beginendendcaseif( mulB == 11'b0 )beginending <= 1'b1 ;next_state <= IDLE ;endelsebeginnext_state <= S_CALE ;endenddefault :beginnext_state <= IDLE ;endendcaseendassign 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 ;initialbeginsys_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 ;#10enIn = 1'b0 ; #100multiplicand = 8'd10 ;multipliter = 8'd20 ;enIn = 1'b1 ;#10enIn = 1'b0 ; $finish ; end// sys_clkalways #5beginsys_clk = ~sys_clk ;endmult_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、基于无符号乘法器的原码乘法器
3、基于无符号乘法器的补码乘法器
4、补码乘法之 “ 正被乘数 ” 乘以 “ 正乘数 ”
5、补码乘法之 “ 负被乘数 ” 乘以 “ 正乘数 ”
6、补码乘法之 “ 正被乘数 ” 乘以 “ 负乘数 ”
7、补码乘法之 “ 负被乘数 ” 乘以 “ 负乘数 ”
8、补码乘法之加性分解乘法器
9、补码乘法之BOOTH乘法器
10、利用特殊资源实现整数乘法