我习惯使用VHDL编程,可一直没找到关于写VHDL综合的书,只找到了这本《Verilog HDL 综合实用教程》。读完还是有些收获。
阻塞式过程赋值与非阻塞式过程赋值(VHDL中使用非阻塞式)
c = a & b; 阻塞式过程赋值
c <= a & b; 非阻塞式过程赋值
两种赋值不会对语句本身的赋值有影响,但会影响以后对赋值结果的引用。书中建议组合逻辑使用阻塞式,时序逻辑使用非阻塞式。且语句块中如果只有一条赋值语句,是阻塞还是非阻塞都没有任何不一样。
非阻塞式过程赋值的赋值对象是在未来(即当前仿真时刻结束时)被赋值。
例 always @ (negedge clockB)
begin
rightshift = rightshift & strobe;
selectfist <= rightshift | xflag;
checkstop <= slectfist ^ mask;
end
endmodule
左边的红线是rightshift,其未经过触发器,右边的是selectfist经过触发器了.
组合逻辑用阻塞式赋值,时序逻辑用非阻塞式赋值(当对变量的赋值和引用都在同一条always中时,可以采用阻塞式)。
阻塞赋值的组合逻辑:
reg TM,TN,TO,TZ;
always @ (A or B or C or
D or E)
begin
TM = A
& B;
TN = C
& D;
TO =
TM|TN|E;
TZ =
!TO;
end
阻塞式是计算A &
B之后立即更新TM的值。既TO使用的是当前的A与B的结果。如果是用非阻塞:
reg TM,TN,TO,TZ;
always @ (A or B or C or
D or E)
begin
TM
<= A & B;
TN
<= C & D;
TO
<= TM|TN|E;
TZ
<= !TO;
end
A &
B的值在当前仿真周期结束之后被赋给TM,所以TO使用的是上一时刻的A与B。若要使非阻塞和阻塞的结果一样,要将非阻塞的always事件表中加入TM、TN、TO:
always @ (A or B or C or D or E or TM or TN or
TO)这样每次TM、TN、TO变化时也要执行这段代码。(但使用ISE6.3对以上三种情况综合的结果完全相同)
又若有这种情况:
always @ (posedge ClkA)
... = DataOut;
always @ (posedge ClkA)
DataOut = ...;
两个进程的执行顺序不定,所以改成:
always @ (posedge ClkA)
... = DataOut;
always @ (posedge ClkA)
DataOut <= ...;
(具体情况具体分析啊)