Permalink
Browse files

Fix up original SV timeunit/timeprecision patch.

This patch modifies the original SystemVerilog timeunit/timeprecision
patch in the following way:

Removed trailing space.

Reworked some code to use standard spacing rules.

Added some comments.

Combined some code.

Major rework of local/global timeunit/timeprecision logic.

Major rework of timeunit/timeprecision declaration/check code.
This was needed to remove the shift/reduce warnings.

Add a number of checks for invalid combinations.
  • Loading branch information...
1 parent c2feeb0 commit 9dce6496fb1b0eb30c869f3da2c4e0ac57cee21d @caryr caryr committed with Jul 11, 2009
Showing with 220 additions and 229 deletions.
  1. +1 −0 compiler.h
  2. +17 −20 lexor.lex
  3. +2 −2 lexor_keyword.gperf
  4. +43 −68 parse.y
  5. +6 −0 parse_misc.h
  6. +146 −136 pform.cc
  7. +5 −3 pform.h
View
@@ -134,6 +134,7 @@ extern bool gn_specify_blocks_flag;
/* If this flag is true, then support/elaborate Verilog-AMS. */
extern bool gn_verilog_ams_flag;
+/* If this flag is true, then support/elaborate SystemVerilog. */
extern bool gn_system_verilog_flag;
/* If this flag is false a warning is printed when the port declaration
View
@@ -108,7 +108,7 @@ W [ \t\b\f\r]+
S [afpnumkKMGT]
TU [munpf]
-
+
%%
/* Recognize the various line directives. */
@@ -250,6 +250,15 @@ TU [munpf]
in_UDP = false;
break;
+ /* Translate these to checks if we already have or are
+ * outside the declaration region. */
+ case K_timeunit:
+ if (have_timeunit_decl) rc = K_timeunit_check;
+ break;
+ case K_timeprecision:
+ if (have_timeprec_decl) rc = K_timeprecision_check;
+ break;
+
default:
yylval.text = 0;
break;
@@ -325,25 +334,13 @@ TU [munpf]
based_size = yylval.number->as_ulong();
return DEC_NUMBER; }
-[0-9]+{TU}?s {
- if(gn_system_verilog_flag)
- {
- yylval.text = strdupnew(yytext);
- return TIME_LITERAL;
- }
- else
- REJECT;
- }
-
-[0-9]*\.[0-9]+{TU}?s {
- if(gn_system_verilog_flag)
- {
- yylval.text = strdupnew(yytext);
- return TIME_LITERAL;
- }
- else
- REJECT;
- }
+ /* This rule handles scaled time values for SystemVerilog. */
+[0-9][0-9_]*(\.[0-9][0-9_]*)?{TU}?s {
+ if(gn_system_verilog_flag) {
+ yylval.text = strdupnew(yytext);
+ return TIME_LITERAL;
+ } else REJECT; }
+
/* These rules handle the scaled real literals from Verilog-AMS. The
value is a number with a single letter scale factor. If
verilog-ams is not enabled, then reject this rule. If it is
View
@@ -162,8 +162,8 @@ tan, GN_KEYWORDS_VAMS_2_3, K_tan
tanh, GN_KEYWORDS_VAMS_2_3, K_tanh
task, GN_KEYWORDS_1364_1995, K_task
time, GN_KEYWORDS_1364_1995, K_time
-timeprecision, GN_KEYWORDS_1800_2005, K_timeprecision
-timeunit, GN_KEYWORDS_1800_2005, K_timeunit
+timeprecision, GN_KEYWORDS_1364_1995, K_timeprecision
+timeunit, GN_KEYWORDS_1364_1995, K_timeunit
tran, GN_KEYWORDS_1364_1995, K_tran
tranif0, GN_KEYWORDS_1364_1995, K_tranif0
tranif1, GN_KEYWORDS_1364_1995, K_tranif1
View
111 parse.y
@@ -35,6 +35,9 @@ class PSpecPath;
extern void lex_start_table();
extern void lex_end_table();
+bool have_timeunit_decl = false;
+bool have_timeprec_decl = false;
+
static svector<PExpr*>* param_active_range = 0;
static bool param_active_signed = false;
static ivl_variable_type_t param_active_type = IVL_VT_LOGIC;
@@ -270,7 +273,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
/* The new tokens from 1800-2005. */
%token K_always_comb K_always_ff K_always_latch K_assert
-%token K_timeprecision K_timeunit
+%token K_timeprecision K_timeunit
+ /* Fake tokens that are passed once we have an initial token. */
+%token K_timeprecision_check K_timeunit_check
/* The new tokens for Verilog-AMS 2.3. */
%token K_abs K_abstol K_access K_acos K_acosh K_analog K_asin K_asinh
@@ -729,7 +734,10 @@ description
delete[] $3;
delete[] $5;
}
- | timeunits_declaration
+ | K_timeunit TIME_LITERAL ';'
+ { pform_set_timeunit($2, false, false); }
+ | K_timeprecision TIME_LITERAL ';'
+ { pform_set_timeprecision($2, false, false); }
;
/* The discipline and nature declarations used to take no ';' after
@@ -738,67 +746,6 @@ description
choose to make the ';' optional in this context. */
optional_semicolon : ';' | ;
-timeunits_declaration_opt
- :local_timeunits_declaration
- |
- ;
-
-timeunits_declaration
- : K_timeprecision TIME_LITERAL ';'
- K_timeunit TIME_LITERAL ';'
- {
- pform_set_timeprecision($2,false,false);
- pform_set_timeunit($5,false,false);
- }
- | K_timeunit TIME_LITERAL ';'
- K_timeprecision TIME_LITERAL ';'
- {
- pform_set_timeunit($2,false,false);
- pform_set_timeprecision($5,false,false);
- }
- | K_timeunit TIME_LITERAL ';'
- {
- pform_set_timeunit($2,false,false);
- }
- | K_timeprecision TIME_LITERAL ';'
- {
- pform_set_timeprecision($2,false,false);
- }
-
- ;
-
-local_timeunits_declaration
- : K_timeprecision TIME_LITERAL ';'
- K_timeunit TIME_LITERAL ';'
- {
- pform_set_timeprecision($2,true,false);
- pform_set_timeunit($5,true,false);
- }
- | K_timeunit TIME_LITERAL ';'
- K_timeprecision TIME_LITERAL ';'
- {
- pform_set_timeunit($2,true,false);
- pform_set_timeprecision($5,true,false);
- }
- | K_timeunit TIME_LITERAL ';'
- {
- pform_set_timeunit($2,true,false);
- }
- | K_timeprecision TIME_LITERAL ';'
- {
- pform_set_timeprecision($2,true,false);
- }
-
-timeunits_declaration_check
- : K_timeunit TIME_LITERAL ';'
- {
- pform_set_timeunit($2,true,true);
- }
- | K_timeprecision TIME_LITERAL ';'
- {
- pform_set_timeprecision($2,true,true);
- }
- ;
discipline_declaration
: K_discipline IDENTIFIER optional_semicolon
{ pform_start_discipline($2); }
@@ -2038,6 +1985,25 @@ cont_assign_list
{ $$ = $1; }
;
+ /* We allow zero, one or two unique declarations. */
+local_timeunit_prec_decl_opt
+ : /* Empty */
+ | local_timeunit_prec_decl
+ | local_timeunit_prec_decl local_timeunit_prec_decl
+ ;
+
+ /* By setting the appropriate have_time???_decl we allow only
+ one declaration of each type in this module. */
+local_timeunit_prec_decl
+ : K_timeunit TIME_LITERAL ';'
+ { pform_set_timeunit($2, true, false);
+ have_timeunit_decl = true;
+ }
+ | K_timeprecision TIME_LITERAL ';'
+ { pform_set_timeprecision($2, true, false);
+ have_timeprec_decl = true;
+ }
+ ;
/* This is the global structure of a module. A module in a start
section, with optional ports, then an optional list of module
@@ -2049,8 +2015,12 @@ module : attribute_list_opt module_start IDENTIFIER
module_port_list_opt
module_attribute_foreign ';'
{ pform_module_set_ports($6); }
- timeunits_declaration_opt
- module_item_list_opt
+ local_timeunit_prec_decl_opt
+ { have_timeunit_decl = true; // Every thing past here is
+ have_timeprec_decl = true; // a check!
+ pform_check_timeunit_prec();
+ }
+ module_item_list_opt
K_endmodule
{ Module::UCDriveType ucd;
switch (uc_drive) {
@@ -2067,8 +2037,9 @@ module : attribute_list_opt module_start IDENTIFIER
}
pform_endmodule($3, in_celldefine, ucd);
delete[]$3;
+ have_timeunit_decl = false; // We will allow decls again.
+ have_timeprec_decl = false;
}
-
;
module_start : K_module | K_macromodule ;
@@ -2527,8 +2498,12 @@ module_item
}
| KK_attribute '(' error ')' ';'
{ yyerror(@1, "error: Malformed $attribute parameter list."); }
- | timeunits_declaration_check
- ;
+
+ | K_timeunit_check TIME_LITERAL ';'
+ { pform_set_timeunit($2, true, true); }
+ | K_timeprecision_check TIME_LITERAL ';'
+ { pform_set_timeprecision($2, true, true); }
+ ;
automatic_opt
: K_automatic { $$ = true; }
View
@@ -70,5 +70,11 @@ extern unsigned long based_size;
extern bool in_celldefine;
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
extern UCDriveType uc_drive;
+/*
+ * Flags to control if we are declaring or checking a timeunit or
+ * timeprecision statement.
+ */
+extern bool have_timeunit_decl;
+extern bool have_timeprec_decl;
#endif
Oops, something went wrong.

0 comments on commit 9dce649

Please sign in to comment.