1. 成员解释:
stream_id: 指示何种设备发出或传送的transaction。一般和transactor相关
data_id: transaction的序号
scenario_id:某设备传送的一组transaction,构成了一个scenario.
vmm_notify
我们只需要指定一个静态的log就可以构造出一个vmm_data实例。即, new(vmm_log log).
2. constraint的命名规则:
must obey constraint:"class_name_valid"
should obey constraint: "class_name_rule or class_name_var_local"
3. 必须补全的函数
virtual function string psdisplay(string prefix);
psdisplay=super.psdisplay(prefix); //输出 prefix以及stream_id,data_id, scenario_id
$sformat(psdisplay, "%s,....", psdisplay,this.member);
endfunction
virtual function bit is_valid(bit silent=1, int kind=0);
is_valid=1;
if(!super.is_valid(silent,kind)) begin
is_valid=0;
return;
end
if(kind) begin
if(this.move==IDLE) begin
if(!silent) `vmm_error(log,"must not be IDLE");
is_valid=0;
return;
end
end
else begin
if(!this.randomize(null))begin
if(!silent) `vmm_error(log,"failed randomization check");
is_valid=0;
return;
end
end
endfunction
virtual function vmm_data allocate();
packet tr=new();
allocate=tr;
endfunction
virtual function vmm_data copy(vmm_data to=null);
packet cpy;
if(to ==null) cpy=new;
else if(!$cast(cpy, to)) begin
`vmm_fatal(log, "Attemping to copy mismatched packet instance");
end
this.copy_data(cpy);
cpy.prop= this.prop; //扩展成员拷贝
.......
copy=cpy;
endfunction
function void post_randomize()
....
endfunction
virtual function bit compare(vmm_data to, output string diff, input int kind = -1);
packet pkt;
compare=0;
if(to==null) begin diff="No target Compare Object!"; return; end
if(!$cast(pkt,to)) begin diff="Not object of the same class!"; return; end
if(..!=..) diff="..." return; end
if(..!=..) diff="..." return; end
diff = "successful compare!";
compare=1;
endfunction
通过copy 和 compare函数不难发现, 源或目的一般用最基本的基类,而在函数中声明一个当前的扩展类的handler,然后检查这源或目是否为空,如果为空则给声明的扩展类的handler分派内存,否则通过cast直接赋值给扩展类的handler。 如果基类handler被赋扩展类的handler后只能看到基类的数据成员和基类虚函数对应的扩展类的函数。
4. transaction(data item) 即 vmm_data 的派生类 的new函数不应该带任何参数。--- generator 的需要。