Lab4采用面向对象封装的方式来搭建验证平台,但是前面的几个Lab都只给16个端口的其中一个灌激励。Lab5将多个组件都封装成类,使得测试平台能够同时驱动所有的端口。
Driver Class
Driver类是由DriverBase基类扩展而来的,基类中(1)定义接口信号、sa/da/payload、Packet类对象等;(2)定义与Driver相关的函数,比如前面的Lab中涉及到的send()
任务。因为每个端口都要发送数据,所以基类中定义了发送数据相关的property和method。
// DriverBase.sv
`ifndef INC_DRIVERBASE_SV
`define INC_DRIVERBASE_SV
class DriverBase;
virtual router_io.TB rtr_io;
string name;
bit[3:0] sa,da; // global variables
bit[7:0] payload[$];
Packet pkt2send;
extern function new(stirng name="DriverBase", virtual router_io.TB rtr_io);
extern virtual task send();
extern virtual task send_addrs();
extern virtual task send_pad();
extern virtual task send_payload();
endclass:DriverBase
// 相当于为DriverBase类创建空间,做一部分的初始化工作:初始化name和interface
function DriverBase::new(stirng name, virtual router_io.TB rtr_io);
if(TRACE_ON) $display("[TRACE]%t %s: %m", $realtime, name);
this.name = name;
this.rtr_io = rtr_io;
//this.pkt2send = new(); // DriverBase中未用到pkt2send,个人认为应为pkt2send分配空间并初始化
endfunction
// send 调用类中的其他方法
task DriverBase::send();
if(TRACE_ON) $display("[TRACE]%t %s: %m", $realtime, this.name);
this.send_addrs();
this.send_pad();
this.send_payload();
endtask:send
task DriverBase::send_addrs();
if(TRACE_ON) $display("[TRACE]%t %s: %m", $realtime, this.name);
this.rtr_io.cb.frame_n[this.sa] <= 1'b0;
for(int i=0; i<4; i++) begin
this.rtr_io.cb.din[this.sa] <= this.da[i];
@(this.rtr_io.cb);
end
endtask:send_addr
task DriverBase::send_pad();
if(TRACE_ON) $