5 UVM Objections

目录

5.1 class hierarchy

5.2 class declaration

5.3 UVM objection Usage

5.4 Methods in uvm_objection

5.5 Callback Hooks

5.6 Drain Time

5.7 UVM Objection示例

5.7.1 An objection in the test component

5.7.2 An objection in the sequence

5.7.2.1 with set_starting_phase and get_starting_phase methods

5.7.2.2 with set_automatic_phase_objection method


uvm_objection类提供了一种机制来协调两个或多个组件(对象)之间的状态信息。uvm_objection类是从uvm_report_object扩展而来的。

5.1 class hierarchy(类层次结构)

5.2 class declaration(类声明)

class uvm_objection extends uvm_report_object

objection涉及raise和drop objection的概念,即内部计数器分别为递增和递减。每个参与的组件和对象可以异步raise或这drop objections。当所有objectons被drop时,计数器值将变为零。必须在开始任何流程/事务之前raise objection,并在流程/事务处理完成后drop。

5.3 UVM objection Usage(使用)

  1. UVM phase机制使用objections来相互协调,当所有objections被drop时,该phase应当结束。它们可以用于所有UVM phase中。
  2. UVM objection可以用于“测试结束”。仿真耗时的活动发生在run phase。如果run phase的所有objections都drop了,则意味着仿真活动已完成。test可以在执行clean up phases后结束。
task reset_phase( uvm_phase phase);
  phase.raise_objection(this);
  ...
  phase.drop_objection(this);
endtask

task run_phase(uvm_phase phase);
  phase.raise_objection(this, "Raised Objection");
  ...
  phase.drop_objection(this, "Dropped Objection");
endtask

注:

1. objections通常用在components和sequences。

2. 其他objects也可以使用objections,但是他们必须使用一个component或者sequence对象上下文。 

5.4 Methods in uvm_objection

5.5 Callback Hooks

回调方法在从uvm_callback类派生的uvm_objection_callback类中定义。

5.6 Drain Time

所有objections之间的等待时间已被drop,调用all_dropped()回调函数称为drain time。【没明白】

5.7 UVM Objection示例

在下面的示例中,没有建立完整的driver、sequence和sequencer之间的通信,因为其目的是为了讲清楚objections机制。

5.7.1 An objection in the test component

在执行run_phase之前调用raise_objection。一旦run_phase的活动完成,就会调用drop_objection。test的run_phase如下所述。

class seq_item extends uvm_sequence_item;
  rand bit[15:0] addr;
  rand bit[15:0] data;
  `uvm_object_utils(seq_item)
  
  function new(string name = "seq_item");
    super.new(name);
  endfunction
  
endclass

class base_seq extends uvm_sequence #(seq_item);
  seq_item req;
  `uvm_object_utils(base_seq)
  
  function new (string name = "base_seq");
    super.new(name);
  endfunction

  task body();
    `uvm_info(get_type_name(), "Base seq: Body started", UVM_LOW);
    req = seq_item::type_id::create("req");
    // send to the driver
    #20;
    `uvm_info(get_type_name(), "Base seq: Body completed", UVM_LOW);
  endtask
endclass


class base_test extends uvm_test;
  base_seq bseq;

  `uvm_component_utils(base_test)
  
  function new(string name = "base_test", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction
 
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    phase.raise_objection(this, "Raise Objection");
    bseq = base_seq::type_id::create("bseq");    
    bseq.start(null);
    phase.drop_objection(this, "Drop Objection");
  endtask
endclass

module tb_top;
  initial begin
    run_test("base_test");
  end
endmodule

Output:

 

UVM_INFO testbench.sv(17) @ 0: reporter@@bseq [base_seq] Base seq: Body started
UVM_INFO testbench.sv(21) @ 20: reporter@@bseq [base_seq] Base seq: Body completed

5.7.2 An objection in the sequence

可以在body task或pre_body/post_body task中raise(提起)和drop(撤销)objection。

class base_seq extends uvm_sequence #(seq_item);
  ...
  task pre_body();
    if(starting_phase != null) starting_phase.raise_objection(this);
  endtask
 
  task body();
    req = seq_item::type_id::create("req");
    // send to the driver
    #20;
   ...
  endtask
 
  task post_body();
    if(starting_phase != null) starting_phase.drop_objection(this);
  endtask
endclass

建议不要将上述代码与uvm1.2一起使用,因为作starting_phase()方法来自uvm_sequence_base在uvm1.2中已被弃用。

sequence中的objection机制可以与以下两种方法一起使用。

  1. With set_starting_phase and get_starting_phase methods
  2. With set_automatic_phase_objection method

5.7.2.1 with set_starting_phase and get_starting_phase methods

两种新方法set_starting_phase and get_starting_phase作为替换被添加。

顾名思义set_starting_phase and get_starting_phase用于设置和检索phase。

注:如果get_starting_phase返回null,那么sequence将不会raise和drop(提起和撤销)objection。

class seq_item extends uvm_sequence_item;
  rand bit[15:0] addr;
  rand bit[15:0] data;
  `uvm_object_utils(seq_item)
  
  function new(string name = "seq_item");
    super.new(name);
  endfunction
  
