Verilog有符号数与无符号数的数值运算

本文详细解析了Verilog HDL中无符号数与有符号数的运算规则,包括位宽不足时的处理方式、中间结果移位操作及不同数制间的运算特性,并对比了逻辑右移与算术右移的区别。

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

一、无符号数

1.高位溢出赋给一个位宽不够的数 

wire [3:0] a=4'b1111;//15
wire [3:0] b=4'b0010;//2
wire [3:0] c;

assign c = a + b;//17=10001

 

wire [3:0] a=4'b1111;
wire [3:0] b=4'b0010;
wire [2:0] c;

assign c = a + b;

高位截断,保留低位 ;

2.高位溢出赋给一个位宽足够的数 

wire [3:0] a=4'b1111;
wire [3:0] b=4'b0010;
wire [4:0] c;

assign c = a + b;

 结果正确;

3.对中间结果移位 

wire [3:0] a=4'b1111;
wire [3:0] b=4'b0010;
wire [3:0] c;

assign c =(( a + b) >> 1); //17=10001

 可以看出是先赋值再移位的

wire [3:0] a=4'b1111;
wire [3:0] b=4'b0010;
wire [4:0] c;

assign c =(( a + b) >> 1); //17=10001

结果正确,左边补0; 

wire  [3:0] a=4'b1111;
wire  [3:0] b=4'b0010;
wire  [4:0] c;

assign c = ((a + b)>>>1) ;

 

>>>算数右移,无符号数还是补0; 


二、有符号数

1.正常运算 

wire signed [3:0] a=4'b1111;//-1
wire signed [3:0] b=4'b0010;//2
wire signed [3:0] c;

assign c =a + b;

 

wire signed [3:0] a=4'b1110;//-2
wire signed [3:0] b=4'b0001;//1
wire signed [3:0] c;

assign c =a + b;

 

2.赋给位宽不够的数 

wire signed [3:0] a=4'b0111;//7
wire signed [3:0] b=4'b0010;//2
wire signed [3:0] c;

assign c =a + b; //9=01001

 wire signed [3:0] a=4'b1001;//-7
wire signed [3:0] b=4'b1110;//-2
wire signed [3:0] c;

assign c =a + b;//-9=10111

舍弃高位 ;

3.赋给位宽足够的数 

wire signed [3:0] a=4'b0111;
wire signed [3:0] b=4'b0010;
wire signed [4:0] c;

assign c =a + b;

 4.给中间结果移位

wire signed [3:0] a=4'b1001;//-7
wire signed [3:0] b=4'b1110;//-2
wire signed [3:0] c;

assign c =(( a + b ) >> 1); //-9=10111

 

wire signed [3:0] a=4'b0111;//7
wire signed [3:0] b=4'b0010;//2
wire signed [3:0] c;

assign c =(( a + b ) >> 1);//9=01001

 逻辑右移,高位都是都是补0;

wire signed [3:0] a=4'b1001;//-7
wire signed [3:0] b=4'b1110;//-2
wire signed [4:0] c;

assign c = ((a + b)>>>1) ;//-9=10111

 

>>>算数右移,截断赋值然后把最高位当符号位,补最高位 ;

总结:

>>逻辑右移,不管有符号还是无符号,都是补0;

>>>算术右移,补最高位;


三、有符号数与无符号数运算 

1.只有两个操作数都是有符号数,才会把两个操作数都看作有符号数计算,否则无论是有符号数还是无符号数都会按照无符号数计算 ;

wire  [3:0] a=4'b1001;
wire signed [3:0] b=4'b1110;
wire signed [4:0] c;

assign c = ((a + b)>>>1);  //-9=10111

 

还是把c当做无符号数移位; 

2.把a赋给b,若a是有符号数,则b高位用a的最高位填充,若a是无符号数,b的高位用0填充 ;

wire  [3:0] a=4'b1001;
wire signed [3:0] b=4'b1001;
wire signed [4:0] c,d;

assign c=a;
assign d=b;

### Verilog有符号数无符号数运算规则 在 Verilog 中处理有符号数无符号数之间的运算是非常重要的,因为这直接影响到程序的行为和结果。以下是详细的运算规则: #### 1. 基本概念 - **无符号数**:表示非负整数值,默认情况下所有的位都是正权。 - **有符号数**:可以表示正数和负数,最高位作为符号位。 #### 2. 运算转换原则 当涉及到不同类型的数进行运算时,遵循特定的原则来决定如何执行这些操作[^1]: - 如果两个操作数均为无符号数,则按无符号数规则进行运算; - 若其中一个为有符号数而另一个为无符号数,在某些上下文中会将它们统一视为无符号数来进行计算[^2]; - 当双方皆是有符号数的时候,则依据有符号数的规定完成相应的加减乘除等动作。 #### 3. 特殊情况下的行为 对于混合模式的操作(即一者为带符号另一者不带),通常编译器会选择把所有参项当作同一种类型对待——要么全部转成无符号形式再做进一步处理;要么保持原有状态并应用对应的算法逻辑去解析最终答案。 #### 4. 比较运算的具体实例 考虑如下代码片段展示了一个具体的例子说明这种差异的影响[^3]: ```verilog reg [3:0] a = 15; // 无符号数, 表示十进制 15 (4&#39;b1111) reg [3:0] b = 14; // 无符号数, 表示十进制 14 (4&#39;b1110) reg signed [3:0] c = -1; // 有符号数, 表示十进制 -1 (4&#39;b1111) reg signed [4:0] d = -2; // 有符号数, 表示十进制 -2 (5&#39;b11110) initial begin if(a <= c) $display("a <= c"); // 成立,因为在比较中二者都被看作无符号数 if(b <= c) $display("b <= c"); // 成立,原因同上 if(c > d) $display("c > d"); // 成立,这里涉及到了不同的宽度但是依然按照各自的补码值对比 end ``` 在这个案例里可以看到即使 `c` 是一个带有符号属性的数据类型,但在其他未指定符号特性的数据相比较时,它会被解释为无符号的形式参到条件判断之中。而对于像 `d` 那样更宽范围内的变量来说也是如此,尽管其内部存储的是负数值,不过一旦进入表达式的求解过程就会依照所处环境的要求调整自身的表现方式以便于顺利完成整个评估流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值