内容主要摘自以下两个链接:
现在FPGA编译器都支持verilog有符号运算的综合,并且综合后的有符号数都是以补码形式存在,明白点说,就是编译器可以自动把有
符号数编码成补码形式。具体在有符号数处理过程中注意那些点,
 
1、有符号二进制加减法原理
有符号数通常以2的补码形式来表示。图1列出了4位二进制表示法所对应正负数。进一步观察,我们发现两种类型数的加减法是一样的,
做加法和减法就是 在数轮上按正时钟转转或按反时钟转。比方说,1001+0100,意味着从1001按照顺时钟方向移动4个位置,其结果
为1101。在无符号数类型中,它 代表(+9)+(+4)=+13;而在有符号数类型中,它则代表(-7)+(+4)=-3。
从数轮上看,若是加法所得的结果溢出了,那么也就是穿越了数轮的临界点。注意这个临界点对于无符号数和有符号数来说,是不一样
的:无符号数,是介于1111和0000之间;有符号数,则是介于0111和1000之 间。
物理加减法的行为正好和数轮的移动类似。只要所有的运算子和结果具有相同的位宽,那么有符号数或无符号数的形式就可用于相同的
电路。比方说,设a、b和sum都是8位信号,表达式
1 sum = a+ b;
无论这些信号被转译成有符号数或无符号数,它都会引用相同的硬件且使用相同的二进制表示法。这种现象在其他算术运算中也是正确
的(但是它不可用于非算术运算中,比方说有理数运算或溢出标志位的生成)。
 

图1 4位二进制数轮
2、位扩展
此外,当运算子或其结果的位宽不同时,我们需要注意区分符号类型。因为不同的符号类型需要扩展方式是不同的。
(1)对于无符号数,前置一个0,即所谓的零扩展位;
(2)对于有符号数来说,需要前置n个所谓的符号扩展位。
 
举个例子,设a和sum为8位信号,b为4位信号即b3b2b1b0。表达式
1 sum = a + b
需要将b扩展为8位。如果是无符号数形式,那么b扩展为0000_b3b2b1b0;如果是有符号数形式,那么b扩展为 b3b3b3b3_b3b2b1b0。
上述表达式所引用的硬件包括位宽扩展电路和加法器。因为对于有符号数和无符号数来说,扩展电路是不同的;所以对上面表达式,有
符号数和无符号数形式,要使用不同的硬件实现。
 
