马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
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启动方式的介绍,看一下上述代码中少了哪一步?
|