非阻塞赋值、阻塞赋值、连续赋值
- 对于时序逻辑,即 always 模块的敏感表为沿敏感信号(多为时钟或复位的正沿或负沿),统一使用非阻塞賦值 <=。例如:
/******************************
时序逻辑中使用非阻塞赋值。
******************************/
module cnt1 (clock, cnt_out);
input clock;
output [3:0] cnt_out;
reg [3:0] cnt_out;
always @(posedge clock)
cnt_out <= cnt_out + 1;
endmodule
- 对于 always 模块的敏感表为电平敏感信号的组合逻辑,统一使用阻塞賦值。例如:
/******************************
always 模块的敏感表为电平敏感信号的组合逻辑, 使用阻塞赋值。请注意, 此例 “cnt_out_plus”虽然被指定为 reg 型, 但是实现时是纯组合逻辑。
******************************/
module cnt2 (cnt_out, cnt_out_plus);
input [3:0] cnt_out;
output [3:0] cnt_out_plus;
reg [3:0] cnt_out_plus;
always @(cnt_out)
cnt_out_plus = cnt_out + 1;
endmodule
- 对于 assign 关键字描述的组合逻辑,称为连续赋值语句,统一使用 =,变量被定义为 wire 型信号。例如:
/******************************
assign 描述的组合逻辑。”cnt_out_plus”被定义为 wire 型信号。
******************************/
module cnt3 (cnt_out, cnt_out_plus);
input [3:0] cnt_out;
output [3:0] cnt_out_plus;
wire [3:0] cnt_out_plus;
assign cnt_out_plus = cnt_out + 1;
endmodule
在 2 和 3 中,为什么不采用类似例 1 中的 cnt_out <= cnt_out + 1; 呢?因为,这样会产生组合逻辑环。组合逻辑环是同步时序逻辑设计的大忌,它会使得时序路径无法被工具所分析,因不同的芯片的延时差异,而造成逻辑功能不稳定。有些已经完成很久的设计,在换了芯片批次后,逻辑功能不正确,大多数都是由组合逻辑环造成的。