Verilog -- 有符号与无符号运算

目录

  • Verilog中有符号与无符号的加法和乘法运算

    • 无符号乘法和加法
    • 有符号乘法和加法
      • 有符号和无符号运算

参考:
https://blog.csdn.net/vivid117/article/details/101427302
http://wscentity.lofter.com/post/1d00edbd_6476453

Verilog中有符号与无符号的加法和乘法运算

无符号乘法和加法

对于无符号的乘法和加法,没有什么好说的,就是直接用‘*’和‘+’。

有符号乘法和加法

有符号和无符号运算

verilog里如果有符号数和无符号数做运算,会强制当作无符号运算
这就涉及verilog处理运算时的法则:
例如 c = a + b; 其中a和b都是四位数,c是五位。在计算时,verilog会将a和b都扩展到5位,然后再做加法,而如果a和b中有无符号数,则位宽扩展就按照无符号数来,也就是高位补0。所以如果a和b中既有无符号又有有符号,结果就不正确了。
解决方法是用 \$signed()来修饰:c = a + $signed(b)这样在c = a + b,这个运算开始的扩位就会按照有符号数的方式进行扩位,在高位补符号位,加法得出的结果就是a、b视为有符号数的结果。
例子:

||| |||
||| |||

可见结果是不是signed倒是无所谓的。但是最好还是加上。

有符号数乘法

例如有符号数[3:0]a * [3:0]b. 其中a=-5,b=7。a用补码表示为1011,b用补码表示是0111,对于这个例子,乘法过程如下:

其中,b的符号位跟a相乘的时候需要注意,如果b的符号位是1,则与a相乘的时候实际表示的是-1*a,所以需要将a的结果按位\(\color{red}{取反加一}\)。上面的例子b的符号位是0,所以结果是101_1101,补码是1100011 = -35。如果遇到符号位是1的情况,比如a=-5,b=-3:

可以看到上面最后一行的结果需要对a进行\(\color{red}{取反加一}\)才正确,并且此时\(\color{red}{取反加一也包括a的符号位}\)。
另外,还需要注意的是所有部分积都要补符号位补到乘法输出值的位数。
其实乘法器就是由加法组成,所以b中的每一位跟a做乘法(异或)之后把部分积累加时,仍然需要遵从加法的原则,扩展符号位直到达到输出位宽,然后再加。
所以有符号乘法跟无符号乘法的区别就在这,无符号乘法不需要考虑符号位扩展问题,而有符号乘法在累加部分积的时候需要做符号位扩展,并且还要考虑符号位参与乘法时的含义不同,也就是说符号位的0表示0,但1却表示-1,所以符号位的1做乘法就不是异或而是\(\color{red}{对所有位取反再加一}\)了。

原文地址:https://www.cnblogs.com/lyc-seu/p/12533226.html

时间: 2024-08-07 22:45:03

Verilog -- 有符号与无符号运算的相关文章

有符号和无符号类型运算

#include <iostream> int main() { unsigned i = 10 , j = 30 ; int m = -42 , n = 30 ; std::cout<<i-j<<std::endl; std::cout<<m*i<<std::endl; std::cout<<unsigned(-420)<<std::endl; return 0 ; } 结论:有符号和无符号类型相运算(加减乘除),先运算

C语言的有符号与无符号,二进制整数的扩展与截断

前一节说了整数的表示方式,,也就是无符号编码与补码编码.这一届说一下二进制整数的扩展与截断,这部分内容与C语言挂钩.so,我们先看以下C语言的有符号和无符号数. C语言中的有符号数和无符号数 有符号数和无符号数的本质区别其实就是采用的编码不同,前者采用补码编码,后者采用无符号编码. 在C语言中,有符号数和无符号数是可以隐式转换的,不需要手动实施强制类型转换.不过也正是因为如此,可能你一不小心就将一个无符号数赋给了有符号数.就会造成出乎意料的结果,就像下面这样: #include <stdio.h

C之有符号与无符号(二)

我们在 C 语言中经常会见到 unsigned 关键字,那么这是什么意思呢?在计算机内,数据类型分为有符号和无符号两种类型.它的最高位用于标识数据的符号:如果最高位为 1,表明这个数为负数:如果是0的则表明这个数为正数.那么我们就来做个试验验证下,代码如下所示: #include <stdio.h> int main() {     char c = -5;     short s = 6;     int i = -7;          printf("c : %d\n"

int类型有符号与无符号内存中 -- C

/* int 有符号 0xffffffff == -1 0xfffffffe == -2 最小 0x80000000 == -21 4748 3648 最大 0x7fffffff == 21 4748 3647 0x00000001 == 1 0x00000000 == 0 int 无符号 最大 0xffffffff == 42 9496 7295 0x80000000 == 21 4748 3648 0x7fffffff == 21 4748 3647 最小 0x00000000 == 0 *

结构体位制 中存在 有符号 与 无符号 -- C

#include <stdio.h> #include <stdlib.h> #include <string.h> /* 有符号 结构体1 */ struct bits { int b1:5; /* 因为是int型,最大设置32位,由于int型是有符号整形, 所以这里5位为有符号类型. 11111 -1 10000 -16 01111 15 00000 0 */ int :2; int b2:2; /* 11 -1 10 -2 01 1 00 0 */ int b3:

C语言 有符号、无符号

C语言 有符号.无符号 有符号无符号说明 一.有符号 signed char 8bit 取值范围:-2^7 ~ 2^7-1 . -128~127 int 32bit 取值范围:-2^31 ~ 2^31-1 . -2147483648~2147483647 long long 64bit 取值范围:-2^63 ~ 2^63-1 #include <stdio.h> int main() { signed int a = -1089474374; //定义有符号整型变量a printf("

有符号和无符号数据类型

原版出处:http://bbs.csdn.net/topics/340253678 C语言中提供了很多整数类型(整型),主要区别在于它们取值范围的大小.int代表有符号的整数,也就是说,用int声明的变量可以是正数也可以是负数,也可以是零,但是只能是整数.比如:int a = 3; int b = 0; int c = -5;以上这些都是合法的.int的取值范围因机器而异,一般而言,在较旧的PC上,int值在内存中一般是按2个字节(16位)进行存储的,在较新的PC以及工作站和大型机上,int值在

Java-java中的有符号,无符号操作以及DataInputStream

1. 无符号和有符号 计算机中用补码表示负数,并且有一定的计算方式:另外,用二进制的最高位表示符号,0表示正数.1表示负数.这种说法本身没错,可是要有一定的解释,不然它就是错的,至少不能解释,为什么字符类型的-1二进制表示是“1111 1111”16进制表示为FF,而不是1000 0001. 在计算机中,可以区分正负的类型,称为有符号类型,无正负的类型,称为无符号类型. 使用二进制中的最高位表示正负 一个字节为8位,按0开始记,那它的最高位就是第7位,2个字节,最高位就是15位,4个字节,最高位

C语言进阶——有符号与无符号02

在计算机的内部,我们所有的信息都是由二进制数字组成的 有符号数的表实法: 在计算机内部用补码的方式表实有符号数 正数的补码位正数的本身 负数的补码为其绝对值取反然后加一得到 例如-7 他在计算机内部的是1111 1001          是这样得到的 7->111->0000 0111->1111 1000->1111 1001 无符号整数的表示: 在计算机内部用原码表实无符号整数 无符号整数默认为正数 无符号整数没有符号位 对于固定长度的无符号整数: max+1=min min