sv运算符,二进制原码反码补码,

1. 注意区别 逻辑操作、按位操作、缩减操作;

逻辑操作通常使用双符号表示,如逻辑与&&,逻辑等==,逻辑左移<<等,其结果可为0,1,x;
按位操作一般使用单符号表示,如按位与&,按位或~,按位异或^等,结果一般为多比特数;
缩减操作也使用单符号表示,但是其操作结果区别于按位操作结果,只能为0,1,x

2. 注意区别逻辑等操作、算术等操作;

逻辑等操作的比较结果可以为0,1,x;而算术等操作的比较只能为0,1;

3. 注意理解逻辑移位的含义,区别于算术移位;

当移位操作一侧都为0时,逻辑左移n位相当于乘以2^n, 逻辑右移n位相当于除以2 ^n;

4. 常用操作有条件操作、拼接和复制操作;

5. 操作符的运算顺序遵循优先级从高到低执行;

一、算术操作符(+ - * / % **)


+ ( 一元加和二元加)    -(一元减和二元减)     *(乘)    /(除)
%(取模,即取余数)    * *(幂运算)


二、相等操作符(==  ! =   ===  ! ==  ==?  !=?)


==(逻辑相等)            !=(逻辑不等)

===(算术全等,case equality)     ! ==(算术非全等,case inequality)

==?(通配符逻辑相等)        !=?(通配符逻辑不等)
 

举例说明逻辑等与算术等的区别:例如:
data = 'b11x0;
addr = 'b11x0;
data == addr;      //该逻辑比较的结果未知,即为x
                   //1. **通常在逻辑比较中,如果有一个操作数中包含有x或z,则结果必定为未知值(x)**
                   
data === addr;     //该算术比较的结果为真,即为1
                   //2. **在算术比较中,把x和z直接当做数值(不考虑物理含义)严格按照字符值进行比较,所以结果只能是0和1**
                   
带有通配符的逻辑等符号,会把**右侧操作数中的x和z直接屏蔽掉**;例如:
data = 'b010z;
addr = 'b0101;
data ==? addr;      //该逻辑比较的结果未知,左侧操作数含有z,不能做匹配值

addr ==? data;      //该逻辑比较的结果为真,值为1
                    //3. **右侧操作数中含有z,被屏蔽,可以直接匹配左侧的1**

三、逻辑操作符(&& || !)

  • &&(逻辑与)    ||(逻辑或)    !(逻辑非)
**无论是单bit数还是多bit数,逻辑操作符运行的结果只能是0,1或者x**,例如:
lock = 'b0110;
port = 'b0100;
lock && port;    //结果为真,即值为1
lock || port;    //结果为真,值为1
!lock;           
!port;           //逻辑非的结果都为0

假设任意操作数内某一位为x或z,如果逻辑操作的结果是未定的,则运算的结果为x。
'b1 || 'bx       //结果为1
'b0 && 'bz       //结果为0
!x               //结果为x

四、按位操作符(~ & | ^  ^~或 ~^)

  • ~(一元非)    &(二元与)    |(二元或)
  • ^(二元异或)     ^ ~, ~ ^(二元同或)
按位操作符区别于逻辑操作符,按位操作的结果不是单一的0或1,**结果位宽与操作数的位宽保持一致。**例如:
a = 'b0110;
b = 'b0100;
a | b;         //结果为'b0110
a & b;         //结果为'b0100

  如果两个操作数的位宽不等,且其中一个操作数为无符号数,则位宽较小的数用0在高位补齐。
  如果两个操作数均为有符号数,则位宽较小的操作数用符号位在高位与位宽最大的数补齐,然后开始操作。例如:
'b0110 ^ 'b10000;
等价于:
'b00110 ^ 'b10000;      //结果为'b10110

4'sb1010 & 8'sb01100010;
等价于:
4'sb11111010 & 8'sb01100010;   //结果为8'sb01100010

五、缩减操作符(& ~& |  ~|  ^  ~^)

  • &(缩减与)    ~ &(缩减与非)    |(缩减或)    ~|(缩减或非)
  • ^ (缩减异或)    ~^(缩减同或)
缩减操作符是对单一操作数上的所有位进行操作,产生1位的操作结果,其结果可以是0,1或者x,例如:
a = 'b0110;
b = 'b0100;
|b;         //结果为'b1
&b;         //结果为'b0
^a;         //结果为'b0
~^a;        //结果为'b1

addr = 4'b01x0;
^addr;       //结果为x
缩减异或操作可以用来确定变量中是否存在任何值为x的位;可以通过if语句进行检查:
if(^addr === 'bx)
   $display("There is an unknown in addr variable");
注意,此处的比较只能使用算术全等进行比较,因为逻辑等的比较结果只能是x,而算术全等比较的结果1,那才是期望的结果。

六、移位操作符(<< >> <<< >>>)

  • <<(逻辑左移)        >>(逻辑右移)
  • <<<(算术左移)        >>>(算术右移)
逻辑移位:由于移位而腾空的位总是填0;
算术移位:左移位腾出空位填0;右移腾出位,对于无符号数填0,对于有符号数填符号位;
reg  [7:0] q;
reg signed [3:0] pm;

q = 8'h17;
pm = 4'sb1011;
则:           //8'h17 = 8'b0001_0111;
q >> 2;       //结果为8'b0000_0101;
q << 2;       //结果为8'b0101_1100;
q <<< 4;      //结果为8'b0111_0000;
q >>> 2;      //结果为8'b0000_0101;

pm >>> 2;     //结果为4'sb1110, 用到了符号位1;

移位操作符可以被用来完成指数运算,但是有一定的约束条件。

 

七、关系操作符(> < >= <=)

  • <(小于)      >(大于)
  • <=(小于等于)    >=(大于等于)
  • 关系操作符的结果为真(结果为1)或假(结果为0),如果操作书中有一位为x或z,则结果为x.
     

八、条件操作符(?:)

  • cond_expresson ? expression1 :expression2
    条件操作符等价于if_else语句。如:
    always @(posedge clk)
       ctr = (data != 25)?(data+1):5;
    //即如果data != 25,则data = data+1;否则 data= 5;
    

    九、拼接和复制操作符({expre1,expres2,…} {repeat_number{expression}})

  • {expre1,expres2,…,expresN}(拼接操作符)       

  •  {repeat_number{expres1,expres2,…,expresN}}(复制操作符)

abus = {3{4'b1011}};           //结果为12'b1011_1011_1011
abus = {{4{1'b1}},4'b1011};    //结果为8'b1111_1011

name = {3{ack}};               //结果与{ack,ack,ack}相同

十、优先级列表 

十一、原码

原码:是最简单的机器数表示法,用最高位表示符号位,其他位存放该数的二进制的绝对值

以带符号位的八位二进制数为例:0010,最高位为1表示这是个负数,在右数第2位有个1,即1*2^1=2,所以表示十进制数-2。

十二、反码

反码:正数的反码和原码一致;负数的反码就是它的原码除符号位外,按位取反

十三、补码

补码:正数的原码、反码、补码都一致;负数的补码等于反码+1

十四、二进制转换

  • 二进制
二进制,逢二进一,数字中只有 0 和 1
例如,数数,二进制的数法是:0,1 接着 10,11 接着 100,101,110,111 接着 1000,1001 ... 1111 以此类推。
  • 十进制
十进制,逢十进一,数字中含有 0,1,2,3,4,5,6,7,8,9
十进制是我们从小就开始学习的,应该没有人不会吧,从1数到100会把,哈哈。
  • 十六进制
十六进制,逢十六进一,表示形式比较特殊,因为10~15不能用数字来展示,不然就乱套了。所以强制规定如下
10 用 A 表示、11 用 B 表示、12 用 C 表示、13 用 D 表示、14 用 F 表示。
那么数数的数法也同理,从 0 ~ F 接着 10 ... 1F ... FF 接着 100 ...... FFF 以此类推。

二进制、八进制、十六进制转换成十进制 

1) 整数部分

例如,将八进制数字 53627 转换成十进制:

53627 = 5×8^4 + 3×8^3 + 6×8^2 + 2×8^1 + 7×8^0 = 22423(十进制)

再如,将十六进制数字 9FA8C 转换成十进制:

9FA8C = 9×16^4 + 15×16^3 + 10×16^2 + 8×16^1 + 12×16^0 = 653964(十进制)

将二进制数字转换成十进制也是类似的道理

11010 = 1×2^4 + 1×2^3 + 0×2^2 + 1×2^1 + 0×2^0 = 26(十进制)

2) 小数部分

例如,将八进制数字 423.5176 转换成十进制:

423.5176 = 4×8^2 + 2×8^1 + 3×8^0 + 5×8^-1 + 1×8^-2 + 7×8^-3 + 6×8^-4 = 275.65576171875(十进制)

小数部分和整数部分相反,要从左往右看,第1位的位权为 8^-1=1/8,第2位的位权为 8^-2=1/64,第3位的位权为 8^-3=1/512,第4位的位权为 8^-4=1/4096 …… 第m位的位权就为 8^-m。

再如,将二进制数字 1010.1101 转换成十进制:

1010.1101 = 1×2^3 + 0×2^2 + 1×2^1 + 0×2^0 + 1×2^-1 + 1×2^-2 + 0×2^-3 + 1×2^-4 = 10.8125(十进制)

小数部分和整数部分相反,要从左往右看,第1位的位权为 2^-1=1/2,第2位的位权为 2^-2=1/4,第3位的位权为 2^-3=1/8,第4位的位权为 2^-4=1/16 …… 第m位的位权就为 2^-m。

将十进制转换为二进制、八进制、十六进制

将十进制转换为其它进制时比较复杂,整数部分和小数部分的算法不一样,下面我们分别讲解。

1) 整数部分

十进制整数转换为 N 进制整数采用“除 N 取余,逆序排列”法。具体做法是:

  • 将 N 作为除数,用十进制整数除以 N,可以得到一个商和余数;
  • 保留余数,用商继续除以 N,又得到一个新的商和余数;
  • 仍然保留余数,用商继续除以 N,还会得到一个新的商和余数;
  • ……
  • 如此反复进行,每次都保留余数,用商接着除以 N,直到商为 0 时为止。

把先得到的余数作为 N 进制数的低位数字,后得到的余数作为 N 进制数的高位数字,依次排列起来,就得到了 N 进制数字。

下图演示了将十进制数字 36926 转换成八进制的过程:

从图中得知,十进制数字 36926 转换成八进制的结果为 110076。

下图演示了将十进制数字 42 转换成二进制的过程:

从图中得知,十进制数字 42 转换成二进制的结果为 101010。

2) 小数部分

十进制小数转换成 N 进制小数采用“乘 N 取整,顺序排列”法。具体做法是:

  • 用 N 乘以十进制小数,可以得到一个积,这个积包含了整数部分和小数部分;
  • 将积的整数部分取出,再用 N 乘以余下的小数部分,又得到一个新的积;
  • 再将积的整数部分取出,继续用 N 乘以余下的小数部分;
  • ……
  • 如此反复进行,每次都取出整数部分,用 N 接着乘以小数部分,直到积中的小数部分为 0,或者达到所要求的精度为止。

把取出的整数部分按顺序排列起来,先取出的整数作为 N 进制小数的高位数字,后取出的整数作为低位数字,这样就得到了 N 进制小数。

下图演示了将十进制小数 0.930908203125 转换成八进制小数的过程:

从图中得知,十进制小数 0.930908203125 转换成八进制小数的结果为 0.7345。

下图演示了将十进制小数 0.6875 转换成二进制小数的过程:

从图中得知,十进制小数 0.6875 转换成二进制小数的结果为 0.1011。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值