Add support for VHDL for-generate
This commit is contained in:
parent
5724f71339
commit
98d928f6e0
|
|
@ -46,6 +46,29 @@ Architecture::Statement::~Statement()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GenerateStatement::GenerateStatement(perm_string gname,
|
||||||
|
std::list<Architecture::Statement*>&s)
|
||||||
|
: name_(gname)
|
||||||
|
{
|
||||||
|
statements_.splice(statements_.end(), s);
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateStatement::~GenerateStatement()
|
||||||
|
{
|
||||||
|
for_each(statements_.begin(), statements_.end(), ::delete_object<Architecture::Statement>());
|
||||||
|
}
|
||||||
|
|
||||||
|
ForGenerate::ForGenerate(perm_string gname, perm_string genvar,
|
||||||
|
range_t*rang, std::list<Architecture::Statement*>&s)
|
||||||
|
: GenerateStatement(gname, s), genvar_(genvar),
|
||||||
|
lsb_(rang->lsb()), msb_(rang->msb())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ForGenerate::~ForGenerate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
SignalAssignment::SignalAssignment(ExpName*name, list<Expression*>&rv)
|
SignalAssignment::SignalAssignment(ExpName*name, list<Expression*>&rv)
|
||||||
: lval_(name)
|
: lval_(name)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ class ExpName;
|
||||||
class SequentialStmt;
|
class SequentialStmt;
|
||||||
class Signal;
|
class Signal;
|
||||||
class named_expr_t;
|
class named_expr_t;
|
||||||
|
class range_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Architecture class carries the contents (name, statements,
|
* The Architecture class carries the contents (name, statements,
|
||||||
|
|
@ -87,6 +88,46 @@ class Architecture : public Scope, public LineInfo {
|
||||||
private: // Not implemented
|
private: // Not implemented
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a base class for various generate statement types. It holds
|
||||||
|
* the generate statement name, and a list of substatements.
|
||||||
|
*/
|
||||||
|
class GenerateStatement : public Architecture::Statement {
|
||||||
|
|
||||||
|
public:
|
||||||
|
GenerateStatement(perm_string gname, std::list<Architecture::Statement*>&s);
|
||||||
|
~GenerateStatement();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline perm_string get_name() { return name_; }
|
||||||
|
|
||||||
|
int elaborate_statements(Entity*ent, Architecture*arc);
|
||||||
|
int emit_statements(ostream&out, Entity*ent, Architecture*arc);
|
||||||
|
void dump_statements(ostream&out, int indent) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
perm_string name_;
|
||||||
|
std::list<Architecture::Statement*> statements_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ForGenerate : public GenerateStatement {
|
||||||
|
|
||||||
|
public:
|
||||||
|
ForGenerate(perm_string gname, perm_string genvar,
|
||||||
|
range_t*rang, std::list<Architecture::Statement*>&s);
|
||||||
|
~ForGenerate();
|
||||||
|
|
||||||
|
int elaborate(Entity*ent, Architecture*arc);
|
||||||
|
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||||
|
void dump(ostream&out, int ident =0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
perm_string genvar_;
|
||||||
|
Expression*lsb_;
|
||||||
|
Expression*msb_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The SignalAssignment class represents the
|
* The SignalAssignment class represents the
|
||||||
* concurrent_signal_assignment that is placed in an architecture.
|
* concurrent_signal_assignment that is placed in an architecture.
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,10 @@ void Architecture::Statement::dump(ostream&out, int indent) const
|
||||||
|
|
||||||
void ComponentInstantiation::dump(ostream&out, int indent) const
|
void ComponentInstantiation::dump(ostream&out, int indent) const
|
||||||
{
|
{
|
||||||
out << setw(indent) << "" << "Component Instantiation file=" << get_fileline() << endl;
|
out << setw(indent) << "" << "Component Instantiation "
|
||||||
|
<< "instance=" << iname_
|
||||||
|
<< " of component=" << cname_
|
||||||
|
<< ", file=" << get_fileline() << endl;
|
||||||
|
|
||||||
for (map<perm_string,Expression*>::const_iterator cur = port_map_.begin()
|
for (map<perm_string,Expression*>::const_iterator cur = port_map_.begin()
|
||||||
; cur != port_map_.end() ; ++cur) {
|
; cur != port_map_.end() ; ++cur) {
|
||||||
|
|
@ -60,6 +63,26 @@ void ComponentInstantiation::dump(ostream&out, int indent) const
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenerateStatement::dump_statements(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
for (list<Architecture::Statement*>::const_iterator cur = statements_.begin()
|
||||||
|
; cur != statements_.end() ; ++cur) {
|
||||||
|
Statement*curp = *cur;
|
||||||
|
curp->dump(out, indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForGenerate::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
out << setw(indent) << "" << "for " << genvar_
|
||||||
|
<< " in" << endl;
|
||||||
|
msb_->dump(out, indent+4);
|
||||||
|
lsb_->dump(out, indent+4);
|
||||||
|
out << setw(indent) << "" << "generate" << endl;
|
||||||
|
dump_statements(out, indent+4);
|
||||||
|
out << setw(indent) << "" << "end generate" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
void SignalAssignment::dump(ostream&out, int indent) const
|
void SignalAssignment::dump(ostream&out, int indent) const
|
||||||
{
|
{
|
||||||
out << setw(indent) << "" << "SignalAssignment file=" << get_fileline() << endl;
|
out << setw(indent) << "" << "SignalAssignment file=" << get_fileline() << endl;
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,24 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc)
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GenerateStatement::elaborate_statements(Entity*ent, Architecture*arc)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
for (list<Architecture::Statement*>::iterator cur = statements_.begin()
|
||||||
|
; cur != statements_.end() ; ++cur) {
|
||||||
|
Architecture::Statement*curp = *cur;
|
||||||
|
errors += curp->elaborate(ent, arc);
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ForGenerate::elaborate(Entity*ent, Architecture*arc)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
errors += elaborate_statements(ent, arc);
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This method attempts to rewrite the process content as an
|
* This method attempts to rewrite the process content as an
|
||||||
* always-@(n-edge <expr>) version of the same statement. This makes
|
* always-@(n-edge <expr>) version of the same statement. This makes
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,35 @@ int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GenerateStatement::emit_statements(ostream&out, Entity*ent, Architecture*arc)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
for (list<Architecture::Statement*>::iterator cur = statements_.begin()
|
||||||
|
; cur != statements_.end() ; ++cur) {
|
||||||
|
Architecture::Statement*curp = *cur;
|
||||||
|
errors += curp->emit(out, ent, arc);
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ForGenerate::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
out << "generate genvar \\" << genvar_ << " ;" << endl;
|
||||||
|
out << "for (\\" << genvar_ << " = ";
|
||||||
|
errors += lsb_->emit(out, ent, arc);
|
||||||
|
out << "; \\" << genvar_ << " <= ";
|
||||||
|
errors += msb_->emit(out, ent, arc);
|
||||||
|
out << "; \\" << genvar_ << " = \\" << genvar_ << " + 1)"
|
||||||
|
<< " begin : \\" << get_name() << endl;
|
||||||
|
|
||||||
|
errors += emit_statements(out, ent, arc);
|
||||||
|
|
||||||
|
out << "end" << endl;
|
||||||
|
out << "endgenerate" << endl;
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
|
||||||
|
|
@ -239,8 +239,8 @@ const VType*parse_type_by_name(perm_string name)
|
||||||
%type <component_specification> component_specification
|
%type <component_specification> component_specification
|
||||||
|
|
||||||
%type <arch_statement> concurrent_statement component_instantiation_statement concurrent_signal_assignment_statement
|
%type <arch_statement> concurrent_statement component_instantiation_statement concurrent_signal_assignment_statement
|
||||||
%type <arch_statement> process_statement
|
%type <arch_statement> for_generate_statement process_statement
|
||||||
%type <arch_statement_list> architecture_statement_part
|
%type <arch_statement_list> architecture_statement_part generate_statement_body
|
||||||
|
|
||||||
%type <choice> choice
|
%type <choice> choice
|
||||||
%type <choice_list> choices
|
%type <choice_list> choices
|
||||||
|
|
@ -633,6 +633,7 @@ concurrent_signal_assignment_statement
|
||||||
concurrent_statement
|
concurrent_statement
|
||||||
: component_instantiation_statement
|
: component_instantiation_statement
|
||||||
| concurrent_signal_assignment_statement
|
| concurrent_signal_assignment_statement
|
||||||
|
| for_generate_statement
|
||||||
| process_statement
|
| process_statement
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -955,6 +956,31 @@ factor
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
for_generate_statement
|
||||||
|
: IDENTIFIER ':' K_for IDENTIFIER K_in range
|
||||||
|
K_generate generate_statement_body
|
||||||
|
K_end K_generate identifier_opt ';'
|
||||||
|
{ perm_string name = lex_strings.make($1);
|
||||||
|
perm_string gvar = lex_strings.make($4);
|
||||||
|
ForGenerate*tmp = new ForGenerate(name, gvar, $6, *$8);
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
|
||||||
|
if ($11 && name != $11) {
|
||||||
|
errormsg(@1, "for-generate name %s does not match closing name %s\n",
|
||||||
|
name.str(), $11);
|
||||||
|
}
|
||||||
|
delete $1;
|
||||||
|
delete $4;
|
||||||
|
delete $8;
|
||||||
|
delete $11;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
generate_statement_body
|
||||||
|
: architecture_statement_part { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
generic_clause_opt
|
generic_clause_opt
|
||||||
: generic_clause
|
: generic_clause
|
||||||
{ $$ = $1;}
|
{ $$ = $1;}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue