UVMC Converter Example - SV Converter Class

This example demonstrates how to define a custom converter for a transaction class that does not extend from ovm_object.

Most SV transactions extend ovm_object and implement the do_pack and do_unpack methods.  The default converter for SV works for these types of transactions, so in most cases you will not need to define an external converter class.

To apply the external converter to a particular cross-language connection, specify it as a type parameter when registering a UVMC connection

uvmc_tlm #(packet, my_converter)::connect( some_port, "some_lookup");
Summary
UVMC Converter Example - SV Converter Class
This example demonstrates how to define a custom converter for a transaction class that does not extend from ovm_object.
User LibraryThis section defines a transaction class, packet, that does not extend from any base class.
Conversion codeThis section defines a converter for our ‘packet’ transaction type.
Testbench codeThis section defines our testbench environment.

User Library

This section defines a transaction class, packet, that does not extend from any base class.  It also defines a generic producer model via `include.  All transactions and components in the user library should be written to be independent of context, i.e. not assume a UVMC or any other outside connetion.

Conversion code

This section defines a converter for our ‘packet’ transaction type.  We will later use this converter when registering cross-language connections to SC.

package convert_pkg;

  `include "ovm_macros.svh"
  import ovm_pkg::*;
  import ovmc_pkg::*;
  import user_pkg::*;

  class convert_packet_base extends uvmc_converter #(packet_base);

    static function void do_pack(packet_base t, ovm_packer packer);
       packer.pack_field_int(t.cmd,32);
       packer.pack_field_int(t.addr,32);
       packer.pack_field_int(t.data.size(),32);
       foreach (t.data[i])
         packer.pack_field_int(t.data[i],8);
    endfunction

    static function void do_unpack(packet_base t, ovm_packer packer);
        int sz;
        t.cmd = packet_base::cmd_t'(packer.unpack_field_int(32));
        t.addr = packer.unpack_field_int(32);
        sz = packer.unpack_field_int(32);
        t.data.delete();
        for (int i=0; i < sz; i++)
          t.data.push_back( packer.unpack_field_int(8) );
    endfunction

  endclass


  class convert_packet extends uvmc_converter #(packet);

    static function void do_pack(packet t, ovm_packer packer);
      convert_packet_base::do_pack(t,packer);
      packer.pack_field_int(t.extra_int,32);
    endfunction

    static function void do_unpack(packet t, ovm_packer packer);
      convert_packet_base::do_unpack(t,packer);
      t.extra_int = packer.unpack_field_int(32);
    endfunction

  endclass

endpackage

Testbench code

This section defines our testbench environment.  In the top-level module, we instantiate the generic producer model.  We also register the producer’s ‘out’ port to have a UVMC connection with a lookup string ‘stimulus’.  The SC-side will register its consumer’s ‘in’ port with the same ‘stimulus’ lookup string.  UVMC will match these two strings and complete the cross- language connection, i.e. the SV producer’s out port will be bound to the SC consumer’s in export.

module sv_main;

  `include "ovm_macros.svh"
  import ovm_pkg::*;
  import ovmc_pkg::*;
  import user_pkg::*;
  import convert_pkg::*;

  // Define env with connection specifying custom converter

  class sv_env extends ovm_env;

    producer #(packet) prod;

    `ovm_component_utils(sv_env)

    function new(string name, ovm_component parent=null);
       super.new(name,parent);
    endfunction

    virtual function void build();
       prod = new("prod", this);
    endfunction

    virtual function void connect();
      uvmc_tlm1 #(.T1(packet),.CVRT_T1(convert_packet))::
                              connect(prod.out, "stimulus");
      uvmc_tlm1 #(.T1(packet),.CVRT_T1(convert_packet))::
                              connect(prod.ap_in, "checker");
    endfunction

  endclass


  sv_env env;

  initial begin
    env = new("env");
    run_test();
  end

endmodule