当前位置: 首页 > news >正文

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、利用特殊资源实现整数乘法


http://www.mrgr.cn/news/97684.html

相关文章:

  • 谈Linux之磁盘管理——万字详解
  • Heap_dijkstra模板
  • K8S核心技术点
  • 物联网外设管理服务平台
  • 【KWDB 创作者计划】_ruby基础语法
  • 大模型是如何把向量解码成文字输出的
  • 畅游Diffusion数字人(21):基于Wan2.1的音频驱动数字人FantasyTalking
  • 急速实现Anaconda/Miniforge虚拟环境的克隆和迁移
  • mysql镜像创建docker容器,及其可能遇到的问题
  • 数据结构和算法(十二)--最小生成树
  • 【组件封装-优化】vue+element plus:二次封装select组件,实现下拉列表有分页、自定义是否可搜索的一系列功能
  • 【杂谈】Godot4.4导出到Android平台(正式导出)
  • 最新版PhpStorm超详细图文安装教程,带补丁包(2025最新版保姆级教程)
  • c语言 文件操作
  • SQL语法进阶篇(二),数据库复杂查询——窗口函数
  • 【蓝桥杯2024省B】好数 三种解法全解析 | C/C++暴力法→剪枝优化→构造法演进
  • GZ036区块链卷一 EtherStore合约漏洞详解
  • React 列表渲染
  • Java 大视界 -- 基于 Java 的大数据分布式缓存技术在电商高并发场景下的性能优化(181)
  • 算法精讲【整数二分】(实战教学)