uvm_primer ch15 和多个对象对话
oop的思想
在一个类或者一个函数中只干一件事情;
使用变量来沟通不同的object,是一个糟糕的方法;
class dice_test extends uvm_test;
`uvm_component_utils(dice_test);
dice_roller dice_roller_h;
coverage coverage_h;
histogram histogram_h;
average average_h;
function void build_phase(uvm_phase phase);
coverage_h = new("coverage_h", this);
histogram_h = new("histogram_h",this);
average_h = new("average_h",this);
dice_roller_h = new("dice_roller_h",this);
endfunction : build_phase
task run_phase(uvm_phase phase);
int the_roll; //定义一个变量
phase.raise_objection(this);
repeat (20) begin
the_roll = dice_roller_h.two_dice();
coverage_h.write(the_roll); //使用变量来沟通不同的object 连接不同的object
histogram_h.write(the_roll);
average_h.write(the_roll);
end
phase.drop_objection(this);
endtask : run_phase
function new(string name, uvm_component parent);
super.new(name,parent);
endfunction : new
endclass : dice_test
观察者模式
之前我们学习过factory模式
现在引入一个新的设计模式,observer模式或者 twitter模式;
发twitter时:
- 不需要知道谁是你的粉丝;
- 不需要知道粉丝在得到twitter后会做什么;
- 甚至不需要有粉丝, 一样可以发twitter;
observer模式中一个对象只需要创建数据并分享出去,其他不用care;
每一个follower会得到一份同样的数据, 每一个follower怎么处理这个数据由各个follower决定;
也就是广播模式;
- uvm_anlysis_port 提供一个广播的途径;uvm_anlysis_port 不是uvm_component 的子类,但是它也是在仿真中始终存在的;使用write()函数来广播数据;使用connect()和subscriber相连接;
- uvm_subscriber extends uvm_component ;包含一个analysis_export;需要自己创建一个write()函数,用来处理收到的数据;
实现subscriber
class average extends uvm_subscriber #(int);
`uvm_component_utils(average);
real dice_total;
real count;
function new(string name, uvm_component parent = null);
super.new(name,parent);
dice_total = 0.0;
count = 0.0;
endfunction : new
function void write(int t);
dice_total = dice_total + t;
count++;
endfunction : write
function void report_phase(uvm_phase phase);
$display ("DICE AVERAGE: %2.1f",dice_total/count);
endfunction : report_phase
endclass : average
连接对象
定义analysis_port
class dice_roller extends uvm_component;
`uvm_component_utils(dice_roller);
uvm_analysis_port #(int) roll_ap; //定义analysis_port
function void build_phase (uvm_phase phase);
roll_ap = new("roll_ap",this);
endfunction : build_phase
rand byte die1;
rand byte die2;
constraint d6 {
die1 >= 1; die1 <= 6;
die2 >= 1; die2 <= 6; }
task run_phase(uvm_phase phase);
int the_roll;
phase.raise_objection(this);
void'(randomize());
repeat (20) begin
void'(randomize());
the_roll = die1 + die2;
roll_ap.write(the_roll); //调用write方法
end
phase.drop_objection(this);
endtask : run_phase
function new(string name, uvm_component parent);
super.new(name,parent);
endfunction : new
endclass : dice_roller
连接analysis_port
- build_phase是top-bottom的模式从顶往下
- connect_phase 是bottom-top模式
class dice_test extends uvm_test;
`uvm_component_utils(dice_test);
dice_roller dice_roller_h;
coverage coverage_h;
histogram histogram_h;
average average_h;
function void connect_phase(uvm_phase phase);
dice_roller_h.roll_ap.connect(coverage_h.analysis_export); //连接analysis_port
dice_roller_h.roll_ap.connect(histogram_h.analysis_export);
dice_roller_h.roll_ap.connect(average_h.analysis_export);
endfunction : connect_phase
function new(string name, uvm_component parent);
super.new(name,parent);
endfunction : new
function void build_phase(uvm_phase phase);
dice_roller_h = new("dice_roller_h", this);
coverage_h = new("coverage_h", this);
histogram_h = new("histogram_h",this);
average_h = new("average_h",this);
endfunction : build_phase
endclass : dice_test
连接关系示意图