uvm_primer ch10 面向对象的testbench
package
当import 一个package之后,可以访问package中所有的定义数据等;
package tinyalu_pkg;
typedef enum bit[2:0] {
no_op = 3'b000,
add_op = 3'b001,
and_op = 3'b010,
xor_op = 3'b011,
mul_op = 3'b100,
rst_op = 3'b111} operation_t;
`include "coverage.svh"
`include "tester.svh"
`include "scoreboard.svh"
`include "testbench.svh"
endpackage : tinyalu_pkg
top中定义dut/interface/testbench,并连接
使用interface连接testbench和dut;
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));
tinyalu_bfm bfm();
testbench testbench_h;
initial begin
testbench_h = new(bfm);
testbench_h.execute();
end
endmodule : top
testbench
testbench中实例化激励/coverage/scb等模块
重点关注virtual tinyalu_bfm bfm;
virtual tinyalu_bfm bfm
是一个对象 该对象在面向对象中等价于模块的端口列表;
virtual 告诉编译器bfm这个变量将来会赋值一个tinyalu_bfm类型的句柄;但是在编译的时候bfm中还没有句柄;
-还有问题关于virtual 存疑
class testbench;
virtual tinyalu_bfm bfm;
tester tester_h;
coverage coverage_h;
scoreboard scoreboard_h;
function new (virtual tinyalu_bfm b);
bfm = b;
endfunction : new
task execute();
tester_h = new(bfm);
coverage_h = new(bfm);
scoreboard_h = new(bfm);
fork
tester_h.execute();
coverage_h.execute();
scoreboard_h.execute();
join_none
endtask : execute
endclass : testbench
激励tester
class tester;
virtual tinyalu_bfm bfm;
function new (virtual tinyalu_bfm b);
bfm = b;
endfunction : new
protected function operation_t get_op();
bit [2:0] op_choice;
op_choice = $random;
case (op_choice)
3'b000 : return no_op;
3'b001 : return add_op;
3'b010 : return and_op;
3'b011 : return xor_op;
3'b100 : return mul_op;
3'b101 : return no_op;
3'b110 : return rst_op;
3'b111 : return rst_op;
endcase // case (op_choice)
endfunction : get_op
protected function byte get_data();
bit [1:0] zero_ones;
zero_ones = $random;
if (zero_ones == 2'b00)
return 8'h00;
else if (zero_ones == 2'b11)
return 8'hFF;
else
return $random;
endfunction : get_data
task execute();
byte unsigned iA;
byte unsigned iB;
shortint unsigned result;
operation_t op_set;
bfm.reset_alu();
op_set = rst_op;
iA = get_data();
iB = get_data();
bfm.send_op(iA, iB, op_set, result);
op_set = mul_op;
bfm.send_op(iA, iB, op_set, result);
bfm.send_op(iA, iB, op_set, result);
op_set = rst_op;
bfm.send_op(iA, iB, op_set, result);
repeat (10) begin : random_loop
op_set = get_op();
iA = get_data();
iB = get_data();
bfm.send_op(iA, iB, op_set, result );
$display("%2h %6s %2h = %4h",iA, op_set.name(), iB, result);
end : random_loop
$stop;
endtask : execute
endclass : tester