学习目标
UVM入门和进阶部分8
学习内容
1.将sequence挂载到sequencer上:
uvm_sequence::start(uvm_sequencer_base sequencer,uvm_sequence_base parent_sequence=null,int this_priority=-1,bit call_pre_post=1)
用户首先应该指明sequencer的句柄,如果sequence是顶层sequence,则可以省略第二个参数parent_sequence的指定;
第三个参数的默认值为-1,会使得该sequence继承parent_sequence的优先级,若为顶层sequence,默认为100,用户也可以自定义优先级数值;
第四个参数建议使用默认值,为1时,uvm_sequence::pre_doby()和uvm_sequence::post_body()两个方法会在uvm_sequence::body()的前后执行
2.将item挂载到sequencer上:
uvm_sequence::start_item(uvm_sequence_item item,int set_priority=-1,uvm_sequencer_base sequencer=null);
uvm_sequence::finish_item(uvm_sequence_item item,int set_priority=-1);
3.对于一个item的完整传送,sequence要在sequencer一侧获得通过权限,才可以顺利将item发送至driver,具体步骤:
创建item
通过start_item()方法等待获取sequencer的授权许可,其后执行parent sequence的方法pre_do()
对item进行随机化处理
通过finish_item()方法在对item进行了随机化处理之后,执行parent sequence的mid_do(),以及调用uvm_sequencer::send_request()和uvm_sequencer::wait_for_item_done()来将item发送至sequencer再完成与driver之间的握手,最后执行了parent_sequence的post_do()
4.注意点:
sequence和item自身的优先级,可以决定什么时刻可以获得sequencer的授权
parent sequence的虚方法pre_do()、mid_do()和post_do()会发生在发送item的过程中间
5.start()的自然代码执行顺序和条件
6.start_item()/finish_item()的自然代码执行顺序和条件
7.发送序列的相关宏
8.uvm_sequencer类自建了仲裁机制,用来保证多个sequence在同时挂载到sequencer时,可以按照仲裁规则允许特定sequence中的item优先通过
9.通过uvm_sequencer::set_arbitration(UVM_SEQ_ARB_TYPE val)函数来设置仲裁模式
10.lock()和grab()锁定机制,grab()更为强势,只需要在sequencer下一次授权周期时就可以无条件得获得授权,可以无视同一时刻内发起传送请求的其他sequence,但是不能无视已经预先获得授权的其他lock或者grab的sequence
11.层次化sequence:hierarchical sequence(hierarchical等级制)、virtual sequence、layering sequence
12.hierarchical sequence例子
typedef enum {
CLKON,CLKOFF,RESET,WRREG,RDREG} cmd_t;
class bus_trans extends uvm_sequence_item;
rand cmd_t cmd;
rand int addr;
rand int data;
constraint cstr{
soft addr=='h0;
soft data=='h0;
}
...
endclass
class clk_rst_seq extends uvm_sequence;
rand int freq;
...
task body();
bus_trans req;
'uvm_do_with(req,{cmd==CLKON;data==freq;})
'uvm_do_with(req,{
cmd==RESET;})
endtask
endclass
class reg_test_seq extends uvm_sequence;
rand int chnl;
...
task body();
bus_trans req;
//对wr寄存器读写测试
'uvm_do_with(req,{cmd==WRREG;addr==chnl*'h4;})
'uvm_do_with(req,{cmd==RDREG;addr==chnl*'h4;})
//对rd寄存器读测试
'uvm_do_with(req,{cmd==RDREG;addr==chnl*'h4+'h10;})
endtask
endclass
class top_seq extends uvm_sequence; //top_seq为hierarchical sequence
... //clk_rst_seq、reg_test_seq为element sequence
task body();
clk_rst_seq clkseq;
reg_test_seq regseq0,regseq1,regseq2;
//打开150mhz时钟,重置断言
'uvm_do_with(clkreq,{
freq==150;})
'uvm_do_with(regreq0,{chnl==0;})
'uvm_do_with(regreq1,{
chnl==1;})
'uvm_do_with(regreq2,{chnl==2;})
endtask
endclass
class reg_master_sequencer ext