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
74
parse.y
74
parse.y
|
|
@ -704,6 +704,8 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
|
|||
|
||||
%type <package> package_scope
|
||||
|
||||
%type <letter> compressed_operator
|
||||
|
||||
%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_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;
|
||||
$$.expr = $3;
|
||||
}
|
||||
| IDENTIFIER compressed_operator expression
|
||||
{ $$.text = $1;
|
||||
$$.expr = pform_genvar_compressed(@1, $1, $2, $3);;
|
||||
}
|
||||
| IDENTIFIER K_INCR
|
||||
{ $$.text = $1;
|
||||
$$.expr = pform_genvar_inc_dec(@1, $1, true);
|
||||
|
|
@ -6633,59 +6639,23 @@ 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
|
||||
: lpvalue K_PLUS_EQ expression
|
||||
{ PAssign*tmp = new PAssign($1, '+', $3);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = 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);
|
||||
: lpvalue compressed_operator expression
|
||||
{ PAssign*tmp = new PAssign($1, $2, $3);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
|
|||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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,
|
||||
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
|
||||
* interesting things to the Verilog. The parse function reads and
|
||||
|
|
|
|||
Loading…
Reference in New Issue