steveicarus / iverilog

Icarus Verilog
https://steveicarus.github.io/iverilog/
GNU General Public License v2.0
2.85k stars 530 forks source link

Support for "inside" statements #1092

Open keegandent opened 9 months ago

keegandent commented 9 months ago

I get the following result during attempted simulation of a state machine

sorry: "inside" expressions not supported yet.

Looking at the code that produces this response, it was made 12 years ago. I'm not sure if that means this doesn't come up a lot for others, but I for one think it's one of the better SystemVerilog quality-of-life features.

I'd be willing to take a stab at this if the existing contributors don't have the bandwidth.

Thanks

caryr commented 9 months ago

Yes, as a volunteer driven project things can move slower than most of us would like. If you would like to contribute we should be able to provide guidance.

keegandent commented 8 months ago

I've started churning through the parser and have identified relevant sections below. I'm not sure what's really good candidates for reuse here, and what needs to be done from scratch. My initial hope was to expand out the inside expression into a set of PEBComp() calls or similar. Is that a reasonable approach, or does it make more sense to go for a more standalone structure. Also, if there are resources I'm overlooking for this project specifically (I'm mostly following the "parsing" section here) or for compiler writing with YACC/bison in general, please let me know what you think might be useful in getting up to speed.

expression
  : expr_primary_or_typename
      { $$ = $1; }
  | inc_or_dec_expression
      { $$ = $1; }
  | inside_expression
      { $$ = $1; }
  // ...
  | expression K_EQ attribute_list_opt expression
      { PEBinary*tmp = new PEBComp('e', $1, $4);
    FILE_NAME(tmp, @2);
    $$ = tmp;
      }
  // ...
// ...
inside_expression /* IEEE1800-2005 A.8.3 */
  : expression K_inside '{' open_range_list '}'
      { yyerror(@2, "sorry: \"inside\" expressions not supported yet.");
    $$ = 0;
      }
  ;
// ...
open_range_list /* IEEE1800-2005 A.2.11 */
  : open_range_list ',' value_range
  | value_range
  ;
// ...
value_range /* IEEE1800-2005: A.8.3 */
  : expression
      { }
  | '[' expression ':' expression ']'
      { }
  ;
// ...
parameter_assign_list
  : parameter_assign
  | parameter_assign_list ',' parameter_assign
  ;

parameter_assign
  : IDENTIFIER initializer_opt parameter_value_ranges_opt
      { pform_set_parameter(@1, lex_strings.make($1), param_is_local,
                param_is_type, param_data_type, $2, $3);
    delete[]$1;
      }
  ;

parameter_value_ranges_opt : parameter_value_ranges { $$ = $1; } | { $$ = 0; } ;

parameter_value_ranges
  : parameter_value_ranges parameter_value_range
      { $$ = $2; $$->next = $1; }
  | parameter_value_range
      { $$ = $1; $$->next = 0; }
  ;

parameter_value_range
  : from_exclude '[' value_range_expression ':' value_range_expression ']'
      { $$ = pform_parameter_value_range($1, false, $3, false, $5); }
  | from_exclude '[' value_range_expression ':' value_range_expression ')'
      { $$ = pform_parameter_value_range($1, false, $3, true, $5); }
  | from_exclude '(' value_range_expression ':' value_range_expression ']'
      { $$ = pform_parameter_value_range($1, true, $3, false, $5); }
  | from_exclude '(' value_range_expression ':' value_range_expression ')'
      { $$ = pform_parameter_value_range($1, true, $3, true, $5); }
  | K_exclude expression
      { $$ = pform_parameter_value_range(true, false, $2, false, $2); }
  ;

value_range_expression
  : expression { $$ = $1; }
  | K_inf      { $$ = 0; }
  | '+' K_inf  { $$ = 0; }
  | '-' K_inf  { $$ = 0; }
  ;

from_exclude : K_from { $$ = false; } | K_exclude { $$ = true; } ;