Functional coverage is not standardized yet in SystemC, but there is a workaround for the case of mixed-language(SystemC/SystemVerilog) verification environments. This workaround makes use of covergroups from SystemVerilog and TLM transactions from SystemC and SystemVerilog. When a sampling point is reached, a TLM transaction is sent from SystemC to SystemVerilog, as seen below:
For this example, the following transaction item is used:
class simple_transaction {
public:
unsigned char m_type;
uint32_t m_len;
std::vector<int> m_data;
};
Suppose we want to observe the values of the headers (i.e. the type and length fields). We’ll write a covergroup in SV:
covergroup header_cg with function sample(simple_transaction recv);
TYPE : coverpoint recv.m_type {
ignore_bins nop = {0};
bins important = {[1:5]};
}
LEN : coverpoint recv.m_len {
illegal_bins zero = {0};
bins min = {1};
bins average = {[2:8]};
bins max = {9,10};
}
endgroup
The SystemC model sends a TLM transaction to SystemVerilog environment every time the sampling event is triggered in SystemC:
void sample_header(const simple_transaction &t) {
// Pack transaction
tlm_generic_payload gp = transaction2gp(t);
// Set other relevant fields in the transaction
socket->b_transport(gp, time);
}
In SystemVerilog the b_transport task unpacks the data and calls the covergroup sampling function:
task b_transport(uvm_tlm_generic_payload gp, uvm_tlm_time delay);
simple_transaction recv = new();
// Deserialize transaction
{>>{recv.m_type, recv.m_len, recv.m_data}} = gp.m_data;
`uvm_info("RECV ITEM", recv.convert2string(), UVM_LOW);
header_cg.sample(recv);
endtask
You can check out the full code on AMIQ’s GitHub
That’s all!