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