我的第一批UVM教程(#1至#6)已于三年前发布。 从那以后,UVM(以及我的知识)已经发展,我一直想更新我的文章和代码。 但这并不容易,因为我的文章和代码紧密结合,读者的一些评论甚至提到了特定的代码行。
UVM 1.2
大约两个月前,Accellera发布了新的UVM 1.2,它激励我更新我的 jelly bean taster。 我认为是时候进行大修了。 有趣的是,我的代码几乎不需要修改。 我做的唯一改变是利用了uvm_sequence_base类的新自动phase objection。 set_automatic_phase_objection函数在执行序列之前自动提出objection,并在结束序列(第25行)后丢弃objection。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function new( string name, uvm_component parent );
super.new( name, parent );
endfunction: new
function void build_phase( uvm_phase phase );
super.build_phase( phase );
jelly_bean_transaction::type_id::set_type_override(
sugar_free_jelly_bean_transaction::get_type() );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
task main_phase( uvm_phase phase );
gift_boxed_jelly_bean_sequence jb_seq;
jb_seq = gift_boxed_jelly_bean_sequence::type_id::create( .name( "jb_seq" ) );
assert( jb_seq.randomize() );
`uvm_info( "jb_seq", jb_seq.convert2string(), UVM_NONE )
jb_seq.set_starting_phase( phase );
jb_seq.set_automatic_phase_objection( .value( 1 ) );
jb_seq.start( jb_env.jb_agent.jb_seqr );
endtask: main_phase
endclass: jelly_bean_test
借此机会,我还简化了记分板,因为环境中使用的分层记分板总是让新手感到困惑。以下是验证组件的简化层次结构。请注意,jelly_bean_sb_subscriber周围的包装已被删除。如果您有兴趣,可以将此图与“概述”中的图形进行比较。
jelly_bean_sb_subscriber已经相应地被简化了。write函数自己检查口味是否具有期望值。
class jelly_bean_sb_subscriber extends uvm_subscriber#( jelly_bean_transaction );
`uvm_component_utils( jelly_bean_sb_subscriber )
function new( string name, uvm_component parent );
super.new( name, parent );
endfunction: new
function void write( jelly_bean_transaction t );
if ( t.flavor == CHOCOLATE && t.sour && t.taste == YUMMY ||
! ( t.flavor == CHOCOLATE && t.sour ) && t.taste == YUCKY ) begin
`uvm_error( get_name(), { "You lost sense of taste!", t.convert2string() } )
end else begin
`uvm_info( get_name(), { "You have a good sense of taste.", t.convert2string() }, UVM_LOW )
end
endfunction: write
endclass: jelly_bean_sb_subscriber
jelly_bean_env直接实例化没有包装的jelly_bean_sb_subscriber(第16行)。
class jelly_bean_env extends uvm_env;
`uvm_component_utils( jelly_bean_env )
jelly_bean_agent jb_agent;
jelly_bean_fc_subscriber jb_fc;
jelly_bean_sb_subscriber jb_sb;
function new( string name, uvm_component parent );
super.new( name, parent );
endfunction: new
function void build_phase( uvm_phase phase );
super.build_phase( phase );
jb_agent = jelly_bean_agent ::type_id::create( .name( "jb_agent" ), .parent( this ) );
jb_fc = jelly_bean_fc_subscriber::type_id::create( .name( "jb_fc" ), .parent( this ) );
jb_sb = jelly_bean_sb_subscriber::type_id::create( .name( "jb_sb" ), .parent( this ) );
endfunction: build_phase
function void connect_phase( uvm_phase phase );
super.connect_phase( phase );
jb_agent.jb_ap.connect( jb_fc.analysis_export );
jb_agent.jb_ap.connect( jb_sb.analysis_export );
endfunction: connect_phase
endclass: jelly_bean_env
您现在可以在EDA Playground上查看并运行新代码!对于那些不了解EDA Playground的人来说,它是由Victor EDA,Inc.开发的基于网络的仿真器。大约两周前,他们添加了Aldec的Riviera-PRO EDU仿真器,这使我们能够使用SystemVerilog的全部功能,包括随机化,SVA和功能覆盖率。多么美妙!谢谢Victor EDA和Aldec!