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.Received on Sun Sep 10 08:47:29 2006
This archive was generated by hypermail 2.1.8 : Sun Sep 10 2006 - 08:47:47 PDT