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

From: Warmke, Doug <doug_warmke_at_.....>
Date: Wed Sep 13 2006 - 23:15:44 PDT
Ben,
 
It's a bit dangerous to try and reason about clocking block behavior
in terms of more standard Verilog constructs such as "reg",
continuous assigns, events, etc.
 
For example, while clocking outputs are assigned with the <= operator,
these are not true NBA assignments. They are close, but not exactly
NBA's. See Mantis 890's rev3 proposal for more details.
 
Also, the objects inside clocking blocks are unique to the language.
They don't require types in their declarations, since they are always
closely associated with some object (either net or variable) outside
the clocking block.  Therefore it's difficult to figure out if they
should
be called "clocking variables" or "clocking nets".  "clocking signal"
seems to have been used in most of the LRM, so that is what 890
proposes we standardize on.  The procedural <= operator is always
used to drive clocking signals, whether they are associated with
a net or variable object outside of the clocking block.  
 
From the above, I hope you can see the inaccuracy in describing
the clocking signal as being implemented as a 'reg'.  (net/variable
and data type will vary depending on context - sometimes 'reg'
may be an appropriate analogy, but not usually).
 
Finally, the LRM doesn't require tools to actually use implicit
continuous
assigns in the way you mention, but that might be a reasonable
approximation of what is going on in some tools in some cases.
 
Regards,
Doug
 


________________________________

	From: vhdlcohen@aol.com [mailto:vhdlcohen@aol.com] 
	Sent: Sunday, September 10, 2006 12:17 PM
	To: jonathan.bromley@doulos.com; Warmke, Doug;
sv-ec@server.eda.org
	Subject: Re: [sv-ec] Clocking blocks: terminology and
clarifications
	
	
	From
http://verificationguild.com/modules.php?name=Forums&file=viewtopic&p=58
22#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 <mailto:jonathan.bromley%40doulos.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
<http://pr.atwola.com/promoclk/1615326657x4311227241x4298082137/aol?redi
r=http%3A%2F%2Fwww%2Eaol%2Ecom%2Fnewaol> . 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 Wed, 13 Sep 2006 23:15:44 -0700

This archive was generated by hypermail 2.1.8 : Wed Sep 13 2006 - 23:16:19 PDT