Add support for increment/decrement operators in generate loop iteration.

As requested in GitHub issue #303.
This commit is contained in:
Martin Whitaker 2020-01-30 21:45:04 +00:00
parent 20d7309ec2
commit 0023804777
3 changed files with 51 additions and 5 deletions

26
parse.y
View File

@ -1,7 +1,7 @@
%{
/*
* Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -448,6 +448,11 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
list<PExpr*>*exprs;
} class_declaration_extends;
struct {
char*text;
PExpr*expr;
} genvar_iter;
verinum* number;
verireal* realtime;
@ -680,6 +685,8 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <case_quality> unique_priority
%type <genvar_iter> genvar_iteration
%token K_TAND
%right K_PLUS_EQ K_MINUS_EQ K_MUL_EQ K_DIV_EQ K_MOD_EQ K_AND_EQ K_OR_EQ
%right K_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ
@ -1492,6 +1499,19 @@ function_declaration /* IEEE1800-2005: A.2.6 */
;
genvar_iteration /* IEEE1800-2012: A.4.2 */
: IDENTIFIER '=' expression
{ $$ = { $1, $3 }; }
| IDENTIFIER K_INCR
{ $$ = { $1, pform_genvar_inc_dec(@1, $1, true) }; }
| IDENTIFIER K_DECR
{ $$ = { $1, pform_genvar_inc_dec(@1, $1, false) }; }
| K_INCR IDENTIFIER
{ $$ = { $2, pform_genvar_inc_dec(@1, $2, true) }; }
| K_DECR IDENTIFIER
{ $$ = { $2, pform_genvar_inc_dec(@1, $2, false) }; }
;
import_export /* IEEE1800-2012: A.2.9 */
: K_import { $$ = true; }
| K_export { $$ = false; }
@ -5257,8 +5277,8 @@ module_item
| K_for '(' IDENTIFIER '=' expression ';'
expression ';'
IDENTIFIER '=' expression ')'
{ pform_start_generate_for(@1, $3, $5, $7, $9, $11); }
genvar_iteration ')'
{ pform_start_generate_for(@1, $3, $5, $7, $9.text, $9.expr); }
generate_block
{ pform_endgenerate(false); }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -3079,6 +3079,25 @@ PAssign* pform_compressed_assign_from_inc_dec(const struct vlltype&loc, PExpr*ex
return tmp;
}
PExpr* pform_genvar_inc_dec(const struct vlltype&loc, const char*name, bool inc_flag)
{
if (!gn_system_verilog()) {
cerr << loc << ": error: Increment/decrement operators "
"require SystemVerilog." << endl;
error_count += 1;
}
PExpr*lval = new PEIdent(lex_strings.make(name));
PExpr*rval = new PENumber(new verinum((uint64_t)1, 1));
FILE_NAME(lval, loc);
FILE_NAME(rval, loc);
PEBinary*tmp = new PEBinary(inc_flag ? '+' : '-', lval, rval);
FILE_NAME(tmp, loc);
return tmp;
}
void pform_set_attrib(perm_string name, perm_string key, char*value)
{
if (PWire*cur = lexical_scope->wires_find(name)) {

View File

@ -1,7 +1,7 @@
#ifndef IVL_pform_H
#define IVL_pform_H
/*
* Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2020 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -519,6 +519,13 @@ extern std::vector<pform_tf_port_t>*pform_make_task_ports(const struct vlltype&l
extern PAssign* pform_compressed_assign_from_inc_dec(const struct vlltype&loc,
PExpr*exp);
/*
* The parser uses this function to convert a genvar increment/decrement
* expression to the equivalent binary add/subtract expression.
*/
extern PExpr* pform_genvar_inc_dec(const struct vlltype&loc, const char*name,
bool inc_flag);
/*
* These are functions that the outside-the-parser code uses the do
* interesting things to the Verilog. The parse function reads and