8.1 事务级设计
验证事务级浮点单元,需要建立一个主控单元生成激励并处理响应,一个覆盖率统计单元用于特定行为的统计和设定完成门限条件,以及一个测试控制单元用于覆盖率达到门限时关闭主控单元。事务级设计和验证平台如图8-1所示。
图8-1 事务级模型
FPU浮点单元的事务级模型非常简单。该设计的核心是forever 循环中间的代码,连续地从输入取得要运算事务,进行计算,返回结果。
compute()函数的功能是取得请求对象(m_req),执行特定的浮点运算,随后产生包含运算结果的响应对象(m_rsp)。compute()的主要结构在下面的case语句中,根据请求选择相应操作代码。
具体的浮点单元算法如上代码所示,这里要注意一些关联问题。操作数中某些特定值在相应的操作中须排除在外。除数为0将出现除0异常,同样如果操作数为0,进行平方根运算是错误的。在上面的这些例子中,相对于任由这些类异常发生,较好的做法为对操作条件进行检测并对异常给出特定的返回。
由于两种异常情况的操作数都为0,应先检测操作数什么时候为0。比较两个浮点数是否相等,(如,a == b、a、b都是浮点类型)是个很好想法。最好能分析一下它们的差别是否接近于0。任何量级小于绝对值1.0-e038的数被认为是“近似0”。要避免除0异常,首先需要检查除数是否为近似0。要避免虚数异常(对负数求平方根),需要检查操作数是否小于0。当检测到这种情况发生时,我们就返回一个特定的常数NaN(不是一个数值)。这个特定的常数在IEEE754标准中定义用于表示浮点数。
FPU浮点单元有两个分析端口——request_ap用于发出请求,response_ap用于接受响应。稍后将通过这两个端口连接覆盖率统计单元和黄金参考模型。
注意事务级的FPU浮点单元没有时序信息。仿真时间不会从0向前推进。在这个事务级模型上,我们感兴趣的是FPU浮点单元的计算结果是否正确,而不是计算何时发生。时序信息是RTL级上的重要信息。
激励生成器(这里称为主控组件,用于负责发出请求,扫描响应)必须生成有意义的操作数序列和操作符并送给浮点单元FPU。
这里用一个简单的机制来控制主控组件的执行。run()任务并发产生两个子线程,即go()和controller()。go()线程用于生成新的激励。
controller()用于控制激励生成器(go()线程)在达到覆盖率要求的门限时停止。通过使用阻塞get()任务,controller() 取得来自覆盖率统计单元的控制事务信息。通过阻塞,控制器不需要推进,它会一直等到控制事务到达。
在覆盖率统计单元和测试控制单元之间交互的事务称为控制事务,控制事务与操作事务不同,用于控制被测单元的操作。go()的核心是loop循环中连续生成随机的请求事务并调用doit(),通过doit()发出这些事务并耐心等待响应。
覆盖率统计单元由avm_subscriber派生而来。它包含了covergroup,covergroup使用从监控器得到的事务流计算覆盖信息。
coverage执行两个独立的操作。cross语句用于确认每个(m_op)操作执行对应的舍入模式(m_round)。coverpoint 语句计算各种操作,当连续出现两个同类型操作时,增加相应bin的统计值。完整的覆盖率就是100%的覆盖,所有cross的情况都出现并每个统计箱bin的计数值至少为1。write()函数根据输入事务统计相关信息,对覆盖率采样,然后检查覆盖率是否达到100%。
当覆盖率达到目标,STOP停止控制事务就会产生并且通过分析端口送出。控制分析端口与主控单元相连,同时完成对主控单元,被测设计DUT和覆盖率统计单元内循环程序的控制。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。