Add support for local genvar declaration in generate loops.
As requested in GitHub issue #304.
This commit is contained in:
parent
0023804777
commit
33b822d997
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2019 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2006-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
|
||||
|
|
@ -26,6 +26,7 @@ PGenerate::PGenerate(LexicalScope*parent, unsigned id)
|
|||
{
|
||||
direct_nested_ = false;
|
||||
scheme_type = GS_NONE;
|
||||
local_index = false;
|
||||
loop_init = 0;
|
||||
loop_test = 0;
|
||||
loop_step = 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_PGenerate_H
|
||||
#define IVL_PGenerate_H
|
||||
/*
|
||||
* Copyright (c) 2006-2019 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2006-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
|
||||
|
|
@ -71,6 +71,9 @@ class PGenerate : public PNamedItem, public LexicalScope {
|
|||
|
||||
// generate loops have an index variable and three
|
||||
// expressions: for (index = <init>; <test>; index=<step>)
|
||||
// the index is local if it was declared in the init expression,
|
||||
// e.g. for (genvar index = <init>; <test>; index=<step>)
|
||||
bool local_index;
|
||||
perm_string loop_index;
|
||||
PExpr*loop_init;
|
||||
PExpr*loop_test;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -899,17 +899,19 @@ bool PGenerate::generate_scope(Design*des, NetScope*container)
|
|||
*/
|
||||
bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
{
|
||||
// Check that the loop_index variable was declared in a
|
||||
// genvar statement.
|
||||
NetScope*cscope = container;
|
||||
while (cscope && !cscope->find_genvar(loop_index))
|
||||
cscope = cscope->parent();
|
||||
if (!cscope) {
|
||||
cerr << get_fileline() << ": error: genvar is missing for "
|
||||
"generate \"loop\" variable '" << loop_index << "'."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
if (!local_index) {
|
||||
// Check that the loop_index variable was declared in a
|
||||
// genvar statement.
|
||||
NetScope*cscope = container;
|
||||
while (cscope && !cscope->find_genvar(loop_index))
|
||||
cscope = cscope->parent();
|
||||
if (!cscope) {
|
||||
cerr << get_fileline() << ": error: genvar is missing for "
|
||||
"generate \"loop\" variable '" << loop_index << "'."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// We're going to need a genvar...
|
||||
|
|
|
|||
7
parse.y
7
parse.y
|
|
@ -567,7 +567,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
|
|||
%type <number> number pos_neg_number
|
||||
%type <flag> signing unsigned_signed_opt signed_unsigned_opt
|
||||
%type <flag> import_export
|
||||
%type <flag> K_packed_opt K_reg_opt K_static_opt K_virtual_opt
|
||||
%type <flag> K_genvar_opt K_packed_opt K_reg_opt K_static_opt K_virtual_opt
|
||||
%type <flag> udp_reg_opt edge_operator
|
||||
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
|
||||
%type <letter> udp_input_sym udp_output_sym
|
||||
|
|
@ -5275,10 +5275,10 @@ module_item
|
|||
| K_genvar list_of_identifiers ';'
|
||||
{ pform_genvars(@1, $2); }
|
||||
|
||||
| K_for '(' IDENTIFIER '=' expression ';'
|
||||
| K_for '(' K_genvar_opt IDENTIFIER '=' expression ';'
|
||||
expression ';'
|
||||
genvar_iteration ')'
|
||||
{ pform_start_generate_for(@1, $3, $5, $7, $9.text, $9.expr); }
|
||||
{ pform_start_generate_for(@2, $3, $4, $6, $8, $10.text, $10.expr); }
|
||||
generate_block
|
||||
{ pform_endgenerate(false); }
|
||||
|
||||
|
|
@ -7341,6 +7341,7 @@ unique_priority
|
|||
presence is significant. This is a fairly common pattern so
|
||||
collect those rules here. */
|
||||
|
||||
K_genvar_opt : K_genvar { $$ = true; } | { $$ = false; } ;
|
||||
K_packed_opt : K_packed { $$ = true; } | { $$ = false; } ;
|
||||
K_reg_opt : K_reg { $$ = true; } | { $$ = false; } ;
|
||||
K_static_opt : K_static { $$ = true; } | { $$ = false; } ;
|
||||
|
|
|
|||
2
pform.cc
2
pform.cc
|
|
@ -1486,6 +1486,7 @@ void pform_genvars(const struct vlltype&li, list<perm_string>*names)
|
|||
}
|
||||
|
||||
void pform_start_generate_for(const struct vlltype&li,
|
||||
bool local_index,
|
||||
char*ident1, PExpr*init,
|
||||
PExpr*test,
|
||||
char*ident2, PExpr*next)
|
||||
|
|
@ -1499,6 +1500,7 @@ void pform_start_generate_for(const struct vlltype&li,
|
|||
|
||||
pform_cur_generate->scheme_type = PGenerate::GS_LOOP;
|
||||
|
||||
pform_cur_generate->local_index = local_index;
|
||||
pform_cur_generate->loop_index = lex_strings.make(ident1);
|
||||
pform_cur_generate->loop_init = init;
|
||||
pform_cur_generate->loop_test = test;
|
||||
|
|
|
|||
1
pform.h
1
pform.h
|
|
@ -292,6 +292,7 @@ extern verinum* pform_verinum_with_size(verinum*s, verinum*val,
|
|||
extern void pform_genvars(const struct vlltype&li, list<perm_string>*names);
|
||||
|
||||
extern void pform_start_generate_for(const struct vlltype&li,
|
||||
bool local_index,
|
||||
char*ident1,
|
||||
PExpr*init,
|
||||
PExpr*test,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2019 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2020 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
|
|
@ -108,6 +108,9 @@ static bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
while (scope) {
|
||||
if (scope->genvar_tmp.str() && path_tail.name == scope->genvar_tmp)
|
||||
return false;
|
||||
|
||||
if (path_tail.name == "#") {
|
||||
cerr << li->get_fileline() << ": sorry: "
|
||||
<< "Implicit class handle \"super\" not supported." << endl;
|
||||
|
|
|
|||
Loading…
Reference in New Issue