这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 换逻辑分析仪+Verilog算术操作符

共1条 1/1 1 跳转至

换逻辑分析仪+Verilog算术操作符

工程师
2024-11-04 11:43:34     打赏

在Verilog HDL中,算术操作符和运算的符号性(有符号或无符号)是理解复杂表达式和赋值语句行为的关键。


算术操作符

Verilog中的算术操作符包括:


+(加法):支持一元加(正数)和二元加(两个数相加)。

-(减法):支持一元减(负数)和二元减(两个数相减)。

***(乘法):两个数相乘。

/(除法):整数除法,结果截断小数部分。

%(取模):求余数,结果的符号与第一个操作数相同。

****(幂运算):计算一个数的幂次方。


运算结果的符号性和位宽

符号性:Verilog中的变量可以是无符号的(默认)或有符号的(通过signed关键字指定)。当表达式中的操作数既有有符号又有无符号时,Verilog会按照特定的规则处理。

表达式中有一个无符号操作数,则其他操作数会被隐式转换为无符号数进行运算。这可能导致意想不到的结果,特别是当涉及到负数时。

位宽:运算结果的位宽由参与运算的操作数中最大的位宽决定。在赋值语句中,如果目标变量的位宽小于运算结果的位宽,则结果会被截断以匹配目标变量的位宽。

如目标变量的位宽大于运算结果的位宽,则结果可能会被符号扩展(对于有符号数)或零填充(对于无符号数)以匹配目标变量的位宽。


示例分析

有符号和无符号数的赋值:

reg [0:5] burst_data; // 无符号寄存器  
integer mtx_addr; // 有符号整型变量  
burst_data = -4'd12; // 赋值给无符号寄存器,结果为52(二进制110100)  
mtx_addr = -4'd12; // 赋值给有符号整型变量,结果为-12(二进制补码110100)


在这个例子中,虽然两个表达式都使用了相同的二进制位模式110100,但由于目标变量的符号性不同,因此解释也不同。


混合有符号和无符号操作数的运算:

burst_data = -4'd12 / 4; // 无符号除法,结果为61(二进制111101,解释为无符号数)  
mtx_addr = -4'd12 / 4; // 有符号除法,结果为-3(二进制补码表示)

在这个例子中,由于burst_data是无符号的,因此除法运算也是无符号的,结果为正数。而mtx_addr是有符号的,因此除法运算也是有符号的,结果为负数。

使用signed和unsigned系统函数:

burst_data = $signed(4'b1101) + 4'sb1001; // 结果为-5(因为$signed将4'b1101解释为-3)  
mtx_addr = $unsigned(5'sb11010 + 5'sh1C) - 5'b01001; // 结果取决于具体的运算过程

在这个例子中,$signed和$unsigned系统函数用于显式地将操作数转换为有符号或无符号数,以控制运算的符号性。

step1:确定输出结果位宽。(一个符号位+两个数据有效为的位宽之和,如1个4bit的有符号数A,和1个5bit的有符号数B相乘,A的有效位是3bit,B的有效位为4bit,则输出结果的有效位宽为7bit,总位宽为8bit)。

step2:计算输出结果的符号位。(两个数据的符号位进行异或,判断是正数还是负数)。

step3:计算输出结果的有效位。(直接将两个数据相乘,得到的结果就是输出结果的有效位)。

step4:将符号位和有效位拼接后输出。

例4:(-3)*(-6)

分析:-3用有符号数表示,原码为3bit的111。-6用有符号数表示,原码为4bit的1110。

step1:确定输出结果位宽。(-3的有效位是2bit,-6的有效位为3bit,则输出结果的有效位宽为5bit,总位宽为6bit)。

step2:计算输出结果的符号位。两个数据的符号位都是1,则1^1=0,则输出结果是正数。

step3:计算输出结果的有效位。2'b11 * 3'b110 = 5'b1_0010。

step4:将符号位和有效位拼接后输出。out=6'b01_0010(+18)

ps:如果输入是补码,则运算之前先转换为原码,在按照以上步骤即可。


无符号数

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

image.png

wire [3:0] a=4’b1111;
wire [3:0] b=4’b0010;
wire [2:0] c;
assign c = a + b;

image.png


有符号数

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;

image.png

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;

image.png


总结

在Verilog中,要特别注意操作数的符号性和位宽,以避免意外的运算结果。

当表达式中混合了有符号和无符号操作数时,要特别小心,因为Verilog会按照特定的规则进行隐式转换。

使用$signed和$unsigned系统函数可以显式地控制运算的符号性。

在编写Verilog代码时,应该清晰地指定变量的符号性和位宽,以确保代码的正确性和可读性。


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]