#129. always过程块_时序逻辑
always过程块_时序逻辑
题目描述
通过前例已经了解到,对于可综合电路,有两种always块的语法形式:
- 组合逻辑电路:
always@(*)
- 时序逻辑电路:
always@(posedge clk)
用always描述的时序逻辑电路,除了像组合逻辑always块那样生成组合逻辑电路外,还会生成一组触发器(或称寄存器),用于寄存组合逻辑的输出。寄存器的输出只有在时钟的上升沿时(posedge clk
)才会更新,其余时刻均保持不变。
阻塞赋值和非阻塞赋值:
在Verilog中,有三种赋值方式,分别为:
- 连续赋值(如
assign x = y;
),该赋值方式只能用于过程块(如always块)之外 - 阻塞赋值(如
x = y;
),该赋值方式只能用在过程块(如always@(*)
)内 - 非阻塞赋值(如
x <= y;
),该赋值方式只能用在过程块内(如always@(posedge clk)
)
在设计Verilog模块时,请遵循以下原则:
- 在组合逻辑的always块内采用阻塞赋值
- 时序逻辑的always块内采用非阻塞赋值
违背这一原则将可能导致难以发现的电路错误,且可能导致仿真与综合的不一致,请用户切记。至于为何这样,初学者可以不必理会,简单理解为verilog语法规范性要求即可。
创建一verilog电路,分别采用上述三种赋值方式实现异或门电路,如下图所示:
Hint
- always块内被赋值的信号都应定义成reg类型
- always块内,组合逻辑采用阻塞赋值(
a = b
),时序逻辑采用非阻塞赋值(a <= b
) - always语句括号内是敏感变量列表,时序逻辑是边沿敏感的,
posedge clk
表示的是clk信号的上升沿,此外,还可以是negedge clk
,表示clk信号的下降沿。
输入格式
一位线网型变量clk,a, b。clk为时钟,a,b为输入
输出格式
一位线网型变量out_assign,out_always_comb,out_always_ff。out_assign为a^b连续赋值得到的结果。out_always_comb为a^b阻塞赋值得到的结果。out_always_ff为a^b非阻塞赋值得到的结果
示例代码
module top(
input clk,
input a,
input b,
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff
);
// 请用户在下方编辑代码
//用户编辑到此为止
endmodule