如何将算法翻译成RTL(一):溢出保护

简介: 如何将算法翻译成RTL(一):溢出保护

本篇文章给大家讲解一下RTL代码中,一个绕不开的话题,即数据溢出。对于纯控制类型的电路,可能只涉及计数器、地址增减这种简单的运算。但是如果大家做过算法类型的电路,位宽确定就会复杂很多,位宽选择的少了,那么就容易溢出,位宽选择的多了,就容易浪费面积。

在不同的情况下选择多长的位宽呢?在什么样的情况下我们对溢出可以无视呢?对于有符号数无符号数又分别怎么处理呢?本篇文章我将和大家一起学习这一问题。

1、什么是溢出?

假如我们有一个3bit的数据,假设是记录输入1出现了多少次,那么它就会从000->001一直变化到111,到111的时候,如果再加1,就会变成000,这个时候就发生了溢出。即绕过了一圈又回到了原点,很多时候我们希望即使你无法继续记录,那好歹保持111不变,如果有这一机制,我们就称之为做了溢出保护

其实上述情况,有个时候是我们设计的位宽不太合理,即可能出现11次,12次的情况,那么你应该多设置1bit,采取4bit就没这个问题了。就好像笔者之前体侧的时候,需要跑6圈,我索性在一圈的中间停了下来,然后等大家都快跑完了再跟上,这样只跑一圈就行了。这种情况就是典型的位宽设置不合理,即跑了几圈都没人记录,缺少高位的记录!

开个玩笑,接下来我们进入正题。

2、不同类型下的溢出保护

下面的例子中如果没有特别说明,则认为均为3比特。并且我们写Verilog的时候,都没有规定是有符号数。即没有声明signed。

2.1、无符号数的两个数相加

这种情况最简单,我想即使大家不看这篇文章,都知道该怎么做。因为两个无符号数相加,即两个正数相加,最大不会超过大的输入的那个数的两倍。所以我们用较宽比特的输入的位宽再加上1作为输出的位宽即可。

即我们算c=a+b的时候,假设a的位宽是x,b的位宽是y。则c的位宽应该是max(x,y)+1。

这样设置可以保证不发生溢出。

2.2、多个无符号数相加

这种情况就复杂一些了,大家就假定所有的输入是全1,其可能到达最大数值是多少即可。根据此数值即可判断相应的位宽。

2.3、两个无符号数相减

首先两个无符号数相减,是有可能减出负数的,这种情况实际上是会自动扩展符号位的(注意,扩展的是符号位,而不是0),因此我们设定的结果位宽应该是减法中最大位宽加上1,并且作为设计者的你要知道,最高比特是符号位。

下面我解释一下仿真的机制:以下的例子都是assign c=a-b;

第一种情况,假设a、b、c都为3bit,假设a为111,b为000, 我们减去0,其实就等于加上0的补码,0的补码还是0,所以结果是111,没什么问题。

第二种情况,假设a、b、c都为3bit,假设a为000,b为001, 我们减去1,其实就认为是加上其补码,即加上111,最终的结果为111,这个时候你实际上无法判断是正7还是负1的,因此我们需要将c定为我们规定的4bit,这个时候在运算过程中,实际上是用0000减去1即加上1111因此得到1111。这个时候我们就非常清楚的知道最终的结果是个负数,真实的情况是负1。

第三种情况:假设a、b是3bit,c是4bit。假设a是111,b是001。这个时候实际上是不会减出负数的,但实际上处理中,也是将输入扩展成4bit进行仿真,即用0111减去1即加上1111,因此得到的结果是0110,即6,完美符合我们的预期。(很多仿真器实际上是在运算的时候,将输入都扩展成32bit,然后结果再截位,这样运算得到的结果和上面的分析得到的结果是一样的,大家可以动手试一下每一种情况)。

再强调一下,作为设计者的你应该知道,哪些情况会出现负数,如果出现负数你怎么进行后续处理,这些都是你自己应该解决的问题,仿真工具无法帮你解决,它能做的就是认为减法是可能减出负数的,并且贴心的为你扩展符号位,而不是扩展0。(大家可以试验一下,实际上你不管结果设置为多少比特,在减法的情况下前面补的都是符号位,而加法的情况下补的都是0,甚至可以不用深究细节,记住上面的结论即可,因为补码就是这么神奇)。

2.4、无符号数的加减混合运算

这种情况也会出现负数,结果位宽应该也是可能出现的结果最大位宽再加一位符号位即可。考虑极限的情况,即能算到的最大值或者最小值来判断。其实上面的情况都是这样,考虑最大最小的情况即可。

2.5、有符号数的加减混合运算

这种情况就相对复杂一些了,实际上有符号数的加法和减法在判断位宽上是没有区别的,其都会在结果上扩展符号位。因为实际上都可能是加一个正数。实际上我们都认为是加法,大家用极限的方式分析即可。

2.6、对无符号数限制输出位宽的情况

比如我们的输入都是3bit的数据,此时限制输出也只可以是3bit,这种情况称为限制输出位宽的情况。此时我们需要用一个溢出位判断,下面的a,b均为3比特。c2也是3比特。相应的如果判断已经溢出了,我们就输出3比特可以输出的最大值,认为最大大到这个值,就不允许再增加了。这种在现实中其实也很常见,比如考试总分是100分,90的基础分和20的Bonus分数,你即便获得了20分,也认为你最高分只能是100。所以100~110最后体现在总分上是没什么区别的。

assign {overflow,c2}=a+b
always@(*) begin
    if(~overflow) c = c2;
    else   c=3'd7;
end

2.7、对有符号数限制输出位宽的情况

这种情况是最复杂的情况,实际上这种情况不能够直接相加。因为两个正数相加和两个负数相加,最后在结果上看可能是相同的两个负数,比如010+010得100,在有符号数中我们认为它是-4,而110+110实际上也会得到100,也认为是-4,但实际上后面那个是真的-4,前面那个是假的。我们必须引入合适的机制去判断。

这个时候我们应该在运算之前先扩展额外的一份符号位,再进行运算。这样多了一比特,实际上不会出现正数相加得到负数的情况了,因为我们有额外的一个比特用于溢出的情况(次高比特)。这样算出来是正数和负数就可以直接用这个扩展的符号位去判断。

我们首先考虑判断符号位,首先考虑算出来是个正数,如果是个正数,再判断有没有溢出,如果溢出了,则限制最大为3'd3。如果是个负数,同样判断是否溢出,注意,负数的溢出其应该是越接近1000,负数的绝对值越大,点大家可以动手算一下。代码如下。

assign a2={a[2],a};
assign b2={b[2],b};
assign c2=a2+b2;
assign c=!c2[3]?(c2[2]?3'd3:c2[2:0]):(!c2[2]?3'd4:c2[2:0])

上面的c2是4个bit,其本质是{sign,over,c2}。这样对照上述代码,应该更加直观。

2.8、两个无符号数乘

这种情况非常简单,比如输入一个是x比特,一个是y比特,则输出定为(x+y)比特就行。

2.9、两个有符号数乘

这种情况和上述一样,比如输入一个是x比特,一个是y比特,则输出定为(x+y)比特就行。

如果你需要限制位宽输出,则取决于你是有符号数还是无符号数相乘,对应于2.6或者2.7的方法,大家可以自己想一下,这里就不重复讲了。

2.10、多个数相乘

如果是4个数相乘,那么输出位宽应该是x+y+z+u-(4-2)。

2.11、简单的除法

首先除法一般是禁止直接用Verilog写的,如果真的这么写了,实际上会保留整数部分,即转换成整除运算,大家可以试一下,比如100除以111,你会仿真得到000。实际项目如果真的要实现除法运算,一般会调用IP,或者手写迭代的方式。

上面的乘法器和除法器只谈了位宽的声明,其具体的实现后面的文章再讲。

目录
相关文章
|
存储 算法 C++
剑指offer(C++)-JZ46:把数字翻译成字符串(算法-动态规划)
剑指offer(C++)-JZ46:把数字翻译成字符串(算法-动态规划)
|
机器学习/深度学习 编解码 算法
如何将算法翻译成RTL(零):绪论
如何将算法翻译成RTL(零):绪论
295 0
|
算法 Python
如何将算法翻译成RTL(四)有符号数的加减法实现
如何将算法翻译成RTL(四)有符号数的加减法实现
208 0
|
算法
如何将算法翻译成RTL(三):Verilog中的Signed本质及用法
如何将算法翻译成RTL(三):Verilog中的Signed本质及用法
296 0
|
算法 Python
如何将算法翻译成RTL(二):带小数的加减法实现
如何将算法翻译成RTL(二):带小数的加减法实现
181 0
|
算法 C++ Python
【每日算法Day 86】面试经典题:把数字翻译成字符串
【每日算法Day 86】面试经典题:把数字翻译成字符串
|
算法
数据结构与算法之[把数字翻译成字符串]&&动态规划
数据结构与算法之[把数字翻译成字符串]&&动态规划
76 0
数据结构与算法之[把数字翻译成字符串]&&动态规划
|
存储 算法
【蚁狮算法】《The Ant Lion Optimizer》原文翻译(附源代码)
【蚁狮算法】《The Ant Lion Optimizer》原文翻译(附源代码)
|
编解码 人工智能 前端开发
Paper:2020年3月30日何恺明团队最新算法RegNet—来自Facebook AI研究院《Designing Network Design Spaces》的翻译与解读
Paper:2020年3月30日何恺明团队最新算法RegNet—来自Facebook AI研究院《Designing Network Design Spaces》的翻译与解读
Paper:2020年3月30日何恺明团队最新算法RegNet—来自Facebook AI研究院《Designing Network Design Spaces》的翻译与解读