Cover property/sequence for transaction objects

I am trying to collect coverage on the sequence of attributes on transaction objects arriving in, say, a uvm_subscriber object

For example, if the transaction has a variable called id, and I would like to cover the sequence where the ID for the transaction objects coming is 0 -> 0 -> 1 -> 0, I could write something like:


class my_subscriber extends uvm_subscriber;
	covergroup cg_seq with function sample(bit id);
		seq0: coverpoint (id) {
            bins seq = (0 => 0 => 1 => 0);
        }
	endgroup

	virtual function void write (my_txn txn);
		cg_seq.sample (txn.id);
	endfunction
endclass : my_subscriber

This works reasonably well.

However, for more complex sequence of IDs, I hit the limit of what a coverpoint sequence can do. For example, this won’t compile because of the $:

	covergroup cg_seq with function sample(bit id);
		seq1: coverpoint (id) {
            bins seq = (0 => 0 => 1[*8:$] => 0);
        }
	endgroup

It certainly seems that I need to use cover property instead, but I am unsure how to do this for transaction level coverage? There is no equivalent sample function for property blocks, as far as I am aware?

I have several workarounds, including writing the code to cover this in procedural code, but was wondering if anyone else had different ideas they’ve used before?

Thanks!