事件队列(event queue)是指每个事件对应一个
队列项,每个队列项包括一项
事件句柄指针,指向该事件的
事件句柄队列;一项事件种类,它是基本事件之一。每当进行一次通信时,由方法驱动事件按照所需执行的事件种类,将事件对应的程序句柄及其优先级加入到事件程序句柄队列。
事件驱动模型
事件驱动模型使用三个队列来管理事件的运行。这三个队列是,
基本事件队列、
事件句柄队列和待执行句柄队列。
事件队列初始化
每当进行一次通信时,由方法驱动事件按照所需执行的事件种类,将事件对应的程序句柄及其优先级加入到事件程序句柄队列。
除了方法驱动事件之外,一次POST通信至少有如下8个事件发生:应用层方法发送事件(0)、消息层发送事件(10)、
数据层发送事件(20)、
传输层发送事件(28)、
传输层接收事件(8)、数据层接收事件(10)、消息层接收事件(20)和应用层方法完成事件(30)。
事件驱动时机
当一次通信的事件被初始化后,可以立即驱动事件执行,也可由事件冲洗功能在以后驱动执行。如果每次通信都立即驱动执行,那么事件驱动模型就与层次模型兼容。使用立即驱动方法不能改进通信性能。在网格系统中,主要采用冲洗功能执行事件句柄。采用冲洗功能,若干个通信可以流水地进行,有利于提高系统的通信效率。
事件句柄
当待执行句柄队列中有事件句柄时,使用
事件句柄冲洗功能将队列中的句柄按
优先级和连接标记顺序执行。连接标记用来说明本次程序完成之后是继续(Continue)执行后续句柄指定程序还是就此停止(Stop)。例如,在传输层发送事件之后,应该中止本次事件序列。当传输层接收到信号(中断)时,驱动接收事件序列,直到应用层的方法完成事件为止。HandlerFlush子程序的基本框架如下:
事件冲洗
当有事件在事件队列时,可以使用事件冲洗功能。事件冲洗功能对每个事件对应的句柄队列进行冲洗,每次将具有相同序号的句柄冲洗到等待执行的句柄队列,并由事件冲洗函数EventFlush(event)冲洗执行队列,如此重复。EventFlush(event)函数的基本框架如下:
Verilog的层次化事件队列
详细地了解Verilog的层次化事件队列有助于如何理解Verilog的阻塞和非阻塞赋值的功能。所谓层次化事件队列指的是用于调度仿真事件的不同的Verilog事件队列。在IEEEVerilog标准中,层次化事件队列被看作是一个概念模型。设计仿真工具的厂商如何来实现事件队列,由于关系到仿真器的效率,被视为技术诀窍,不能公开发表,本节也不作详细介绍。
在
IEEEl364—1995
Verilog标准的5.3节中定义了:层次化事件队列在逻辑上分为用于当前仿真时间的4个不同的队列,和用于下一段仿真时间的若干个附加队列。
动态事件队列
动态事件队列(下列事件执行的顺序可以随意安排):
停止运行的事件队列
停止运行的事件队列:
#0延时阻塞赋值。
非阻塞事件队列
非阻塞事件队列:
更新非阻塞赋值语句LHS(左边变量)的值。
监控事件队列
监控事件队列:
其他指定的PLI命令队列
其他指定的PLI命令队列
以上5个队列就是Verilog的“层次化事件队列”。
动态事件队列
大多数Verilog事件是由动态事件队列调度的,这些事件包括阻塞赋值、连续赋值、—play命令、实例和原语的输入变化以及它们的输出更新、非阻塞赋值语句RHS的计算等。而非阻塞赋值语句LHS的更新却不由动态事件队列调度。
在IEEE标准允许的范围内被加入到这些队列中的事件只能从动态事件队列中清除,其他队列中的事件要等到被“激活”后,即被排人动态事件队列中后,才能真正开始等待执行。IEEEl364—1995Verilog标准的5.4节介绍了一个描述其他事件队列何时被“激活”的算法。
非阻塞赋值更新事件队列和监控事件队列
在当前仿真时间中,另外两个比较常用的队列是非阻塞赋值更新事件队列和监控事件队列。非阻塞赋值LHS变量的更新是按排在非阻塞赋值更新事件队列中,而RHS表达式的计算是在某个仿真时刻随机地开始的,与上述其他动态事件是一样的。
和显示命令是排列在监控事件队列中。在仿真的每一步结束时刻,当该仿真步骤内所有的赋值都完成以后,和显示出所有要求显示的变量值的变化。
在Verilog标准5.3节中描述的第4个事件队列是停止运行事件队列,所有井0延时赋值都排列在该队列中。采用#0延时赋值是因为对
Verilog理解不够深入的设计人员希望在两个不同的程序块中给同一个变量赋值,他们企图在同一个仿真时刻,通过稍加延时赋值来消除
Verilog可能产生的竞争冒险。这样做实际上会产生问题。因为给Verilog模型附加完全不必要的#o延时赋值,使得定时事件的分析变得很复杂。我们认为采用#0延时赋值根本没有必要,完全可用其他的方式来代替,因此不推荐使用。
RunLoop的事件队列
简介
每次运行RunLoop, 线程中的RunLoop会自动处理线程中的任务, 并且通知观察者, 汇报当前的状态, 顺序如下
RunLoop的一般应用
在子线程中开启一个RunLoop, 做为常驻线程
自动释放池
手势识别等等