Hi, All - Arturo replied to my recent post with some good points and I know there is a lot of caution at some companies regarding X-optimism and X-pessimism. See Arturos great reply below, and then I have added more notes below Arturo's, just because I am not crazy about the ?: usage inside of always blocks. At 07:25 PM 12/5/2005, Arturo Salz wrote: >Cliff, > >I agree with everything you wrote. Your coding examples that may are >still prone to simulation/synthesis mismatches. BTW I'm not blasting >this reply to the reflector; I'll let you decide whether to share this >or not. > >The resettable FF should be: > always_ff @(posedge clk or posedge reset) q <= reset ? '0 : d > >The problem with your (i.e. the typical) code: > > always_ff @(posedge clk or posedge reset) > if (reset) q <= '0; > else q <= d; > >is that when reset is X or Z, the above functions correctly as a latch >(q <= d) when in fact it should not --- I saw this problem in a design >that simulated correctly and was found to have a bug that was discovered >after manufacture. Since the problem was in the reset circuitry, the >entire design was rendered useless and had to be re-spun. > >Ditto, for the level-sensitive latch: > > always_latch > if (reset) q <= '0; > else if (clk) q <= d; > >Should be done as: > > always_latch q <= reset ? '0 : (clk ? d : q); > >It may be a little know detail, but the "?" operator preserves X whereas >if (or case) will cause simulation to make a deterministic decision >based on a non-deterministic value, and synthesis cannot generate such >hardware. These details largely go unnoticed until someone has a >catastrophic failure. BTW, some formal tools will catch these types of >problems but usually very late in the design cycle. > > Arturo Arturo's point are all well taken and perhaps the safest coding style would employ the style shown by Arturo. I have personally never been bitten by clk-X or reset-X problems. They tend to cause more catastrophic failures that are easily traced back to the offend clk or reset problems; however, other if-else tests are more susceptible to X-optimism/pessimism and are not as easily identified. I have two objections to the ?: notation: (1) I don't think it is very clear unless one is used to the coding style. This of course is a personal preference. (2) ?: only works with single-statement assignments unless one is prepared to use lots of concatenation. Since I frequently group together multiple similar register assignments in the same always_ff block, the ?: fails synthesis unless I am prepared to break up the assignments into multiple separate always_ff blocks. That having been said, Arturo's comments are all valid. Suggested SV enhancement?? Add "ifx" and "elsex" keywords that basically do $isunknown (^reduction) on the tested expression and if the resultant expression is X, make X-assignments to all variables enclosed within the ifx or elsex block. A similar capability would be useful on a case statement - BTW I don't care what the keywords are ultimately called. These would basically be if-else test with built-in assertions. For now, perhaps the problem is better handled using assertions with my preferred coding style? See the following testbench-register example with reset going to X and Z. You can run the example as is and see the effects that Arturo has described. You can recompile with +define+X_CATCH to see Arturo's solution in action, which does indeed show the problems more clearly. You can also recompile with +define+FATAL to see the $fatal action block stop the simulation on the first problem. BTW - I know I have an interesting assertion problem in this example. It is hard to catch X's on the clk if the clk is the sample signal for the property. Perhaps Arturo has a suggested improvement. `timescale 1ns/1ns `define CYCLE 10 module tb; parameter SIZE=16; wire [SIZE-1:0] q; logic [SIZE-1:0] d; logic clk, rst_n; initial begin clk <= '0; forever #(`CYCLE/2) clk = ~clk; end register #(.SIZE(SIZE)) r1 (.q(q), .d(d), .clk(clk), .rst_n(rst_n)); initial begin $timeformat(-9,0,"ns",10); $monitor("%t: q=%h d=%h clk=%b rst_n=%b", $stime, q, d, clk, rst_n); end initial begin rst_n <= '0; d <= '1; @(posedge clk); @(negedge clk) rst_n <= '1; @(negedge clk) rst_n <= 'x; // Make reset go to X d <= {SIZE/2{2'b10}}; @(negedge clk) d <= ~d; @(negedge clk) rst_n <= '1; @(negedge clk) rst_n <= 'z; // Make reset go to Z d <= {SIZE/4{4'b1001}}; @(negedge clk) d <= ~d; @(negedge clk) $finish; end endmodule module register #(parameter SIZE=8) ( output logic [SIZE-1:0] q, input [SIZE-1:0] d, input clk, rst_n); property check_clk_rst_Xs; @(posedge clk) !($isunknown({clk,rst_n})); endproperty ILLEGAL_CLK_RST_VALUES: assert property (check_clk_rst_Xs); `ifdef FATAL else $fatal; `endif `ifdef X_CATCH always_ff @(posedge clk or negedge rst_n) q <= (!rst_n) ? '0 : d; `else always_ff @(posedge clk or negedge rst_n) if (!rst_n) q <= '0; else q <= d; `endif endmodule Regards - Cliff ---------------------------------------------------- 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 Tue Dec 6 11:33:38 2005
This archive was generated by hypermail 2.1.8 : Tue Dec 06 2005 - 11:34:31 PST