Verilog 非阻塞赋值的仿真综合问题

上传人:daj****de 文档编号:172176978 上传时间:2022-12-01 格式:DOCX 页数:10 大小:76.57KB
收藏 版权申诉 举报 下载
Verilog 非阻塞赋值的仿真综合问题_第1页
第1页 / 共10页
Verilog 非阻塞赋值的仿真综合问题_第2页
第2页 / 共10页
Verilog 非阻塞赋值的仿真综合问题_第3页
第3页 / 共10页
资源描述:

《Verilog 非阻塞赋值的仿真综合问题》由会员分享,可在线阅读,更多相关《Verilog 非阻塞赋值的仿真综合问题(10页珍藏版)》请在装配图网上搜索。

1、在Verilog语言最难弄明白的结构中“非阻塞赋值”要算一个。甚至是一些很有经验的工程师也不完全明白“非阻塞赋值”在仿真器(符合IEEE标准的)里是怎样被设定执行的,以及什么时候该用“非阻塞赋值”。这篇文章将介绍怎样设定“非阻塞赋值”和“阻塞赋值”,给出了重要的使得编码可以被正确地综合的编码指导方针,和避免仿真竞争的编码风格细节。1.0介绍众所周知的逻辑建模方针是:*在always块里用“阻塞赋值=”产生组合逻辑。*在always块里用“非阻塞赋值=”产生时序逻辑。但是为什么?(外注:在实现组合逻辑的assign结构中,当然采用阻塞赋值语句否则的话编译工具会提醒你进行修改的。)普通的回答是:那

2、只是关于仿真的,即使不遵照上面的规则也照样可以产生正确的综合结果。但问题是综合前的仿真结果也许会跟综合后的电路行为仿真不匹配。要明白上述建模方针背后的原因,就必须明白“非阻塞赋值”和“阻塞赋值”它们的功能和时序安排(thefunctionalityandschedulingofblockingandnonblockingassignments.)这篇文章将详细描述有关问题。文章里将用到两个缩写形式:RHS(right-hand-side)和LHS(left-hand-side)。前者指等式右边的表达式或者变量(RHSexpressionorRHSvariable),后者指指等式左边的表达式或者

3、变量(RHSexpressionorRHSvariable)2.0Verilog仿真竞争条件IEEEVerilogStandard2定义:“保证性的赋值描述”和“非保证性的赋值”描述分别用“非阻塞赋值”和“阻塞赋值”。(Determinism,section5.4.1;Nondeterminism,section5.4.2&Raceconditions,section5.5)IEEEVerilog标准允许在同一仿真时间里赋值竞争的产生。当赋值陈述有所不同时,会产生不同的结果。(译注:即可以认为:“非阻塞赋值”有更高的优先权对变量进行赋值或者是指陈述的次序不同会产生不同结果?)为了避免含竞争的描

4、述(racecondition),明白Verilog非阻塞赋值”和“阻塞赋值”的时序安排是非常重要的。3.0阻塞赋值(blockingassignments)阻塞赋值由等号=”表示。“阻塞赋值”由它的赋值操作行为而得名:当没有其它的Verilog描述可以打断“阻塞赋值”时,操作将会估计RHS的值并完成赋值。“阻塞”即是说在当前的赋值完成前阻塞其它类型的赋值任务。一个例外是:对阻塞操作的RHS进行延时(delays)的阻塞赋值(在延时未完成前不会阻塞其它赋值任务),但是这被我们认为是不好的编码方式。“阻塞赋值“可以看作一步进程(one-stepprocess):当没有其它可以打断赋值的描述时,估

5、计等式右边(RHS)的指并赋予左边(LHS)。在同一个always块里面,阻塞赋值结果将一直持续下去直到赋值结束。阻塞赋值的一个问题是:当一个程序块(比如always块)阻塞赋值描述里面的“RHS变量”同时是另外一个程序块(比如always块)阻塞赋值描述里面的“LHS变量”,并且两个等式的执行被安排在同一个仿真时间步里面执行(比如同一个时钟上升沿),那么竞争条件就产生了,这样的情况下其执行次序将是未知的。为了举例说明这种情况,请看Verilog代码描述的例一:modulefboscl(y1,y2,clk,rst);outputyl,y2;inputclk,rst;regy1,y2;alway

6、s(posedgeclkorposedgerst)if(rst)y1=0;/resetelsey1=y2;always(posedgeclkorposedgerst)if(rst)y2=1;/presetelsey2=y1;endmoduleExample1-Feedbackoscillatorwithblockingassignments依据IEEEVerilog标准,这两个always块可以以任意的次序执行。如果在reset后第一个块先被执行,结果将是y1和y2都获得赋值1;如果在reset后第二个块先被执行,结果将是y1和y2都被赋值0。这个例子清楚地展示了一个Verilog竞争条件地产

7、生。4.0非阻塞赋值(nonblockingassignments)非阻塞赋值使用一个小于等于号“=”。非阻塞赋值”由它的赋值操作行为而得名:在一个时间步(timestep)的开始估计RHSexpression的值并在这个时间步(timestep)结束时用等式右边的值更新取代LHS。在估算RHSexpression和更新LHSexpression的中间时间段,其它的对LHSexpression的非阻塞赋值可以被执行。即是说“非阻塞赋值”从估计RHS开始并不阻碍执行其它的Verilog描述。“非阻塞赋值”可以看作二步进程(one-stepprocess):在时间步开始估计RHS;在时间步结束时更

8、新LHS;“非阻塞赋值”为寄存器数据类型而设,所以只能被允许在程序块里面出现,比如initial块和always块。不允许持续性赋值(continuousassignments)。为了举例说明,请看Verilog编码例二:modulefbosc2(y1,y2,clk,rst);outputy1,y2;inputclk,rst;regy1,y2;always(posedgeclkorposedgerst)if(rst)y1=0;/resetelsey1=y2;always(posedgeclkorposedgerst)if(rst)y2=1;/presetelsey2=y1;endmoduleE

9、xample2-Feedbackoscillatorwithnonblockingassignments依据IEEEVerilog标准,这两个块可以以任意的次序执行。在reset后,不管哪一个块先被执行,在时间步的开始两个RHSexpression同时被估值,在时间步结束LHSvariables同时更新赋值。在使用者看来,这两个非阻塞描述是并行发生的。5.0Verilog编码指导仿真在对“非阻塞赋值”和“阻塞赋值”作更深一步的举例和说明之前,现列举八条指导方针是有帮助的。这些仿真可以帮助正确地用Verilog对硬件建模和仿真。谨遵这些方针可以帮助Verilog设计者减少所遇到的90-100%的

10、Verilog竞争。#1:当为时序逻辑建模,使用“非阻塞赋值”。#2:当为锁存器(latch)建模,使用“非阻塞赋值”。#3:当用always块为组合逻辑建模,使用“阻塞赋值”#4:当在同一个always块里面既为组合逻辑又为时序逻辑建模,使用“非阻塞赋值”。#5:不要在同一个always块里面混合使用“阻塞赋值”和“非阻塞赋值”。#6:不要在两个或两个以上always块里面对同一个变量进行赋值。#7:使用$strobe以显示已被“非阻塞赋值”的值。#8:不要使用#0延迟的赋值。关于这些指导方针的来源,这篇文章的余下部分将会给出。Verilog的新手们一定要记住并使用这些方针直到完全弄明白了它

11、们根本的功能。遵循这些方针将会帮助你避免“Verilog痛苦”(“deathbyVerilog!”)。6.0层积事件列(stratifiedeventqueue)仔细地考察一下Verilog的层积事件列(stratifiedeventqueue,见表一)可以帮助解释Verilog的层积事件列是如何发挥作用的。对于用于安排仿真事件顺序的不同Verilog事件列,“层积事件列”是一个迷人的和有想象力的名字。在IEEEVerilog标准里被描述成一种概念上的模范-用于鉴定各个供应商的仿真器能力,尽管它们各自对事件列的执行细节是它们各自所独有的。这些细节问题不是本章所要讨论的。(外注:首先一个“事件轴

12、”可以用来理解仿真事件:当前时刻tlt2t3)。在IEEE1364-1995Verilog标准的5.3节,“层积事件列”被划分为四个迥然不同的列,它们分别归为当前仿真时间列和将来仿真时间Blockingas&ignm.ont&ContinuousassignmentsEvaluat*RHSofnonblockinga&lgunionts-TlieseeventsmayMli&du膈inanyorder列。SdisplaycoinmandoKcutioninputsandchangeoutputs.ofprimJ#oblocking谴旬ni膈rmUpdateLH5ofnonblPekingass

