Systemverilog covergroup

M

Michael

Guest
Hi,

I know I can define bins as a sequence with "repeat range" of a
single value like:
bins seq = (ST_IDLE => ST_ADDR => ST_DATA [* 1:$] => ST_WAIT =>
ST_IDLE);

But how can define a "repeat range" for a sequence? I expected it as:
bins nseq = (ST_IDLE => (ST_ADDR => ST_DATA) [* 1:$] => ST_IDLE);

But it won't pass compilation.

Thank you.
 
On Sat, 6 Feb 2010 03:48:51 -0800 (PST), Michael wrote:

I know I can define bins as a sequence with "repeat range" of a
single value like:
bins seq = (ST_IDLE => ST_ADDR => ST_DATA [* 1:$] => ST_WAIT =
ST_IDLE);

But how can define a "repeat range" for a sequence? I expected it as:
bins nseq = (ST_IDLE => (ST_ADDR => ST_DATA) [* 1:$] => ST_IDLE);

But it won't pass compilation.
I don't think you can do that.

For more complicated sequences like this, it's usually better
to use property coverage. The syntax is not so very
different (indeed, coverage sequence syntax is really just
a borrowed subset of property syntax) but properties allow
much more flexible specification of sequential activity.
Something like this (untested, but not far from the truth):

// Your state variable
enum {ST_IDLE, ST_ADDR, ST_DATA, ST_WAIT, ST_IDLE} st_var;

// Your original coverage sequence
covergroup state_cg @(posedge clk);
coverpoint st_var {
bins seq = (
ST_IDLE =>
ST_ADDR =>
ST_DATA [* 1:$] =>
ST_WAIT =>
ST_IDLE);
}
endgroup

// Clock for sequences
default clocking st_ck @(posedge clk); endclocking
//
// Your more complex sequence, built from component sequences
sequence access_seq;
st_var == ST_ADDR ##1 st_var == ST_DATA;
endsequence
//
sequence idle_seq;
st_var == ST_IDLE;
endsequence
//
sequence burst_seq;
idle_seq ##1 access_seq [*1:$] ##1 idle_seq;
endsequence
//
// Get coverage
cover property (burst_seq);

Sequences also allow you to do a load of interesting
things as the sequence progresses; those interesting things
can then be fed into coverage. For example, suppose you
wanted coverage on the number of beats in a burst. You
could rewrite "burst_seq" like this:

sequence burst_seq;
int beat_count; // Local variable of the sequence
(idle_seq, beat_count=0) ##1
(access_seq, beat_count++) [*1:$] ##1
(idle_seq, cover_beat_count(beat_count));
endsequence

Now the "cover_beat_count" function gets called whenever
the sequence's "cover property" runs to completion. So
you can easily get it to collect interesting coverage:

int beat_count_for_coverage;
//
covergroup beat_count_cg;
coverpoint beat_count_for_coverage {
// set up desired bins here
}
endgroup
//
function void cover_beat_count(int count);
beat_count_for_coverage = count;
beat_count_cg.sample();
endfunction

The extra variable "beat_count_for_coverage", and the
function to set up the variable and invoke coverage
on it, is necessary but a little tiresome. In the
new SV-2009 standard there is a new way of calling
the covergroup's sample() method that allows you
to pass in some information. When the tool vendors
implement that, you will be able to put this
directly into the sequence:

... ##1 (idle_seq, beat_count_cg.sample(beat_count));

HTH
--
Jonathan Bromley
 
On Feb 7, 12:07 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
On Sat, 6 Feb 2010 03:48:51 -0800 (PST), Michael wrote:
  I know I can define bins as a sequence with "repeat range" of a
single value like:
bins seq = (ST_IDLE => ST_ADDR => ST_DATA [* 1:$] => ST_WAIT =
ST_IDLE);

But how can define a "repeat range" for a sequence? I expected it as:
bins nseq = (ST_IDLE => (ST_ADDR => ST_DATA) [* 1:$] => ST_IDLE);

But it won't pass compilation.

I don't think you can do that.

