Hi folks, There was a request at the last meeting for some example code demonstrating the short-circuiting operator issue. Will Adams and I created the following example. Recent versions of three major simulation tools all short-circuit the logical AND and conditional operators, but an older version (2005) of at least one of these tools does not. Below is the example and two output files - one for short-circuit and one not. As an added bonus, I will indulge in some pontificating. My stance on the issue is: 1. Freescale wants the standard to define a portable language - that's the most important reason we make standards. Leaving a common, useful usage of common operators undefined/ambiguous is clearly not a portable definition. 2. This change might require some vendors to change implementations, and possibly some users to change code. There is disagreement over whether this constitutes "breaking backwards compatibility" or not. I strongly believe the term is misused in this case. When implementations of useful features diverge due to lack of standardization (which is the case here - the behavior of these operators is not unambiguously defined in the standard), the right thing to do is to standardize, even if it means someone would have to change. If there are practical obstacles to standardizing, well, let's get them on the table and try to do the best we can, but I think it is wrong to avoid standardizing on principle because it would require someone to change. 3. I have a fear that if synthesis is allowed to omit short-circuiting logic in the interests of optimization, then there will be pressure on formal vendors to follow this interpretation, leaving us (someday) with a design that simulates properly and passes formal verification, but turns out to have bugs after we've spent a bundle on masks and consumed months of schedule. Ouch! 4. If people don't like this proposal, I can live with that, as long as we choose something to remove the ambiguity. Even if it's something crazy (e.g., only short-circuit in programs, only short-circuit for certain kinds of operands), that's better than what we have now. However, it is critical that no allowance be made for other applications (synthesis, formal, coverage, etc.) to choose a different semantic from simulation, otherwise we leave the door open for bugs. 5. Note that I am not arguing for removing all ambiguity across the board. Just this week I argued in favor of leaving the evaluation order of unique case item expressions undefined in some cases. There is a cost-benefit analysis that must be done for each of these decisions. For the case item expressions, my judgment is that it is both rare and bad style to rely on this ordering, and I would not want to sacrifice performance for this. If it were possible to disallow it, I would. On the other hand, with the logical operators, we can argue about style, but it's certainly not rare for users to rely on short-circuiting, particularly in testbenches. The only benefit I see to allowing the current state of affairs to continue is that people with fragile RTL models will not have to risk their synthesis results changing ("fragile" in the sense that they rely on the ambiguity going one way, and produce bad results if it goes the other). Of course, such designs are also precisely the ones at risk of suffering from item 3 above. The cost of leaving it as-is is portability and verifiability. --Mike -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean. module sc ; // Just print message and return its argument unchanged. // The message is the side effect. function automatic int f( int i ) ; f = i ; $display( "** f() called with value %0d", i) ; endfunction initial begin int x; // logical AND x = f( 0 ) && f( 1 ); $display( "(f(0) && f(1)) is %0d" , x ) ; // bitwise AND x = f( 0 ) & f( 1 ); $display( "(f(0) & f(1)) is %0d" , x ) ; // conditional x = ( f( 0 ) ? f( 1 ) : 1'b0 ); $display( "(f(0) ? f(1) : 1'b0) is %0d" , x ) ; end endmodule ** f() called with value 0 ** f() called with value 1 (f(0) && f(1)) is 0 ** f() called with value 0 ** f() called with value 1 (f(0) & f(1)) is 0 ** f() called with value 0 ** f() called with value 1 (f(0) ? f(1) : 1'b0) is 0 ** f() called with value 0 (f(0) && f(1)) is 0 ** f() called with value 0 ** f() called with value 1 (f(0) & f(1)) is 0 ** f() called with value 0 (f(0) ? f(1) : 1'b0) is 0Received on Tue Nov 27 15:58:08 2007
This archive was generated by hypermail 2.1.8 : Tue Nov 27 2007 - 15:58:21 PST