13、lgnmemscoinmondexecution$strobecommand&x&cutionOthrspecificPL1c&nmondsFigureI-Veriloystratifiedeventqueue激活事件列”(ActiveEvents)是最多的被预备执行的Verilog事件,包括非阻塞赋值、连续赋值、$display命令、利用对实例(instance)和初原元件(primitive,可能这样翻不合适,但是知道Verilog的家伙都知道这个,就先将就着了!)更新的输出值估出实例(instance)和初原元件(primitive)的输入值、估出“非阻塞赋值”的RHSexpressio

14、ns0注意“非阻塞赋值”的LHS不在“激活事件列”里更新值。事件可以被加到任意的事件列里(由IEEE标准强制约束的)但是只可能从“激活事件列”里被移出。其它事件列里的事件最终总是要成为“激活事件”的(或者提升为“激活事件)。IEEE1364-1995Verilog标准第5.4节列出了当其它事件列(eventqueues)被激活后的算法。在当前仿真时间里,两个常见的事件列(eventqueues)是“非阻塞赋值更新”事件列和“monitor”事件列。具体描述如下:“非阻塞赋值更新”事件列(Thenonblockingassignupdateseventqueue)即是“非阻塞赋值”的LHSexp

15、ression被安排更新赋值的那些事件。在一个仿真时间步(simulationtimestep)的开始,“RHSexpression的估值”与其它被激活事件是以任意的次序进行的。“monitor事件列是由那些被安排的“$strobe”和“$monitor”显示命令带来的。$strobe和$monitor用于显示一个仿真时间步结束时变量更新后的值(这时该仿真时间步里所有的赋值分配都已经完成)。IEEE1364-1995Verilog标准第5.3节描述了“怠惰事件列”,即被赋为零延迟(#0)的事件。实际上“零延迟”是有缺陷的。一般设计者使用零延迟是想为在不同程序块(proceduralblocks

16、)被赋值的变量提供一个避免仿真竞争的环境。设计者希望一个赋值语句在另一个之后“一点儿”替代前面赋值。这是没必要的,只会增加(仿真器)分析事件列的难度。作者不知道有哪一种情况下必须要使用零延迟以至于不用零延时就不能用别的不同的、更有效的编码风格来达到所想的目的。所以不推荐使用零延迟。建模方针8:不要使用零延迟。上面图一的“层积事件列”将经常参考以用来解释下面的Verilog行为描述例子。“事件列”也将作为证明5.0节列举的八条建模方针的参考。7.0自触发always块一般来讲,一个always块不能够自触发。考虑下面例三的振荡器:moduleoscl(clk);outputclk;regclk;

17、initial#10clk=0;always(clk)#10clk=clk;endmoduleExample3-Non-self-triggeringoscillatorusingblockingassignments这个振荡器使用“阻塞赋值”,这样的话RHS估值和LHS赋值是不被打断地执行。在clk边沿触发能被安排执行之前,非阻塞赋值就已经必须安排执行。即在边沿事件之前,对clk的赋值已经完成。所以,没有“触发事件”(clk)来触发always块里面的触发事件(totriggerthe(clk)trigger)。与之形成对比的是,例4的振荡器使用“非阻塞赋值”:moduleosc2(clk)

18、;outputclk;regclk;initial#10clk=0;always(clk)#10clk=clk;endmoduleExample4-Self-triggeringoscillatorusingnonblockingassignmentsclk=0在第一个(clk)触发之后,非阻塞赋值的RHSexpression被估值,并且LHS值被送入“非阻塞赋值更新”事件列。在“非阻塞赋值更新事件列”被激活以前,仿真过程遇到clk触发描述,所以always块又一次对clk信号变化敏感-然后在同一时间步的结束当LHS被更新时,clk被又一次触发。所以osc2是可以自触发的(尽管不是我们有必要推

19、荐的风格)。tinestep),LHS更新,clk=lI(Hk)-厦生Mk事田羿待.开始BHWi值01CfiSfiT芫毕,lk_rep=l溢心,等特、开始(外注:这个另外添加的仿真波形可以帮助理解,原文里并没有。其中clk_reg表示寄存在内存的clk值。)8.0流水线建模图二示意了一个简单的时序(sequential)流水线寄存器。dq1q3FiginU2SqLienlidlpipeline英占和成从例5到例8列举了一个工程师可能选用的4种使用阻塞赋值为它建模的方案modulepipeb1(q3,d,clk);output7:0q3;input7:0d;inputclk;reg7:0q3,q