3、Verilog-1995中的有符号数
在Verilog-1995中,只有integer数据类型被转移成有符号数,而reg和wire数据类型则被转移成无符号数。由于integer 类型有固
定的32位宽,因此它不太灵活。我们通常使用手动加上扩展位来实现有符号数运算。下面的代码片段将描述有符号数和无符号数的运算:
01 reg [7:0] a, b;
02 reg [3:0] c,
03 reg [7:0] sum1, sum2, sum3, sum4;
04 . . .
05 // same width. can be applied to signed and unsigned
06 sum1 = a + b;
07 // 寄存器c高位自动扩展0
08 sum2 = a + c;
09 // 高位手动扩展0
10 sum3 = a + {4{ 1'b0 }, c};
11 // 高位手动扩展符号位
12 sum4 = a + {4{c[3]}, c};
在第一条语句中,a、b和sum1有相同的位宽,因此无论是转译成有符号数还是无符号数,它都将引用相同的加法器电路。
在第二条语句中,c的位宽仅为4,在加法运算中,它的位宽会被调整。因为reg类型被作为无符号数看待,所以c的前面会被自动置入0扩展位。
在第三条语句中,我们给c手动前置4个0,以实现和第二个表达式一样的效果。
在第四条语句中,我们需要把变量转译成有符号数。为了实现所需的行为,c必须扩展符号位到8位。没有其他的办法,只好手动扩展。
在代码中,我们重复复制c的最高位4次(4{c[3]})来创建具有扩展符号位的8位数。
4、Verilog-2001中的有符号数
在Verilog-2001中,有符号形式也被扩展到reg和wire数据类型中。在定义时加一个关键字signed,可以按照下面的方式定义:
   input  signed [ 7:0] a, b;
   output  signed [15:0] c;
   wire signed [15:0] x;
   reg signed [15:0] y;
使用有符号数据类型, 第2节所述代码可以被改写为:
1 reg signed [7:0] a, b;
2 reg signed [3:0] c;
3 reg signed [7:0] sum1, sum4;
reg signed [10:0] sum5;
4 . . .
5 // same width. can be applied to signed and unsigned
6 sum1 = a + b;
7 // automatic sign extension
8 sum4 = a + c;
sum5 = a + c;
第一条语句将引用一个常规的加法器,因为a、b和sum1具有相同的位宽。
第二条语句,所有的右手边变量都具有signed数据类型,c被自动扩展符号位到8位。因此,无需再手动添加符号位,即使sum5位
宽与a和c都不一样也是会自动扩展到11位的。
5、有符号数与无符号数据混合使用
在小型的数字系统中,我们通常可以选用有符号数或者无符号数。然而,在一些大型的系统中,会包括不同形式的子系统。Verilog
是一种弱类型语 言,无符合变量和有符号变量可以在同一表达式中混用。根据Verilog的标准,只有当所有右手边的变量具有
signed数据类型属性的时候,扩展符号位才被执行。否则,所有的变量都只扩展0。考虑下面的代码片段:
1 reg signed [7:0] a, sum;
2 reg signed [3:0] b;
3 reg [3:0] c;
4 . . .
5 sum = a + b + c;
由于c不具有signed数据类型属性,因此右手边的变量b和c的扩展位为0。
Verilog有两个系统函数,$signed和$unsigned(),用以将括号内的表达式转换为signed和unsigned数据类型。比方说,
我们可以转换c的数据类型,
1 sum = a + b + $signed(c);
现在,右手边的所有变量都具有signed数据类型属性,因此b和c将扩展符号位。
在复杂的表达式中,混用signed和unsigned数据类型将引入一些微妙的错误,因此应当避免混用。如果真的很有必要,那么
表达式需要保持简单,同时通用转换函数,以确保数据类型的一致性。
需要补充的是$signed和$unsigned是可以综合的。
 
5、对于有符号的移位运算“>>”,高位是补0的
 
例子:对输入a,b取平均值,然后赋值给c输出
     always @(posedge clk)
        c<=(a+b)>>1;
1.a,b均为无符号数,结果正确
2.a,b中一个为有符号数(a),另一个为无符号数(b),编译器会自动将无符号数(b)转换成有符号数,这样就成了2个有符号数
之间的运算了,结果是个有符号数,此时
1>如果a+b结果为正数(最高位为0),那么结果正确
2>如果a+b结果为负数(最高位为1),那么结果错误,因为移位运算新移入的位将用0来填补,此时负数将变为正数,显然错误。
 
所以综上,在进行有符号数运算的时候,最好像如下这样写:
reg signed [3:0] a;
reg signed [3:0] b;
reg signed [3:0] c;
 always @(posedge clk)
c<=(a+b)/2;
这样就可以避免不必要的错误。
 
 
 
 
 

Verilog有符号数处理的更多相关文章

  1. verilog 有符号数运算

    1)之前的笔记写过<补码探讨>,可知在FPGA综合成电路的时候最底层都是以补码的形式在运算,正数的补码就是本身,负数的补码要取反+1. (2)那么Verilog中编程的时候对编程人员来说, ...

  2. verilog中的有符号数运算

    verilog中的有符号数运算 http://hi.baidu.com/lixu1113/item/d00dc095f86aed48f142159a verilog中的有符号数运算 有符号数的计算:若 ...

  3. verilog中的有符号数理解(转)

    verilog中的有符号数运算 有符号数的计算:若有需要关于有号数的计算,应当利用Verilog 2001所提供的signed及$signed()机制. Ex: input  signed [7:0] ...

  4. verilog中符号位的扩展问题

    以下内容转自 艾米电子 - 使用有符号数,Verilog(http://www.cnblogs.com/yuphone/archive/2010/12/12/1903647.html) Verilog ...

  5. Verilog有符号整型数(signed int)比大小

    本文参考了https://blog.csdn.net/wenxinwukui234/article/details/42119265/ 关于2进制补码的思考和讨论. ================= ...

  6. C语言基础(5)-有符号数、无符号数、printf、大小端对齐

    1.有符号数和无符号数 有符号数就是最高位为符号位,0代表正数,1代表负数 无符号数最高位不是符号位,而就是数的一部分而已. 1011 1111 0000 1111 1111 0000 1011 10 ...

  7. matlab和FPGA中无符号数和有符号数的转化(转)

    在FPGA 设计过程中经常会遇到关于数表示之间的转化问题,最常见的是无符号数和有符号数之间的转化问题.(1)在FPGA设计过程中,能够很直接的看出数字的位宽,但经常以无符号数的形式输出,在后继的处理中 ...

  8. quartus ii有符号数的问题(待完善)

    1.有符号数是以补码的形式存储的,在modelsim仿真时,补码自动转换为有符号的十进制数. 2.关于截位的问题: 当只取寄存器中的其中m位时,这时候取得的数是按照无符号位来处理的? 3.reg型数据 ...

  9. C语言中无符号数和有符号数之间的运算

    C语言中无符号数和有符号数之间的运算 C语言中有符号数和无符号数进行运算(包括逻辑运算和算术运算)默认会将有符号数看成无符号数进行运算,其中算术运算默认返回无符号数,逻辑运算当然是返回0或1了. un ...

随机推荐

  1. neo4j配置(转)

    我的neo4j配置 # 修改第9行,去掉#,修改数据库名 dbms.active_database=wkq_graph.db # 修改第12行,去掉#.修改路径,改成绝对路径 dbms.directo ...

  2. java 与 CDH kafka集成

    本文主要是通过在网上找到的例子进行演示: 一.说明      开发环境如下:      idea + jdk 1.8 + maven      maven 中引用的架包如下: 二. 生产者 impor ...

  3. margin居中显示

    标签(空格分隔): margin居中 margin居中: 如下图的代码查看: <!DOCTYPE html> <html lang="en"> <he ...

  4. gym 101982 B题 Coprime Integers

    题目链接:https://codeforces.com/gym/101982/attachments 贴一张图吧: 题目意思就是给出四个数字,a,b,c,d,分别代表两个区间[a,b],[c,d],从 ...

  5. centos7 安装部署jenkins

    一.简介 jenkins是一个Java开发的开源持续集成工具,广泛用于项目开发,具有自动化构建.测试和部署等功能,它的运行需要Java环境. 二.搭建环境准备:# cat /etc/redhat-re ...

  6. Tomcat start.bat闪退:JRE_HOME环境变量配置不对

    最近在配置Tomcat上遇到startup.bat启动闪退,在网上找了很多方法,都没解决.后来在网上找到两种问题,更改了两次,解决了.现将我遇到的问题分享,希望对遇到同样问题有帮助. 1.很多初学者对 ...

  7. vue动态绑定background:url绑不上的问题

    场景: 利用swipper做轮播图,在联调的时候发现有些图片存在有些图片不存在 原因:图片路径中存在 (),和 background:url() 会冲突 解决方法: 一:oss图片路径避免出现括号 ( ...

  8. slot-scope

    插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示.以及怎样显示由父组件来决定. 实际上,一个slot最核心的两个问题在这里就点出来了,是显示不显示和怎样显示. 由于插槽是一块模板,所 ...

  9. MyEclipse 编译错误 web项目中的 js,jsp报错 更改

    搜索   validation   语法检测 必须 选定一个  不然不编译

  10. SqlServer数据库链接字符串

    完整链接字符串: 1."DataSourse=.\你的实例;Initial Catalog=yourdatabase;User ID=*;Password=*;Trusted_Connect ...