• Verilog基础:仿真时x信号的产生和x信号对于各运算符的特性


    相关阅读

    Verilog基础icon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12263729.html?spm=1001.2014.3001.5482


            信号爆x也许是所有IC人的噩梦,满屏的红色波形常让人头疼不已,但x信号的产生原因却常常只有几种,只要遵循一定的代码规范,就可以避免产生信号中出现x的问题。

            最常见问题就是使用了未初始化的reg型变量,因为reg型变量在被创建后使用默认值x。如果在初始化变量之前在其他地方提前使用了,便有可能造成x态的传播。为了避免,可以给所有时序逻辑中用到的reg型变量赋初值(不可综合),但更为推荐的是为所有时序逻辑中使用到的reg型变量添加复位逻辑(可综合)并确保复位,如下所示。对于组合逻辑中使用到的reg型变量,只需要确保始终有正确的驱动即可。

    1. reg a = 0;
    2. reg b;
    3. always@(posedge clk, negedge rst_n)begin
    4. if(rst_n)
    5. b <= 0;
    6. else
    7. b <= ***;
    8. end

            连续赋值语句也可能会导致x信号的产生,在连续赋值语句对wire型线网赋值时,如果出现了多个驱动源同时驱动为不同的值(除z外,因为z看做没有驱动)时,会显示为不定态,直到多个驱动不冲突,如下所示。

    1. //一个很幼稚的例子
    2. assign a = 1'b0;
    3. assign a = 1'b1; //赋值冲突,所以a的值为x
    4. //一个依旧很幼稚的例子
    5. initial begin
    6. b = 1'b0;
    7. c = 1'b1;
    8. end
    9. assign a = b;
    10. assign a = c; //同样是赋值冲突,所以a的值为x
    11. //一个复杂一点的例子
    12. wire a;
    13. reg b, c;
    14. initial begin
    15. b = 1'b0;
    16. c = 1'b0;
    17. #5 c = 1'b1;
    18. #5 c = 1'b0;
    19. #5 c = 1'b1;
    20. #5 c = 1'b0;
    21. end
    22. assign a = b;
    23. assign a = c; //因为有时冲突,有时不冲突,所以a的值交替为0和x,最后为0
    24. //一个迷惑一点的例子
    25. wire a;
    26. reg b, c;
    27. initial begin
    28. b = 1'b0;
    29. c = 1'b0;
    30. #25;
    31. #5 c = 1'b1;
    32. #5 c = 1'b0;
    33. #5 c = 1'b1;
    34. #5 c = 1'b0;
    35. end
    36. assign a = b;
    37. assign #20 a = c; //因为连续赋值有延迟,而25ns后每次c改变的脉冲都小于20ns,所以没有进行赋值,最后的c值为0,因此a的值一直是0

            有些运算也可能会产生x信号,下面简单介绍,但需要注意的是,他们大多只是x信号的传播者,而不是x信号的制造者。

    算数操作符+、-、*、/、%、**

            对于算术运算符,当操作符的操作数中出现了x时,无论原本结果是否可能全部或部分确认,结果全为x值。

    1. a = 3'b001;
    2. b = 3'bx01;
    3. $display("result is %b",a+b);//结果为xxx
    4. a = 3'bx01;
    5. b = 3'b000;
    6. $display("result is %b",a*b);//结果为xxx

    比较运算符<、<=、>、>=、===、!==、==、!=

            对于<、<=、>、>=、==、!=,它们的比较结果是0或1,但是如果操作数中存在x,比较结果为x。

            对于===、!==,它们严格比较两个操作数中的x,因此结果只能为0或1。。

    1. b = 3'b111;
    2. c = 3'b0x1;
    3. $display("result is %b",b<c);//结果为x
    4. b = 3'b0x1;
    5. c = 3'b0x1;
    6. $display("result is %b",b===c);//结果为1

    逻辑操作符&&、||、!

            逻辑运算符的运算结果为0或1,但是如果操作数中存在x,结果为x。

    1. b = 3'b0x1;
    2. c = 3'b001;
    3. $display("result is %b",b&&c);//结果为x
    4. c = 3'b0x1;
    5. $display("result is %b",!c);//结果为x

    位运算操作符&、|、^、~^、~

            位运算符按位对操作数进行操作,注意对于这些运算符,某位的x不会影响其他非x位的结果。且x与1为x,x与0为0,x或1为1,x或0为x。对于异或、同或和取反运算,x位的结果是x。

    1. b = 3'b0x1;
    2. c = 3'bx11;
    3. $display("result is %b",b&c);//结果为0x1
    4. b = 3'b0x1;
    5. c = 3'bx11;
    6. $display("result is %b",b^c);//结果为xx0

    规约运算符&、|、^、~&、~&、~^

            规约运算符的运算结果为0或1,对于&,如果操作数中存在0,结果为0(不管是否含有x),对于|,如果操作数中存在1,结果为1(不管是否含有x)。其他情况下,如果操作数中有x,结果为x。

    1. b = 3'bx10;
    2. $display("result is %b",|b);//结果为1
    3. b = 3'bx10;
    4. $display("result is %b",&b);//结果为0
    5. b = 3'bx10;
    6. $display("result is %b",^b);//结果为x

    移位操作符<<、>>、<<<、>>>

            <<、>>为逻辑移位,即补0移位。而<<<、>>>为算数移位,对于有符号的操作数,算数右移>>>时会在左边补符号位(最高位),其他情况下,算数移位和逻辑移位效果一样。

            当移位操作符的右操作数中有x时,结果为x。

    1. b = 3'b1x1;
    2. $display("result is %b",b>>1'bx);//结果为xxx
    3. b = 3'b1x1;
    4. $display("result is %b",b<<1);//结果为x10
    5. signed reg b;
    6. b = 3'bx01;
    7. $display("result is %b",b>>>1);//结果为xx0

    条件运算符?:

            当条件中因为有x无法确定是否为0时,结果会含有x,但不一定全是x。对于这一点,感兴趣的可以看往期文章,有关于表达式位宽和符号拓展的讨论。

    1. b = 3'b0x;
    2. $display("result is %b",b?2'sb1:2'sb0);//结果为xx
    3. b = 3'b1x;
    4. $display("result is %b",b?1'sb1:2'sb0);//结果为11(符号拓展)
    5. b = 3'b0x;
    6. $display("result is %b",b?2'b1:2'b0);//结果为0x(补零拓展)

    连接运算符{}

            对于连接运算符,某一位的x不会影响其他位。

    $display("result is %b",{1'bx,3'b111});//结果为x111

    向量的位选、域选

             当位选超出界限时,会返回x。当域选超出界限时,超出的部分会用x填充。当数组索引超出界限时,结果全为x。

    1. b = 3'b111;
    2. $display("result is %b",b[3]);//结果为x
    3. b = 3'b111;
    4. $display("result is %b",b[4:2]);//结果为xx1
    5. reg [2:0] c [1:0]
    6. c[0] = 3'b000;
    7. c[1] = 3'b111;
    8. $display("result is %b",c[2]]);//结果为xxx

  • 相关阅读:
    Docker Register 搭建私有镜像仓库
    MTK Logo 逆向解析之 rawx 全解压
    炫酷3D按钮
    部署lamp
    股票交易接口使用步骤
    【云原生】微服务架构SpringCloud和Dubbo的区别?
    C++类大小计算
    使用字节流读取文件中的数据的几种方式
    [附源码]java毕业设计社区生鲜仓库管理系统
    论文解读(PPNP)《Predict then Propagate: Graph Neural Networks meet Personalized PageRank》
  • 原文地址:https://blog.csdn.net/weixin_45791458/article/details/134470851