首页 > 编程知识 正文

fpga位宽转换,高位宽显卡

时间:2023-05-03 09:52:12 阅读:164204 作者:3980

Verilog和SystemVerilog作为“松散型”语言被许多工程师广泛应用于设计验证领域,但这并不是说它们可以在各种电路结构和验证环境中自由使用。 特别是在计算不同位宽的信号时,自己的公式往往与预期的结果不一致,甚至怀疑自己的数学有没有教体育老师,所以本文举例说明不同位宽的信号

首先,让我们看一下运算的位宽一致,但计算结果与期望不一致的例子。

【例】在该例中,希望将运算结果向右移动1位,以便保留两个数之和的进位。

【模拟结果】

在本示例中,) sig1 sig2)的结果必须为“1_1110_0011”,后面的结果必须包含进位位“1”,但实际上是resina 为什么会这样呢? 这是因为,在式(sig1 sig2)的进位操作时,会产生位宽与sig1和sig2的最宽数一致的中间结果。 在本示例中,由于sig1和sig2都具有8位宽,所以中间结果不包括进位比特,并且因此,由于执行了移位操作的中间结果实际上只包括sig1和sig2的"和"部分,所以移位后的结果进位比特"消失" 为了解决这样的问题,有必要保持能够在中间结果中有效地保留和进位,但是如何实现进位结果的保持和参与移位操作呢? 让我们看几个例子。

【例】方法1 :添加宽位宽数据扩展结果

【模拟结果】

在本例中,对sig1和sig2进行加法运算时,追加了9位宽的0。 可以指定大于8位的任何0。 以这种形式(SIG1SIG 29’B0 _ 0000 _ 0000 )执行加法操作时,所有操作数都将扩展到9位进行计算。 ) SIG1- SIG 2’B0因为在移位中间9位宽的结果时,将进位位一起移位,所以最终结果包括我们预期的进位位(sig1 sig2)。 除了这种方法外,还可以通过类型转换来实现操作位宽的扩展,如下例所示。

【示例】tmdds :使用静态类型转换

【模拟结果】

模拟结果同上例。

在本示例中,通过将sig1和sig2中任一个用" int ' "转换为32位,在操作sig1和sig2的情况下,将所有操作数展开为32位进行计算,在移位操作时将该32位的中间结果移位,此时的最终结果是REE

其实,除了上述两种方法之外,最安全的操作方法是在进行操作时,充分估计操作的各结果的位宽。 请考虑以下示例:

【例】方法3 :扩展代入式的相关操作数的位宽

【模拟结果】

在本例中,result的位宽声明为9位宽,但sig1和sig2进行运算时,会扩展为9位宽。 此时,sig1 sig2的结果也为9位。 也就是说,此时,将两个个数相加后的进位位会保留,因此,此时进行移位操作后的输出结果中将包含进位位。

Verilog和SystemVerilog出现上述示例问题是因为Verilog和SystemVerilog在分析表达式时不太了解操作数的位宽以及如何处理表达式结果的位宽。 实际上,在Verilog和SystemVerilog中,表达式的位宽是根据一定的规则确定的,但该规则的依据是参与特定表达式的各种运算符和操作位宽,从而将表达式定义为自定义和上下文定义

self-determined表达式的位宽仅由表达式操作数的位宽决定。 此类表达式的位宽不受表达式上下文的影响。 也就是说,不受公式其他部分的影响。

context-determined表达式的位宽取决于表达式和整个语句的其他子表达式的位宽。

这两种表达可能很抽象,但下表对常见运算操作后的表达式的位宽进行了总结和分类,有助于具体运算时的理解。 (请参见IEEE1800 2012 Chapter 11 )其中黄色部分是self-determined表达式中常用的运算符。

下面将结合上述运算符和示例进行说明。

【例】

【模拟结果】

分析示例结果:

1st和2nd:因为&sig1和&sig2并未出现在赋值表达式中,并且符合“& op”条件,所有操作数位宽self-determined,通过上表分析&sig1和&sig2的结果均为1位,与仿真结果一致。

3rd:因为&sig1和&sig2并未出现在赋值表达式中,&sig1和&sig2分别计算完成后的结果均为1位,并且这两个&运算的结果位于“+”左右两侧,两个1位数相加的结果仍为1位,所以仿真结果为0。

4th和5th:因为“&sig1+sig2”和“sig1+&sig2”并未出现在赋值表达式中,所以所有操作数的位宽self-determined,sig1和sig2均位于“+”运算符两侧,此时“+”操作结果位宽取决于“+”操作符操作数最大位宽,所以在4th中显示的结果与sig1的位宽相同,而5th中显示的结果与sig2位宽相同。

6th:“sig1+sig2”的结果产生的原因与4th和5th相同,“sig1+sig2”结果由sig1和sig2位宽最宽的那个数决定,所以显示结果位宽同sig2。

7th:在“result = (&sig1 + &sig2)>>1”中,因为&sig1和&sig2符合“& op”条件,所以先会计算&sig1和&sig2的结果,应该为1位,但是作为赋值表达式(赋值表达式右侧操作数位宽由context-determined决定,即由赋值表达式左右两侧位宽最宽的数决定)右侧的操作数“&sig1”和“&sig2”的位宽由赋值表达式两侧的操作数共同决定,因为表达式左侧的result位宽为10位,所以&sig1和&sig2进行“+”操作时,位宽会被扩展为10位宽,所以最终的计算结果如仿真结果所示:’h00_0000_0001。

8th和9th:与7th计算过程类似,此处不再赘述。

10th:在“result = (sig1 + sig2) >>1”中,sig1和sig2在进行计算时的位宽由赋值表达式两侧的操作数共同决定,因为表达式左侧的result位宽为10位,所以sig1和sig2进行“+”操作时,位宽会被扩展为10位宽,所以最终的计算结果如仿真结果所示:’h01_0111_11111。

11th、12th、13th和14th与上述计算过程类似,此处不再赘述。

那么,当赋值表达式左侧操作数的位宽小于右侧某个操作数的位宽时,结算结果还是上述示例那样吗?请看下例。

【示例】

【仿真结果】

示例中,result的位宽为7位,所以7th-14th计算结果相较于上例均发生了高位截断情况。可见,当操作数位于赋值表达式左右两侧时,赋值表达式最终结果的位宽由赋值表达式赋值表达式左侧操作数决定,但是其中的各种运算及中间结果位宽需要对赋值表达式两侧数的位宽都进行考虑,即context-determined。所以,为了获得期望的结果,在使用各种操作数进行运算时,需要注意以下几点:

Ø 操作数的符号特性,是否为有符号数,因为牵扯到数据拓宽时高位补位;

Ø 操作数的位宽,特别是在赋值表达式中位于赋值表达式两侧操作数的位宽;

Ø 操作表达式所使用的运算符(self-determined);

Ø 表达式是否位于赋值表达式中,决定了是self-determined还是context-determined。

而在实际过程中,我们的表达式往往即包含了self-determined运算又包含了context-determined,那么我们在具体运算时可以参考如下步骤:

第一步:先确定赋值表达式左右两侧的self-determined运算,并对其完成解析;

第二步:根据赋值表达式两侧最大的位宽对赋值表达式左右两侧表达式的位宽进行扩展;

第三步:左右两侧拓展后的操作数进行相关运算,但是需要注意,赋值表达式的最终结果将不会被拓展;

更多内容请关注下面公众号!

本文纯属学习之用,欢迎指正文中不足,封面图片若有侵权,请及时沟通!

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。