1、先看看常问的问题
1.1简单叙述阻塞赋值和非阻塞赋值的区别:
(1)阻塞赋值(=)必须是阻塞赋值完成后,才进行下一条语句的执行;赋值一旦完成,等号左边的变量值立即变化。在同一个块中,非阻塞赋值表达式的书写顺序不影响赋值的结果。硬件没有对应的电路。(要点为串行,立即生效)
(2)非阻塞赋值(<=),在赋值开始时计算表达式右边的值,在本次仿真周期结束时才更新被赋值变量,即赋值不是立即生效的;非阻塞赋值允许块中其他语句同时执行。在同一个块中,非阻塞赋值表达式的书写顺序不影响赋值的结果。硬件有对应的电路。
(要点:并行,不是立即生效,同时执行)
1.2具体例子:移位寄存器
(1)阻塞赋值按照下面的写法生成的并非移位寄存器

module pipe(
input d,
input clk,
output q3
);
reg q1,q2,q3;
always@(posedge clk)
	begin
			q1=d;
			q2=q1;
		   q3=q2;
	end
endmodule

综合效果如下图所示:

用阻塞赋值实现移位寄存器的代码:
module pipe(
input d,
input clk,
output q3
);
reg q1,q2,q3;
always@(posedge clk)
begin
q3=q2;
q2=q1;
q1=d;
end
endmodule
也就是说,在阻塞赋值的块中,各个语句的顺序不一样,综合出来的结果是不同的。

(2)将上面两个换成非阻塞赋值后,综合出来的结果都是移位寄存器且结果相同。
第一种情况的代码及对应电路

module pipe(
input d,
input clk,
output q3
);
reg q1,q2,q3;
always@(posedge clk)
	begin
			q1<=d;
			q2<=q1;
		   q3<=q2;
	end
endmodule


第二种情况的代码和对应的电路

module pipe(
input d,
input clk,
output q3
);
reg q1,q2,q3;
always@(posedge clk)
	begin
		q3<=q2;
		q2<=q1;
		q1<=d;
	end
endmodule


2、两个多选题

第一个题:ABD
分析原因:不选C的原因,非阻塞赋值也可描述组合逻辑电路,只是这样的代码风格不好。
这个题我也不能确定是不是这样理解,如果您发现有不对的,望您能指点我一下。我不选C是来源于下面:

第二个题:ABD

3、看夏宇闻老师《Verilog数字系统设计教程》的读书笔记
阻塞赋值对应的电路结构往往与触发沿没有关系,只与输入的电平变化有关系;非阻塞赋值对应的电路结构往往与触发沿有关系,只有在触发沿时才有可能发生赋值的情况。
阻塞赋值操作符是“=”,非阻塞赋值操作符是“<=”。
阻塞的概念是指在同一个always块中,其后面的赋值语句从概念上是前一句赋值语句结束后再开始赋值的。
非阻塞赋值的概念是指在赋值操作开始时刻计算RHS表达式,赋值操作结束时刻更新LHS。关键来了,always块里的其他语句是同时进行计算RHS表达式和更新LHS的。

非阻塞赋值操作只能对寄存器类型变量进行赋值,因此只能用在“initial”块和“always”块等过程块中,非阻塞赋值不能用于连续赋值(assign语句)。
个人理解:阻塞赋值是指过程块中的语句是串行执行的(即一条语句执行完成才能执行下一条语句);非阻塞赋值是指过程块中的语句是并行执行的,即所有的语句都可以在赋值操作开始时刻同时计算RHS,在赋值操作结束时刻同时更新LHS。

8个要点:
(1) 时序电路建模时,用非阻塞赋值(<=)。
(2) 锁存器电路建模时,用非阻塞赋值(<=)。
(3) 用always块建立组合逻辑时,用阻塞赋值(=)。
(4) 在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值。
(5) 在同一个always块中不要既用非阻塞赋值又用阻塞赋值。
(6) 不要在一个以上的always块中为同一个变量赋值。
(7) 用$strobe系统任务来显示用非阻塞赋值的变量值。
(8) 在赋值时不要使用#0延迟。

4、希望加强记忆的部分内容
(1)KaTeX parse error: Expected 'EOF', got '#' at position 322: …FFFFFF,t_70)(2)#̲0延时赋值:在非阻塞赋值操作前…strobe
(4)verilog层次化事件队列

5、思考题
思考题:
(1) 用电平敏感列表触发条件的always块表示组合逻辑时,应该用哪一种赋值。
阻塞赋值
(2) 用带时钟沿触发条件的always块表示时序电路时,应该使用哪一种赋值?
非阻塞赋值

(3) 为什么不能在多个always块中为同一个变量赋值?
可能会导致竞争冒险,即使使用非阻塞赋值也可能产生竞争冒险。因为always块的执行顺序其实是随机的,所以仿真的时候会产生竞争冒险。

(4) 为什么不能用$display系统任务来显示用阻塞赋值的变量值?

也就是display命令的执行在非阻塞赋值之前执行
(5) s t o r e 和 store和 storedisplay这两个显示用系统任务有什么不同?各用于什么场合?
简言之: s t o r e 是 显 示 在 非 阻 塞 赋 值 结 束 后 的 值 。 store是显示在非阻塞赋值结束后的值。 storedisplay是显示在非阻塞赋值操作之前的值。
细节如下:
s t r o b e 和 strobe和 strobemonitor显示命令是排列在监控事件队列中。在仿真的每一步结束时刻,当该仿真步骤内所有的赋值都完成以后, s t r o b e 和 strobe和 strobemonitor显示出所有要求显示的变量值的变化。

(6) 仿真器在处理阻塞和非阻塞赋值操作队列过程中有什么不同?
阻塞赋值是由动态事件队列调度的,而非阻塞赋值不是由动态事件队列调度的。
(7) 为什么在可综合verilog模块的设计中,必须注意并遵守本章的8条原则?

关键词:避免出现冒险和竞争的现象;保证综合前仿真和综合后仿真一致。