Connection between SC -> SV without Generic Payload(GP)

There aren’t a sample(SC->SV) in UVM connect Kit.
So I couldn’t understood how to make connection between SC and SV.
I generated source but I had some problem on my source of UVM connect(SC → SV).
Then I asked about it on this forum. But It’s fixed.
So I’d like to put sources(SC->SV) on this forums.

///// SystemC /////


///// producer.h /////
#include <string>
#include <iomanip>
using std::string;

#include <systemc.h>
#include <tlm.h>
using namespace sc_core;
using namespace tlm;

template <class T>
class producer : public sc_module {
public:
  sc_port<tlm_blocking_transport_if<T> > out;
  sc_event done;

  producer(sc_module_name nm) : out("out")
  {
    SC_THREAD(run);
  }

  SC_HAS_PROCESS(producer);

  void run() {
        sc_time delay;
        T t;

        int d_size;
        short cmd;
        int unsigned addr;
        vector<char> data;
        char unsigned tmp;

        d_size = (rand() % 8) + 1;
        for(int i=0; i < d_size; i++) {
          tmp = rand();
          data.push_back(tmp);
        }
        t.set_data_copy(data);

        for (int i=0; i < d_size; i++) {
          printf("===== Loop Number %d / %d =====\n", i+1, d_size);
          delay = sc_time(10,SC_NS);
          cmd  = rand();
          addr = rand();
          t.cmd  = cmd;
          t.addr = addr;
          out->b_transport(t, delay);
        }
        done.notify();
  }

};

///// sc_converter_trans.cpp /////
#include <vector>
using std::vector;

#include <systemc.h>
using namespace sc_core;

#include "uvmc.h"
using namespace uvmc;

// (begin inline source)
namespace user_lib {

  using namespace uvmc;

  class packet_base
  {
    public:

   short cmd;
   int addr;
   vector<char> data;

    virtual void do_pack(uvmc_packer &packer) const {
      packer << cmd << addr << data;
    }

    virtual void do_unpack(uvmc_packer &packer) {
      packer >> cmd >> addr >> data;
    }

    virtual void set_data_copy(vector<char> data_in) {
      for(int i=0; i < data_in.size(); i++) {
           data.push_back(data_in[i]);
      }
    }

  };

  class packet : public packet_base
  {
    public:
    unsigned int extra_int;

    virtual void do_pack(uvmc_packer &packer) const {
      packet_base::do_pack(packer);
      packer << extra_int;
    }

    virtual void do_unpack(uvmc_packer &packer) {
      packet_base::do_unpack(packer);
      packer >> extra_int;
    }
  };
}

using namespace user_lib;

UVMC_PRINT_3(packet_base,cmd,addr,data)
UVMC_PRINT_EXT_1(packet,packet_base,extra_int)

#include "producer.h"

template <class T>
class producer_uvm : public producer<T> {

  public:

  producer_uvm(sc_module_name nm) : producer<T>(nm) {
    SC_THREAD(objector);
  }

  SC_HAS_PROCESS(producer_uvm);

  void objector() {
    uvmc_raise_objection("run");
    wait(this->done);
    uvmc_drop_objection("run");
  }

};

int sc_main(int argc, char* argv[])
{
  producer_uvm<packet> prod("producer");
  uvmc_connect(prod.out,"stimulus");
  sc_start();
  return 0;
}

///// SystemVerilog(UVM) /////


