【Verilog学习】-04-程序
这里的取题目名字程序其实不是特别好,这里应该主要是procedure,也就是always、initial等其他模块包含的那一段代码。
always(组合电路)
always模块可以用来生成组合电路,其和块外面的assign有着相同的作用,主要是语法方面有着一定的区别。
在always块中使用组合逻辑,输出(也就是被驱动的等式的左边)需要用寄存器类型的变量。例如下面两种写法的功能是一样的。
1 | module top_module( |
这里的(*)是指的是敏感列表,如果是组合逻辑的话,需要用这样的写法,如果把所有的信号列出来会容易出错,十分不建议。
always(时序电路(clocked))
阻塞和非阻塞赋值(Blocking and Non-Blocking Assignment)
- Continuous assignments (
assign x = y;
). Can only be used when not inside a procedure (“always block”). - Procedural blocking assignment: (
x = y;
). Can only be used inside a procedure. - Procedural non-blocking assignment: (
x <= y;
). Can only be used inside a procedure.
阻塞赋值和非阻塞赋值都是指的是procedure中的一部分,组合逻辑中用阻塞赋值,时序逻辑中用非阻塞赋值。
if
在使用if语句的时候,要考虑到所有的情况。如果有情况没有考虑到,也就是else没有写,那么,在生成电路的时候,编译器就会默认将其保持不变,即会产生一个锁存器(Latche),因此,需要考虑这个锁存器的影响。
也就是说要写成下面这种完整的形式:
1 | if(flag)begin |
case
语法结构
1 | always @(*) begin // This is a combinational circuit |
语法和C有点区别:没有switch,不用break,case可以有重复的情况
casez
1 | always @(*) begin |
casez只关心某一位,并且逻辑上是顺序去判断(通过增加相应的电路)。
在写case语句的时候可以提前赋上初值,这样可以减少代码量:
1 | //直接考虑所有情况 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Xuanyao's Blog!