Verilog 延时模型

  众所周知,Verilog提供了5中表示延迟的语句:

1 (#5) a = b;// blocking assignment with LHS··············1
2 
3 a = (#5) b;// blocking assignment with RHS··············2
4 
5 (#5) a <= b;// non-blocking assignment with LHS·········3
6 
7 a <= (#5) b;// non-blocking assignment with RHS·········4
8 
9 assign (#5) a = b;// continuous assignment with LHS·····5

  前面四个都是写在always块内。

 

  连续赋值没有RHS。

 

  3.和1没有实质区别。

  4.和2区别不大。用在时钟沿触发的always块内就可以模拟FF传输延迟,C到Q端。写在always @(*)里面就可以模拟wire的传输延迟,但2不行。

  5.0时刻,计算右边表达式的值,生成左边的结果,暂存为temp,等待5个时钟单位,再把temp赋值给a。等待期间,b的任何变化都都会刷新temp的值以及等待时间。因此体现为组合逻辑惯性延迟(电容滤波效果)。

 

  5与2的区别在于,2把所有变化都记录下来,在5个时间单位之后赋值给左边。但是5在右边每次变化都会把上次暂存的值清空更新,因此5对于小于5个时钟周期的变化不敏感。

  而为什么5能模拟惯性延迟,1却不行呢?答案很简单,我们只需要把实际的电路波形图画出来,就明白了。 

 

  可以,但永远不要使用0延迟。

  不同仿真器的结果可能不同。

 

  

工作之后对这个又有了一些新的感悟,这里更新记录一下。
因为公司用的都是verilog/sv,所以虽然数字电路的综合结果都是组合/时序电路,但是verilog仿真器又确实会在乎所谓的阻塞和非阻塞赋值,没办法必须搞明白。
首先可以将delay control分为两类,一种是assign,一种是procedure assign.
assign 就是最常见的assign. 其delay control有只有一种:
assign #5 a = b;

这种写法在仿真中体现为滤波效果,即在b上任意小于5时间单位的变化不会体现在a上,实际电路建模等同于电容引起的延迟。
(对于verdi,等于5时间单位的可以被传输过来)。

procedure assign 根据blocking和unblocking的区别,共有四种。

ieee的标准中,对a和b的值进行swap操作可以写成:

fork

    a = #5 b;
    b = #5 a;

join

  这种写法等效于

fork

    begin
        temp = b;
        #5 a = temp;
    end
    begin
        temp1 = a;
        #5 b = temp1;
    end
join

  如果写成:

fork
    #5 a =  b;
    #5 b =  a;
join

  就会出现race condition。

这种写法叫intra-assignment,上面提到的区别对blocking和unblocking都适用。

    a = #5 b;
posted @ 2020-08-28 19:54  天山明月  阅读(2520)  评论(0编辑  收藏  举报