///// consumer.sv /////
import uvm_pkg::*;
`include "uvm_macros.svh"

class consumer #(type T=int) extends uvm_component;

   uvm_tlm_b_target_socket #(consumer #(T), T) in;

   int num_pkts;

   `uvm_component_param_utils(consumer #(T))

   function new(string name, uvm_component parent=null);
      super.new(name,parent);
      in = new("in", this);
      num_pkts = 10;
   endfunction : new

   virtual task b_transport (T t, uvm_tlm_time delay);
     `uvm_info("CONSUMER/PKT/RECV",{"\n",t.sprint()},UVM_MEDIUM)
        #(delay.get_realtime(1ns,1e-9));
   endtask

endclass

///// sv_converter_trans.sv /////
package user_pkg;

  `include "uvm_macros.svh"
  import uvm_pkg::*;

  class packet_base extends uvm_sequence_item;

    `uvm_object_utils(packet_base)

    rand shortint cmd;
    rand int addr;
    rand byte data[$];

    function new(string name="");
      super.new(name);
    endfunction

    constraint c_data_size { data.size() inside { [1:10] }; }

    virtual function void do_pack(uvm_packer packer);
      super.do_pack(packer);
      `uvm_pack_int(cmd)
      `uvm_pack_int(addr)
      `uvm_pack_queue(data)
    endfunction

    virtual function void do_unpack(uvm_packer packer);
      super.do_unpack(packer);
      `uvm_unpack_int(cmd)
      `uvm_unpack_int(addr)
      `uvm_unpack_queue(data)
    endfunction

    virtual function string convert2string();
      //return $sformatf("addr:%h data:%p",addr,data);
      return $sformatf("addr:%h data:%h",addr,data);
    endfunction

    virtual function bit do_compare(uvm_object rhs, uvm_comparer comparer);
      packet_base rhs_;
      if (!$cast(rhs_,rhs)) begin
        `uvm_fatal("PKT/COMPARE/BADTYPE",$sformatf("Argument rhs (name=%s type=%s), is not of type packet",rhs.get_name(),rhs.get_type_name()))
        return 0;
      end
      if (!super.do_compare(rhs,comparer))
        return 0;
      if (cmd  != rhs_.cmd)  comparer.result++;
      if (addr != rhs_.addr) comparer.result++;
      if (data != rhs_.data) comparer.result++;
      return (comparer.result == 0);
    endfunction

    function void do_print(uvm_printer printer);
      super.do_print(printer);
      printer.print_field("cmd",cmd,16);
      printer.print_field("addr",addr,32);
      printer.print_array_header("data",data.size(),"queue(byte)");
      foreach (data[i])
        printer.print_field($sformatf("[%0d]",i),data[i],8);
      printer.print_array_footer(data.size());
    endfunction

  endclass


  class packet extends packet_base;

    `uvm_object_utils(packet)

    rand int extra_int;

    function new(string name="");
      super.new(name);
    endfunction

    virtual function void do_pack(uvm_packer packer);
      super.do_pack(packer);
      `uvm_pack_int(extra_int)
    endfunction

    virtual function void do_unpack(uvm_packer packer);
      super.do_unpack(packer);
      `uvm_unpack_int(extra_int)
    endfunction

    virtual function string convert2string();
      return $sformatf("%s extra_int:%h",super.convert2string(),extra_int);
    endfunction

  endclass

endpackage : user_pkg

`include "consumer.sv"

// (begin inline source)
module sv_main;

  `include "uvm_macros.svh"
  import uvm_pkg::*;
  import uvmc_pkg::*;
  import user_pkg::*;

  // Define env with connection specifying custom converter

  //sv_env env;
  consumer #(packet) cons = new ("cons");

  initial begin
    uvmc_tlm #(packet)::connect(cons.in, "stimulus");
    run_test();
  end

endmodule

Thank you.
Best Regards

In reply to akira_aus_nwz:

Hi, I tried running the above example and and getting below error. Any inputs on this?

UVMC-Error: SC-side proxy channel for ‘producer.out’ with mask ‘4’ and id ‘1’ not compatible with connected SV-side proxy port for ‘cons.in’ with mask ‘7’ and id 1
UVM_ERROR /data/digital/shivaan/wa/UVMC/uvmc-2.3.0//src/connect/sv/uvmc_common.sv(467) @ 0: reporter [UVMC] Cannot bind SV-side UVMC proxy with name ‘cons.in’ or its alternative lookup name, ‘stimulus’ (mask=7)
UVM_FATAL @ 0: reporter [BUILDERR] stopping due to build errors

The Makefile I am using is as below:

include $(UVMC_HOME)/examples/common/Makefile.ius

all: sc2sv

sc2sv:
(MAKE) -f Makefile.ius LOG=@
SV_FILE=sv_converter_trans.sv
SC_FILE=sc_converter_trans.cpp
run

clean:
rm -rf work .log vsim transcript *.vstf *.log.cmp modelsim.ini

sim: run

run:
(IUS) \ -sc_main \ (SC_FILE)
(SV_FILE) \ (ARGS)
2>&1 | tee (EXAMPLE).log (CHECK)

Let me please know if I am missing something.


Thank you.