Need help with a syntax error when creating new coverage object

I’m SV beginner and is following a tutorial to write a very simple OOP testbench. Now I’m onto writing coverage.sv, but I’m stopped by a syntax errors that seems so obvious yet I can’t wrap my head around. Maybe my brain’s just shorted or tripped somewhere, but… could really use some help to get over this.

################################
This is the scoreboard I wrote, inside I’m creating an object of coverage class and calling its method collect_packet at the end. The errors I get from VCS is this:


//Error-[SE] Syntax error
//Following verilog source has syntax error :
//"scoreboard.sv", 6: token is '='
//coverage cov=new();
//               ^

I’m also pasting the coverage.sv later. And also the entire testbenches.

################################
The script I’m using to run the testbench is runsim.coverage :

vcs -debug_pp -sverilog -R -l vcs.log 					\
testbench.sv 								\
switch_interface.sv 							\
switch.sv 								\
testcase.sv								\
+ntb_random_seed_automatic						\
-cm line+cond+branch+fsm+tgl						\
-cm path -lca								\
-cm_log ./coverage.log							\
-cm_dir ./COVERAGE							\

################################

class scoreboard;
	mailbox rcv_from_drv; //mailbox that holds arriving packets from drive.sv
	mailbox rcv_from_mon; //mailbox that holds arriving packets from drive.sv 
	
	//Add coverage.sv class as a data member inside scoreboard.sv
	**coverage cov=new();**

	function new(input mailbox drv2sb, input mailbox mon2sb);
		this.rcv_from_drv = drv2sb;
		this.rcv_from_mon = mon2sb;
	endfunction

	//scoreboard compares 2 packets
	task compare(input mailbox rcv_from_drv, input mailbox rcv_from_mon);

		bit		error;
		packet		pkt_from_drv;
		packet		pkt_from_mon;

	//get a packet from rcv_from_drv mailbox, then assign it to pkt_from_drv
		rcv_from_drv.get(pkt_from_drv);
		$write("pkt_from_drv:"); pkt_from_drv.print_drv();

	//get a packet from rcv_from_mon mailbox, then assign it to pkt_from_mon
		rcv_from_mon.get(pkt_from_mon);
		$write("pkt_from_mon:"); pkt_from_mon.print_mon();

		if(
		    pkt_from_mon.src_addr != (pkt_from_drv.src_addr+1) || //OR pkt_from_mon.dst_addr != (pkt_from_drv.src_addr+1
		    pkt_from_mon.src_data != (pkt_from_drv.src_data+1)    //OR pkt_from_mon.dst_addr != (pkt_from_drv.src_addr+1
		  ) begin
		    $display("time=%0t ERROR: Packet Mismatches!\n", $time);
		    error++;
		    //$display("error = %0d", error);
		end

	//if none of the fields mismatches, print PASS
		if(error==0) $display("time=%0t PASS:Packet Matches!\n", $time);
	endtask


	//collect coverage information using the pkt_from_drv packet
	**cov.collect_coverage(pkt_from_drv);**
endclass
class coverage;
	packet		covpacket;

	covergroup	switchcov;
	src_addr:		coverpoint covpacket.src_addr{
								bins	low_addr	={[48'h000000000000:48'h333333333333]};
								bins	med_addr	={[48'h333333333334:48'h999999999999]};
								bins	high_addr	={[48'h99999999999A:48'hDDDDDDDDDDDF]};
								bins	leftover	=default;
								}
	src_data:		coverpoint covpacket.src_data{
								bins	low_data	={[32'h00000000:32'h33333333]};
								bins	med_data	={[32'h33333334:32'h99999999]};
								bins	high_data	={[32'h9999999A:32'hCCCCCCCF]};
								bins	leftover	=default;

								}
	addr_x_data:		cross src_addr, src_data;
	endgroup

	function new();
		switchcov  = new();
	endfunction

	task collect_coverage(input packet pkt_from_drv);
		this.covpacket = pkt_from_drv;
		switchcov.sample();
	entask


endclass

In reply to tyyang:

Make sure that your coverage class is declared before your scoreboard class. If it is and it’s still failing, try moving the instantiation to the constructor:


        coverage cov;
 
	function new(input mailbox drv2sb, input mailbox mon2sb);
                this.cov = new();
		this.rcv_from_drv = drv2sb;
		this.rcv_from_mon = mon2sb;
	endfunction

Maybe your simulator just gets confused by the syntax.

In reply to Tudor Timi:

As Timi mentioned, this is an LRM requirement (Section 19.4) that Covergroups be created/assigned in the new method.

Section 19.4:

An embedded covergroup variable may only be assigned in the new method. An embedded coverage group
can be explicitly instantiated in the new method. If it is not, then the coverage group is not created and no
data will be sampled.

In reply to cgales:

That’s a valid point, but as a clarification, the coverage identifier refers to a class in this case and not an embedded covergroup.

In reply to Tudor Timi:

Hi Tudor,
Thank you for you help.
I modified the include directives in my testcase.sv and made sure include "coverage.sv" is before include “scoreboard.sv”. This indeed helped. Now the syntax error at new() is gone. But instead a syntax error appear:
Error-[SE] Syntax error
Following verilog source has syntax error :
“scoreboard.sv”, 42: token is ‘.’
cov.collect_coverage(pkt_from_drv);
^
This happens no matter cov object is created inside the constructor of scoreboard or outside.
Seems the problem is still with cov object? What could be the problem…?

In reply to tyyang:

Hi tyyang,

"scoreboard.sv", 42: token is '.'
cov.collect_coverage(pkt_from_drv);

You must place it inside a task/function