20、2,q1;always(posedgeclk)beginq1=d;q2=q1;q3=q2;endendmoduleExample5-Badblocking-assignmentsequentialcodingstyle#1Fjjiire3-ActualsxTthesizedresult!9.0阻塞赋值&简单例子有许多将Verilog和Verilog综合的书,它们举了很多成功地利用“阻塞赋值”为一些简单的时序电路建模的小例子。例13是一个在大多数Verilog书本里用来为一个触发器(flip-flop)建模的例子(这是简单而有缺陷的阻塞赋值建模,但是它确实可以工作):moduledffb(q,d

21、,clk,rst);outputq;inputd,clk,rst;regq;always(posedgeclk)if(rst)q=1b0;elseq=d;endmoduleExample13-Simpleflawedblocking-assignmentD-flipflopmodel-butitworks!如果工程师们想把所有的模块(module)都集中到一个always里面描述,“阻塞赋值”可以用来正确地为所需要的逻辑建模、仿真和综合。但是不幸的是这个原因导致了喜欢在其它情况下也使用“阻塞赋值”的习惯,并且更复杂的时序always块将会产生竞争条件-在前面已经详细阐述过。moduledffx

22、(q,d,clk,rst);outputq;inputd,clk,rst;regq;always(posedgeclk)if(rst)q=1b0;elseqRegisterequivalenttohasbeenremovedFound1-bitregisterforsignal.Found1-bitxor2forsignal.Found1-bitregisterforsignal.)Summary:inferred2D-typeflip-flop(s).没有办法通过调整描述次序的方法来正确建模除非引入一个临时的变量(外注:例如引入“wiren2”modulexxxxx(q3,clk,pre_n

23、)outputq3;inputclk,pre_n;regq3,q2,q1;wiren1,n2;assignn1=q1Aq3;assignn2=q3;always(posedgeclkornegedgepre_n)if(!pre_n)beginq3=1b1;q2=1b1;q1=1b1;endelsebeginq3=q2;q2=n1;q1=n2;endendmodule这样可以得到正确的综合结果:Found1-bitregisterforsignal.Found1-bitxor2forsignal.Found1-bitregisterforsignal.Found1-bitregisterfors

24、ignal.Summary:inferred3D-typeflip-flop(s).)。可以通过把所有赋值弄到一个等式的方式(one-lineequations)来避免使用临时变量,例如下面的例16所示。但是现在编码显得更难于理解尤其当涉及的表达式更大更长时,编写代码和调试都变得比较困难,因此不鼓励使用这种风格。modulelfsrb2(q3,clk,pre_n);outputq3;inputclk,pre_n;regq3,q2,q1;always(posedgeclkornegedgepre_n)if(!pre_n)q3,q2,q1=3b111;elseq3,q2,q1=q2,(q103),

25、q3;endmoduleExample16-FunctionalbutcrypticLFSRwithblockingassignments如果把例15和例16的阻塞赋值(blockingassignment)都替换为非阻塞赋值(nonblockingassignment),如下面例17和18所示,那么所有的仿真都将如我们对一个LFSR所期望的那样。modulelfsrn1(q3,clk,pre_n);outputq3;inputclk,pre_n;regq3,q2,q1;wiren1;assignn1=q1人q3;always(posedgeclkornegedgepre_n)if(!pre_

26、n)beginq3=1b1;q2=1b1;q1=1b1;endelsebeginq3=q2;q2=n1;q1=q3;endendmoduleExample17-FunctionalLFSRwithnonblockingassignmentsmodulelfsrn2(q3,clk,pre_n);outputq3;inputclk,pre_n;regq3,q2,q1;always(posedgeclkornegedgepre_n)if(!pre_n)q3,q2,q1=3b111;elseq3,q2,q1=q2,(q1q3),q3;endmoduleExample18-Functionalbutcr

27、ypticLFSRwithnonblockingassignments根据8.0段例子pipeline和10.0段例子LFSR,我们推荐对所有时序逻辑建模时使用非阻塞赋值(nonblockingassignment)。相似的分析也将显示出对latch建模时使用非阻塞赋值(nonblockingassignment)是最安全的。#1:当为时序逻辑建模,使用“非阻塞赋值”。#2:当为锁存器(latch)建模,使用“非阻塞赋值”。11.0组合逻辑使用阻塞赋值(blockingassignment)用Verilog可以有很多种方法为组合逻辑建模,但是当使用always块来为组合逻辑建模时,应该使用阻塞

