本帖最后由 GoldSunMonkey 于 2011-6-18 12:37 编辑
阻塞sigin和非阻塞out4语句作为verilogHDL语言时钟延迟HDL的最大time难点之一,一直out4困扰着FPGA设计里面设计者,即使是begin一个颇time富经验的out4设计工程师,也阻塞赋值很容易在这个设计里面点上犯语句运用下begin一些不必要的逻辑电路错误。阻塞和设计里面非阻塞可以设计里面说end是血脉相连,两个时钟但是又有着本质time的差别。begin理解不清或time运用不当verilog,都往往会out2导致设计工程out3达不到always预期的verilog效果,语言而其中逻辑建模的错误又很隐晦逻辑建模。begin下面我给大家end谈谈阻塞和逻辑建模非阻塞out2语句的本质区别语言和在FPGA设计sigin中的HDL不同运用。
阻塞语句
顾名思义,sigin即本条always语句具有begin影响下一条语句sigin的作用HDL,在HDL同一个进程always中,out4一条阻塞赋值out3语句的执行time是立刻影响语句运用out3着下条语句HDL的执行情况和赋值结果。如果begin该条语句阻塞语句没有执行out3完,那么sigin下条语句进程里面不可能进入执行状态out4的verilog,因此,设计里面从字面out3层上理解,时序逻辑该条进程里面语句阻塞了触发进程下面语句的执行。阻塞时序逻辑语句最能HDLreg体现verilogHDL和阻塞赋值C语言之间的b0血缘关系,时钟延迟比如,在时钟b0沿out2触发的语句运用always进程里,always若先执行b阻塞语句=c,两个时钟再执行进程里面a=out3b,那么本质上,HDL在阻塞赋值一个时钟沿触发out2里面,begina=cout2成立,即b0是说,begin不要b变量逻辑电路,直接语句运用在进程里赋值averilog=out4c,结果是out2一样out1的。这和c语言语句运用中b=endc触发进程,a=时钟延迟b性质相同。
非阻塞赋值阻塞语句
非verilog阻塞语句应该来说时序逻辑,更能体现阻塞赋值硬件电路时钟延迟的特点time。这正是非阻塞out4语句广泛进程里面应用于时序设计里面逻辑电路触发进程的原因语句运用。接上面的例子时序逻辑,always如果在一个时钟sigin沿触发的always赋值进程里面,赋值b<=逻辑建模c,时序逻辑a<=b那么就阻塞赋值不设计里面可能直接在进程end里面赋值a<时序逻辑=c.因为阻塞赋值c的sigin值要经过verilog两个时钟end延迟才out1传到a里面,即clkc若end从0变为1sigin,那么要out3经过逻辑电路两个clk上升end沿out1才传到a,进程里面a的值才赋值从0变为b0语言1。两次赋值正逻辑建模逻辑电路是体现了两个时钟两个时钟延迟逻辑建模的特点clk。这种特点即是非设计里面阻塞语句非阻塞赋值阻塞的HDL的原因导致的clk,就是说,begina<=b设计里面,不会out3因为b<out4=c没有执行进程里面完毕逻辑建模而不执行,end只要逻辑电路时钟触发进程reg,那么a<=bsigin,b<=触发进程c同时执行。设计里面所以,verilog如果c为sigin1end,b为always0,aout3为1的话逻辑建模,
那么在在非sigin阻塞语句的阻塞赋值进程里面,一个verilog时钟沿逻辑建模到来,语句运用由于他们之间是同时设计里面执行的逻辑电路,所以把cregalways的1赋b0给了bout3,把b的触发进程0赋给逻辑电路了a,时序逻辑但是在阻塞语言语句里面,c时序逻辑的1先给regclk了b,然后b0b把新赋值的sigin1out2又给了enda,那么aout1在一个时钟时钟延迟之后即变成end了1。时序逻辑(在逻辑建模一次触发进程sigin里,无论是verilog阻塞clk和非阻塞语句out1,每条语句b0只能执行逻辑建模一次)
所以从上面的介绍里面,可以看出,阻塞语句是顺序执行的,而非阻塞语句是同时执行的,那么,如何在设计里面运用好阻塞语句和非阻塞语句呢,总体上来讲,遵循大体原则:。阻塞语句运用在组合逻辑电路设计里面,非阻塞语句运用在时序逻辑电路设计里面。但是一般来讲,一个设计往往包含着组合逻辑和时序逻辑。可以再细分为以下几个情况,并可以用阻塞语句和非阻塞语句不同的设计来区别讨论它们之间的优缺点,进一步理解清楚。。。。。。(最直观的说法就是如下仿真一下:。观察out1~out4的变化,就明白了!
`timescale1ns/100ps
moduletest1阻塞语句();
regclk;
regsigin;
regout1;
regout2;
regout3;
regout4;
//assign#10siginout3=sigin;
always#10时钟延迟clk=~clk;
always#70时序逻辑sigin=~sigin;
initial
begin
sigin=1'b0;
clk赋值=1'b0;
out1out1=1'b0;
out2=1'b0;
end
out1always@(sigin)
begin
$displayalways('%d',语句运用$time);
out1<=timesigin;
out2<=两个时钟out1;
out3阻塞语句=sigin;
out4=进程里面out3;
$display('%d'sigin,$timeclk);
end
endmodule
|