3.2 加法运算
加法运算可以说是数字信号处理中最基本的运算,减法、乘法运算都可以通过加法运算实现。加法运算也可以说是数字信号处理中最简单的运算,算法规则、单一。在目前的FPGA中,可采用分布式逻辑实现加法,也可采用嵌入式资源实现加法,各有优势。本节以最基本的一位全加器为“源”,引出多位加法器的原理与实现方法,在此基础上,对加法树(Adder Tree)与加法链(Adder Chain)的硬件结构进行分析与比较。
3.2.1 一位全加器
一位全加器是实现多位加法器的基础。它的输入端是被加数A、加数B及较低位的进位CIN,输出端是本位和S及向较高位的进位COUT。根据二进制加法运算规则可知其真值表如表3.5所示。由真值表利用卡诺图化简可得输出与输入的逻辑关系表达式,如式(3.3)和式(3.4)所示。
表3.5 一位全加器真值表
式中,“⊕”表示异或(XOR)。
根据逻辑关系表达式,可进一步得出一位全加器的硬件电路图,如图3.5所示,图中均采用国际通用逻辑符合。
图3.5 一位全加器的硬件电路图
综上所述,加法运算的3个要素是被加数、加数和低位的进位,它们共同决定了输出和与高位的进位。
3.2.2 加法原理与多位加法器
加法运算最有可能出现的问题就是溢出,即运算结果超出了给定位宽所能表示的数的范围。例如,两个一位十进制数相加9 +8,其结果为17,显然是无法用一位十进制数表示的。
在硬件设计时,为防止溢出而导致计算结果错误,就要预先采取一定的措施。为便于阐述,这里以两个4-bit二进制数相加为例,它们均以二进制补码表示。根据前文论述可知,4-bit二进制补码所能表示的数的范围是[-24-1,24-1 -1]即[-8,7]。分以下几种情况进行分析。
1. 正数+正数
两个4-bit二进制数相加,其结果可能是4-bit二进制数(未溢出),也可能是5-bit二进制数(溢出)。当结果为前者时较好理解,如1 +3 =4,二进制计算如图3.6所示。图3.6(b)是对被加数与加数进行符号位扩展之后相加。这也进一步明确了符号位扩展是不影响数值大小的。
当结果为后者时,如3+6 =9,二进制计算如图3.7所示。图3.7(b)是对被加数与加数进行符号位扩展之后相加。
图3.6 正数+正数未溢出情形
图3.7 正数+正数溢出情形
对于图3.7(a),如果是无符号数,那么结果是正确的;如果是有符号数,那么1001是-7的补码,显然结果是错误的。错误的原因在于数值9已经超出了4-bit二进制补码所能表示的数的范围,即溢出,而结果又始终是以补码形式看待的。这正是执行加法运算时非常关键的一个问题。对于图3.7(b),不论是从有符合数的角度看还是从无符号数的角度看,结果都是正确的,这正是设计师所期望的。
2. 正数+负数
正数+负数也就是减法,减法其实质上仍是加法,因为减去一个数等效于加上这个数的补码。显然,在这种情况下不会溢出。以2+(-3)为例,二进制计算如图3.8所示。其中,-3的4-bit二进制补码为1101,5-bit二进制补码为11101。计算结果1111是-1的4-bit二进制补码,11111是-1的5-bit二进制补码。可见,结果是正确的。
3. 负数+负数
分溢出与未溢出两种情形。对于未溢出情形,以(-2)+(-3)为例说明,二进制计算如图3.9所示。
图3.8 正数+负数的情形
图3.9 负数+负数未溢出情形
对于结果11011,其低4位(1011)是-5的4-bit二进制补码,11011是-5的5-bit二进制补码,111011是-5的6-bit二进制补码,显然结果是正确的。
对于溢出情形,以(-3)+(-6)为例说明,二进制计算如图3.10所示。
对于图3.10(a),如果只取低4 位(0111),那么显然结果是错误的。对于图3.10(b),取低5 位结果是正确的,前提是对两个加数进行了符合位扩展。符号位扩展并不改变数值大小,即1011 与11011 都是 -3 的补码。
图3.10 负数+负数溢出情形
对于其他情况,正数-负数可归结为正数+正数,负数-负数可归结为正数+负数。
通过以上分析,可得如下结论:两个N-bit二进制补码数相加,为防止溢出时导致计算结果错误,可将这两个加数先进行符号位扩展,变为N+1-bit二进制数,然后相加,结果亦取N+1位,可保证运算正确。
根据多位加法器原理可知,对于两个N-bit二进制补码数相加,可利用N个一位全加器搭建而成。图3.1 1所示为两个4-bit二进制补码数相加(A+B)的硬件电路图。其中,被加数、加数、和的最高位分别为A3、B3、S4,它们是符号位。末级进位端最终形成了和的符号位。
由于减去一个数等效于与这个数的补码相加,这样减法操作就变成了加法操作。根据图3.2所示的求补过程,对图3.1 1稍作改动即可形成如图3.12所示的两个4-bit二进制数相减(A-B)的硬件电路图,图中首先对减数B通过反相器逐位求反。
图3.1 1 两个4-bit二进制补码数相加的硬件电路图
图3.12 两个4-bit二进制数相减的硬件电路图
对比图3.1 1和图3.12可以发现,两者的结构是相同的,很多逻辑是可以共享的。为此,将两者合二为一,引入控制端control,通过它来切换加法操作与减法操作。这样就形成了如图3.13所示的加法、减法可切换的硬件电路图,图中,当control为0时,执行A+B,当control为1时,执行A-B。
图3.13 加法、减法可切换的硬件电路图
在采用VHDL或Verilog语言描述多位加法器或多位减法器时,并不需要先构造一个全加器,再按照上述电路图搭建(上述电路图只是为了阐述其实现原理),只需要对数据先进行符号位扩展,然后对扩展后的数据直接相加或直接相减即可。
3.2.3 复数加法
在某些应用场合需要执行复数加法运算。复数加法的原理很简单,实部和实部相加得到和的实部,虚部和虚部相加得到和的虚部,如式(3.5)所示。在式(3.5)中,a、b、c、d、e、f均为实数,j为虚数单位。可见,复数加法最终被分解为实数加法。一次复数加法由两次实数加法构成。
根据上述原理可得如图3.14所示的复数加法的硬件结构。
图3.14 复数加法的硬件结构
图3. 14(a)采用了两个加法器,并行执行实部和虚部的加法。图3. 14(b)则采用了一个加法器,通过分时复用,分别求和。显然,前者在速度上有优势,后者在资源上有优势。
3.2.4 加法树与加法链
在很多应用场合都会涉及多个数相加求和,如式(3.6)所示。
此时,可采用加法树,也可采用加法链。加法树结构如图3.15所示。为了提高系统速度,采用了流水线技术。在图3.15中,D表示D触发器,在本书后续章节中均采用此方式表示D触发器。
图3.15 加法树结构
图3.15中是一个3级加法树,每级加法器的位宽依次递增,防止溢出导致计算错误。全流水,从输入到输出需要3个时钟周期。显然,将此结构推广,如果要求 N个数的和,则需要ceil [log2 N]级加法树。该结构非常清晰,可高速运行。但整个设计性能的瓶颈在于末级的加法树,如图3.15中的阴影所示,它们将产生较大的功耗。
对于式(3.6),可采用加法链结构,如图3.16所示。为了正确相加,a3 相比于a2 和a1 推迟一个时钟周期进入加法器,a4相比于a3 推迟一个时钟周期进入加法器,后续各加数进入时刻以此类推。因此,从输入到输出需要7个时钟周期。显然,相对于加法树,此结构时序稍显复杂,但结构中每个加法器的等级是一致的。
图3.16 加法链结构