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
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* 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;
|
direct_nested_ = false;
|
||||||
scheme_type = GS_NONE;
|
scheme_type = GS_NONE;
|
||||||
|
local_index = false;
|
||||||
loop_init = 0;
|
loop_init = 0;
|
||||||
loop_test = 0;
|
loop_test = 0;
|
||||||
loop_step = 0;
|
loop_step = 0;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef IVL_PGenerate_H
|
#ifndef IVL_PGenerate_H
|
||||||
#define 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
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* 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
|
// generate loops have an index variable and three
|
||||||
// expressions: for (index = <init>; <test>; index=<step>)
|
// 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;
|
perm_string loop_index;
|
||||||
PExpr*loop_init;
|
PExpr*loop_init;
|
||||||
PExpr*loop_test;
|
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)
|
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
|
|
@ -899,6 +899,7 @@ bool PGenerate::generate_scope(Design*des, NetScope*container)
|
||||||
*/
|
*/
|
||||||
bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||||
{
|
{
|
||||||
|
if (!local_index) {
|
||||||
// Check that the loop_index variable was declared in a
|
// Check that the loop_index variable was declared in a
|
||||||
// genvar statement.
|
// genvar statement.
|
||||||
NetScope*cscope = container;
|
NetScope*cscope = container;
|
||||||
|
|
@ -911,6 +912,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We're going to need a genvar...
|
// We're going to need a genvar...
|
||||||
int genvar;
|
int 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 <number> number pos_neg_number
|
||||||
%type <flag> signing unsigned_signed_opt signed_unsigned_opt
|
%type <flag> signing unsigned_signed_opt signed_unsigned_opt
|
||||||
%type <flag> import_export
|
%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 <flag> udp_reg_opt edge_operator
|
||||||
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
|
%type <drive> drive_strength drive_strength_opt dr_strength0 dr_strength1
|
||||||
%type <letter> udp_input_sym udp_output_sym
|
%type <letter> udp_input_sym udp_output_sym
|
||||||
|
|
@ -5275,10 +5275,10 @@ module_item
|
||||||
| K_genvar list_of_identifiers ';'
|
| K_genvar list_of_identifiers ';'
|
||||||
{ pform_genvars(@1, $2); }
|
{ pform_genvars(@1, $2); }
|
||||||
|
|
||||||
| K_for '(' IDENTIFIER '=' expression ';'
|
| K_for '(' K_genvar_opt IDENTIFIER '=' expression ';'
|
||||||
expression ';'
|
expression ';'
|
||||||
genvar_iteration ')'
|
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
|
generate_block
|
||||||
{ pform_endgenerate(false); }
|
{ pform_endgenerate(false); }
|
||||||
|
|
||||||
|
|
@ -7341,6 +7341,7 @@ unique_priority
|
||||||
presence is significant. This is a fairly common pattern so
|
presence is significant. This is a fairly common pattern so
|
||||||
collect those rules here. */
|
collect those rules here. */
|
||||||
|
|
||||||
|
K_genvar_opt : K_genvar { $$ = true; } | { $$ = false; } ;
|
||||||
K_packed_opt : K_packed { $$ = true; } | { $$ = false; } ;
|
K_packed_opt : K_packed { $$ = true; } | { $$ = false; } ;
|
||||||
K_reg_opt : K_reg { $$ = true; } | { $$ = false; } ;
|
K_reg_opt : K_reg { $$ = true; } | { $$ = false; } ;
|
||||||
K_static_opt : K_static { $$ = 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,
|
void pform_start_generate_for(const struct vlltype&li,
|
||||||
|
bool local_index,
|
||||||
char*ident1, PExpr*init,
|
char*ident1, PExpr*init,
|
||||||
PExpr*test,
|
PExpr*test,
|
||||||
char*ident2, PExpr*next)
|
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->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_index = lex_strings.make(ident1);
|
||||||
pform_cur_generate->loop_init = init;
|
pform_cur_generate->loop_init = init;
|
||||||
pform_cur_generate->loop_test = test;
|
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_genvars(const struct vlltype&li, list<perm_string>*names);
|
||||||
|
|
||||||
extern void pform_start_generate_for(const struct vlltype&li,
|
extern void pform_start_generate_for(const struct vlltype&li,
|
||||||
|
bool local_index,
|
||||||
char*ident1,
|
char*ident1,
|
||||||
PExpr*init,
|
PExpr*init,
|
||||||
PExpr*test,
|
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)
|
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* 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) {
|
while (scope) {
|
||||||
|
if (scope->genvar_tmp.str() && path_tail.name == scope->genvar_tmp)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (path_tail.name == "#") {
|
if (path_tail.name == "#") {
|
||||||
cerr << li->get_fileline() << ": sorry: "
|
cerr << li->get_fileline() << ": sorry: "
|
||||||
<< "Implicit class handle \"super\" not supported." << endl;
|
<< "Implicit class handle \"super\" not supported." << endl;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue