乘法器介绍

news2024/11/7 1:43:58

阵列乘法器

实现乘法的比较常用的方法是类似与手工计算乘法的方式:

对应的硬件结构就是阵列乘法器(array multiplier)它有三个功能:产生部分积累加部分积最终相加

在这里插入图片描述

阵列乘法器的关键路径为(下图标出了两条可能的关键路径):

假设乘数为N,被乘数为M。则上面的乘法器产生N个部分积,乘法位数为M,则需要N×M个二输入AND门以及N−1个M位加法器。可以得到关键路径延时为:

t m u l t = [ ( M − 1 ) + ( N − 2 ) ] t c a r r y + ( N − 1 ) t s u m + t a n d t_{mult}=[(M−1)+(N−2)]t_{carry}+(N−1)t_{sum}+t_{and} tmult=[(M1)+(N2)]tcarry+(N1)tsum+tand

进位保留乘法器

背景:由于阵列乘法器中有许多几乎一样的关键路径,因此通过调整晶体管的尺寸来提高性能效果有限。

解决:进位输出可以沿着对角线传播而不是向左传递,这样传播并不改变结果,只需要加入额外的一排加法器(向量合并加法器vector-merging)来产生最终的结果。这样的乘法器叫做进位保留乘法器

其关键路径为图中灰色部分,且只有一条。 其传播延时为:

t m u l t = t a n d + ( N − 1 ) t c a r r y + t m e r g e t_{mult}=t_{and}+(N−1)t_{carry}+t_{merge} tmult=tand+(N1)tcarry+tmerge

可见,相比于阵列乘法器,进位保留乘法器增加了部分面积,但关键路径唯一确定。

下图是进位保留加法器的布图(floorplan)结构。其规整的结构适合自动化生成。

树形乘法器

部分积的求和加法器可以安排为树形以减少关键路径和减少加法器。其中两个点的是半加器,三个点的是全加器。其压缩过程可以分为下面几步:

在这里插入图片描述

在这里插入图片描述

可见,前面的两部只需要三个半加器和三个全加器,最后一步是简单的加法器链。只比较前面部分的话,进位保留加法器的前面部分需要6个全加器和6个半加器!优点:除了节省乘法器需要的硬件,Wallace树形乘法器也可以减少传播延时,其延时 O ( l o g 1.5 ( N ) ) O(log_{1.5}(N)) O(log1.5(N))

缺点: 非常不规则,版图设计复杂。

Booth乘法器

假设A和B是乘数和被乘数,且有:

A = a n − 1 a n − 2 … a 1 a 0 B = b n − 1 b n − 2 … b 1 b 0 A ∗ B = ( 0 − a 0 ) × B × 2 0 + ( a 0 − a 1 ) × B × 2 1 + ( a 1 − a 2 ) × B × 2 2 + ⋯ + ( a n − 2 − a n − 1 ) × B × 2 n − 1 = B × [ − a n − 1 × 2 n − 1 + ∑ i = 0 n − 2 a i × 2 i ] = B × V a l ( A ) \begin{align}A&=a_{n−1}a_{n−2}…a_1a_0 \\ B&=b_{n−1}b_{n−2}…b_1b_0 \\ A*B&=(0−a_0)×B×2^0+(a_0−a_1)×B×2^1+\\&(a_1−a_2)×B×2^2+⋯+(a_{n−2}−a_{n−1})×B×2^n−1\\ &=B×[−a_{n−1}×2^{n−1}+∑_{i=0}^{n−2}a_i×2^i]\\&=B×Val(A)\end{align} ABAB=an1an2a1a0=bn1bn2b1b0=(0a0)×B×20+(a0a1)×B×21+(a1a2)×B×22++(an2an1)×B×2n1=B×[an1×2n1+i=0n2ai×2i]=B×Val(A)

上述是以补码形式进行的

上面的公式推导了booth乘法对乘数的分解原理,实际上在编码时只需要公式3,可以做如下的编码表:

a i a_i ai a i − 1 a_{i−1} ai1 a i − 1 − a i a_{i−1}−a_i ai1ai操作
000+0,右移一位
10-1减B,右移一位
110+0,右移一位
011加B,右移一位

例: N = 7 , B = 22 = ( 0010110 ) 2 , A = − 34 = − ( 0100010 ) 2 N=7,B=22=(0010110)_2,A=−34=−(0100010)_2 N=7,B=22=(0010110)2,A=34=(0100010)2

首先计算-B的补码(算法中要用到): − B ‾ = ( 1101010 ) 2 \overline{−B}=(1101010)_2 B=(1101010)2以及A的补码: A ‾ = ( 1011110 ) 2 \overline{A}=(1011110)_2 A=(1011110)2

硬件计算过程如下:

在这里插入图片描述

1、被乘数B与乘数A均以补码的形式参加乘法运算,运算结果是积的补码 。

2、部分积和被乘数B采用双符号位,乘数A采用单符号位 。

3、初始部分积为0。运算前,在乘数A的补码末位添加一位附加位An+1,初始值为0 。

4、根据AnAn+1的值,按照上表进行累加右移操作,右移时遵循补码的移位规则 。

5、累加n+1次,右移n次,最后一次不右移 。

6、实际上,对于公式中的每一项 ( a i − 1 − a i ) × B × 2 i (a_{i−1}−a_i)×B×2^i (ai1ai)×B×2i都对应实际算法中的每一步。 ( a i − 1 − a i ) (a_{i−1}−a_i) (ai1ai)决定了B的系数,右移操作因为作用在[A][Q]寄存器上,所以实际上是相当于将积右移,等价于B左移,所以这一步对应 × 2 i ×2^i ×2i操作。加减B的操作都作用在[A]寄存器上,保证了 × 2 i ×2^i ×2i后的B能够作用在正确的位上。

基2booth乘法器设计

`timescale 1ns/1ps
module booth_fsm
# (parameter DATAWIDTH = 8)
(
  input                        clk,
  input                        rstn,
  input                        en,
  input        [DATAWIDTH-1:0] multiplier,                            
  input        [DATAWIDTH-1:0] multiplicand,
  output reg                   done,
  output reg [2*DATAWIDTH-1:0] product
);

parameter   IDLE   = 2'b00,
            ADD    = 2'b01,
            SHIFT  = 2'b11,
            OUTPUT = 2'b10;

reg  [1:0]              current_state, next_state;  // state registers.
reg  [2*DATAWIDTH+1:0]  a_reg,s_reg,p_reg,sum_reg;  // computational values.
reg  [DATAWIDTH-1:0]    iter_cnt;                   // iteration count for determining when done.
wire [DATAWIDTH:0]      multiplier_neg;             // negative value of multiplier

always @(posedge clk or negedge rstn)
  if (!rstn) current_state = IDLE;
  else current_state <= next_state;

// state transform
always @(*) begin
  next_state = 2'bx;
  case (current_state)
    IDLE  : if (en) next_state = ADD;
            else    next_state = IDLE;
    ADD   : next_state = SHIFT;
    SHIFT : if (iter_cnt==DATAWIDTH) next_state = OUTPUT;
            else            next_state = ADD;
    OUTPUT: next_state = IDLE;
  endcase
end

// negative value of multiplier.
assign multiplier_neg = -{multiplier[DATAWIDTH-1],multiplier}; 
// algorithm implemenation details.
always @(negedge clk or negedge rstn) begin
  if (!rstn) begin
    {a_reg,s_reg,p_reg,iter_cnt,done,sum_reg,product} <= 0;
  end else begin
  case (current_state)
    IDLE :  begin
      a_reg    <= {multiplier[DATAWIDTH-1],multiplier,{(DATAWIDTH+1){1'b0}}};
      s_reg    <= {multiplier_neg,{(DATAWIDTH+1){1'b0}}};
      p_reg    <= {{(DATAWIDTH+1){1'b0}},multiplicand,1'b0};
      iter_cnt <= 0;
      done     <= 1'b0;
    end
    ADD  :  begin
      case (p_reg[1:0])
        2'b01       : sum_reg <= p_reg+a_reg; // + multiplier
        2'b10       : sum_reg <= p_reg+s_reg; // - multiplier
        2'b00,2'b11 : sum_reg <= p_reg;       // nop
      endcase
      iter_cnt <= iter_cnt + 1;
    end
    SHIFT :  begin
      p_reg <= {sum_reg[2*DATAWIDTH+1],sum_reg[2*DATAWIDTH+1:1]}; // right shift 
    end
    OUTPUT : begin
      product <= p_reg[2*DATAWIDTH:1];
      done <= 1'b1;
    end
  endcase
 end
end

endmodule

testbench:

`timescale 1ns/1ps

// Basic exhaustive self checking test bench.
`define TEST_WIDTH 10
module booth_fsm_tb;

reg clk;
reg rstn;
reg en;
//integer multiplier1;
//integer multiplicand1;
reg [`TEST_WIDTH-1:0] multiplier;
reg [`TEST_WIDTH-1:0] multiplicand;
wire    done;

//输入 :要定义有符号和符号,输出:无要求
wire signed [2*`TEST_WIDTH-1:0] product;
wire signed [`TEST_WIDTH-1:0]                m1_in;
wire signed [`TEST_WIDTH-1:0]                m2_in;

reg  signed [2*`TEST_WIDTH-1:0] product_ref;
reg  [2*`TEST_WIDTH-1:0] product_ref_u;
assign m1_in = multiplier[`TEST_WIDTH-1:0];
assign m2_in = multiplicand[`TEST_WIDTH-1:0];

booth_fsm #(.DATAWIDTH(`TEST_WIDTH)) booth 
(
  .clk(clk),
  .rstn(rstn),
  .en(en),
  .multiplier(multiplier),                            
  .multiplicand(multiplicand),
  .done  (done),
  .product(product)
 );

always #1 clk = ~clk;

integer num_good;
integer i;
initial begin
  clk = 1;
  en = 0;
  rstn = 1;
  #2 rstn = 0; #2 rstn = 1;
  
  num_good = 0;
  multiplier=0;
  multiplicand=0;
  #8;

  for(i=0;i<4;i=i+1) begin
    en = 1;
    multiplier=10'b10000_00000+i;
    multiplicand=10'b00000_00010+i;

    wait (done == 0);
    wait (done == 1);
	product_ref=m1_in*m2_in;
    product_ref_u=m1_in*m2_in;
    if (product_ref !== product) 
         $display("multiplier = %d multiplicand = %d proudct =%d",m1_in,m2_in,product);
        @(posedge clk);
  end		
  $display("sim done. num good = %d",num_good);

end

initial begin
	$fsdbDumpfile("tb.fsdb");
    $fsdbDumpvars();
    $fsdbDumpMDA();
    $dumpvars();
    #1000 $finish;
 end
endmodule

仿真波形:
在这里插入图片描述

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

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

相关文章

Clion开发STM32之ESP8266系列(四)

前言 上一篇: Clion开发STM32之ESP8266系列(三) 本篇主要内容 实现esp8266需要实现的函数串口3中断函数的自定义&#xff08;这里没有使用HAL提供的&#xff09;封装esp8266服务端的代码和测试 正文 主要修改部分 核心配置头文件(添加一些宏定义) sys_core_conf.h文件中…

【报错】检索 COM 类工厂中 CLSID 为 {28E68F9A-8D75-11D1-8DC3-3C302A000000} 的组件失败错误

【报错】检索 COM 类工厂中 CLSID 为 {28E68F9A-8D75-11D1-8DC3-3C302A000000} 的组件失败错误 情况描述解决方法修改目标平台CPU类型下载组件文件复制到指定路径运行指定命令行程序 情况描述 在使用C#进行工控软件开发&#xff0c;需要连接通过OPC连接DCS系统时&#xff0c;需…

STM32--ESP8266物联网WIFI模块(贝壳物联)--温湿度数据上传服务器显示

本文适用于STM32F103C8T6等MCU&#xff0c;其他MCU可以移植&#xff0c;完整资源见文末链接 一、简介 随着移动物联网的发展&#xff0c;各场景下对于物联控制、数据上传、远程控制的诉求也越来越多&#xff0c;基于此乐鑫科技推出了便宜好用性价比极高的wifi物联模块——ESP…

PowerShell系列(五):PowerShell通过脚本方式运行笔记

目录 一、四种执行方式介绍 1、当前文件夹运行命令 2、直接指定完整文件路径执行 3、通过cmd命令直接执行 4、通过Windows计划任务执行PowerShell脚本 二、通过脚本方式执行命令的优势 往期回顾 PowerShell系列&#xff08;一&#xff09;&#xff1a;PowerShell介绍和cm…

Java 异常处理和最佳实践(含案例分析)

概述 最近在代码 CR 的时候发现一些值得注意的问题&#xff0c;特别是在对 Java 异常处理的时候&#xff0c;比如有的同学对每个方法都进行 try-catch&#xff0c;在进行 IO 操作时忘记在 finally 块中关闭连接资源等等问题。回想自己对 java 的异常处理也不是特别清楚&#x…

第一章 软件工程概论

文章目录 第一章 软件工程概论1. 软件危机1.1.1 软件危机的介绍1.1.2 产生软件危机的原因与软件本身特点有关软件开发与维护的方法不正确有关 1.1.3 消除软件危机的途径例题 软件工程1.2.1 软件工程的介绍1.2.2 软件工程的基本原理1.2.3 软件工程方法学1. 传统方法学2. 面向对象…

集群间 ssh 互信免密码登录失败处理

一、问题描述 某次GreePlum集群免密配置过程中&#xff0c;需要使用普通用户实现ssh免密登录&#xff0c;前方反馈root用户已可完成免密登录&#xff0c;但普通用户同样配置&#xff0c;未生效&#xff0c;提示需输入密码才可以。 现场环境&#xff1a; 二、问题分析处理 …

安卓packageinfo的知识点

PackageInfo类包含AndroidManifest.xml文件的信息。 一些常用的属性如下&#xff1a; 获得PackageInfo //获取指定包名的packageInfo&#xff0c;并且包含所有的内容提供者 val pack context.packageManager.getPackageInfo(context.packageName,PackageManager.GET_PROVIDE…

GPT从入门到精通之 Tensorflow2.x 中如何使用 GPT 模型

Tensorflow2.x 中如何使用 GPT 模型 GPT 模型是自然语言处理&#xff08;NLP&#xff09;领域中一种重要的预训练模型。 TensorFlow2.x 是目前最流行的机器学习和深度学习框架之一&#xff0c;对 GPT 模型的支持度也非常高。在本篇文章中&#xff0c;我们将详细介绍如何使用 T…

前后端交互四、跨域与JSONP

零、文章目录 前后端交互四、跨域与JSONP 1、同源策略和跨域 &#xff08;1&#xff09;同源 如果两个页面URL的协议&#xff0c;域名和端口都相同&#xff0c;则两个页面具有相同的源。 例如&#xff0c;下表给出了相对于 http://www.test.com/index.html 页面的同源检测&…

【iOS_Swift_Alamofire实现网络请求】

文章目录 前言导入库原生网络请求单例封装一个原生网络请求Alamofire用法Alamofire的返回响应将返回的data转为字典/字符串 总结 前言 学习swift继续延续之前的思路&#xff0c;对照着OC学&#xff0c;从UI起手&#xff0c;学习到对应的自适应布局。 今天再次学习了swift的原生…

MySQL分库分表全攻略:从小白到大神的进阶指南!

大家好&#xff0c;我是小米&#xff0c;一个热爱技术的程序员。今天&#xff0c;我来和大家聊一下关于MySQL中的分库分表技术&#xff0c;相信对于开发者和DBA来说是一个非常重要的话题。 什么是分库分表 首先&#xff0c;我们先来了解一下什么是分库分表。分库分表是指将原本…

Apifox(1)比postman更优秀的接口自动化测试平台

Apifox介绍 Apifox 是 API 文档、API 调试、API Mock、API 自动化测试一体化协作平台&#xff0c;定位 Postman Swagger Mock JMeter。通过一套系统、一份数据&#xff0c;解决多个系统之间的数据同步问题。只要定义好 API 文档&#xff0c;API 调试、API 数据 Mock、API 自…

scratch躲避陨石 中国电子学会图形化编程 少儿编程 scratch编程等级考试三级真题和答案解析2023年5月

目录 scratch躲避陨石 一、题目要求 1、准备工作 2、功能实现 二、案例分析

性能测试计划,怎么写显得你能更专业?

性能测试计划 性能测试是一种非常重要的测试类型&#xff0c;用于确定系统或应用程序在特定负载下的性能指标。以下是一个性能测试计划的建议步骤&#xff1a; 目标 首先&#xff0c;定义性能测试的目标和范围。这包括测试的系统或应用程序以及所需测试的性能指标&#xff0…

基于蒙特卡洛模拟法的电动汽车充电负荷研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

开源项目的流程

开源的好处 增加知名度和使用量&#xff1a;开源项目可以让更多人知道和使用&#xff0c;进而增加项目的知名度和使用量。提高代码质量&#xff1a;开源项目需要接受有可能来自全球的开发者审核和参与&#xff0c;这样可以使得项目代码得到更多高质量的反复审查和改进。快速修…

计算机视觉 | 目标检测与MMDetection

目 录 目标检测的基本范式 滑窗使用卷积实现密集预测锚框多尺度检测与FPN 单阶段&无锚框检测器选讲 RPNYOLO、SSDFocal loss 与 RetinaNetFCOSYOLO系列选讲 一、目标检测的基本范式 1、什么是目标检测 给定一张图片 ——》用矩形框框出所感兴趣的物体同时预测物体类…

前后端交互一、服务器概念与初识Ajax

零、文章目录 前后端交互一、服务器概念与初识Ajax 1、上网的过程 网络相关知识请参考网络详解HTTP相关知识请参考HTTP详解 &#xff08;1&#xff09;客户端与服务器 **上网的目的&#xff1a;**通过互联网获取和消费资源 **服务器&#xff1a;**上网过程中&#xff0c;负…

基于STM32的智能粮仓系统设计

一、项目背景 随着粮食质量要求的提高和储存方式的改变&#xff0c;对于粮仓环境的监测和控制也愈发重要。在过去的传统管理中&#xff0c;通风、防潮等操作需要定期人工进行&#xff0c;精度和效率都较低。而利用嵌入式技术和智能控制算法进行监测和控制&#xff0c;不仅能够…