持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天!
面向对象的验证平台又一个module和4个类组成
- top:例化testbench类的顶层模块
- testbench: 顶层类
- tester: 激励驱动
- scoreboard: 检查器
- coverage:收集功能覆盖率
基于对象顶层module
顶层验证平台做了三件事:
- 引入类的定义
- 例化DUT和BFM,定义验证平台类变量
- 例化并驱动验证平台类、
引入类的定义
在搭建基于对象的验证平台,我们把所有的类定义和共享资源都放在SV包里,用package就可以在多个module中共享类和变量的定义。当引入package时,可以访问package中所有的定义和声明的数据。
module top;
import tinyalu_pkg::*;
`include "tinyalu_macros.svh"
tinyalu DUT(.A(bfm.A),.B(bfm.B),.op(bfm.op)),
.clk(bfm.clk),.reset_n(bfm.reset_n),
.start(bfm.start),.done(bfm.done),.result(bfm.result));
例化DUT和BFM,定义验证平台类变量
已经在package里定义了验证平台变量,在顶层module,例化了DUT和BFM,并声明验证平台变量
tinyalu DUT(.A(bfm.A),.B(bfm.B),.op(bfm.op)),
.clk(bfm.clk),.reset_n(bfm.reset_n),
.start(bfm.start),.done(bfm.done),.result(bfm.result));
tinyalu_bfm bfm();
testbench testbench_h;
上面的代码跟基于module的代码有相似之处,除了把激励,自检,功能覆盖模块转换成了testbench类,现在有存放testbench对象的testbench_h变量了。
例化并启动testbench 对象
需要例化验证平台对象并传入BFM句柄,之后,用testbench_h的一个方法启动验证TinyALU:
initial begin
testbench_h = new(bfm);
testbench_h.execute();
end
endmodule:top
使用new()函数传入BFM句柄来新建一个验证平台,这个跟例化module的时候把BFM放进端口列表里相似,然后我们调用testbench_h.execute()验证TinyALU。 由于验证平台有一个BFM的拷贝,里面就可以用BFM的task来驱动激励,然后观察这些信号来检查输出和覆盖率
tester 类
测试机器随机指令对TinyALU进行激励,最后得到全部的功能覆盖。基于类的测试器跟基于module的测试器是一样的,不过有三处不同:用的是类的定义;用变量访问BFM而不是端口列表;用execute()方法而不是initial块。这里是类的定义:
class tester;
virtual tinyalu_bfm bfm;
function new (virtual tinyalu_bfm b);
bfm = b;
endfunction:new
上面的代码定义了tester类,定义了操作BFM的变量,这个变量在构造函数里赋值。
模块集合
在了解了整个基于对象的验证平台,顶层的module例化DUT和作为BFM的SV接口,在例化中连接DUT和BFM.
顶层的initial 块创建了验证平台对象并在new()方法中传入BFM句柄。这个顶层验证平台对象创建验证模块对象并为每个对象传入BFM句柄的拷贝。
之后在验证平台对象用fork... join_none块来多线程启动模块对象的execute().我们的验证平台跟之前的module运行起来是一样,不同之处在于我们获得了OOP之中的灵活性和重用性。