关于有、无符号数之间的运算,经常会混淆,特此记录。
运算规则有以下几条:
- 两个有符号数运算,结果是有符号数。
- 两个无符号数运算,结果是无符号数。
- 一个有符号数和一个无符号数运算,如果结果位宽>操作数位宽,由于操作数中存在无符号数,会默认将有符号数0扩展到结果位宽,再运算(相当于做了无符号运算);如果结果位宽=操作数位宽,由于不需要扩位,此时可以实现有符号与无符号运算。
根据上述规则,需要注意的易错点:
wire [ 7:0] a,b;
wire [15:0] c;
assign c = a*b;//两个无符号数相乘得到无符号结果
assign c = $signed(a)*$signed(b);//两个有符号数相乘得到有符号结果
assign c = $signed(a)*b;//结果是无符号数
assign c = $signed(a*b);//这种写法,会先做两个无符号数相乘,得到无符号数c_unsigned,然后$signed(c_unsigned),要注意这种写法与$signed(a)*$signed(b)是不等价的
如果想做一个有符号数和一个无符号数运算,并得到有符号结果,可以手动将无符号操作数做零扩展至结果位宽,然后使用$signed()函数将运算变为有符号运算。
wire [ 7:0] a,b;
wire [15:0] c;
assign c = $signed(a)*$signed({8'h0,b});//结果是有符号数
如果结果位宽与操作数位宽相同,则可以这样写:
wire [7:0] a,b;
wire [7:0] c;
assign c = $signed(a)*b;
3万+

被折叠的 条评论
为什么被折叠?



