您的位置:首页 > 其它

最通俗的理解:verilog语言的理想和物理时序的现实

2012-06-19 17:42 274 查看
学习了TimeQuest一段时间,感觉很纠结。大部分的资料都是直接引用权威的Altera文档,那些公式那些严谨的表达,让我一头雾水,几个星期都没缓过神来。

我憎恨这种自以为高明的表述方式!后面无意间看到akuei2的文章,受到启发,结合自己的经验,写一下我对这些概念的通俗化的理解。

Verilog的过程赋值提供了为寄存器型变量的赋值方法,里面包含阻塞赋值(=)和非阻塞赋值(<=)。多条阻塞赋值语句是顺序执行的,而多条非阻塞语句是并行执行的。

在时序逻辑中一般使用的非阻塞赋值(<=)为变量赋值,在执行到赋值语句时,仅仅对”<=”右侧的表达式的值进行评估,但并不马上执行赋值,然后继续执行后面的操作,这个过程就像没有阻断程序的运行一样。以一个简单的模块来介绍。

module Reg_Time

(

input CLK,

input RSTn,

input[3:0] Data,

output[3:0] Reg1

);

reg[3:0] rReg1;

always@(posedge CLK or negedge RSTn)

if(!RSTn)

rReg1 <= 1'b0;

else rReg1 <= Data;

assign Reg1 = rReg1;

endmodule

modelsim仿真一下,如下图一:



图一

我们对上图做一下标记,以便说明。

第一根黄竖线,第一个clk上升沿(注意这是一个时刻)

第二根黄竖线,第二个clk上升沿(注意这是一个时刻)

这里面第一个上升沿执行” rReg1 <= Data”,第一个上升沿过后的i=1(时间段)的整个时间段内,Reg1的值是没有更新的。第二个上升沿一启动,寄存器Reg1值更新了!

按照verilog语言本身的表达,我们可以理解成图二:



图二

这仅仅是按照硬件语言本身的表达在我们头脑里产生的作用图,第一个上升沿决定输出第一个Data:第2个上升沿决定输出第二个Data:第二个上升沿到来的瞬间,Reg1更新了,这样的效果其实在硬件上应该是图三如示:



图三

图二和图三明显存在着很大差距,图二的第二个上升沿在数据开头,图三的上升沿在数据的中间,而且还有了verilog语言无法表达的时间Tsu和Thd,这说明了数据在第二个上升沿的时刻前已经到达了。所以图二的第一个上升沿决定输出Data:12时,我们在i=1这个时间段内,数据已经出发了,即:在第i=1的这个时间段期间,进行评估的动作既是已经发送了数据,我们可以理解成:数据在路上。

寄存器的建立(Tsu)和保存(Thd)时间都需要保证,不然寄存器不能正常锁存住数据。图二和图三的CLK都是理想时钟,没有算进延迟因素,一个周期的时间是Tclk。

图二很值得去理解,启动沿(也就是第一个上升沿)决定发送数据,在i=1的时间段内对这个数据进行评估,其实这个评估就是在发送数据,数据路径会存在延迟,只要数据在锁存沿的Tsu之前到达,我们知道一个时钟周期就是Tclk,那么剩下的Tclk-Tsu时间就是实际给数据物理行进的时间。这样的过程也说明了,不管你数据到没到达,我只给你Tclk-Tsu这么多时间,看你能不能提前到,如果等你这个时间还没到,那就对不起了。当然了,这是刚好满足后级寄存器建立时间的数据到达时间,那么实际的情况是怎么样呢,实际的数据是经过了物理路径过来的,在不考虑时钟偏移的情况下抵达时间就是:Tco+Tdata(如下图五)



图四

有人会问,这里是两个寄存器的分析,那工程里面是一个寄存器的两次赋值,情况一样吗。其实这和两个寄存器的分析是完全一样的!

经过通俗的分析,现在总结一下,建立时间不但和当前时钟沿有关,还和上一个时钟沿有关,因为当前一个时钟沿只是要求你在上一个时钟沿后,数据过来的时间,即Tclk-Tsu。但是呢,有实际的情况啊,我的数据是经过重重路径过来的,需要消耗的时间为Tco+Tdata。最终导致了setup slack=Data required time-Data arrival time=(Tclk-Tsu)-( Tco+Tdata)。就是说,你的女朋友要求你Data required time时间内赶到她那里和她一起去看电影,你呢,走路消耗了Data arrival time时间,如果你的走路时间太长了,超过她的要求了,对不起,她生气了,不理你了,电影也就泡汤啦,哈哈!这里没有考虑时钟偏移的问题,因为一般FPGA时钟用了全局时钟树资源,所以skew非常之小,可以忽略不计。

好了,有人问了,那Thd呢,怎么保证呢?

我们再来看看verilog表现下的理想图二。这个Thd在理想时序图里的确不好理解,因为没有后移的表现形式,正是这个没有后移的表现,让人以为Thd是0!!!其实物理情况才不是这样。我们先来理解保持时间这个字面的意思,就是数据要持续的一段时间。保持,那么谁让它不保持了呢,呵呵,那就是下一个时钟啊,因为下一个时钟的数据要来了,所以你得赶紧捂住一段时间。

我上面说过verilog的非阻塞表达在进行数据评估的时候可以认为是数据已经出发了,只是等待建立锁存,而恰恰有时因为下一个时钟节拍的数据13对上一个数据12的保持时间有影响,那么下一节拍的数据什么时候到来,很明显下一节拍的数据13又是经历了Tco+Tdata这些时间匆匆赶来,一看,你此节拍的数据12保持时间Th过了没有呢?过了,那就成功把数据12打入触发器。还没过,那就是保存数据12失败。

于是hold slack = Tco+Tdata –Th。

这个保持,我也希望来个很直白的表述,因为我们知道,为什么要有个保持时间,有谁催它?其实我们都懂,是下一个时钟节拍的数据在催它,因为这一节拍过去下一节拍的数据即将到来,在下一节拍数据到来之前先把正当时的数据保持锁存住!

总结一下,不管是建立时间还是保持时间,我都用到了要求时间和实际时间的概念,第二个时钟上升沿相关的就是要求的时间,第一个时钟上升沿相关的就是实际时间。在时钟周期是Tclk的时间下,建立的要求时间就是Tclk-Tsu之内,数据要过来,实际数据过来的时间是Tco+Tdata,于是就有了setup slack=建立的要求时间-建立的实际时间=(Tclk-Tsu)-( Tco+Tdata)。保持的要求时间就是Th之内,下一个数据不要到来,如果到来就无法保存数据了,而保持的实际时间呢,就是下一个时钟的数据到达时间:Tco+Tdata,于是有了hold slack=保持的要求时间-保持的实际时间= Tco+Tdata –Th。建立就是提前到,保持就是而后来。

(以上图片除了图一,其它图片来自引用。)

(欢迎转载,请注明出处---愤怒de狂奔)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: