Verilog 中signed和$signed()的用法

关注、星标公众号,精彩内容每日送达
来源:网络素材

1、在verilog中有时会用signed修饰符来修饰定义的数据,运算的时候也会用$signed()任务来强制转换数据,那么signed的修饰是为什么呢,是为了区分有符号数和无符号数的加法和乘法吗?其实不是的,因为有符号数和无符号数据的加法强结果和乘法器结构是一样的,signed的真正作用是决定如何对操作数扩位的问题。

2、verilog中的加法和乘法操作前,会先对操作数据扩位成结果相同的位宽,然后进行加法或者乘法处理。比如a/b都为4位数据,c为5位数据,c = a + b,这个运算的时候会先把a和b扩位成5位,然后按照无符号加法进行相加。a/b没有被signed修饰的时候会按照无符号数的扩位方式进行扩位,即高位补0,加法的结果当然也是a、b为无符号数相加的结果。

3、如果想把a、b作为有符号数来相加,那么就得在a/b数据定义的时候用signed修改,或者在计算的时候用$signed()来修饰,这样在c = a + b,这个运算开始的扩位就会按照有符号数的方式进行扩位,在高位补符号位,加法得出的结果就是a、b视为有符号数的结果。当然c要视为有符号数据。

e5e16464b9fcd31cd9fac19499d8e86e.png3e283d2705ad4a151a98b39e1ae64a77.png

4de3790a6bc58eb632d596f35927a568.png

$signed()函数

返回有符号的值,值得注意的是verilog中的负数其实是{1’b1,pos_num},而并非高级语言中的补码。使用中最好通过增加$signed{1’b符号,正数}来实现转换以避免错误。

此外在对signed wire 或signed reg 赋值时,右侧的所有变量最好全部加上$signed函数转换,以防止遗漏,造成数据错误

signed变量移位操作时最好使用<<<和>>>,防止对符号位进行操作,导致数据出错

(全文完)

图片

想要了解FPGA吗?这里有实例分享,ZYNQ设计,关注我们的公众号,探索

### Verilog 中 `$signed` 的用法Verilog 中,`$signed` 是一种用于显式指定表达式的有符号属性的关键字。它通常被用来处理无符号数据类型的数值运算,使其按照有符号数的方式参与计算或比较操作。 #### 基本概念 当变量未声明为 `signed` 类型时,默认情况下会被视为无符号数。如果需要将其作为有符号数来解释,则可以使用 `$signed` 关键字强制转换其行为[^1]。这使得设计者能够在不改变原始信号定义的情况下灵活控制数值的解析方式。 #### 使用场景 以下是几个常见的应用场景: 1. **算术运算** 如果两个操作数之一是非 signed 定义而另一个是 signed 或者两者均为 unsigned 但是期望按带符号方式进行加减乘除等操作时,可以通过应用此函数实现正确结果。 2. **条件判断** 对于涉及负值检测或者范围检查的情况尤其重要,因为错误地将正整数当作补码形式可能会引发逻辑失误。 3. **接口传递参数** 当模块间交换的数据可能具有不同签名特性时(即发送方视作 signed 而接收端默认 unsigned),利用该机制可确保一致性。 #### 示例代码展示 下面提供了一些具体的例子说明如何运用 `$signed`: ```verilog // Example demonstrating arithmetic operations using $signed. module arithmetics; reg [7:0] a = 8'b1111_1111; // -1 as twos complement but treated as 255 by default wire [9:0] sum; always @(*) begin // Treat 'a' as signed during addition even though declared without sign attribute sum = $signed(a) + 8'd1; end endmodule :aritmetics ``` 在此片段中,尽管寄存器 `a` 初始化了一个典型的八位二进制反码表示 `-1`,但由于缺乏 explicit declaration, 默认会认为这是个很大的正值 (`255`). 加入 `$signed()` 后能够得到预期的结果也就是零. 另外还有关于比较的例子如下所示: ```verilog always @(posedge clk or negedge resetn)begin if(!resetn)begin counter<=0; end else if (($unsigned(counter)<threshold_low)||($signed(counter)>threshold_high))begin state <= NEXT_STATE; end end ``` 这里展示了在一个状态机里混合使用了两种类型转化的情形——对于下限采用的是自然顺序排列所以不需要特别标注;而对于上限则考虑到可能存在溢出到负区域的现象故采用了相应的措施加以防范. ### 总结 通过合理部署 `$signed` 它的对应物 `$unsigned`, 开发人员可以在必要时刻调整数字的表现形态从而避免潜在隐患并提升程序健壮性.[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值