验证平台加入factory机制
factory机制
initial begin
my_driver drv;
drv = new("drv", null);
drv.main_phase(null);
$finish();
end
tb中my_driver的实例化及drv.main_phase的显式调用与uvm并没有关系
- factory机制:自动创建一个类的实例并调用其中的函数(function)和任务(task)
代码分析
`ifndef MY_DRIVER__SV
`define MY_DRIVER__SV
class my_driver extends uvm_driver;
`uvm_component_utils(my_driver)
function new(string name = "my_driver", uvm_component parent = null);
super.new(name, parent);
`uvm_info("my_driver", "new is called", UVM_LOW);
endfunction
extern virtual task main_phase(uvm_phase phase);
endclass
task my_driver::main_phase(uvm_phase phase);
`uvm_info("my_driver", "main_phase is called", UVM_LOW);
top_tb.rxd <= 8'b0;
top_tb.rx_dv <= 1'b0;
while(!top_tb.rst_n)
@(posedge top_tb.clk);
for(int i = 0; i < 256; i++)begin
@(posedge top_tb.clk);
top_tb.rxd <= $urandom_range(0, 255);
top_tb.rx_dv <= 1'b1;
`uvm_info("my_driver", "data is drived", UVM_LOW);
end
@(posedge top_tb.clk);
top_tb.rx_dv <= 1'b0;
endtask
`endif
`timescale 1ns/1ps
`include "uvm_macros.svh"
import uvm_pkg::*;
`include "my_driver.sv"
module top_tb;
reg clk;
reg rst_n;
reg[7:0] rxd;
reg rx_dv;
wire[7:0] txd;
wire tx_en;
dut my_dut(.clk(clk),
.rst_n(rst_n),
.rxd(rxd),
.rx_dv(rx_dv),
.txd(txd),
.tx_en(tx_en));
initial begin
clk = 0;
forever begin
#100 clk = ~clk;
end
end
initial begin
rst_n = 1'b0;
#1000;
rst_n = 1'b1;
end
initial begin
run_test("my_driver");
end
endmodule
- 一个run_test语句会创建一个my_driver的实例,并且会自动调用my_driver的main_phase
- 根据类名创建一个类的实例,这是uvm_component_utils宏所带来的效果
- 所有派生自uvm_component及其派生类的类都应该使用uvm_component_utils宏注册
仿真结果
- 波形输出

从波形文件看,dut没有信号输入输出 - 结果输出

结果只输出到“main_phase is called”,根本没有输出“data is drived”,而按照预期,它应该输出256次
- 分析
tb中由显式创建my driver实例变为通过factory机制 run_test()创建,没有显式调用$finish函数结束,但程序执行到main_phase is called停止了。这里与UVM的objection机制有关
initial begin
my_driver drv;
drv = new("drv", null);
drv.main_phase(null);
$finish();
end
initial begin
run_test("my_driver");
end