verilog中符号位的扩展问题

以下内容转自艾米电子 - 使用有符号数,Verilog(http://www.cnblogs.com/yuphone/archive/2010/12/12/1903647.html)

Verilog-1995中的有符号数

在Verilog-1995中,只有integer数据类型被转移成有符号数,而reg和wire数据类型则被转移成无符号数。由于integer类型有固定的32位宽,因此它不太灵活。我们通常使用手动加上扩展位来实现有符号数运算。下面的代码片段将描述有符号数和无符号数的运算:

 1 reg [7:0] a, b;
 2 reg [3:0] c,
 3 reg [7:0] sum1, sum2, sum3, sum4;
 4 . . .
 5 // same width. can be applied to signed and unsigned
 6 sum1 = a + b;
 7 // automatica 0 extension
 8 sum2 = a + c;
 9 // manual 0 extension
10 sum3 = a + {{4{1‘b0}}, c};
11 // manual sign extension
12 sum4 = a + {{4{c[3]}}, c};

在第一条语句中,a、b和sum1有相同的位宽,因此无论是转译成有符号数还是无符号数,它都将引用相同的加法器电路。

在第二条语句中,c的位宽仅为4,在加法运算中,它的位宽会被调整。因为reg类型被作为无符号数看待,所以c的前面会被自动置入0扩展位。

在第三条语句中,我们给c手动前置4个0,以实现和第二个表达式一样的效果。

在第四条语句中,我们需要把变量转译成有符号数。为了实现所需的行为,c必须扩展符号位到8位。没有其他的办法,只好手动扩展。在代码中,我们重复复制c的最高位4次(4{c[3]})来创建具有扩展符号位的8位数。

3 Verilog-2001中的有符号数

在Verilog-2001中,有符号形式也被扩展到reg和wire数据类型中。哈哈,新加一个关键字,signed,可以按照下面的方式定义:

reg signed [7:0] a, b

使用有符号数据类型, 第2节所述代码可以被改写为:

reg signed [7:0] a, b;
reg signed [3:0] c;
reg signed [7:0] sum1, sum4;
. . .
// same width. can be applied to signed and unsigned
sum1 = a + b;
// automatic sign extension
sum4 = a + c;

第一条语句将引用一个常规的加法器,因为a、b和sum1具有相同的位宽。

第二条语句,所有的右手边变量都具有signed数据类型,c被自动扩展符号位到8位。因此,无需再手动添加符号位。

在小型的数字系统中,我们通常可以选用有符号数或者无符号数。然而,在一些大型的系统中,会包括不同形式的子系统。Verilog是一种弱类型语言,无符合变量和有符号变量可以在同一表达式中混用。根据Verilof的标准,只有当所有右手边的变量具有signed数据类型属性的时候,扩展符号位才被执行。否则,所有的变量都只扩展0。考虑下面的代码片段:

1 reg signed [7:0] a, sum;
2 reg signed [3:0] b;
3 reg [3:0] c;
4 . . .
5 sum = a + b + c;

由于c不具有signed数据类型属性,因此右手边的变量b和c的扩展位为0。

Verilog有两个系统函数,$signed和$unsigned(),用以将括号内的表达式转换为signed和unsigned数据类型。比方说,我们可以转换c的数据类型,

sum = a + b + $signed(c);

现在,右手边的所有变量都具有signed数据类型属性,因此b和c将扩展符号位。

在复杂的表达式中,混用signed和unsigned数据类型将引入一些微妙的错误,因此应当避免混用。如果真的很有必要,那么表达式需要保持简单,同时通用转换函数,以确保数据类型的一致性。

时间: 2024-11-06 03:39:23

verilog中符号位的扩展问题的相关文章

Verilog中变量位宽注意

Verilog中,变量定义方式可以为:reg[位宽-1:0] 数据名:reg[位宽:1] 数据名.其他变量也类似. 以reg变量cnt为例,当cnt位宽为4时,可定义为reg[3:0] cnt,或者定义为reg[4:1] cnt 当cnt赋值为3时,reg[3:0] cnt:cnt=3 等效为 cnt[3]=0,cnt[2]=0,cnt[1]=1,cnt[0]=1; reg[4:1] cnt:cnt=3 等效为 cnt[4]=0,cnt[3]=0,cnt[2]=1,cnt[1]=1; 当cnt被

C++ 中注意,零扩展和符号位扩展

版权声明:本文为博主原创文章,未经博主允许不得转载. 首先,介绍一下两种扩展的定义 转 http://blog.csdn.net/jaylong35/article/details/6160736 符号扩展:当用更多的内存存储某一个有符号数时,由于符号位位于该数的第一位,扩展之后,符号位仍然需要位于第一位,所以,当扩展一个负数的时候需要将扩展的高位全赋为1.对于正数而言,符号扩展和零扩展是一样的,因为符号位就是0. 比如一个用一个8位二进制表示-1,则是10000001 如果把这个书用16位二进

浅谈Java中的补零扩展和补符号位扩展

今天,魏屌出了一道题,题目如下: 定义一个大头序的byte[]a={-1,-2,-3,-4},转换成short[]b.问b[0]和b[1]分别是多少? 乍一看,这题不难,无非就是移位操作,再进行组合.但是呢?对于用Java的童鞋来说,这里面有一个坑,稍不注意可能就踩进去了.在说之前,我先把代码和答案贴出来吧. 看到这里,可能有的童鞋比较奇怪,为啥要&0xff,这不相当于没变化吗?非也,不信我举个例子. 答案是-127和129.很奇怪不是吗?我想的明明都是-127啊!!! 解答这个问题之前,我们先

char 变成int型后的符号位扩展

二进制负数: 原码就是原来的表示方法 反码是除符号位(最高位)外取反 补码=反码+1 1个字节它不管怎么样还是只能表示256个数,因为有符号所以我们就把它表示成范围:-128-127.它在计算机中是怎么储存的呢?可以这样理解,用最高位表示符号位,如果是0表示正数,如果是1表示负数,剩下的7位用来储存数的绝对值的话,能表示27个数的绝对值,再考虑正负两种情况,27*2还是256个数.首先定义0在计算机中储存为00000000,对于正数我们依然可以像无符号数那样换算,从00000001到011111

关于符号位扩展你又知道多少

转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/37535577 作者:小马 先看两段代码, 一个是C,一个是java. int _tmain(int argc, _TCHAR* argv[]) { char b = 0x83; short s1 = (short)b; short s2 = (short)(b&0xff); printf("s1 = %d\n", s1); printf("s2 = %

有符号数,符号位扩展

char readbuf[64]; int data_size = (readbuf[7]<<24)|(readbuf[4]<<16)|(readbuf[5]<<8)| readbuf[6]; int data_size = (readbuf[7]<<24)+(readbuf[4]<<16)+(readbuf[5]<<8)+readbuf[6]; readbuf :  09 00 3c 16 00 00 96 00 00 00 00

如何去掉[email&#160;protected]中的@符号Linux文件扩展信息

如何去掉[email protected]中的@符号Linux文件扩展信息ls -lart [email protected] 10 rlanffy staff 340B 3 6 2015 [email protected] 1 rlanffy staff 630B 6 10 17:22 [email protected] 1 rlanffy staff 4.8K 8 12 14:17 [email protected] 3 rlanffy staff 102B 8 14 12:10 [emai

二进制中的符号位的区分以及表示

问题1: 二进制中的表数范围是怎么得来的? 无符号是0-255: 有符号是-128-127:为什么是这样的范围? 8位二进制码有2^8=256个状态.如果用来表示无符号数,就可以表示0~255恰好256个二进制数:而如果表示带符号数,则最高位就是符号位,0表示"+",1表示"-",剩下的7位用来表示绝对(采用补码形式).0用"+0"表示,正数为+1~+127,负数为-1~-127,剩下一个"-0"则用来表示-128(在数学中,

c语言中获取整数和浮点数的符号位

1. 为什么要获得符号位 很多时候,我们需要判断数值的正负,来做相应的逻辑处理.条件判断语句可以很好的完成这个需求.有时候会有下面的情况, if (x > 0) { x = x - 1; } else { x = 1 - x; } if (x < 0) { x = -x; } 正负只是数值的符号位变化,或是计算结果的符号位变化.但是我们需要用一个判断,首先条件判断会影响效率,其次格式不够简洁美观.所以,有时候希望能不用条件判断也解决问题.而数值的符号位已经被存储在了数值的最高位,可以利用这点来