70,Verilog-2005标准篇:过程时序控制简介

Verilog HDL 对过程语句的发生时间有两种显式时序控制。第一种是延迟(delay)控制,其中表达式指定了从最初遇到语句到语句实际执行之间的持续时间。延迟表达式可以是电路状态的一个动态函数,也可以是一个简单的数字,将语句的执行时间分开。延迟控制是指定激励波形描述的一项重要功能。

第二种时序控制是事件(event)表达式,它允许将语句执行延迟到与此过程同时执行的过程中发生某些模拟事件。模拟事件可以是网络net或变量variable上的值变化(隐式事件),也可以是从其他过程触发的显式命名事件(显式事件)的发生。最常见的事件控制是时钟信号上的正或负边沿。

时序控制可以通过以下三种方法表示:

- delay控制,由 # 符号引入

- event控制,由符号 @ 引入

- wait语句,其操作类似于event控制和 while 循环的组合

下表1描述了过程语句中的时序控制:

delay控制介绍

与没有延迟控制的过程语句相比,延迟控制后的过程语句应执行指定的延迟。如果延迟表达式求值为未知值或高阻抗值,则应解释为零延迟。如果延迟表达式求值为负值,则应解释为与time变量位宽相同的无符号整数。

例 1-下面的示例将任务的执行延迟了10个时间单位:

#10 rega = regb;

例 2-接下来的三个示例提供了使用延迟表达式的延迟过程赋值:

#d rega = regb; // d is defined as a parameter

#((d+e)/2) rega = regb; // delay is average of d and e

#regr regr = regr + 1; // delay is the value in regr

event控制介绍

过程语句的执行可与网络net或变量variable的值变化或已声明事件的发生同步。网络net或变量variable的值变化可用作触发语句执行的事件,这就是所谓的检测隐式事件。事件也可以基于变化的方向,即朝向值 1(posedge)或朝向值 0(negedge)。posedgenegedge 事件的行为如表1所示,可描述如下:

- 在从1到x、z或0,以及从x或z到0的转换过程中,应检测到negedge边沿

- 在从0到 x , z , 或1,以及从x或z到1的转换过程中,应检测到posedge边沿

表1:检测negedgeposedge边沿

event表达式的值发生任何变化时,都应检测到隐式事件。边沿事件只能在event表达式的最低有效位上检测到。event表达式中任何操作数的值发生变化而表达式的结果没有变化时,不应作为event事件进行检测。

例如以下示例展示了event边沿控制语句:

@r  rega = regb; // controlled by any value change in the reg r

@( posedge  clock)  rega = regb; // controlled by posedge on clock

forever  @( negedge  clock)  rega = regb; // controlled by negative edge

event “或”操作符介绍

在事件event敏感列表中,任意多个事件通过逻辑 “或”操作后,任何一个事件的发生都会触发后面过程语句的执行。关键字(or)或逗号字符(,)可用作事件逻辑运算符。在同一个事件表达式中,可以组合使用这两种运算符。逗号(,)分隔的敏感列表与或(or)分隔的敏感列表同义。

例如下面两个例子分别显示了两个和三个event事件的逻辑

@(trig  or  enable) rega = regb; // controlled by trig or enable

@( posedge  clk_a  or   posedge  clk_b  or  trig) rega = regb;

下面的示例展示了逗号 ( , ) 作为事件逻辑运算符的使用:

always  @(a, b, c, d, e)

always  @( posedge  clk,  negedge  rstn)

always  @(a  or  b, c, d  or  e)

隐式event表达式列表

event控制的事件表达式列表是寄存器传输级(RTL)仿真中常见的错误源。用户往往会忘记在事件表达式中添加在时序控制语句中读取的某些网络net或变量variable。隐式事件表达式 @* 是一种方便的速记方法,它可以将时序控制语句(可以是一个语句组)读取的所有网络net或变量variable添加到事件表达式中,从而消除这些问题。

语句中出现的网络net或变量variable标识符都将自动添加到事件表达式中,包括所有出现在赋值右侧、函数和任务调用、case和条件表达式、赋值左侧的索引变量或case项表达式的网络和变量。但以下情况除外:

- 仅出现在waitevent事件表达式中的标识符。

- 仅出现在赋值左侧变量的标识符。

下面举例说明:

例子1:

always  @(*)  // equivalent to @(a  or  b  or  c  or  d  or  f)

y = (a & b) | (c & d) | myfunction(f);

例子2:

always  @*  begin  // equivalent to @(a  or  b  or  c  or  d  or  tmp1  or  tmp2)

tmp1 = a & b;

tmp2 = c & d;

y = tmp1 | tmp2;

end

例子3:

always  @*  begin   // equivalent to @(b)

@(i) kid = b;  // i is not added to @*

end

例子4:

always  @*  begin   // equivalent to @(a  or  b  or  c  or  d)

x = a ^ b;

@*             // equivalent to @(c  or  d)

x = c ^ d;

end

例子5:

always  @*  begin   // same as @(a  or  en)

y = 8'hff;

y[a] = !en;

end

例子6:

always  @*  begin   // same as @(state  or  go  or  ws)

next = 4'b0;

case  (1'b1)

state[IDLE]:  if  (go)  next[READ] = 1'b1;

               else      next[IDLE] = 1'b1;

state[READ]:   next[DLY ] = 1'b1;

state[DLY ]:  if  (!ws)  next[DONE] = 1'b1;

               else      next[READ] = 1'b1;

state[DONE]:   next[IDLE] = 1'b1;

endcase

end

电平敏感型wait事件控制

过程语句的执行也可以延迟,直到某个条件为真。这是使用wait语句实现的,它是事件控制的一种特殊形式。与基本事件控制(由 @ 字符指定)的边沿敏感性不同,wait语句的性质是电平敏感的。

wait语句执行时应评估一个条件;如果该条件为假,则wait语句之后的过程语句应保持阻塞状态,直到该条件变为真时才继续执行。wait语句的形式如表1所示:

表1:wait语法规则

例如下面的示例展示了如何使用 wait 语句完成对电平敏感型事件的控制:

begin

wait  (!enable) #10 a = b;

#10 c = d;

end

如果进入过程块时使能值enable为 1,则wait 语句将停止下一条语句(#10 a = b; )的评估,直到使能值变为 0。如果在进入 begin-end 过程块时使能值已经为0,那么赋值 " a = b; " 将在延迟10个时间单位后立刻执行,不会再发生额外的等待。

点赞加关注博主(ID:FPGA小飞)的博文,咱们一起系统学习verilog最终标准IEEE Std 1364-2005吧!

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值