概述
今天在做IC的模块验证时,发现某个模块的输出信号为x态,一般遇到x态首先思考以下几种情况:
- 变量未进行初始化
- 多个相同驱动强度的信号同时驱动1和0
- 代码中直接赋值的x态
- 如果是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态的情况了。*_*
最后
以上就是高兴书包为你收集整理的verilog中assign和always@(*)的区别和易忽略的点的全部内容,希望文章能够帮你解决verilog中assign和always@(*)的区别和易忽略的点所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复