目录
1.定义driver时传递给uvm_driver参数有什么用?
2.4 UVM终极大作:sequence
1.定义driver时传递给uvm_driver参数有什么用?
class my_driver extends uvm_driver#(my_transaction);//传递参数
......
......
for(int i = 0; i < 2; i++) begin
req = new("req");//直接例化使用,省略my_transaction req
assert(req.randomize() with {pload.size == 200;});
drive_one_pkt(req);
end
.....
.....
endclass
2. 引入sequence/sequencer是为了什么?
之前的激励都是在driver中产生,driver顾名思义只负责驱动.引入两者之后,激励在sequence(seq)中产生,但是无法直接从sequence传递至driver,因为sequence不是compoent,所以seq需要挂载到sequencer(sqr)上.最终发送至driver上.
3.uvm_do实现了什么?
1.例化my_transaction 2,随机化刚才的实例 3.发送至sqr
原来实现在driver,唯一不同的是,第三步driver会直接驱动至dut,代码如下:
task my_driver::main_phase(uvm_phase phase);
phase.raise_objection(this);
vif.data <= 8'b0;
vif.valid <= 1'b0;
while(!vif.rst_n)
@(posedge vif.clk);
for(int i = 0; i < 2; i++) begin
req = new("req");
assert(req.randomize() with {pload.size == 200;});
drive_one_pkt(req);
end
4.容易遗忘的driver和sqr在agent中的连接
这里sqr和seq/drv两者之间有一定的流程,源代码比较复杂(比如三者之间请求/批准具体是怎么实现的),先不做了解.
但是有一个点比较容易遗忘,便是为了满足drv向sqr申请transaction而建立的通道.需求是:drv向sqr申请transaction,解决是:连接seq_item_export.尤其sqr.sv很干净,你看不到seq_item_expor.其实这个是在源代码中可见.
//uvm_sequencer的new函数
function uvm_sequencer::new (string name, uvm_component parent=null);
super.new(name, parent);
seq_item_export = new ("seq_item_export", this);
endfunction
5.item_done()
参考p.46页,具体思路暂时忘了,后续补一下
6.如何启动seq?
1.某个compoent的main_phase中,使用seq.star(sqr)启动.注意使用objection,objection和transaction生命周期紧密相关.
2.某个compoent的build_phase中,使用default_sequence自动启动.这里使用到了config_db,但是有几个特殊之处①第三个第四个以及uvm_object_wrapper不知道什么逻辑.②只有set没有get
另外注意objection,手动启动和自动启动的objection相关代码,后者是使用starting_phase进行raise/drop
//手动启动
task my_env::main_phase(uvm_phase phase);
my_sequence seq;
phase.raise_objection(this);
seq = my_sequence::type_id::create("seq");
seq.start(i_agt.sqr);
phase.drop_objection(this);
endtask
//自动启动
class my_sequence extends uvm_sequence #(my_transaction);
my_transaction m_trans;
function new(string name= "my_sequence");
super.new(name);
endfunction
virtual task body();
if(starting_phase != null)
starting_phase.raise_objection(this);
repeat (10) begin
`uvm_do(m_trans)
end
#1000;
if(starting_phase != null)
starting_phase.drop_objection(this);
endtask
`uvm_object_utils(my_sequence)
endclass