SV Functional Coverage : Instruction sequence?

S

Shenli

Guest
Hi all,

When verify a CPU, I encounter a SV functional coverage problem.
I'd like to check whether there are some back-to-back instructions
sequence happened that I am interested in.
Like the instruction sequence:
....
Inst_1 R1, R2
Inst_4 R3, R4
Inst_9 R2, R2
....
But how to define the cover_group? AFAIK, there are control coverage
and data coverage, shall I combine them together to get the
Instruction sequence coverage?

Another questions that always confused me: I have a transaction
generator and monitor(which connected input driver). Shall I get
coverage from transaction generator directly or from the monitor
connected input driver? IMHO, they are the same. But, what's your
opinion?

Any suggestions are welcome!

Best regards,
Davy
 
On Mon, 25 Jun 2007 01:18:55 -0700,
Shenli <zhushenli@gmail.com> wrote:

When verify a CPU, I encounter a SV functional coverage problem.
I'd like to check whether there are some back-to-back instructions
sequence happened that I am interested in.
Like the instruction sequence:
...
Inst_1 R1, R2
Inst_4 R3, R4
Inst_9 R2, R2
...
But how to define the cover_group?
I suggest the answer depends on how many such sequences you
wish to identify.

In any case, you need to create an event that will fire
each time you have a valid new instruction code. For
example, suppose your CPU has a signal "DECODE" that
goes high while your instruction decode unit is looking
at the instruction code. Then it would be easy to
create an event based on that - maybe @(posedge DECODE).

If you have only one or two sequences to find, it's
probably easiest to write SVA sequences and cover them....
I'm assuming you have already defined some suitable constants
for the instructions you care about, with Z bits in any
don't-care fields so that you can use wild-equality comparison:

default clocking CPU_decode @(posedge DECODE); endclocking
sequence CPU_function_preamble;
instr_buffer ==? instr_CALL
##1
instr_buffer ==? instr_PUSH_FP
##1
instr_buffer ==? instr_MOVE_SP_TO_FP
endsequence
sequence CPU_function_postamble;
instr_buffer ==? instr_MOVE_FP_TO_SP
##1
instr_buffer ==? instr_POP_FP
##1
instr_buffer ==? instr_POP_PC
endsequence
cover property (CPU_function_preamble);
cover property (CPU_function_postamble);

But if you have more than a few sequences to cover, you can use
the transition coverage feature in SV:

covergroup CG_instruction_sequences @(posedge DECODE);
coverpoint instr_buffer; // probably want bins definition here
transition tr_preamble:
instr_CALL => instr_PUSH_FP => instr_MOVE_SP_TO_FP;
transition tr_postamble:
instr_MOVE_FP_TO_SP => instr_POP_FP => instr_POP_PC;
endgroup

Another questions that always confused me: I have a transaction
generator and monitor(which connected input driver). Shall I get
coverage from transaction generator directly or from the monitor
connected input driver? IMHO, they are the same. But, what's your
opinion?
Standard methodology answer: Do it from the monitor, because at
some future time you may create a design where the stimulus to
this block comes from another piece of RTL instead of from the
testbench. If you put coverage in the stimulus generator, then
that coverage will disappear if you replace the stimulus
generator with another RTL block. But the monitor can stay in
place. Read any of the standard methodology texts for much more
on this sort of reuse issue.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Mon, 25 Jun 2007 09:44:29 +0100, Jonathan Bromley
<jonathan.bromley@MYCOMPANY.com> wrote:

But if you have more than a few sequences to cover, you can use
the transition coverage feature in SV:
Ah yes, but you can use them only if you get the
syntax right, and don't mix up two different verification
languages..... sorry. Let's try again:

covergroup CG_instruction_sequences @(posedge DECODE);
coverpoint instr_buffer {
bins ..... <coverage on individual instructions> .....;
bins tr_preamble = // Transition coverage:
( instr_CALL => instr_PUSH_FP => instr_MOVE_SP_TO_FP );
bins tr_postamble =
( instr_MOVE_FP_TO_SP => instr_POP_FP => instr_POP_PC );
}
endgroup

Delivering training on three different languages in four weeks
can have a terrible effect on a mind :)
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Jun 25, 4:18 am, Shenli <zhushe...@gmail.com> wrote:
Hi all,

When verify a CPU, I encounter a SV functional coverage problem.
I'd like to check whether there are some back-to-back instructions
sequence happened that I am interested in.
Like the instruction sequence:
...
Inst_1 R1, R2
Inst_4 R3, R4
Inst_9 R2, R2
...
But how to define the cover_group? AFAIK, there are control coverage
and data coverage, shall I combine them together to get the
Instruction sequence coverage?

Another questions that always confused me: I have a transaction
generator and monitor(which connected input driver). Shall I get
coverage from transaction generator directly or from the monitor
connected input driver? IMHO, they are the same. But, what's your
opinion?

Any suggestions are welcome!

Best regards,
Davy
As a simple alternative to SV sequences, you may use configurable
verilog component "match_seq" to match clocked sequences of any
events. Note, that the clock, supplied to this component, may be not
an actual design clock but generated "system-level clock" which
syncrhonizes higher-level transactions.


-------------------------------------------------------------
module match_seq (clk, rst_n, seq, match);
parameter BWIDTH = 1; // match sequence length
parameter SCP = 1'b0; // Single Cycle Pattern matching (default :
multicycle)
input clk, rst_n;
input [BWIDTH-1:0] seq;
output match;

reg [BWIDTH-1:0] seq_p, count;

always @(posedge clk) begin
if (!rst_n) count <= BWIDTH;
else begin
seq_p <= seq;
if (seq != seq_p | SCP)
if (seq == 1'b1 << count-1) count <= count-1;
else count <= BWIDTH;
if (count == 0) count <= BWIDTH;
end
end
assign match = (count == 0);

endmodule
-------------------------------------------------------------
For example:
match_seq #3 i_match1 (clk, rst_n, {address==55 & data==66 &
tran==write, address==33 & data==11 & tran==read, address==99 &
data==99 & tran==idle}, match1);

You may add any number of sequence matching components and then cover
only their "match" signals.

Regards,
-Alex
 
On Mon, 25 Jun 2007 12:52:54 -0700,
Alex <agnusin@gmail.com> wrote:

As a simple alternative to SV sequences, you may use
configurable verilog component "match_seq"
Simple, but single-threaded and therefore somewhat
fragile, surely?
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Simple, but single-threaded and therefore somewhat
fragile, surely?
Sorry, I don't understand the "single-threaded" claim.
Every other instantiation of sequence matching component adds another
thread.

Regards,
-Alex
 
Simple, but single-threaded and therefore somewhat
fragile, surely?
By itself, each instantiation of sequence matching component is single-
threaded. However, another instantiation of sequence matching
component adds another thread. Just instantiate the number of
components to match all required patterns.

Regards,
-Alex
 
On Jun 25, 5:12 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
On Mon, 25 Jun 2007 09:44:29 +0100, Jonathan Bromley

jonathan.brom...@MYCOMPANY.com> wrote:
But if you have more than a few sequences to cover, you can use
the transition coverage feature in SV:

Ah yes, but you can use them only if you get the
syntax right, and don't mix up two different verification
languages..... sorry. Let's try again:

covergroup CG_instruction_sequences @(posedge DECODE);
coverpoint instr_buffer {
bins ..... <coverage on individual instructions> .....;
bins tr_preamble = // Transition coverage:
( instr_CALL => instr_PUSH_FP => instr_MOVE_SP_TO_FP );
bins tr_postamble =
( instr_MOVE_FP_TO_SP => instr_POP_FP => instr_POP_PC );
}
endgroup

[SNIP]

Hi Jonathan,

Thanks a lot :)

There is another problem according to your code. From the code, we
know that the transition coverage is given at signal layer. Can I do
transition coverage in transaction layer.
For example,
I have two command list

At signal layer,
(cmd1 => cmd2 => cmd3) will trig transition_1_2_3
(cmd4 => cmd5 => cmd6) will trig transition_4_5_6

At transaction layer,
(transition_1_2_3 => transition_4_5_6) will trig
transition_1_2_3_4_4_6

Can I do this in cover_group?

Best regards,
Davy


Delivering training on three different languages in four weeks
can have a terrible effect on a mind :)
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Mon, 25 Jun 2007 19:42:17 -0700,
Shenli <zhushenli@gmail.com> wrote:


There is another problem according to your code. From the code, we
know that the transition coverage is given at signal layer. Can I do
transition coverage in transaction layer.
Of course. Simply trigger the covergroup procedurally, using its
sample() method, at a moment when the transaction data is
complete. You may need to put copies of the relevant transaction
data into a place where the covergroup can see it, of course.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Jun 26, 4:06 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
On Mon, 25 Jun 2007 19:42:17 -0700,

Shenli <zhushe...@gmail.com> wrote:
There is another problem according to your code. From the code, we
know that the transition coverage is given at signal layer. Can I do
transition coverage in transaction layer.

Of course. Simply trigger the covergroup procedurally, using its
sample() method, at a moment when the transaction data is
complete. You may need to put copies of the relevant transaction
data into a place where the covergroup can see it, of course.
Hi Jonathan,

Thanks :)
Another question, is sample() method a part of the IEEE1800 standard?
It seems I cannot find it in the standard.

Best regards,
Davy

--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Tue, 26 Jun 2007 01:54:49 -0700,
Shenli <zhushenli@gmail.com> wrote:

Another question, is sample() method a part of the IEEE1800 standard?
It seems I cannot find it in the standard.
Clause 18.7, "Predefined coverage methods".

--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Mon, 25 Jun 2007 13:40:31 -0700,
Alex <agnusin@gmail.com> wrote:

Simple, but single-threaded and therefore somewhat
fragile, surely?

By itself, each instantiation of sequence matching component is single-
threaded. However, another instantiation of sequence matching
component adds another thread. Just instantiate the number of
components to match all required patterns.
Alex, I understand the motivation to get a simple replacement
for SVA that works in (let's say) 80% of simple cases, but I
don't understand how your implementation is robust enough
to be worth deploying widely. For example, suppose you write
a sequence {conditionA, conditionB, conditionC} and on the
first cycle it happens that both conditionA and conditionC
are true. Your sequence counter will reset! So in fact
when you write a sequence

{A, B, C}

your sequence detector is *really* looking for

{ A && !B && !C, !A && B && !C, !A && !B && C }

And my "single-thread" accusation stands: you have only one
state variable, count, in the module - so a single instance of
the module cannot detect overlapping sequences. If you instance
the module more than once on the same set of signals, you STILL
cannot detect overlapping sequences because all your instances
will do exactly the same thing, in lockstep.

I also have the same objection to your example that I have
to OVL: it's completely opaque to users. A SVA sequence is
written using a standardised language; users can read the
code and see what it does. SVA empowers users. Your module,
and the OVL checker modules, DISempower users by providing
opaque functionality for something that is quite hard to
document. Indeed, sequential regular expression languages
such as SVA are probably the clearest and most effective
way to document such things. So why not simply execute
the documentation? Programming doesn't get better than that.

Historically, the field of assertion languages is "owned"
by a community of very sophisticated and clever theorists.
So some parts of the languages are very difficult indeed.
But those same clever theorists have given us something
that is extremely clear, well-defined, and (in simple
cases) quite easy to use. It's extremely easy to learn
the basics of SVA or PSL, and extremely hard to make a
good job of replicating their functionality for yourself.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Jun 26, 5:48 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
On Mon, 25 Jun 2007 13:40:31 -0700,

Alex <agnu...@gmail.com> wrote:
Simple, but single-threaded and therefore somewhat
fragile, surely?

By itself, each instantiation of sequence matching component is single-
threaded. However, another instantiation of sequence matching
component adds another thread. Just instantiate the number of
components to match all required patterns.

Alex, I understand the motivation to get a simple replacement
for SVA that works in (let's say) 80% of simple cases, but I
don't understand how your implementation is robust enough
to be worth deploying widely. For example, suppose you write
a sequence {conditionA, conditionB, conditionC} and on the
first cycle it happens that both conditionA and conditionC
are true. Your sequence counter will reset! So in fact
when you write a sequence

{A, B, C}

your sequence detector is *really* looking for

{ A && !B && !C, !A && B && !C, !A && !B && C }

And my "single-thread" accusation stands: you have only one
state variable, count, in the module - so a single instance of
the module cannot detect overlapping sequences. If you instance
the module more than once on the same set of signals, you STILL
cannot detect overlapping sequences because all your instances
will do exactly the same thing, in lockstep.

I also have the same objection to your example that I have
to OVL: it's completely opaque to users. A SVA sequence is
written using a standardised language; users can read the
code and see what it does. SVA empowers users. Your module,
and the OVL checker modules, DISempower users by providing
opaque functionality for something that is quite hard to
document. Indeed, sequential regular expression languages
such as SVA are probably the clearest and most effective
way to document such things. So why not simply execute
the documentation? Programming doesn't get better than that.

Historically, the field of assertion languages is "owned"
by a community of very sophisticated and clever theorists.
So some parts of the languages are very difficult indeed.
But those same clever theorists have given us something
that is extremely clear, well-defined, and (in simple
cases) quite easy to use. It's extremely easy to learn
the basics of SVA or PSL, and extremely hard to make a
good job of replicating their functionality for yourself.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.

Hi Jonathan,
First of all, my answer was inspired by Shenli's request: "Any
suggestions are welcome!".

Also, I have some arguments behind my implementation too.

1. Do Shenli really need to cover multi-threaded (aka pipelined)
functionality? It is not not defined in the original task definition.
SVA always assumes that there is a need for this. I assume, that not
really. If there is a requirement for single thread, so your
implementation with SVA is not correct, since it may collect "false
coverage".

2. Multi-threaded functionality of SVA constructs may cause even more
problems, since dynamic threads do not fit naturally into the concept
of hardware design. For example, SVA may collect false coverage (as
well as SVA assertion may pass) observing false multi-threading
behavior when logic does not allow it.

3. There was a discission about this issue on Verification Guild:
http://www.verificationguild.com/modules.php?name=Forums&file=viewtopic&t=1744&highlight=sva+thread

It was quite difficult to develop simple user requirement with SVA.
Ben Cohen proposed to enhance SVA with "one_thread" construct:
"This is why I think that we may need a one_thread() function that
causes the tool to only handle one thread, instead of multiple
threads."

As I see it, the standard which is not yet implemented in EDA tool
flow already requires some important enhancements. So, do we really
need to wait for new standard, and then for all EDA vendors and tools
supporting it? And where is a guarantee that improved SV standard
won't have another issues with basic verification infrastructure
support?

4. My component is synthesisable. It means that it can be used not
only in dynamic simulation, but also with formal model checking and
emulation (I used it to implement the watchdog logic in FPGA,
connecting it's output to status register). More than that, it can be
reusable part of design itself. And for all of that, I guarantee 0-
cost and highest level of reuse (all you need is Verilog 95
support) ;). With SVA, only part of it is synthesisable, and it is
hard to understand which part exactly and which tools support which
synthesisable part.

5. Finally, component-based approach easily work with SV, since SV is
still backward copatible to good old Verilog. In my opinion, it does
not harm, but rather complements SV and provides a feedback for the
future standard development.

Regards,
-Alex
 

Welcome to EDABoard.com

Sponsor

Back
Top