Support compressed assignment statements for genvar loops
SystemVerilog supports using compressed assignment operators for the genvar for loop variable update. Add support for this in a similar way as increment/decrement operators by transforming the statement to its uncompressed equivalent. E.g. `x += y` gets transformed to `x = x + y`. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
3438078c90
commit
410c8207ef
76
parse.y
76
parse.y
|
|
@ -704,6 +704,8 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
|
||||||
|
|
||||||
%type <package> package_scope
|
%type <package> package_scope
|
||||||
|
|
||||||
|
%type <letter> compressed_operator
|
||||||
|
|
||||||
%token K_TAND
|
%token K_TAND
|
||||||
%nonassoc K_PLUS_EQ K_MINUS_EQ K_MUL_EQ K_DIV_EQ K_MOD_EQ K_AND_EQ K_OR_EQ
|
%nonassoc K_PLUS_EQ K_MINUS_EQ K_MUL_EQ K_DIV_EQ K_MOD_EQ K_AND_EQ K_OR_EQ
|
||||||
%nonassoc K_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ K_NB_TRIGGER
|
%nonassoc K_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ K_NB_TRIGGER
|
||||||
|
|
@ -1495,6 +1497,10 @@ genvar_iteration /* IEEE1800-2012: A.4.2 */
|
||||||
{ $$.text = $1;
|
{ $$.text = $1;
|
||||||
$$.expr = $3;
|
$$.expr = $3;
|
||||||
}
|
}
|
||||||
|
| IDENTIFIER compressed_operator expression
|
||||||
|
{ $$.text = $1;
|
||||||
|
$$.expr = pform_genvar_compressed(@1, $1, $2, $3);;
|
||||||
|
}
|
||||||
| IDENTIFIER K_INCR
|
| IDENTIFIER K_INCR
|
||||||
{ $$.text = $1;
|
{ $$.text = $1;
|
||||||
$$.expr = pform_genvar_inc_dec(@1, $1, true);
|
$$.expr = pform_genvar_inc_dec(@1, $1, true);
|
||||||
|
|
@ -6633,63 +6639,27 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
compressed_operator
|
||||||
|
: K_PLUS_EQ { $$ = '+'; }
|
||||||
|
| K_MINUS_EQ { $$ = '-'; }
|
||||||
|
| K_MUL_EQ { $$ = '*'; }
|
||||||
|
| K_DIV_EQ { $$ = '/'; }
|
||||||
|
| K_MOD_EQ { $$ = '%'; }
|
||||||
|
| K_AND_EQ { $$ = '&'; }
|
||||||
|
| K_OR_EQ { $$ = '|'; }
|
||||||
|
| K_XOR_EQ { $$ = '^'; }
|
||||||
|
| K_LS_EQ { $$ = 'l'; }
|
||||||
|
| K_RS_EQ { $$ = 'r'; }
|
||||||
|
| K_RSS_EQ { $$ = 'R'; }
|
||||||
|
;
|
||||||
|
|
||||||
compressed_statement
|
compressed_statement
|
||||||
: lpvalue K_PLUS_EQ expression
|
: lpvalue compressed_operator expression
|
||||||
{ PAssign*tmp = new PAssign($1, '+', $3);
|
{ PAssign*tmp = new PAssign($1, $2, $3);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| lpvalue K_MINUS_EQ expression
|
;
|
||||||
{ PAssign*tmp = new PAssign($1, '-', $3);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| lpvalue K_MUL_EQ expression
|
|
||||||
{ PAssign*tmp = new PAssign($1, '*', $3);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| lpvalue K_DIV_EQ expression
|
|
||||||
{ PAssign*tmp = new PAssign($1, '/', $3);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| lpvalue K_MOD_EQ expression
|
|
||||||
{ PAssign*tmp = new PAssign($1, '%', $3);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| lpvalue K_AND_EQ expression
|
|
||||||
{ PAssign*tmp = new PAssign($1, '&', $3);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| lpvalue K_OR_EQ expression
|
|
||||||
{ PAssign*tmp = new PAssign($1, '|', $3);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| lpvalue K_XOR_EQ expression
|
|
||||||
{ PAssign*tmp = new PAssign($1, '^', $3);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| lpvalue K_LS_EQ expression
|
|
||||||
{ PAssign *tmp = new PAssign($1, 'l', $3);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| lpvalue K_RS_EQ expression
|
|
||||||
{ PAssign*tmp = new PAssign($1, 'r', $3);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| lpvalue K_RSS_EQ expression
|
|
||||||
{ PAssign *tmp = new PAssign($1, 'R', $3);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
statement_or_null_list_opt
|
statement_or_null_list_opt
|
||||||
|
|
|
||||||
24
pform.cc
24
pform.cc
|
|
@ -2873,6 +2873,30 @@ PExpr* pform_genvar_inc_dec(const struct vlltype&loc, const char*name, bool inc_
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PExpr* pform_genvar_compressed(const struct vlltype &loc, const char *name,
|
||||||
|
char op, PExpr *rval)
|
||||||
|
{
|
||||||
|
pform_requires_sv(loc, "Compressed assignment operator");
|
||||||
|
|
||||||
|
PExpr *lval = new PEIdent(lex_strings.make(name));
|
||||||
|
FILE_NAME(lval, loc);
|
||||||
|
|
||||||
|
PExpr *expr;
|
||||||
|
switch (op) {
|
||||||
|
case 'l':
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
expr = new PEBShift(op, lval, rval);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
expr = new PEBinary(op, lval, rval);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
FILE_NAME(expr, loc);
|
||||||
|
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
void pform_set_attrib(perm_string name, perm_string key, char*value)
|
void pform_set_attrib(perm_string name, perm_string key, char*value)
|
||||||
{
|
{
|
||||||
if (PWire*cur = lexical_scope->wires_find(name)) {
|
if (PWire*cur = lexical_scope->wires_find(name)) {
|
||||||
|
|
|
||||||
3
pform.h
3
pform.h
|
|
@ -477,6 +477,9 @@ extern PAssign* pform_compressed_assign_from_inc_dec(const struct vlltype&loc,
|
||||||
extern PExpr* pform_genvar_inc_dec(const struct vlltype&loc, const char*name,
|
extern PExpr* pform_genvar_inc_dec(const struct vlltype&loc, const char*name,
|
||||||
bool inc_flag);
|
bool inc_flag);
|
||||||
|
|
||||||
|
extern PExpr* pform_genvar_compressed(const struct vlltype &loc,
|
||||||
|
const char *name, char op, PExpr *rval);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are functions that the outside-the-parser code uses the do
|
* These are functions that the outside-the-parser code uses the do
|
||||||
* interesting things to the Verilog. The parse function reads and
|
* interesting things to the Verilog. The parse function reads and
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue