Hi, Nasim - I'm afraid I find myself in almost complete disagreement with your recommendations and in fact, I am surprised to see some of these recommendations coming from a verification engineer. You also have a major flaw in your latch example that would have been avoided by using the always_latch. First, let me point out that there is no defined order of execution of the initial block and all of the always block variations (defined below). That having been said, I have noted that most, if not all, of the major Verilog simulation vendors actually schedule the always block statements before scheduling initial block statements in the active events region (although this is not defined in the LRM - and should be defined). This is why time-0 initial block statements trigger always blocks that are sensitive to signals assigned at time-0 in an initial block. I personally do not count on this ordering and I recommend that time-0 initial block assignments be made with nonblocking assignments to guarantee this ordering. The new always_comb, always_latch and always_ff blocks do trigger once automatically at time-0, as you have noted before. More below - BTW - I do like you list and methodical approach even if I disagree with your recommendations. At 03:02 PM 12/5/2005, Nasim Hussain wrote: >ummm... sorry for making this reply too long... > >it's just a personal opinion, but if i were to choose from these 7 : > > (1) initial > (2) always > (3) always_comb > (4) always_ff > (5) always_latch > (6) always @* > (7) final > > >i am *ONLY* going to advise users to use 1, 2 & 3, and that is it. >i have no need for 4, 5, 6 & 7. I strongly disagree. >to model an asynch. resettable FF (for behavioral code) - > > always @(posedge clk or posedge reset) begin > if (reset) q[(SIZE - 1):0] <= {SIZE {1'b0}}; > else q[(SIZE - 1):0] <= d[(SIZE - 1):0]; > end > >is as good as it can get. it's simple, concise and reflects the actual >intent of what i need for the tool to do. no need for it to do any kind >of checking, it needs to know all that it needs to know from what i have >given or specified. Close. always_ff @(posedge clk or posedge reset) if (reset) q <= '0; // using new 0-fill SystemVerilog syntax else q <= d; q and d are sized in the module header declaration and '0 fills exactly the number of 0's needed to avoid lint-tool warnings. The extra begin-end in you example actually encourages a coding style that could fail synthesis. If somebody accidentally adds another assignment after the begin statement, simulation would run but synthesis would fail. Better to drop the begin-end from a clocked always block (poor coding style). >i find > always_ff @(posedge clock iff reset==0 or posedge reset) begin > ... > ... > ... > end > >confusing and serves me no real purpose. again, a personal opinion. >just don't make assignments to the same variable from *different* >procedural blocks. i am sure you all know that. The extra iff test might improve simulator performance in the future, but in general, I agree that it offers little value in this context. What you seem to be missing is that the new always_variety statements have built-in assertions. If a tool does do the additional checking (optional), the designer has indicated intent in the always_variety block and it can be checked by a tool. I expect both synthesis and linting tools will do this checking. Simulators? I don't know if they will ever do this checking or not. The second safeguard built into the new always_variety statements is the checking for accidental assignments to the same variable from more than one always_variety block, and this happens at compile time. Why wouldn't you want the additional checking (again, surprising from a verification engineer). A possible added benefit to using the always_ff is the potential to RTL-code dual data-rate flip-flops. Because user intent is known (always_ff) future synthesis tools may allow us to code always_ff (clk or posedge reset) and understand that flops that clock on both clock edges are intended (we may want to overload the edge keyword to avoid mistakes due to omissions - always_ff @(edge clk or posedge reset)). Tektronix has been using dual data-rate flip-flops for more than a 15 years to do high-speed data acquisition. >same deal with latches. for example, all i need for an asynch. >resettable LATCH is - > > always @(d or posedge clk or posedge reset) begin > if (reset) q[(SIZE - 1):0] <= {SIZE {1'b0}}; > else if (clk) q[(SIZE - 1):0] <= d[(SIZE - 1):0]; > end > >i have absolutely no need for always_latch. yes, it might save me from >typing in a few extra words, but i think that is it. as a rule: we never >use blocking timing controls inside sequential elements. And your code has mistakes that would have been avoided with the always_latch. This mistake might not be caught during simulation but it will fail during synthesis. Synthesis tools enforce a coding style that requires that EITHER all signals in a sensitivity list have an edge or none of the signals have an edge. You have mixed them and it will cause a synthesis tool failure. There are two problems with this coding style that do not correspond to real hardware. First, the clock signal is not really edge-sensitive, it is level sensitive to handle the transparent mode (in this case, the simulation appears to function correctly, but it also works if the posedge is removed). Second, a problem occurs when reset is removed (negedge reset) because if the latch is in transparent mode when reset is removed, the d-input should immediately propagate to the q-output, but that will not occur until the next sensitivity trigger occurs (wrong functionality). always_latch if (reset) q <= '0; else if (clk) q <= d; (and again, remove the potentially problematic begin-end) >also, i am not sure when and where always_ff and always_latch fires, but >i am speculating it must be within the *active* slot, along with it's >gazillion other friends. my understanding (hopefully not flawed) is that >all of > > (3) always_comb > (4) always_ff > (5) always_latch > >will happen AFTER the "initial" (w/ blocking timing control) and >"always" blocks... meaning somewhat at the end of the active slot, but >before the beginning of the inactive slot ? Yes and no. Yes they all fire in the active events region, just like always blocks (we would not want the behavior to be any different), but no, they are not defined to fire after initial blocks (and again, most implementations fire the initial blocks after the always blocks). >till today, i don't fully comprehend all of the intricacies associated >with using "always @*" and consequently, i have maintained my distance >from it. "inferred" sensitivity lists aren't big on my plate. telling a >tool to be automatically sensitive to ALL the signals that it believes >it read within a procedural block - to me, that is a risky game. most of >the time, you want ALL signals on the RHS of assignments + signal >enables within the conditional if-else-if statements, but ... Again, I completely disagree. The @* removed problems related to missing signals from the sensitivity list. These missing signals were often difficult to debug if a linting tool was not used, and always yielded a mismatch between pre- and post-synthesis simulations. The @* removed the silly requirement to list all signals twice, once in the functional statements and again the sensitivity list of the always block. Do you worry about the implied sensitivity list of a continuous assignment?? I apologize but not "fully comprehend"-ing a new and powerful construct is a poor reason to avoid it. The @* is more concise and fixes common sensitivity list problems - that's "Win-Win!" >... that said, i believe using SV's always_comb might be of some >benefit, despite it being somewhat of an older, but wiser brother to >"always @*". Actually, @* was part of Verilog-2001. It was the "older ... brother." It could be used to model combinational logic and latches. The always_comb and always_latch were new SystemVerilog additions that indicated designer-intent, included built-in assertions (if implemented) and avoided the troublesome multi-block assignment to a common variable. always_comb builds its sensitivity list the same way as always @*. Your fears of always @* are illogical. I still think always @* has use in verification because now an engineer does not have to think about verification code in terms of combinational logic and latches. >always_comb (if it fires AFTER initial and always blocks) >can be useful to catch changing signals at time 0 (kind of similar to >C/C++'s do-while loop where it is guaranteed to execute at least once). > > > >finally, i have absolutely no need for the "final" block. Again, I disagree. Have you ever had final reporting code not execute because of $finish race conditions? I have. All the time! As was discussed on one of the SV threads in recent months, you can think of final blocks as $finish subroutines. It is important to remember that nonblocking assignments are not allowed (only code that is permitted in a function is allowed) and $strobe commands will not fire in time ($finish finishes in the active events region before the postponed $strobe commands can be activated). My biggest complaint about final blocks is that they should report and error or warning if somebody puts a $strobe inside a final block. EDA vendors are going to field lots of questions about final-$strobe if this is not done. >my conclusion - for me (can't speak for other people) - > > (1) initial YES, of-course! Yes - testbenches and program blocks. > (2) always YES, of-course! Rarely used any more. Supported for legacy code. > (3) always_comb USE, but judiciously! > (4) always_ff NOT necessary! > (5) always_latch NOT necessary! Yes-Yes and Yes!! Built-in assertions. Visible designer intent. Removes silly sensitivity list mistakes (like your latch-code above). Flags errors whenever multiple assignments are made to the same variable. Very surprising conclusion from a verification engineer. > (6) always @* NO! Yes in Verilog-only environments and yes even in SystemVerilog verification code. > (7) final NEVER! Yes - for final reporting of testbench statistics to avoid the $finish-race condition. >thanks. >-nasim Regards - Cliff >---------------------------------------------------------------------- >Nasim Hussain | Life is short, --- _ o _~o _ o >UltraSPARC Verification | go wherever ---- _`\<, _`\<, _`\<, >SUN Microsystems, Inc. | you want... --- ( )/( ) ( )/( ) ( )/( ) >work - (408) 720-4927 | >home - (650) 967-7730 | ---------------------------------------------------- Cliff Cummings - Sunburst Design, Inc. 14314 SW Allen Blvd., PMB 501, Beaverton, OR 97005 Phone: 503-641-8446 / FAX: 503-641-8486 cliffc@sunburst-design.com / www.sunburst-design.com Expert Verilog, SystemVerilog, Synthesis and Verification TrainingReceived on Mon Dec 5 18:03:56 2005
This archive was generated by hypermail 2.1.8 : Mon Dec 05 2005 - 18:04:32 PST