[sv-bc] Errata proposals -- 2 fixes for pattern-matching syntax

From: Rishiyur S. Nikhil <nikhil@bluespec.com>
Date: Fri May 21 2004 - 07:13:55 PDT

These errata proposals describe and fix two small syntactic
problems in pattern-matching syntax.

Nikhil

This proposal fixes two small problems in pattern-matching syntax

Erratum: Fix a syntactic ambiguity in pattern-matching syntax by replacing ‘&&’ by ‘&&&’.

Nikhil, May 20, 2004.

 

This is a purely syntactic fix; no change in semantics.

 

This problem was independently identified by Brad Pierce (Synopsys) and Mieszko Lis (Bluespec).  Both of them also independently suggested the same solution.

 

The Problem: ambiguity of && operator

                                  

Currently, in conditional expressions, conditional statements and pattern-matching case statements, the syntax allows a sequence of patterns-matches and boolean expressions, separated by &&:

 

cond_predicate ::=

expression_or_cond_pattern { && expression_or_cond_pattern }

 

case_pattern_item ::=

pattern [ && expression ] : statement_or_null

 

The && is a sequential (C-like) conjunction, i.e., evaluated left-to-right, and fails as soon as a False element is encountered.   But && is also the normal Verilog AND operator, which does not have these left-to-right sequential semantics.   This leads to an ambiguity, e.g.,

 

if (e1 && e2 && e3) …

 

Here, it’s not clear which version of && is intended.

 

Proposed Solution:

 

Replace && with &&& for the sequential pattern-matching connective.

.

Note: &&& is already a Verilog 2001 operator, but it is only used for timing_check_conditions in timing_check_events, and so there is no overlap with the proposed use in pattern-matching.

 

Specific LRM changes:

 

·        In Syntax 7-6, Syntax 8-3, and Appendix A.6.6, replace

cond_predicate ::=

expression_or_cond_pattern { && expression_or_cond_pattern }

with

cond_predicate ::=

expression_or_cond_pattern { &&& expression_or_cond_pattern }

 

·        In Syntax 8-3 and Appendix A.6.7, replace

case_pattern_item ::=

pattern [ && expression ] : statement_or_null

with

case_pattern_item ::=

pattern [ &&& expression ] : statement_or_null

 

·        Replace “&&” by “&&&” in the following places:

o       In Section 8.4.1.1, 1st para of section, 3rd line

o       In Section 8.4.1.1, 2nd example on page 84

o       In Section 8.4.1.1, 3rd  example on page 85

o       In Section 8.4.1.1, 4th  example on page 85

o       In Section 8.4.1.2, page 85, 1st para of section, line 1

o       In Section 8.4.1.2, 3rd example on page 86

o       In Section 8.4.1.3, page 86, line 2 of section

 

This proposal fixes two small problems in pattern-matching syntax

Erratum: Fix a syntactic problem in pattern syntax by using `.’ (period)  in front of pattern variables instead of in front of constant expressions.

Nikhil, May 20, 2004.

 

This is a purely syntactic fix; no change in semantics.

 

This problem was identified by users, and the proposed solution is preferred by users.  Also, in the early discussions on pattern-matching in SV-BC, Yong Xiao (Synopsys) actually expressed his preference for the solution given here.

 

The Problem: Role of `.’ in pattern syntax

 

Currently, in pattern syntax:

pattern ::=

    variable_identifier

| . constant_expression

constant expressions must be preceded by a `.’ (period).  The purpose is to distinguish them from variable identifiers.  E.g., a pattern `x’ is a pattern variable, implicitly declared at this place in the pattern, shadows any surrounding x, and gets bound to the value against which it is matched.  Whereas, a pattern `.x’ is a constant expression, i.e., x must be a constant available in the current scope, and this constant is tested for equality against a value.

 

After 6 months of experience writing codes, users by far prefer the reverse convention, i.e., the ‘.’ should be in front of pattern variables instead of in front of constant expressions.

  • A pattern like `.23’ is syntactically a constant expression pattern testing the value for equality with the constant 23, but can easily be mis-read as a real number
  • In the reverse convention, there is a better semantic match between `.x’ (variable pattern) and `.*’ (the wildcard pattern), i.e, in both cases, the pattern-match always succeeds, and the `.*’ can be read as just choosing not to introduce a pattern variable.
  • People find the reverse convention to be more natural, i.e., the special `.’ flags the new and special concept of pattern variables instead of the existing concept of constant expressions.

 

Proposed solution:

 

Move the `.’ (period) from being in front of constant_expressions to be in front of  variable_identifiers.

 

Specific LRM changes:

 

  • In Syntax 8-4 and Appendix A.6.7.1:

pattern ::=

   variable_identifier

| .*

| . constant_expression

| …

add `.’ in front of variable_identifier and remove `.’ from the constant_variable line:

pattern ::=

  . variable_identifier

| .*

| constant_expression

| …

 

  • In Section 8.4.1.1, page 84, 1st example, 2nd arm of case statement:

tagged Valid n : $display ("v is Valid with value %d", n);

add `.’ before ‘n’ pattern:

tagged Valid .n : $display ("v is Valid with value %d", n);

 

  • In Section 8.4.1.1, page 84, 2nd example:

case (instr) matches

  tagged Add {r1, r2, rd} && (rd != 0): rf[rd] = rf[r1] + rf[r2];

  tagged Jmp j :                        case (j) matches

 tagged JmpU a     : pc = pc + a;

 tagged JmpC {c, a}: if (rf[c]) pc = a;

      endcase

endcase

add `.’ before all identifier patterns:

case (instr) matches

  tagged Add {.r1, .r2, .rd} && (rd != 0): rf[rd] = rf[r1] + rf[r2];

  tagged Jmp .j :                          case (j) matches

    tagged JmpU .a      : pc = pc + a;

    tagged JmpC {.c, .a}: if (rf[c]) pc = a;

  endcase

endcase

 

  • In Section 8.4.1.1, page 85, 1st example:

case (instr) matches

  tagged Add {.*,.*, . 0} : ; // no op

  tagged Add {r1, r2, rd} : rf[rd] = rf[r1] + rf[r2];

  tagged Jmp j :            case (j) matches

                 tagged JmpU a     : pc = pc + a;

                 tagged JmpC {c,a} : if (rf[c]) pc = a;

               endcase

endcase

remove `.’ before the `0’ and add `.’ before all identifier patterns:

case (instr) matches

  tagged Add {.*,.*, 0}      : ; // no op

  tagged Add {.r1, .r2, .rd} : rf[rd] = rf[r1] + rf[r2];

  tagged Jmp .j              : case (j) matches

      tagged JmpU .a       : pc = pc + a;

      tagged JmpC {.c, .a} : if (rf[c]) pc = a;

    endcase

endcase

 

  • In Section 8.4.1.1, page 85, 2nd example:

case (instr) matches

  tagged Add s: case (s) matches

    {.*,.*, . 0} : ; // no op

    {r1,r2, rd} : rf[rd] = rf[r1] + rf[r2];

  endcase

  tagged Jmp j: case (j) matches

    tagged JmpU a     : pc = pc + a;

    tagged JmpC {c,a} : if (rf[c]) pc = a;

  endcase

endcase

remove `.’ before the `0’ and add `.’ before all identifier patterns:

case (instr) matches

  tagged Add .s: case (s) matches

    {.*,.*, 0}      : ; // no op

    {.r1, .r2, .rd} : rf[rd] = rf[r1] + rf[r2];

  endcase

  tagged Jmp .j: case (j) matches

     tagged JmpU .a       : pc = pc + a;

     tagged JmpC {.c, .a} : if (rf[c]) pc = a;

   endcase

endcase

  • In Section 8.4.1.1, page 85, 3rd example:

case (instr) matches

  tagged Add {r1,r2,rd} && (rd != 0) : rf[rd] = rf[r1] + rf[r2];

  tagged Jmp (tagged JmpU a)         : pc = pc + a;

  tagged Jmp (tagged JmpC {c,a})     : if (rf[c]) pc = a;

endcase

add `.’ before all identifier patterns:

case (instr) matches

  tagged Add {.r1, .r2, .rd} && (rd != 0) : rf[rd] = rf[r1] + rf[r2];

  tagged Jmp (tagged JmpU .a)             : pc = pc + a;

  tagged Jmp (tagged JmpC {.c, .a})       : if (rf[c]) pc = a;

endcase

 

  • In Section 8.4.1.1, page 85, 4th example:

case (instr) matches

  tagged Add {reg2:r2,regd:rd,reg1:r1} && (rd != 0): rf[rd] = rf[r1] + rf[r2];

  tagged Jmp (tagged JmpU a)                       : pc = pc + a;

  tagged Jmp (tagged JmpC {addr:a,cc:c})           : if (rf[c]) pc = a;

endcase

add `.’ before all identifier patterns:

case (instr) matches

  tagged Add {reg2:.r2,regd:.rd,reg1:.r1} && (rd != 0): rf[rd] = rf[r1] + rf[r2];

  tagged Jmp (tagged JmpU .a)                         : pc = pc + a;

  tagged Jmp (tagged JmpC {addr:.a,cc:.c})            : if (rf[c]) pc = a;

endcase

 

  • In Section 8.4.1.1, page 86, 1st example:

if (e matches (tagged Jmp (tagged JmpC {cc:c,addr:a})))

add `.’ before all identifier patterns:

if (e matches (tagged Jmp (tagged JmpC {cc:.c,addr:.a})))

 

  • In Section 8.4.1.1, page 86, 2nd  example:

if (e matches (tagged Jmp j),

    j matches (tagged JmpC {cc:c,addr:a}))

add `.’ before all identifier patterns:

if (e matches (tagged Jmp .j),

    j matches (tagged JmpC {cc:.c,addr:.a}))

 

  • In Section 8.4.1.1, page 86, 3rd  example:

if (e matches (tagged Jmp (tagged JmpC {cc:c,addr:a}))

add `.’ before all identifier patterns:

if (e matches (tagged Jmp (tagged JmpC {cc:.c,addr:.a}))

 

Received on Fri May 21 07:13:55 2004

This archive was generated by hypermail 2.1.8 : Fri May 21 2004 - 07:14:09 PDT