Re: [sv-ec] Clocking blocks: terminology and clarifications

From: <vhdlcohen_at_.....>
Date: Sun Sep 10 2006 - 12:16:33 PDT
 From http://verificationguild.com/modules.php?name=Forums&file=viewtopic&p=5822#5822
 while discussing modports and clocking blocks: "But inside an interface, and hidden behind a modport that provide directionality and the implicit continuous assignment, they can be assigned procedurally just fine. "
 
 Using example below, t_if.b is a wire, but t_if.cb1.b is a reg (because it's an output).
 There is an implicit "assign t_if.b=t_if.cb1.b;"
 This is why I can do:
 t1_if.cb1.b <= 1'b1; // in an procedural block
 assign t1_if.b= w_a;
 Is my understanding on this correct? Model simulates OK on 2 simulators. 
 Ben Cohen
 www.systemverilog.us
 ---
 `timescale 1ns / 1ns
 interface t_if (input wire clk);
 wire a, b;
 
 default clocking cb1 @(posedge clk);
 input a;
 output b;
 endclocking : cb1
 endinterface : t_if
 
 module bentest;
 logic lgc_a, lgc_b, clk;
 wire w_a, w_b;
 initial begin
 clk <= '0;
 forever #5 clk = ~clk;
 end
 
 t_if t1_if (.*);
 
 initial @(t1_if.cb1) begin 
 t1_if.cb1.b <= 1'b1; // t_if.cb1.b behaves as a reg 
 end
 
 assign t1_if.b= w_a; // t_if.b behaves as a wire
 assign w_a = 1'b0;
 endmodule
    
 -----Original Message-----
 From: jonathan.bromley@doulos.com
 To: doug_warmke@mentor.com; sv-ec@server.eda.org
 Sent: Sun, 10 Sep 2006 8:47 AM
 Subject: RE: [sv-ec] Clocking blocks: terminology and clarifications
 
  Doug and all,

First, many thanks are due for your excellent clarifications in
document SV-890-2 (attached to Mantis 890).  It helps a lot. 
Incidentally, it provides resolutions for almost all the issues
raised by the examples that Cliff Cummings posted on Friday
(subject "[sv-ec] Clocking Block Examples").

Second, thanks for your specific and helpful responses to my
questions of August 4th.

However, I confess to some slight discomfort with one of your 
proposed solutions.  I apologise (just a little bit) for 
continuing to whinge on about this, but there's no doubt we 
have a serious problem: clockings are well-established in 
user code and vendor methodologies, but we have three major
tools with three dramatically divergent implementations, so 
there's definitely something fishy going on.  If the expert 
implementors at the Big Three can't decide unambiguously 
what the LRM means, there's little hope for ordinary users 
and trainers like me.

I don't have write access to Mantis so I am obliged to offer
my concerns in this email.  I hope it's not too inconvenient.
Most of what I say below is just commentary and "friendly
amendment", but I'll start out with the two issues that
seem to me to need really careful scrutiny and where I
actively disagree with Doug.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Should a clocking output be permitted to drive a
program variable?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I don't believe so.  Clocking outputs ultimately drive 
their target variables by NBA, which is (for various
good reasons) illegal on program variables.  Why
should clockings be allowed to circumvent this rule?
Note that Doug's proposed amendment to LRM 16.2 clearly
(and, in my opinion, correctly) states that even variable
*ports* of a program are program variables, and thus 
can't be driven by NBA.  So the oft-proposed idiom of
a program with output ports that will be connected to
the DUT, and with a clocking block having those ports
as clocking outputs, is in my opinion unusable.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Are clocking signals and clocking INPUTS distinct objects?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[See my later section re. clocking OUTPUTS for discussion 
of why I don't think it's such a problem for outputs.]

Given the following:

    logic L;
    clocking C @ (posedge CLK);
      input #2 L;
    endclocking : C

I cannot accept that C.L and L are merely two 
views of the same thing.

There are many places in Verilog where objects have
magic timing semantics so that a write to the object
is not reflected on the object until some time later.
For example: 
  wire A = #3 B;
In such situations I do not usually need to understand
that there are different objects within the simulator,
even though it's clear that the simulator implementation
must provide some temporary storage somewhere.  The key
reason why I can safely remain ignorant is that 

    there is no way for me to inquire about the 
    written value other than by waiting for it to
    propagate to the driven object after the delay.

In other words, even if there is an additional object,
I have no way to read it, detect events on it or 
otherwise make use of it.

For clocking *inputs* the situation is very different.
Not only can I write to the clocking input from external
code, I can also read BOTH the clocking input (L) AND the
corresponding clocking signal (C.L).  They are two entirely
distinct objects *visible from user code*.  Events on
L and events on C.L happen at different times, and
there can be many events on L that have no counterpart
on C.L.  For large slices of simulation time, L and C.L
can be seen to have different values.  They are manifestly
distinct objects.  To insist that they are the same thing
is gratuitous obfuscation.

Once we accept that they are different, we must specify
how C.L is updated.  Doug did so very clearly in SV-890-2
(update for clause 15.12) - this appears as part of a 
description of the special behavior of #0 sampling, but 
I assume it's intended to apply to any clocking input:

  when the clocking event occurs, the sampled value 
  shall be updated and available for reading the 
  instant the clocking event takes place and before 
  any other statements are executed.

If the last phrase ("before any other statements are executed")
were not present, we would be back to my current understanding
of clocking - that it's wrong to read a clocking input signal
such as C.L from within design code (the Active region) because
that represents a write/read race between updating of the
clocking signal on the clocking event, and reading it from
Active code.  Reading from program code in the Reactive region
is of course fine.

I have a big, big problem with this stipulation that the 
updating take place before any other statements are executed.
You could argue that it merely imposes an event ordering that
was already one of the set of possible orderings, and in simple
cases that is certainly true; but it still leaves plenty of 
opportunities for races if you have more than one clocking
block - I'll try to post some simple examples later.  So I
suggest that it's a bad idea because it instils a false sense
of security that cannot be sustained across all possible
configurations of clocking blocks.  Far better to leave the
indeterminacy there, and work around it the right way by 
making use of program blocks.

Unfortunately, such a stipulation is required to legitimize 
any usage of clocking blocks where the "testbench" side of 
the clocking is coded in a module or interface, rather than 
in a program.  An expert from one of the vendors, whose 
SV-TB methodology does exactly this, stated recently in a
Verification Guild post that such use of clockings was
race-free because the clocking input signals were updated
in the way SV-890-2 describes.  Interestingly, at the time of
that statement there was as far as I know absolutely no 
justification for it anywhere in the SV-LRM or on Mantis.


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Terminology
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[JONATHAN]
> > We lack a well-defined way of talking about the variables
> > (signals, nets, whatever) in a clocking block.  Given
> > 
> >   wire Wi, Wo;
> >   logic Li, Lo;
> >   clocking cb @(posedge Clk);
> >     input Wi, Li;
> >     output Wo, Lo;
> >   endclocking
> > 
> > we have created "objects" cb.Li, cb.Wo etc.  The LRM
> > does not seem to offer a generic term for these "objects".
> > In various places in the text the phrase "clocking block 
> > variables" is used to describe this notion, but it is
> > nowhere rigorously defined and its usage appears to be
> > somewhat arbitrary.  Am I entitled to use the phrase
> > "clocking block variable", unambiguously and exclusively,
> > to describe these access points that appear in a clocking?

[DOUG]
> I looked through Section 15 to see the frequency
> of the various terms used to describe these objects.
> "clocking signal" is used much more often than "clocking
> variable".  So it seems it would be easier to stick with
> "clocking signal".
> In addition, these objects have somewhat unusual semantic
> characteristics and restrictions.  Using a standard SV
> term like "variable" or "net" could mislead people into
> thinking these objects are plain variables or nets that
> live in the clocking scope.  Using the unusual term (for SV)
> "signal" connotes that some unusual semantics are going
> on here.
> I'm fine either way.  The above are the salient points
> I can think of right now.  My initial vote is "signal".

I, too, am happy with anything that's unambiguous.  My 
(by now almost obsessive) concern was to find a way of
talking about "cb.X" that is distinct from "X".  Note 
that I'm not trying to pre-judge the issue of whether
cb.X and X are distinct objects or two aspects of the
same object; that's why I was careful to put "object" 
in quotes.  As long as we reserve "clocking signal"
for things like "cb.X", and use "clocking output" or
"clocking input" as a generic description of things
like X, I'm fine.  I'll try to adhere to that throughout.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Are clocking signals and clocking OUTPUTS distinct objects?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DOUG]
> Consider this simple program fragment:
> 
>   program(output logic d);
> 
>   clocking cb begin
>     output #2ns d;
>   endclocking
>   ...
> 
> There are several possibilities on how to consider d and cb.d:
> 1. cb.d is a syntactic-sugar form of referring to d.
>    When driving cb.d with <=, it is like directly writing
>    to d with special delay semantics.  There is only one
>    variable stored.
> 2. cb.d and d are independently stored variables.
>    There is an update semantic like:
>     always @(cb) d <= #2 cb.d;
> 3. cb.d and d are independently stored variables.
>    There is a semantic like:
>     always @(cb) if (someone_did_a_sync_drive_to_d) d <= #2 cb.d;
> 
> Jonathan's desire here seems to be for something like 2.
> Cliff's reading seems to be either 1 or 3.
> I think there is some evidence for 3, in particular
> the second sentence of this paragraph from 15.14.2:
> 
>    The variable j is an output to two clocking blocks using
>    different clocking events (posedge versus negedge). When driven,
>    the variable j shall take on the value most recently assigned
>    by either clocking block.

[JONATHAN]
I'm not sure I can extract much meaning from that last sentence, 
because its terminology isn't well defined, but I would be
entirely comfortable with either of Doug's interpretations (2) or (3).
At least one existing implementation follows (2), as Cliff discovered
in his examples, and I find that behavior attractive and convenient;
but I can easily get it from an implementation that does (3), so once 
again I'm happy with either so long as it's unambiguous and consistent.

For clocking *outputs* I don't think there's any way to tell the
difference between (1) and (3), since it's impossible to read
the value cb.d from within user code.  The story about value-resolution
of drives to a clocking signal, and the postponement of those drives
to the Reactive region of the current or next timeslot in which 
the clocking event occurs, makes it all nice and race-free provided
the clocking event comes from a design value change rather than from
within the program.  Personally I regard it as a user error to trigger
a clocking block from an event on a program variable - anyone disagree?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Multiple clocking blocks driving an output net
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DOUG]
> Tried to take care of these suggestions in the
> latest 890 proposal, SV-890-2.htm.

Looks fine - it's what I see as the commonsense interpretation.


Thanks
-- 
Jonathan Bromley, Consultant

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

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223                   Email: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573                           Web: http://www.doulos.com

This message may contain personal views which 
are not the views of Doulos Ltd., unless specifically stated.
   
________________________________________________________________________
Check out the new AOL.  Most comprehensive set of free safety and security tools, free access to millions of high-quality videos from across the web, free AOL Mail and more.
Received on Sun Sep 10 12:16:55 2006

This archive was generated by hypermail 2.1.8 : Sun Sep 10 2006 - 12:17:16 PDT