28、赋值(blockingassignment)。如果在某个always块里面只有一个赋值(表达),那么使用阻塞或者非阻塞赋值都可以正确工作。但是如果您对养成好的编码习惯有兴趣的话,还是要“总是用阻塞赋值对组合逻辑建模”。一些设计师建议非阻塞赋值不应该只为编写时序逻辑,它也可以用来编写组合逻辑。当然对于简单的组合逻辑always块这是可以的,但是对于在一个always块里面含有多个赋值陈述,例如例19含有and-or的陈述,使用了不含延迟(delay)的非阻塞赋值会造成仿真不正确,或者要使仿真正确您需要另外的添加敏感事件列表(sensitivitylistentries),和“多登入路径”(mul

29、tiplepasses)来贯穿always块以使得仿真正确。接下来的问题是从仿真需要多长时间来看,这是低效率的(外注:即降低仿真的performance)o例19的y输出建立在3个依次执行的陈述上(外注:tmp1=a&b;tmp2=c&d;y=tmp1|tmp2;)。由于非阻塞赋值的LHS变量值更新是在对RHS表达式估值之后,所以tmp1和tmp2的值仍然是该always块上一个登入口的值而不是在这一个仿真时间步(simulationtimestep)结束时被更新的值。因此y的值将受旧的tmp1和tmp2影响,而不是这次扫描过的always块内被更新的值。moduleao4(y,a,b,c,d

30、);outputy;inputa,b,c,d;regy,tmpl,tmp2;always(aorborcord)begintmp1=a&b;tmp2=c&d;y=tmp1|tmp2;endendmoduleExample19-Badcombinationallogiccodingstyleusingnonblockingassignments例20与例19是一样的,不同之处在于tmpl和tmp2被添加到事件列表中去了。如第7段(section7.0)中所述,在非阻塞赋值更新事件队列”中当非阻塞赋值更新LHS变量时,always块将会“自触发”并使用最新的tmpl和tmp2来更新y输出。现在y输

31、出值正确了因为增加使用了两条“登入路径”(twopasses)贯穿整个always块。使用更多的“登入路径”来贯穿always块等于降低仿真器的性能,因此如果可以有合理的一些代码变化可以取代这种用法的话,就尽量避免这种用法。moduleao5(y,a,b,c,d);outputy;inputa,b,c,d;regy,tmp1,tmp2;always(aorborcordortmp1ortmp2)begintmp1=a&b;tmp2=c&d;y=tmp1|tmp2;endendmoduleExample20-Inefficientmulti-passcombinationallogiccodin

32、gstylewithnonblockingassignments发展一个好的习惯可以避免使用“多登入路径”(multiplepasses)贯穿always块,即使用阻塞赋值为组合逻辑建模。moduleao2(y,a,b,c,d);outputy;inputa,b,c,d;regy,tmp1,tmp2;always(aorborcord)begintmp1=a&b;tmp2=c&d;y=tmp1|tmp2;endendmoduleExample21-Efficientcombinationallogiccodingstyleusingblockingassignments例21与例19一样,不同

33、之处只在于用阻塞赋值替代了非阻塞赋值。这保证了在一个“登入路径”贯穿always后y输出的正确(guaranteethatthey-outputassumesthecorrectvalueafteronlyonepassthroughthealwaysblock?)。因此有下面的编码方针:#3:当用always块为组合逻辑建模,使用“阻塞赋值”12.0时序-组合混合逻辑建模:使用非阻塞赋值很多时候为了方便我们把时序和一些简单的组合逻辑放在一起。当我们把时序和组合编码放在一个always块的时候,像编写时序逻辑一样使用非阻塞赋值为这种混合逻辑建模,如下面的例22:modulenbex2(q,a,

34、b,clk,rst_n);outputq;inputclk,rst_n;inputa,b;regq;always(posedgeclkornegedgerst_n)if(!rst_n)q=1b0;elseq=a人b;endmoduleExample22-Combinationalandsequentiallogicinasinglealwaysblock与例22相同的逻辑也可以使用两个分立的always块-一个是纯粹的时序逻辑(使用非阻塞赋值),另一个是纯粹的组合逻辑(使用阻塞赋值)-建模,例如下面的例23:modulenbexl(q,a,b,clk,rst_n);outputq;inputc

35、lk,rst_n;inputa,b;regq,y;always(aorb)y=a人b;always(posedgeclkornegedgerst_n)if(!rst_n)q=1b0;elseq=y;endmoduleExample23-Combinationalandsequentiallogicseparatedintotwoalwaysblocks#4:当在同一个always块里面既为组合逻辑又为时序逻辑建模,使用“非阻塞赋值”。13.0其它混合“阻塞”与“非阻塞”赋值建模方针Verilog允许在一个always块里面自由混合“阻塞”与“非阻塞”赋值。一般情况下在同一个always块里面混

36、合“阻塞”与“非阻塞”赋值是“衰婆”风格(poorcodingstyle,呵呵,借用电影钢琴教师里的翻译“衰婆”,刚好poor发音与“婆”有些相近。不过可能引起大家一阵反胃,女士们一阵痛恨-向导演,可不要向我!),尽管Verilog允许这样做。下面的例24的仿真和综合都将是正确的,因为“阻塞”与“非阻塞”赋值不是针对同一个变量来的。尽管这可以“正常工作”,但是作者不推荐这种风格。moduleba_nba2(q,a,b,clk,rst_n);outputq;inputa,b,rst_n;inputclk;regq;always(posedgeclkornegedgerst_n)begin:ffr

37、egtmp;if(!rst_n)q=1b0;elsebegintmp=a&b;q=tmp;endendendmoduleExample24-Blockingandnonblockingassignmentinthesamealwaysblock-generallyabadidea!下面的例25在大多数情况下仿真是正确的,但是新思(Synopsys)工具会报告语法错误因为针对同一个既进行了“阻塞赋值”又进行了“非阻塞赋值”。这样的编码必须进行修改才可以综合。(Error:Cannotmixblockingandnonblockingassignmentsonsignal.)moduleba_nb

38、a6(q,a,b,clk,rst_n);outputq;inputa,b,rst_n;inputclk;regq,tmp;always(posedgeclkornegedgerst_n)if(!rst_n)q=1b0;/blockingassignmenttoqelsebegintmp=a&b;q=tmp;/nonblockingassignmenttoqendendmoduleExample25-Synthesissyntaxerror-blockingandnonblockingassignmenttothesamevariable为了养成好的编写习惯,作者推荐始终坚持:#5:不要在同一个

39、always块里面混合使用“阻塞赋值”和“非阻塞赋值”。14.0对同一变量多处赋值(Multipleassignmentstothesamevariable)对同一变量在二个以上(包括二个)always块里面进行赋值就是一种Verilog竞争生成环境-即使使用非阻塞赋值。在下面例26里,二个always块对q进行赋值,同时使用非阻塞赋值。因为这些always块可以以同一次序安排执行,仿真输出呈竞争条件。modulebadcodel(q,d1,d2,clk,rst_n);outputq;inputd1,d2,clk,rst_n;regq;always(posedgeclkornegedgerst

40、_n)if(!rst_n)q=1b0;elseq=d1;always(posedgeclkornegedgerst_n)if(!rst_n)q=1b0;elseq=d2;endmoduleExample26-Raceconditioncodingstyleusingnonblockingassignments当新思(Synopsys)工具读这段编码时,会产生如下警告:Warning:Indesignbadcodel,thereis1multiple-drivernetwithunknownwired-logictype.当忽略这个警告并编译上面的例子时,推断结果是二个触发器的输出将作为一个an

41、d门的输入。在这个例子里综合前(pre-synthesis)仿真结果与综合后(post-synthesis)仿真结果不匹配。#6:不要在两个或两个以上always块里面对同一个变量进行赋值。15.0常见的“非阻塞”神话(外注:指与事实不符或严格说不正确的见解、想法)15.1非阻塞赋值和$display神话:“对非阻塞赋值使用$display命令不起作用。”事实:非阻塞赋值在$display命令之后才被更新赋值。moduledisplay_cmds;rega;initial$monitor($monitor:a=%b,a);initialbegin$strobe($strobe:a=%b,a);

42、a=0;a=1;$display($display:a=%b,a);#1$finish;endendmodule下面的仿真输出结果显示出$display命令在“激活事件列”(theactiveeventqueue)里被执行的情形:在“非阻塞赋值更新”这个事件被执行之前。$display:a=0$monitor:a=1$strobe:a=115.2赋“零延迟”神话:“零延迟#0使得该赋值事件在时间步结束时发生”事实:零延迟#0使得赋值事件处于“非激活事件列”modulenb_schedule1;rega,b;initialbegina=0;b=1;a=b;b=a;$monitor(%0dns:$

