sequence进阶
sequence的仲裁
多个sequence发送给一个sequencer的情况,使用的两种方式:
class virtual_seqence extends uvm_sequence;
virtual task body();
sub_sequene seq_0;
sub_sequene seq_1;
//第一种方式
p_sequencer.apb_mst_sqr.set_arbitration(SEQ_APB_STRICT_FIFO);
fork
`uvm_do_on_pri_with(seq_0,p_sequencer.apb_mst_sqr,100,{seq_0.addr==0;});
`uvm_do_on_pri_with(seq_1,p_sequencer.apb_mst_sqr,200,{seq_1.addr==1;});
join
//第二种方式
p_sequencer.apb_mst_sqr.set_arbitration(SEQ_APB_WEIGHTED);
fork
`uvm_do_on_pri_with(seq_0,p_sequencer.apb_mst_sqr,1,{seq_0.addr==0;});
`uvm_do_on_pri_with(seq_1,p_sequencer.apb_mst_sqr,2,{seq_1.addr==1;});
join
endclass
lock & grab
允许sequence获得对sequencer的独占访问权
lock()和unlock():被插入sequencer仲裁队列的最后面
grab()和ungrab():直接被放入sequencer仲裁队列的最前面
response
应用:如AXI乱序操作则需要response
sequence需根据driver对transaction的反应决定接下来发送数据→在sequence中使用get_response,在driver中使用put_reponse
当只有put的情况而没有get情况下,队列中存满8个response时,会发出溢出错误提示
solution:用response_handler,调用函数use_response_handler(1),此值默认是0
sequence library
一个sequence可以加入多个不同的sequence library中;
可以有多个sequence加入同一个sequence library中。
layer sequence
注意端口连接问题
config_db
使用uvm_config_db配置机制来传递接口,可以将接口的传递与获取彻底分离开
//四个参数,前两个参数决定路径;第一个参数null等于uvm_root::get()
uvm_config_db#(type T)::get( uvm_component cntxt, string inst_name, string field_name, T value )
uvm_config_db#(type T)::set( uvm_component cntxt, string inst_name, string field_name, T value )
uvm_config_db#(type T)::exists(uvm_component cntxt,string inst_name,string field_name,bit spell_chk = )
uvm_config_db#(type T)::wait_modified( uvm_component cntxt, string inst_name, string field_name)
配置接口
top_tb文件中set interface:
即可在driver中get该interface:
若为uvm_test_top.apb_env.* 则env下的component都能get到该interface
若为uvm_test_top.apb_env* 则env下的component,包括env都能get到该interface
配置sequence/ 配置参数
配置到object:config类
整合需要配置的变量,放置到一个uvm_object中,再使用其在验证环境中传递
定义test case,将该config实例化并传递给apb_env中所有的component:
driver中get该cfg,并做类型转化;输出得到config中的值:
create和new的区别:create可用factory机制,new不行
得到seqence路径的两种方法
component里的值传到object sequence里:
多重set/get发送覆盖规则:
同层次set,后执行覆盖先执行
非同层次set,高层次覆盖低层次
message
//某个component的冗余度阈值
get_report_verbosity_level()
set_report_verbosity_level()
//把env.i_agt及其下所有的component的冗余度阈值设置为UVM_HIGH
env.i_agt.set_report_verbosity_level_hier(UVM_HIGH);
`define uvm_info(ID,MSG,VERBOSITY)
typedef enum
{
UVM_NONE=0,
UVM_LOW=100,
UVM_MEDIUM=200,//默认,小于等于阈值显示
UVM_HIGH=300,
UVM_FULL=400,
UVM_DEBUG=500
}uvm_verbosity
`define uvm_warning(ID,MSG)
`define uvm_error(ID,MSG)
`define uvm_ fatal(ID,MSG)//会结束仿真
越关键的阈值越小
warning、error、fatal默认UVM_NONE
error和fatal区别:发现一个error继续仿真,fatal直接停止
设置uvm_error计数结束
//退出阈值为5,0表示此值不可以被后面的设置语句重载
<sim command>+UVM_MAX_QUIT_COUNT=5,0
message的实现(信息打印到log中)
在monitor中定义打印信息:
base_test中创建file,读取文件,action并将error放入err_result_file中:
err_result.log中显示: