Sequence机制
1、什么是UVM的sequence机制
控制和产生一系列的事物,并通过某种方法将事物发送给driver的机制。具有控制何时产生事物,产生事物并将事物发送(通过sequencer)给driver的功能。Sequence是一个产生和发送数据的过程,会消耗仿真时间。只有在task_phase中才会启动。
事物产生和发送流程:
(1)当进入某个task_phase之后,sequence被启动产生事物,并将事物发送给sequencer。
(2)当driver需要驱动事物发送给DUT时,首先向sequencer发送事物请求,sequencer再将产生好的事物发送给driver。
(3)driver处理完事物,会发送完成响应,并发送给sequencer,在转发给sequence。sequence收到响应会产生下一个事物。
2、 Sequence机制的原理
Sequence机制主要涉及到三个组件sequence、sequencer和driver。分别讲述三个组件所做的事情。
1、Sequencer: 当sequencer启动时,首先会检查自身的default_sequence是否配置,如果配置了就会创建实体,设置该sequence的starting_phase并随机化该sequence。最后调用sequence的start()函数启动该sequence。
2、Sequence:当sequence的start的函数启动,sequence会执行body方法,产生事物,并将事物发送给sequencer放入FIFO中储存。Sequence会等待一个driver的完成响应,得到之后会退出该次事物的产生。
3、Driver:首先向sequencer发送一个事物请求,然后等待事物,sequencer会将产生好的事物发送给driver,driver在处理完该事物后,返回一个完成响应。
//driver
task ahb_driver::main_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req); //发送事物请求
do_driver(req); //处理事物发送给DUT
#100;
seq_item_port.item_done(); //返回完成标志响应
end
endtask
//sequence.sv
virtual task body();
if(starting_phase != null)
starting_phase.raise_objection(this);
repeat(10) begin
`uvm_do(req); //实现item的产生,并等待完成标志响应
end
#100
if(starting_phase != null)
starting_phase.drop_objection(this);
endtask
sequencer的功能源代码已经完成,不需要自己另外单独设置。
3、 uvm_do_*宏介绍
1、根据sequence_item实例,随机化产生数据
`uvm_do(SEQ_OR_ITEM)
2、 在随机化数据的基础上,添加约束
`uvm_do_with(SEQ_OR_ITEM,CONSTRAINTS)
3、 随机化同时,显式的指定使用哪个sequencer来发送此transaction
`uvm_do_on(SEQ_OR_ITEM,SEQR)
4、参数与上式相同
`uvm_do_on_with(SEQ_OR_ITEM, SEQR, CONSTRAINTS)
4、Sequence机制的实现流程:
(1) 传入句柄是sequence_item类型时,调用start_item函数,随机化item,最后调用finish_item函数。
virtual task body()
my_transaction tr;
if(starting_phase != null)
starting_phase.raise_objection(this);
repeat(item_num) begin
//`uvm_do(req)
tr = my_transaction::type_id::create("tr");//实例化事物
start_item(tr);//对事物进行设置
tr.randomize();//随机化事物
finish_item(tr);
get_response(rsp);//获取完成标志响应
end
#100;
if(starting_phase != null)
starting_phase.drop_objection(this);
endtask
//driver.sv//返回响应
rsp = my_transaction::type_id::create("rsq");
$cast(rsp, req.clone());
rsp.set_id_info(req);
seq_item_port.put_response(rsp);
seq_item_port.item_done();
(2) 如果是sequence类型,直接调用start函数。
Sequence启动方法:
1//test.sv
uvm_config_db#(uvm_object_wrapper)::set(this,"*.m_seqr.run_phase","default_sequence", my_sequence::get_type());
2//test.sv
virtual task run_phase(uvm_phase phase);
my_sequence m_seq;
phase.raise_objection(this);//raise objection
m_seq = my_sequence::type_id::create("m_seq");//实例化sequence
m_seq.start(m_env.m_agent.m_seqr);//指定sequencer
phase.drop_objection(this);
endtask