verilog中assign和always@(*)的区别和易忽略的点

今天在做IC的模块验证时,发现某个模块的输出信号为x态,一般遇到x态首先思考以下几种情况:

  1. 变量未进行初始化
  2. 多个相同驱动强度的信号同时驱动1和0
  3. 代码中直接赋值的x态
  4. 如果是PAD电路上的X态,则另外考虑两个同类型的输入方向的PAD连接在一起,并且其中一个PAD为上拉,一个PAD为下拉

但这个模块中既没有发现同时驱动1和0,也没有在代码中直接赋值x态,产生x态值的信号是在always(*)中赋值,赋值语句类似如下:

module test;

reg tmp0;
reg tmp1;
wire out0;
wire out1;
always @(*) begin
    tmp0 = 1'b0;
    tmp1 = 1'b1;
end

assign out0 = tmp0;
assign out1 = tmp1;

endmodule

搜索后发现always(*)和assign是有一些差别的。

verilog描述组合逻辑一般常用的有两种:

       assign赋值语句和always@(*)语句。

两者之间的差别有:

       1. 被assign赋值的信号定义为wire型,被always@(*)结构块下的信号定义为reg型,值得注意的是,这里的reg并不是一个真正的触发器,只有敏感列表为上升沿触发的写法才会综合为触发器,在仿真时才具有触发器的特性。

       2. 另外一个区别则是更细微的差别:举个例子,

wire a;
reg b;

assign a = 1'b0;

always@(*)
    b = 1'b0;

在这种情况下,使用vcs仿真时a将会正常驱动为0, 但是b却是不定态。这是为什么?verilog规定,always@(*)中的*是指该always块内的所有输入信号的变化为敏感列表,也就是仿真时只有当always@(*)块内的输入信号产生变化,该块内描述的信号才会产生变化,而像always@(*) b = 1'b0;

这种写法由于1'b0一直没有变化,所以b的信号状态一直没有改变,由于b是组合逻辑输出,所以复位时没有明确的值(不定态),而又因为always@(*)块内没有敏感信号变化,因此b的信号状态一直保持为不定态。事实上该语句的综合结果有可能跟assign一样(本人没有去尝试),但是在功能仿真时就差之千里了。

又需要多考虑一种出现X态的情况了。*_*

  • 13
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值