For more complicated sequences like this, it's usually better
to use property coverage.  The syntax is not so very
different (indeed, coverage sequence syntax is really just
a borrowed subset of property syntax) but properties allow
much more flexible specification of sequential activity.  
Something like this (untested, but not far from the truth):

  // Your state variable
  enum {ST_IDLE, ST_ADDR, ST_DATA, ST_WAIT, ST_IDLE} st_var;

  // Your original coverage sequence
  covergroup state_cg @(posedge clk);
    coverpoint st_var {
      bins seq = (
        ST_IDLE =
        ST_ADDR =
        ST_DATA [* 1:$] =
        ST_WAIT =
        ST_IDLE);
    }
  endgroup

  // Clock for sequences
  default clocking st_ck @(posedge clk); endclocking
  //
  // Your more complex sequence, built from component sequences
  sequence access_seq;
    st_var == ST_ADDR ##1 st_var == ST_DATA;
  endsequence
  //
  sequence idle_seq;
    st_var == ST_IDLE;
  endsequence
  //
  sequence burst_seq;
    idle_seq ##1 access_seq [*1:$] ##1 idle_seq;
  endsequence
  //
  // Get coverage
  cover property (burst_seq);

Sequences also allow you to do a load of interesting
things as the sequence progresses; those interesting things
can then be fed into coverage.  For example, suppose you
wanted coverage on the number of beats in a burst.  You
could rewrite "burst_seq" like this:

  sequence burst_seq;
    int beat_count; // Local variable of the sequence
    (idle_seq, beat_count=0) ##1
    (access_seq, beat_count++) [*1:$] ##1
    (idle_seq, cover_beat_count(beat_count));
  endsequence

Now the "cover_beat_count"  function gets called whenever
the sequence's "cover property" runs to completion.  So
you can easily get it to collect interesting coverage:

  int beat_count_for_coverage;
  //
  covergroup beat_count_cg;
    coverpoint beat_count_for_coverage {
      // set up desired bins here
    }
  endgroup
  //
  function void cover_beat_count(int count);
    beat_count_for_coverage = count;
    beat_count_cg.sample();
  endfunction

The extra variable "beat_count_for_coverage", and the
function to set up the variable and invoke coverage
on it, is necessary but a little tiresome.  In the
new SV-2009 standard there is a new way of calling
the covergroup's sample() method that allows you
to pass in some information.  When the tool vendors
implement that, you will be able to put this
directly into the sequence:

   ... ##1 (idle_seq, beat_count_cg.sample(beat_count));

HTH
--
Jonathan Bromley
Thank you very much for the explanations.
Can I use "sequence" in the covergroup directly? Or I need to use
function as you described?

Best regards,
Michael
 
On Sat, 6 Feb 2010 23:05:29 -0800 (PST), Michael wrote:

Can I use "sequence" in the covergroup directly?
No. There are at least two things you need to be
careful about here:

1)
SV assertion constructs, such as "sequence...endsequence"
and "cover property(...);", must be created and used inside
a STATIC design element such as a module or interface.
They cannot go inside classes, and they certainly cannot
go inside a covergroup. The example I wrote assumes that
the covergroup is part of a module, not in a class. If
your covergroups are in classes, things become a little
more complicated - but you can still use the same idea.

2)
Property coverage and covergroup ("functional") coverage
are quite different ideas in SystemVerilog. All the tools
use a single integrated coverage database for both, and
also for the more traditional sorts of coverage such as
statement and expression coverage, but the mechanisms
are really very different. The code I showed you is an
attempt to combine useful features of both.

Or I need to use
function as you described?
If you simply wish to count how many times a given
sequence occurred, you don't need covergroups at all;
the "cover property" statement on a sequence does
everything you need. My second code sketch was
intended to show how you can collect additional
information during the life of a sequence, and use
the covergroup mechanism to get coverage on that
additional data. For that second approach, yes,
there is at present no sane way to do it without
using at least one helper function.
--
Jonathan Bromley
 

Welcome to EDABoard.com

Sponsor

Back
Top