verilog有符号数使用方法简介

您所在的位置:网站首页 有符号的二进制运算怎么判断结果的符号 verilog有符号数使用方法简介

verilog有符号数使用方法简介

2024-07-10 12:57| 来源: 网络整理| 查看: 265

参考:

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3