verilog 语义理解
在verilog使用过程中,产生以下几个问题
- wire 和 reg 的语义是什么,有什么不同?
- 阻塞赋值和非阻塞赋值的语义是什么?
- assign 和 always 语义是什么?
弄清语义是为了正确的使用,不仅是结果正确,比如有时候可能两种写法得到的结果是一样的但是从语义来看会有一种是更适合当前语境的.
我并不想陷入到这些verilog语句转化成何种可执行代码这种实现原理级别的理解,只是想了解这个语句被设计出来是为了描述何种硬件.
wire 和 reg
- wire 属于 net类型, reg 属于variable类型.
wire: 表示结构实体之间的物理连接, 其不保存值,其值由其驱动器决定, 默认值是z
reg: 表示数据存储单元, 默认值是x
阻塞赋值和非阻塞赋值
- continuous assignment 和 procedural assignment.
continuous assignment: 给net赋值
procedural assignment: 给variable赋值
- 可以看到阻塞赋值和非阻塞赋值都是procedural assignment,也就是说都是给variable赋值.
阻塞赋值(blocking procedural assignment): always块里的逻辑是阻塞的,也就是执行有先后顺序,相当于是只有第一个逻辑的触发器连接到外部时钟,当时钟来临时第一个逻辑完成执行后向后传播时钟,这就会有延迟,也就是阻塞.
非阻塞赋值(Nonblocking procedural assignment):always块里的逻辑执行是并行的,每个var都有一个触发器同时接收触发信号触发赋值.用 <=
表示.
!!伪代码
eg:
a = 1;
b = 2;
c = 3;
always clk
{
a = 0;
b = a;
c = b;
} // 结果是:a=b=c=0
always clk
{
a <= 0;
b <= a;
c <= b;
}结果是: a=0, b=1, c=2
两种方式在一个过程中不能混用, 上面的理解在混用时也能用于大部分情况,已知不适用的情况: a = b; b <= a;
这种循环依赖的, 而且b <= a; a=b
和它的结果都不一样,目前认为混用是没有语义的,虽然语法上不会报错.
assign 和 always
always 实际上是和 initial task function是一起的属于structured procedures.
- initial: start of simulation
- always: 这里就好理解了是对应的initial的,总是可能被执行的流程
- task 和 function 是结构化代码的方法,暂不研究.
assign: 表示 continuous assignment,
参考资料: IEEE.1364-2005