Add support for increment/decrement operators in generate loop iteration.
As requested in GitHub issue #303.
This commit is contained in:
parent
20d7309ec2
commit
0023804777
26
parse.y
26
parse.y
|
|
@ -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); }
|
||||
|
||||
|
|
|
|||
21
pform.cc
21
pform.cc
|
|
@ -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)) {
|
||||
|
|
|
|||
9
pform.h
9
pform.h
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue