Overriding the type of sequence items

Hi,

I’d like to override the type of items an agent uses using “set_inst_override”. That way I can have generic agent for a bus family and instance the agents without them needing to know which family member they’re dealing with. So I used “set_inst_override(”<path to agent>*,…);".

This worked fine when the agent’s sequences were autonomous but it stopped working when I began using a virtual sequence to drive the sequences.

Investigating I found that the reason is that “do” is creating the item using “ovm_sequence::create_item” which uses “ovm_sequence_item::get_full_name()” to work out the path for override purposes. “ovm_sequence_item::get_full_name()” returns the hierarchy to the sequence via the virtual sequencer (if there is one) and not via the sequencer (and thus the agent) so the override fails.

It doesn’t seem right to me that overriding the type of an item should depend upon how the sequence has been invoked.

I can get around this by creating my own item by calling create_object directly and passing it the correct path (assuming I can find it out reliably) but is this a good idea?

I have created an example by modifying one of Stuart’s virtual sequence examples from here.

The original example doesn’t have agents so I’ve applied the override directly to the sequencer and it’s children, but I don’t think that changes anything materially. There is one test (called “test”) which configures the default sequence for the sequencer to run “simple_seq” and also for the virtual sequencer to run “vsimple_seq” which invokes “simple_seq”.

When “simple_seq” is invoked as the default sequence it’s path is “ovm_test_top.env.sequencer0.simple_seq” and the driver gets “derived_item”, which is as intended

When “simple_seq” is invoked by “vsimple_seq” it’s path is “ovm_test_top.env.vsequencer0.vsimple_seq.s_seq” and the driver gets
“simple_item” which is not as intended.

module test;
  `include "ovm.svh"
  class simple_item extends ovm_sequence_item;
    `ovm_object_utils(simple_item)
    function new (string name="simple_item", 
      ovm_sequencer_base sequencer = null,
      ovm_sequence parent_seq = null);
      super.new(name, sequencer, parent_seq);
    endfunction : new
  endclass : simple_item
  
  class derived_item extends simple_item;
    `ovm_object_utils(derived_item)
    function new (string name="simple_item", 
      ovm_sequencer_base sequencer = null,
      ovm_sequence parent_seq = null);
      super.new(name, sequencer, parent_seq);
    endfunction : new
  endclass : derived_item
  
  class simple_vsequencer extends ovm_virtual_sequencer;
    `ovm_declare_sequence_lib
    function new (string name, ovm_component parent);
      super.new(name, parent);
      `ovm_update_sequence_lib
    endfunction : new
    `ovm_component_utils(simple_vsequencer)
    virtual function void build();
      super.build();
      add_seq_cons_if("foo");
      add_seq_cons_if("bar");
    endfunction
  endclass : simple_vsequencer
  
  class simple_sequencer extends ovm_sequencer;
    function new (string name, ovm_component parent);
      super.new(name, parent);
      `ovm_update_sequence_lib_and_item(simple_item)
    endfunction : new
    `ovm_declare_sequence_lib
    `ovm_component_utils(simple_sequencer)
  endclass : simple_sequencer
  
  class simple_seq extends ovm_sequence;
    rand int foo;
    int bar;
    simple_item s_item;
    function new(string name="simple_seq",
      ovm_sequencer_base sequencer=null,
      ovm_sequence parent_seq=null);
      super.new(name, sequencer, parent_seq);
    endfunction
    `ovm_sequence_utils_begin(simple_seq, simple_sequencer)    
      `ovm_field_int(foo, OVM_ALL_ON)
      `ovm_field_int(bar, OVM_ALL_ON)
    `ovm_sequence_utils_end
    virtual task body();
      $display("%0t : simple_seq(%s) body() starting...", $time,get_full_name());
      #10;
      `ovm_do(s_item)
      $display("%0t : simple_seq item done!", $time);
      bar = foo + 1;
      #40;
    endtask
  endclass : simple_seq
  
  class vsimple_seq extends ovm_sequence;
    simple_seq s_seq;
    function new(string name="simple_seq",
      ovm_sequencer_base sequencer=null,
      ovm_sequence parent_seq=null);
      super.new(name, sequencer, parent_seq);
    endfunction
    `ovm_sequence_utils(vsimple_seq, simple_vsequencer)    
    virtual task body();
      $display("%0t : vsimple_seq body() starting...", $time);
      #100;
      $display("%0t : vsimple_seq body() doing sequence...", $time);
      `ovm_do_seq(s_seq, p_sequencer.seq_cons_if["bar"])
    endtask
  endclass : vsimple_seq
  
  class simple_driver extends ovm_driver;
    ovm_sequence_item item;
    function new (string name, ovm_component parent);
      super.new(name, parent);
    endfunction : new
    `ovm_component_utils(simple_driver)
    task run();
      while(1) begin
        #10;
        $display("%0t : simple_driver getting next item...", $time);
        seq_item_prod_if.get_next_item(item);
        $display("%0t : simple_driver got item type %s",$time,item.get_type_name());
       seq_item_prod_if.item_done();
      end
    endtask: run
  endclass : simple_driver
  
  
  class simple_env extends ovm_env;

    `ovm_component_utils(simple_env)

    function new (string name, ovm_component parent=null);
      super.new(name, parent);
    endfunction : new
  
    simple_vsequencer vsequencer0;
    simple_sequencer sequencer0;
    simple_driver driver0;
    
    virtual function void build();
      assert($cast(vsequencer0,create_component("simple_vsequencer","vsequencer0")));
      assert($cast(sequencer0,create_component("simple_sequencer","sequencer0")));
      assert($cast(driver0,create_component("simple_driver","driver0")));
    endfunction : build

    virtual function void connect();
      driver0.seq_item_prod_if.connect_if(sequencer0.seq_item_cons_if);
      sequencer0.seq_prod_if.connect_if(vsequencer0.seq_cons_if["bar"]);
    endfunction : connect
  endclass : simple_env

  class test extends ovm_test;
    `ovm_component_utils(test)
    
    function new(
      string name = "ice_ocp_demo_base_test",
      ovm_component parent=null
    );
      super.new(name,parent);
    endfunction : new
    
    simple_env env;
   
    virtual function void build();
      set_inst_override("env.sequencer0*","simple_item","derived_item");
      set_config_string("env.sequencer0", "default_sequence", "simple_seq");
      set_config_string("env.vsequencer0", "default_sequence", "vsimple_seq");
      $cast(env, create_component("simple_env", "env"));
      super.build();
    endfunction : build

    task run();
      #10000;
      $display("%0t : Finishing", $time);
      $finish();
    endtask : run
  endclass : test

 initial 
  begin
    $display("Beginning test...");
    run_test();
  end 
endmodule

Cheers

Rob