Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

section 6.23 of LRM 2017 results in a syntax error #100

Open
fpgauserdude opened this issue Aug 29, 2024 · 3 comments
Open

section 6.23 of LRM 2017 results in a syntax error #100

fpgauserdude opened this issue Aug 29, 2024 · 3 comments

Comments

@fpgauserdude
Copy link

The following code produces an error:

package test2;

typedef enum
   {
     UNKNOWN = 0,
     BYTES,
     INT,
     FLOAT
   } type_e;

class Container #(type T);
  typedef T data_t;

  function type_e get_type();
    case (type(T))
      type(byte): return BYTES;
      type(longint): return INT;
      type(real): return FLOAT;
      default: return UNKNOWN;
    endcase // case (type(T))
  endfunction
endclass // Container

endpackage

Error:
$ svinst test2.sv
files:
parse failed: "test2.sv"
test2.sv:11:1
|
11 | class Container #(type T);
| ^

Commenting out the case statement allows the parser to succeed.

This code compiles fine on a commercial parser. See section 6.23 of the 1800-2017 LRM.

@dalance
Copy link
Owner

dalance commented Sep 13, 2024

The actual code in section 6.23 is like below.

bit [12:0] A_bus, B_bus;
parameter type bus_t = type(A_bus);
generate
  case (type(bus_t))
    type(bit[12:0]): addfixed_int #(bus_t) (A_bus,B_bus);
    type(real): add_float #(type(A_bus)) (A_bus,B_bus);
  endcase
endgenerate

This shows type operator can be used in generate case statement.
According to Formal syntax of LRM, the type operator can be used as constant_expression.

type_reference ::= type ( expression )
constant_primary ::= type_reference
constant_expression ::= constant_primary

But the expression which can be used in case_statement is expression not constant_expression. This means type operator can't be used at case statement in function like your code.

case_statement ::= [ unique_priority ] case_keyword ( case_expression ) case_item { case_item } endcase
case_expression ::= expression

On the other hand, generate case takes constant_expression, so type operator can be used.

case_generate_construct ::= case ( constant_expression ) case_generate_item { case_generate_item } endcase

@fpgauserdude
Copy link
Author

Making that expression constant is not possible in my code. It would remove the purpose of using that feature in the first place. I am using the preprocessor to remove problematic code from sv-parse (since the preprocessor actually works properly!) Despite these small problems, sv-parse is the best open-source SystemVerilog parser that I can find anywhere--for lots of reasons. This is excellent work that has made things possible for me that were kludgy at best in the past. I appreciate it.

It would be interesting to see the discrepancies between the LRM and the grammars the commercial tools actually use. I imagine there are lots of differences.

@dalance
Copy link
Owner

dalance commented Sep 17, 2024

I am sorry for inconvenience, but supporting tool-specific behavior is difficult.
So I think your workaround is reasonable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants