Verification Martial Arts: A Verification Methodology Blog

Transactors and Virtual Interface

Posted by Vidyashankar Ramaswamy on January 8th, 2010

In my previous blog post I have shown high level view of a transactor and its properties. In this article I look into more details about developing a reusable transactor with a physical interface. There are many ways to connect a transactor to the physical interface. Everybody is aware of how we used do this in the object constructor. This is similar to hardwiring the connection in the environment. Another way is to make the interface configurable by the environment thus removing any dependency between the test, env and the DUT interface. This can be accomplished in two steps. The first step is to create an object wrapper for the virtual interface and make it as one of the properties of the transactor. The second step is to set this object using VMM configuration options either from the enclosing environment or from top level.

image

Step1. Developing the port object

VMM set/get options cannot be used directly to set a virtual interface. To make this work, we have to implement an object wrapper for the virtual interface. Sample code is shown below. Please note that the class name (master_port) and the interface name (vip_if) should be changed appropriately. EX – axi_master_port, axi_if… etc

File: master_port.sv
class master_port extends vmm_object;

virtual vip_if.master mstr_if;

function new (string name, virtual vip_if.master mstr_if);
super.new(null, name);
this.mstr_if = mstr_if;
if (mstr_if != null)
`vmm_note(log, “\n**** Master I/F created ****\n”);
else
`vmm_error(log, “\n**** Master Interface is NULL ****\n”);
endfunction

endclass: master_port

Step2. Configuring the Virtual Interface

In the transactor’s connect phase, get a handle to the virtual interface using the vmm_opts get method. This establishes the connection between the transactor and the DUT pin interface. Please do not forget to check the object handles and print debug messages using VMM messaging service. This will greatly reduce the debug time if things are not connected properly in the environment.

File: master.sv

//////////////////// Master Model //////////////
class master extends vmm_xactor;
`vmm_typename(master)
// Variables declaration
virtual vip_if.master mstr_if;

////////////// Connect_vitf method ////////////////
function void connect_vitf(vip_if.master mstr_if);
begin
if (mstr_if != null)
this.mstr_if = mstr_if;
else
`vmm_fatal(log, “Virtual port [Master] is not available”);
end
endfunction: connect_vitf

////////////// Connect Phase ////////////////
function void connect_ph();
begin
master_port mstr_port_obj;
bit is_set;
// Interface connection
if ($cast(this.mstr_port_obj, vmm_opts::get_object_obj(is_set, this, “vip_mstr_port“))) begin
if (mstr_port_obj != null)
this.connect_vitf(mstr_port_obj.mstr_if);
else
`vmm_fatal(log, “Virtual port [Master] wrapper not initialized”);
end

end
endfunction: connect_ph

endclass: master

Finally, the interface is set using vmm_opts set method in the environment. In VMM 1.2, the verification environment is created by extending the vmm_group base class object. VMM 1.2 supports both explicit and implicit phasing mechanism. In the implicit phasing mechanism, the connect phase is used to configure the virtual interface. Use the connect_vitf() method directly to have similar support in the explicit phasing mechanism. Sample code is shown below. Please note that the interface (master_if_p0) is instantiated in the top level test bench (tb_top).

File: vip_env.sv

//////////////////// Environment  //////////////

`include “vmm.sv”

class vip_env extends vmm_groups;
`vmm_typename(vip_env)

// Variables declaration
master_port mstr_p0;

////////////// Build Phase ////////////////
function void build_ph();
begin

mstr_p0 = new(“master_port”, tb_top.master_if_p0);

end
endfunction: build_ph

////////////// Connect Phase ////////////////
function void connect_ph();
begin
bit is_set;

// Set the master port interface
vmm_opts::set_object(“VIP_MSTR:vip_mstr_port“, mstr_p0, env);

end
endfunction

endclass: vip_env

Explicit phasing environment:

Extend vmm_env to create the explicit phasing environment. The connect_vitf() method is called in the build phase of the environment. Sample code is shown below. Please note that one can use transactor iterater instead of using the object hierarchy to call the connect_vitf() method.

File: vip_env.sv

//////////////////// Environment  //////////////
`include “vmm.sv”

class vip_env extends vmm_env;
`vmm_typename(vip_env)

// VIP’s used …
master mstr_drvr;

////////////// Build Phase ////////////////
function
void build();
begin
super.build();

// Set the master port interface
this.mstr_drvr.connect_vitf(tb_top.master_if_p0);

end
endfunction:
build

endclass: vip_env

Please feel free to comment and share your opinion on this. In my next article I shall discuss more about the transactor’s interface and how to develop them using VMM1.2 features.

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Google Buzz
  • LinkedIn
  • RSS
  • Twitter

4 Responses to “Transactors and Virtual Interface”

  1. Shunty Says:

    Thanks Vidyasankar, Nice explanation.

    As we know vmm_opts in vmm-1.2 comes with some more flexiblibilty of setting/getting the configurations/objects. And the examples shows how to use this advantage.
    Which is something good, as I believe the vmm_opts come as a boon in the code where we have hierarchial references in the code deep down under the hierarchies to pass the config. OR interfaces.

    Hoever, Here in the above example,
    -> Implicit phased env. is using the vmm_opts::set/get to get the wrapper object.
    -> But in explicit env, we are again using the hierarchial references(To call connect_vitf which could be far away in the complex SoC env.). One could avoid it and use the same approach of setting/getting of object which is used for implicit env.

    However to make it happen,
    A) If absolute addresses are used in vmm_opts::set_object, then
    one should have the parent of every explicitly phased component also, (which could be vmm_object).

    This will be possible if components(Either explicit OR implicitly phased), which are extended from vmm base classes, have a parent and there should be an absolute address of every component to which it could be addressed.

    B) Set the object globally using the vmm_opts::set_object(“”,Object,null); and access it using vmm_opts::get_obj.

    But to use this approach is again an individual choice and the complexity of env.

    Thanks.

  2. Vidyashankar Says:

    Hi Shunty,

    Thanks for the comment. As you have rightly said, it depends on the VIP and the environment.

    Regards.

  3. Verification Martial Arts » Blog Archive » Extending Hierarchical Options in VMM to work with all data types Says:

    [...] [...]

  4. Verification Martial Arts » Blog Archive » The right name at the right space: using ‘namespace’ in VMM to set virtual interfaces Says:

    [...] to a particular transactor can be done in various ways in VMM, as discussed in the following blogs: Transactors and Virtual Interface and Extending Hierarchical Options in VMM to work with all data types. In addition to these, one [...]

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>