43、monitor:a=%bb=%b,$stime,a,b);$display(%0dns:$display:a=%bb=%b,$stime,a,b);$strobe(%0dns:$strobe:a=%bb=%bn,$stime,a,b);#0$display(%0dns:#0:a=%bb=%b,$stime,a,b);#1$monitor(%0dns:$monitor:a=%bb=%b,$stime,a,b);$display(%0dns:$display:a=%bb=%b,$stime,a,b);$strobe(%0dns:$strobe:a=%bb=%bn,$stime,a,b);$disp

44、lay(%0dns:#0:a=%bb=%b,$stime,a,b);#1$finish;endendmodule下面的仿真输出结果显示出$display命令在“非激活事件列(theinactiveeventqueue)里被执行的情形:在“非阻塞赋值更新”这个事件被执行之前。0ns:$display:a=0b=10ns:#0:a=0b=T0ns:$monitor:a=1b=00ns:$strobe:a=Tb=01ns:$display:a=1b=01ns:#0:a=Tb=01ns:$monitor:a=1b=01ns:$strobe:a=Tb=0#7:使用$strobe以显示已被“非阻塞赋值”的

45、值。15.3对同一变量多处进行“非阻塞赋值”神话:“在同一个always块里对同一变量多处进行非阻塞赋值没有被明确定义。”事实:Verilog标准定义了以上操作。最后一个非阻塞赋值操作将赢得最后结果。引用IEEE1364-1995VerilogStandard2,pg.47,section5.4.1-Determinism如下:“非阻塞赋值由它们被陈述的次序决定被执行的情况,考虑下面的例子:initialbegina=0;a=1;endWhenthisblockisexecuted,therewillbetwoeventsaddedtothenonblockingassignupdateque

46、ue.Thepreviousrulerequiresthattheybeenteredonthequeueinsourceorder;thisrulerequiresthattheybetakenfromthequeueandperformedinsourceorderaswell.Hence,attheendoftime-step1,thevariableawillbeassigned0andthen1.换句话说:“最后一个非阻塞赋值操作将赢得优先权。”指导方针和结论(概要):#1:当为时序逻辑建模,使用“非阻塞赋值”。#2:当为锁存器(latch)建模,使用“非阻塞赋值”。#3:当用alw

47、ays块为组合逻辑建模,使用“阻塞赋值”#4:当在同一个always块里面既为组合逻辑又为时序逻辑建模,使用“非阻塞赋值”。#5:不要在同一个always块里面混合使用“阻塞赋值”和“非阻塞赋值”。#6:不要在两个或两个以上always块里面对同一个变量进行赋值。#7:使用$strobe以显示已被“非阻塞赋值”的值。#8:不要使用#0延迟的赋值。谨遵这些方针可以帮助Verilog设计者减少所遇到的90-100%的Verilog竞争。16.0最后注意:“nonblocking”的拼写“nonblocking”经常被拼错为“non-blocking”。作者认为这是“微软化”的拼写方式。工程师们在“

48、non”和“blocking之间插入一个“-”是为了满足微软的拼写检查不致报错。在IEEE1364-1995里正确的拼写应该是:nonblocking0(外注:呵呵,你已经看到了,在这个文档里面所有的nonblocking都被下划了红色波浪线。)参考文献:IEEEP1364.1DraftStandardForVerilogRegisterTransferLevelSynthesisIEEEStandardHardwareDescriptionLanguageBasedontheVerilogHardwareDescriptionLanguage,IEEEComputerSociety,IEEE

49、Std1364-1995CliffordCummings,CorrectMethodsForAddingDelaysToVerilogBehavioralModels,InternationalHDLConference1999Proceedings,pp.23-29,April1999.(外注:以上参考文献原文的。译文中第4页“事件轴”引自中科院计算所张亮编著、人民邮电出版社2000年10月出版的数字电路设计与VerilogHDL;一些综合报告来自Xilinx公司的综合软件XST。)作者和联系方式(外注:偷懒省略。总之“Mr.Cummings,amemberoftheIEEE1364VerilogStandardsGroup(VSG)since1994虽然文章所涉很使我们感到“离”众书“叛道”,但其实是足够可信的【并且使我疑团大释,所以拿出来让使用Verilog的家伙一齐“开怀”,译文中太多错误和缺点请大家不吝指正!】。

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!