endclass

class base_seq extends uvm_sequence #(seq_item);
  seq_item req;
  uvm_phase phase;
  `uvm_object_utils(base_seq)
  
  function new (string name = "base_seq");
    super.new(name);
  endfunction

  task pre_body();
    `uvm_info(get_type_name(), "Inside pre_body", UVM_LOW);
    phase = get_starting_phase; // Retrieve phase information
    if (phase != null) phase.raise_objection(this);
  endtask
  
  task body();
    `uvm_info(get_type_name(), "Base seq: Body started", UVM_LOW);
    req = seq_item::type_id::create("req");
    // send to the driver
    #20;
    `uvm_info(get_type_name(), "Base seq: Body completed", UVM_LOW);
  endtask
  
  task post_body();
    `uvm_info(get_type_name(), "Inside post_body", UVM_LOW);
    if (phase != null) phase.drop_objection(this);
  endtask
endclass

class base_test extends uvm_test;
  base_seq bseq;

  `uvm_component_utils(base_test)
  
  function new(string name = "base_test", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction
 
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    bseq = base_seq::type_id::create("bseq");
    bseq.set_starting_phase(phase); // Set starting phase
    bseq.start(null);
  endtask
endclass

module tb_top;
  initial begin
    run_test("base_test");
  end
endmodule

Output: 

UVM_INFO testbench.sv(18) @ 0: reporter@@bseq [base_seq] Inside pre_body
UVM_INFO testbench.sv(24) @ 0: reporter@@bseq [base_seq] Base seq: Body started
UVM_INFO testbench.sv(28) @ 20: reporter@@bseq [base_seq] Base seq: Body completed
UVM_INFO testbench.sv(32) @ 20: reporter@@bseq [base_seq] Inside post_body

5.7.2.2 with set_automatic_phase_objection method

uvm1.2还添加了set_automatic_phase_objection自动raise和drop当前sequence的objection。相应的,在执行sequence之前无需调用raise_objection,sequence执行结束之前无需调用drop_objection。

相反,设置set_automatic_phase_objection(1) 在sequence的new() 函数中或者在sequence start之前。

class seq_item extends uvm_sequence_item;
  rand bit[15:0] addr;
  rand bit[15:0] data;

  `uvm_object_utils(seq_item)
  
  function new(string name = "seq_item");
    super.new(name);
  endfunction
  
endclass

class base_seq extends uvm_sequence #(seq_item);
  seq_item req;
  uvm_phase phase;
  `uvm_object_utils(base_seq)
  
  function new (string name = "base_seq");
    super.new(name);
  endfunction

  task pre_body();
    `uvm_info(get_type_name(), "Inside pre_body", UVM_LOW);
  endtask
  
  task body();
    `uvm_info(get_type_name(), "Base seq: Body started", UVM_LOW);
    req = seq_item::type_id::create("req");
    // send to the driver
    #20;
    `uvm_info(get_type_name(), "Base seq: Body completed", UVM_LOW);
  endtask
  
  task post_body();
    `uvm_info(get_type_name(), "Inside post_body", UVM_LOW);
  endtask
endclass

class base_test extends uvm_test;
  base_seq bseq;

  `uvm_component_utils(base_test)
  
  function new(string name = "base_test", uvm_component parent = null);
    super.new(name, parent);
  endfunction
  
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction
 
  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    bseq = base_seq::type_id::create("bseq");
    bseq.set_starting_phase(phase);
    bseq.set_automatic_phase_objection(1);
    bseq.start(null);
  endtask
endclass

module tb_top;
  initial begin
    run_test("base_test");
  end
endmodule

Output:

UVM_INFO testbench.sv(18) @ 0: reporter@@bseq [base_seq] Inside pre_body
UVM_INFO testbench.sv(22) @ 0: reporter@@bseq [base_seq] Base seq: Body started
UVM_INFO testbench.sv(26) @ 20: reporter@@bseq [base_seq] Base seq: Body completed
UVM_INFO testbench.sv(30) @ 20: reporter@@bseq [base_seq] Inside post_body

注:如果sequence的body里有一个forever循环请不要设置set_automatic_phase_objection(1),因为objections将永远不会被drop。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值