Verilgo中有两种赋值语句,用"="表示的"Blocking Assignment"和用"<="表示的"Non-Blocking Assignment"。
有意思的是,这两种赋值语句对是否"blocking"的解释并不如其字面那样易于理解。
看下面的例子,尝试分别画出两个模块对应的电路图:
module rtl_a(clk, data, regc, regd, rege); input data, clk; output regc, regd, rege; reg regc, regd, rege; always @(posedge clk) begin regc <= data; regd = regc; rege <= regd; end endmodule module rtl_b(clk, data, regc, regd, rege); input data, clk; output regc, regd, rege; reg regc, regd, rege; always @(posedge clk) begin regc = data; regd <= regc; rege = regd; end endmodule
问题的关键是regc,regd,rege这三个变量中,哪两个是一样的。对于"rtl_a"来说,如果你认为 regd==regc 的话,那你就错了。
正确的答案如下(上面的部分对应rtl_a)。
其实问题的关键就是理解所谓的"Blocking"到底是针对什么而言。"Blocking"是什么模拟器(simulator)来说的。
当看到"=",即所谓的Blocking Assignment时,simulator会等到该条语句对应的动作实际执行后才去调度一下条语句。而"<=",即"Non-Blocking Assignment"则无需等待语句的实际执行就可以去安排调度下一条语句。
这里用了"调度"这个词,是因为simulator的任务实际上主要是安排一系列的"event"的发生,就像一个调度员。