verilog有符号数使用方法简介

参考:

https://www.cnblogs.com/yuandonghua/p/signed.html

https://blog.csdn.net/a389085918/article/details/79915685

1 有符号数定义

        有符号数的定义通过关键词signed实现,如果不使用signed则默认都为无符号数。定义2个8位的有符号的变量:

reg signed [7:0]     a;
wire signed [7:0]    b;

2 有符号数的表示

        verilog中的有符号数以补码形式表示。

reg signed	[7:0]	a;

initial begin

a = -25;

$display("a = %b", a);

a = 37;
	
$display("a = %b", a);

end

        仿真输出:

a = 11100111
a = 00100101

        显然11100111是-25的二进制补码 ,00100101是37的二进制补码。

3 有符号数的使用

        verilog中的有符号数常用于进行运算操作(加、减、乘)。

3.1 $signed()和$unsigned()函数

        在进行有符号数运算的代码设计时,往往需要用到2个系统函数$signed()和$unsigned()。一般$signed()使用较多,$unsigned()使用较少。

        这两个函数的作用是告诉编译器所修饰的变量的二进制数据被当作有符号数($signed())或无符号数($unsigned())来处理。并不对变量数据做任何转换操作。

reg [7:0]               data0;
reg signed [7:0]        data1;

initial begin
	
data0 = 8'b1111_0000;	
	
$display("data0 = %0d", data0);	
$display("data0 = %0d", $signed(data0));

data0 = 8'b0111_0000;

$display("data0 = %0d", data0);
$display("data0 = %0d", $signed(data0));

data1 = 8'b1111_0000;	
	
$display("data1 = %0d", data1);	
$display("data1 = %0d", $unsigned(data1));

data1 = 8'b0111_0000;

$display("data1 = %0d", data0);
$display("data1 = %0d", $unsigned(data1));

end

        仿真结果:

data0 = 240
data0 = -16
data0 = 112
data0 = 112
data1 = -16
data1 = 240
data1 = 112
data1 = 112

3.2 有符号数运算

        在设计时,任何运算的表达式中不能将有符号变量和无符号变量进行混用。必须保证全都为无符号变量或有符号变量,如果至少存在1个无符号变量,那么整个表达式的运算过程会被当作无符号数运算。考虑如下情况:

reg signed	[7:0]   a;
reg [7:0]           b;
reg [8:0]           c;
reg signed [8:0]    d;
				

initial begin
	
a = -7;
b = 138;

$display("a = %b", a);	
$display("b = %b", b);

c = a + b;
d = a + b;

$display("c = %b", c);				
$display("c = %0d", c);	
$display("d = %b", d);	
$display("d = %0d", d);
	
end	

        仿真结果:

a = 11111001
b = 10001010
c = 110000011
c = 387
d = 110000011
d = -125

        显然a和b都被当作无符号数相加。

        如果表达式中存在1个有符号数(a),那么运算结果必须定义为signed有符号变量(d),而且另外的无符号数(b)都应该转换为有符号数的形式表示。这可以通过$signed()来实现。考虑下面两种使用方法:

reg signed [7:0]    a;
reg [7:0]           b;
reg signed [8:0]    d;

initial begin

a = -7;
b = 138;

$display("a = %b", a);	
$display("b = %b", b);

d = a + $signed(b);
$display("d = %b", d);	
$display("d = %0d", d);

d = a + $signed({1'b0, b});
$display("d = %b", d);	
$display("d = %0d", d);

end

        仿真结果:

a = 11111001
b = 10001010
d = 110000011
d = -125
d = 010000011
d = 131

        显然第1种用法的结果是错的,第2种用法的结果是正确的。因为138的8位二进制为10001010,其最高位为1,如果直接使用$signed(b),那么编译器会把10001010当作负数(-118)的二进制补码,所以b就被当作-118使用了。正确的方法应该是在最高位之前补上1个正数的符号位0,确保补码为正数。

  • 31
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MmikerR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值