| 
×
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册  sequence的启动和执行
 
 1)使用default_sequence启动 (全自动) 使用sequence机制之后,在不同的测试用例中,可以将不同的sequence设置成sequencer的main_phase的default_sequence。 当sequencer执行到main_phase时,发现有default_sequence,那么它就自动启动sequence。当一个sequence启动后会自动执行sequence的body任务。  文件:src/ch6/section6.1/6.1.2/my_case0.sv function void my_case0::build_phase(uvm_phase phase);
 case0_sequence cseq;
 super.build_phase(phase);
 
 cseq = new("cseq");
 uvm_config_db#(uvm_sequence_base)::set(this, "env.i_agt.sqr.main_phase", "default_sequence", cseq);
 endfunction
 
 
 
 
 2)通过start任务启动(半自动) 先实例化一个sequence,然后通过start任务启动:(实例化和start可以分布在不同的phase中) 应用示例: class定义:
 my_sequence my_seq;
 build_phase:
 my_seq = my_sequence::type_id::create("my_seq");
 configure_phase/main_phase/xx_phase:
 my_seq.start(sequencer);
 
 
 上述示例中,其实不需要使用set-drain_time(),因为已经设置了等待标志位;set_drain_time()一般设置在RM中,具体延时时间设置为该模块处理一个包的最大延时; 
 小扩展:set_drain_time ()的使用 无论任何功能的模块,都有其处理延时。如图5-5a所示,0时刻DUT开始接收输入,直到p时刻才有数据输出。 在sequence中,n时刻发送完毕最后一个transaction,如果此时立刻drop_objection,那么最后在n+p时刻DUT输出的包将无法接收到。 因此,在sequence中,最后一个包发送完毕后,要延时p时间才能drop_objection: UVM为所有的objection设置了drain_time这一属性,假如在main_phase中设置了drain_time,, 当UVM在main_phase检测到所有的objection被撤销后,接下来会检查有没有设置drain_time。 如果没有设置,则马上进入到post_main_phase,否则延迟drain_time后再进入post_main_phase。 (drain_time可以在任何phase中设置,呈现的效果就是该phase会在所有objection撤销后,再延迟drain_time再进入下一个phase) 
 3)通过start_item/finish_item(手动) 1. class里定义sequence; 2. 实例化sequence; 3. 指定sequence的sequencer; 4. 创建一个transaction,然后通过start_item/finish_item发送;  class tc_xx extends tc_base; my_sequence    my_seq;      // 定义sequence
 endclass
 
 function void tc_xx::build_phase(uvm_phase phase);
 super.build_phase(phase);
 this.my_seq = my_sequence::type_id::create("my_seq", this);   // 实例化sequence
 endfunction
 
 task tc_xx::pre_main_phase(uvm_phase phase);
 super.pre_main_phase(phase);
 this.my_seq.set_sequencer(this.env.your_sqr);    // 指定对应的sequencer
 endtask
 
 task tc_xx::main_phase(uvm_phase phase);
 a_sequence_item    a_item;
 a_item = a_sequence_item::type_id::create("a_item");   // 创建transaction
 a_item.randomize() with { 约束1/2/3};                  // 创建特殊约束
 
 this.my_seq.start_item(a_item);        // 发送transaction
 this.my_seq.finish_item(a_item);
 endtask
 
 
 
 3. 返回rsp的sequence应用实例 假设有一个model,收到读请求的req后,需要返回rdata,具体实现: 思路:1. 需要检测是否收到读请求的transaction;     2. 收到后,需要生成rsp的transaction,通过sequence发送出去; class model extends uvm_component;
 my_sequence    seq;
 uvm_blocking_get_port #(uvm_sequence_item) in_port;
 ...
 endclass
 
 function model::new(string name, uvm_component parent);
 super.new(name, parent);
 in_port = new("in_port", this);
 this.seq = my_sequence::tyoe_id::create("seq");
 endfunction
 
 task model::run_phase(uvm_phase phase);
 super.run_phase(phase);
 gen_rsp();
 endtask
 
 task model::gen_rsp();
 uvm_sequence_item  item;
 req_sequence_item  req;
 
 forever begin
 this.in_port.get(item);
 if(!$cast(req,item)) begin
 `uvm_error(xxxxx)
 end
 
 if(req.rd == 1) begin
 rsp_sequence_item    rsp;
 rsp = rsp_sequence_item::type_id::create("rsp");
 
 rsp.rdata = data[req.addr];
 
 seq.start_item(rsp);
 seq.finish_item(rsp);
 end
 end
 endtask
 
 
 按照上述通过start_item/finish_itam启动方式的介绍,看一下上述代码中少了哪一步? 
 
 
 |