购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.3 溢出保护

2.3.1 什么是溢出

如果一个信号的位宽设定为 n 位,但却用它来表示超过 n 位所能表示的数,导致该数在表示时发生意想不到的变化,称为溢出。例如,a和b都是3位,运算如下。

根据极限分析法c应该为4位,但实际上c只开辟了3位,会产生什么结果呢?原本要求c的取值范围是0~15,当计算值为0~7时,3位的c也可以正确表示。但当计算值为8~15时,需要4位表示,c的位宽只有3位,最高位溢出到了c的外面,无法被传输和保存,于是8~15在c中就显示为0~7。结果显然是错误的,因此在计算时须完全杜绝溢出的发生。

2.3.2 是否需要溢出保护

溢出保护就是在电路设计上加入防止溢出的措施。该措施的目的,不是为了扩大信号的取值范围,而是在保持信号取值范围的前提下,对于超出该范围的数值进行限制。如果是正数超出范围,就将超出的部分限制在能够表示的最大正数上。如果是负数超出范围,就将超出的部分限制在能够表示的最小负数上。

是否需要加入溢出保护措施,须根据位宽是否受限而定。

若位宽不受限,开辟的位宽足够,则不需要溢出保护,因为不会发生溢出。位宽的确定原则已在2.2节进行了说明。

若位宽受限,则需要溢出保护措施。位宽受限是指信号的位宽无法由设计者根据模块设计的需要自行决定,而是要受限于外部的规定。规定的位宽比实际需要的位宽要小,如果不保护,则溢出必然发生。

位宽受限是在电路设计中经常发生的。在2.2.7节已说明了芯片内各模块端口位宽定义的方法和根据,因此,芯片设计本身就是先已知端口位宽,再设计内部结构的过程。在此过程中,位宽受限不可避免。

从信息论的角度,也可以论证位宽受限是不可避免的。位宽越宽,表示的数据范围越大,说明信息量越丰富。为了保证最终结果的精度,中间过程应该使用比结果更高的精度。一个精度递减的例子如图2-4所示,图中A、B、C表示一个模块内经历的3个运算步骤。A的运算结果位宽为 n +2,B的结果位宽为 n +1,C的结果位宽为 n (即为最终的输出位宽)。位宽依次减小的过程,代表信息量在逐级损失。为了保证最终输出的信息量,需要在内部运算时产生更多的信息量,然后使其减小到规定值。

图2-4 运算过程中精度的递减

2.3.3 无符号信号的溢出保护

无符号信号的溢出保护如下例所示,其中,输入a和b均为3位,可知输出应为4位,但实际输出c只有3位。因此,声明了信号线ovf,用来容纳1位溢出。ovf是overflow(溢出)的简写。计算结果不直接输出给c,而是以c2作为过渡信号。若ovf为0,即计算结果在0~7范围内,说明运算结果没有溢出,c2的值就直接赋给c;若ovf为1,即计算结果在8~15范围内,说明有溢出发生,c2的值是错误的,应将c的值限定为它所能表示的最大值7。

根据位宽受限的位数来决定ovf的位宽,如下例中,输入a和b均为4位,其相加结果应为5位,但实际只允许输出3位,则需要开辟2位ovf,用以容纳溢出的位宽。只有ovf的2位均为0时,才说明不溢出。出现多个溢出位是不合理的,加法的面积被无意义地浪费了,说明输入信号的位宽过大,已超出了最终的需求,因而a和b在输入到一个设计之前就应该自行进行位宽限制和溢出保护。

有时,电路的表达实际上是带溢出位的,只是没有单独命名为ovf,如下例实际上是上例的改写,只是将c2的位宽扩展为5位,使得c2涵盖了上例中ovf和c2的意义。

用MATLAB将c2进行溢出保护,得到c的过程如下,其中,2^3表示2 3 ,因为在RTL中,c的位宽为3,最大表示7。

用MATLAB仿真出无溢出保护的情况下可能发生的溢出结果如下例所示。其中,mod表示求模操作,它会将c2的数值模8,使得结果控制在0~7之间,这正是发生溢出时的效果。

若c2只可能溢出1位,则可以将上述MATLAB代码简化为如下语句,更能直观体现溢出后的效果。

2.3.4 有符号信号的溢出保护

对于有符号数的溢出保护,其目的是为了防止图2-1中数值3加1变为-4,或-4减1变为3。在加入溢出保护后,数值3加1将继续保持3,因为3位宽的信号能表示的最大正数就是3,同理,-4减1将继续保持-4。

一个可能的误区是,认为溢出保护是将较大的数值变为较小的数值。这一观点对于正数是成立的,但对于负数来说,溢出保护恰恰是将较小的数值变为较大的数值。例如,将-7变为-4,而-4>-7。

在RTL中,常会在运算中保留较多的位宽,而在结果输出时对位宽进行截取。比如运算得到的结果是一个4位信号,但最后只需要保留3位。4位信号的表示范围是-8~7,而3位信号的表示范围缩小为-4~3,因此,正数中所有超过3的数值都变为3,而负数中所有小于-4的值都变为-4。溢出保护的本质是将数值的绝对值控制在更小的范围内。

有符号信号的溢出保护如下例所示。输入信号a和b都是3位有符号信号,根据极限分析法,相加结果应为4位,范围是-8~6,但输出位宽只允许为3位,因此必须进行溢出保护。计算过程中,先对参与运算的信号进行位宽补齐,使位宽与输出结果的位宽一致。补位宽用的是符号位。计算得到过渡信号c2后,以c2的最高位(即符号位)来决定溢出保护的策略。对于正数结果,限定其最大值,而对于负数结果,限定其最小值。c2的次高位用于判断溢出与否。正数溢出的标志是c2的次高位为1,负数溢出的标志是c2的次高位为0。从图2-1所展示的补码罗盘可知,负数情况下,次高位为0,则绝对值较大,说明发生了溢出。

可以总结出,对于无符号信号的溢出保护,假设限制位宽比实际需要少1位,则需要补充1个溢出位来辅助判断是否溢出。对于有符号信号的溢出保护,同样假设限制位宽比实际需要少1位,虽然只需要补充1位,但判断溢出时却根据高2位来判断。补充的最高位用来判断结果的符号,次高位用来判断是否溢出。

注意 上例中的-4,除了使用二进制表示法3'b100外,还可以用-3'd4这种比较直观的十进制表示法,综合器会将其转换为3'b100。

在MATLAB中,假设已经得到c2,对它建立同样的溢出保护机制,从而得到位宽受限的信号c,其代码如下。在正数的溢出判断上,当c2为4时,也当作溢出,它会被强行赋值为3,而当c2为-4时,却不算溢出,必须是小于-4的情况下才被赋值为-4。

在电路中,设计者为了节省面积,很多时候也不做溢出保护。此时,要保证位宽保留得足够大,使之能够满足系统运转时对位宽的全部需求,同时又不发生溢出,就必须要在算法上进行验证。验证思路是:构造溢出后出现错误的场景,若仿真结束时未出现该场景,说明没有发生溢出。下例给出了使用MATLAB构造的溢出场景,实际电路如果发生真正的溢出,则溢出后的数值与下例中计算得到的一致。通过MATLAB模拟电路溢出场景,可以快速暴露出电路的溢出风险。

若c2只可能溢出1位,则可以将上述MATLAB代码简化为如下语句,更能直观体现溢出后的效果。

对比无符号溢出和有符号溢出的两种MATLAB建模,可以发现,在原数都只溢出1位的情况下,同样是输出信号位宽为 n ,无符号时溢出的边界是2 n ,而有符号时溢出的边界是 2 n− 1 和2 n− 1 。再看溢出的后果,无符号时是原数减去2 n ,使得结果从一个很大的数变成了较小的数,而有符号时若原数是正数,则溢出后的数是原数减去2 n ,这将使该数变成负数,若原数是负数,则溢出后的数是原数加上2 n ,这将使该数变为正数。

因此,计算结果超出位宽范围的情况可以早在MATLAB算法建模阶段就被发现,从而提醒算法人员及时调整位宽,防止不正确的位宽决策进入RTL设计流程。 0Q5qOsAqN0ZyuSmKU4NSbaP6qrHU5UCKQRPloP+pNiofuEOGFql3V6YT8wR12Iz4

点击中间区域
呼出菜单
上一章
目录
下一章
×