verilog有符号数使用方法简介

本文深入探讨Verilog中有关有符号数的定义、表示及使用方法,包括如何通过signed关键字定义有符号变量,以及补码形式的表示方式。文章还详细介绍了$signed()和$unsigned()函数的应用,并通过实例演示了有符号数运算的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:

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,确保补码为正数。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

MmikerR

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

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

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

打赏作者

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

抵扣说明:

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

余额充值