Add support for VHDL's loop statements
This commit is contained in:
parent
743cb234c0
commit
60deb775ca
|
|
@ -346,3 +346,10 @@ void named_expr_t::dump(ostream&out, int indent) const
|
||||||
out << setw(indent) << "" << name_ << "=>";
|
out << setw(indent) << "" << name_ << "=>";
|
||||||
expr_->dump(out, indent);
|
expr_->dump(out, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void range_t::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
left_->dump(out, indent);
|
||||||
|
out << setw(indent) << "" << (direction_ ? "downto" : "to");
|
||||||
|
right_->dump(out, indent);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,8 @@ const VType*parse_type_by_name(perm_string name)
|
||||||
|
|
||||||
const VType* vtype;
|
const VType* vtype;
|
||||||
|
|
||||||
|
range_t* range;
|
||||||
|
|
||||||
std::list<InterfacePort*>* interface_list;
|
std::list<InterfacePort*>* interface_list;
|
||||||
|
|
||||||
Architecture::Statement* arch_statement;
|
Architecture::Statement* arch_statement;
|
||||||
|
|
@ -211,7 +213,7 @@ const VType*parse_type_by_name(perm_string name)
|
||||||
%type <vtype> subtype_indication
|
%type <vtype> subtype_indication
|
||||||
|
|
||||||
%type <text> architecture_body_start package_declaration_start
|
%type <text> architecture_body_start package_declaration_start
|
||||||
%type <text> identifier_opt logical_name suffix
|
%type <text> identifier_opt identifier_colon_opt logical_name suffix
|
||||||
%type <name_list> logical_name_list identifier_list
|
%type <name_list> logical_name_list identifier_list
|
||||||
%type <compound_name> prefix selected_name
|
%type <compound_name> prefix selected_name
|
||||||
%type <compound_name_list> selected_names use_clause
|
%type <compound_name_list> selected_names use_clause
|
||||||
|
|
@ -219,6 +221,9 @@ const VType*parse_type_by_name(perm_string name)
|
||||||
%type <sequ_list> sequence_of_statements if_statement_else
|
%type <sequ_list> sequence_of_statements if_statement_else
|
||||||
%type <sequ> sequential_statement if_statement signal_assignment_statement
|
%type <sequ> sequential_statement if_statement signal_assignment_statement
|
||||||
%type <sequ> case_statement procedure_call procedure_call_statement
|
%type <sequ> case_statement procedure_call procedure_call_statement
|
||||||
|
%type <sequ> loop_statement
|
||||||
|
|
||||||
|
%type <range> range
|
||||||
|
|
||||||
%type <case_alt> case_statement_alternative
|
%type <case_alt> case_statement_alternative
|
||||||
%type <case_alt_list> case_statement_alternative_list
|
%type <case_alt_list> case_statement_alternative_list
|
||||||
|
|
@ -832,6 +837,7 @@ identifier_list
|
||||||
|
|
||||||
identifier_opt : IDENTIFIER { $$ = $1; } | { $$ = 0; } ;
|
identifier_opt : IDENTIFIER { $$ = $1; } | { $$ = 0; } ;
|
||||||
|
|
||||||
|
identifier_colon_opt : IDENTIFIER ':' { $$ = $1; } | { $$ = 0; };
|
||||||
|
|
||||||
if_statement
|
if_statement
|
||||||
: K_if expression K_then sequence_of_statements
|
: K_if expression K_then sequence_of_statements
|
||||||
|
|
@ -993,6 +999,60 @@ logical_name_list
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
loop_statement
|
||||||
|
: identifier_colon_opt
|
||||||
|
K_while expression_logical K_loop
|
||||||
|
sequence_of_statements
|
||||||
|
K_end K_loop identifier_opt ';'
|
||||||
|
{
|
||||||
|
if($1 && strcmp($1, $8))
|
||||||
|
errormsg(@1, "Loop statement name doesn't match closing name.\n");
|
||||||
|
if($1) delete[]$1;
|
||||||
|
if($8) delete[]$8;
|
||||||
|
|
||||||
|
ExpLogical* cond = dynamic_cast<ExpLogical*>($3);
|
||||||
|
if(!cond) {
|
||||||
|
errormsg(@3, "Iteration condition is not a correct logical expression");
|
||||||
|
}
|
||||||
|
WhileLoopStatement* tmp = new WhileLoopStatement(cond, $5);
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
|
||||||
|
sorrymsg(@1, "Loop statements are not supported");
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| identifier_colon_opt K_for
|
||||||
|
IDENTIFIER K_in range K_loop
|
||||||
|
sequence_of_statements
|
||||||
|
K_end K_loop identifier_opt ';'
|
||||||
|
{
|
||||||
|
if($1 && strcmp($1, $10))
|
||||||
|
errormsg(@1, "Loop statement name doesn't match closing name.\n");
|
||||||
|
if($1) delete[] $1;
|
||||||
|
if($10) delete[] $10;
|
||||||
|
|
||||||
|
ForLoopStatement* tmp = new ForLoopStatement(lex_strings.make($3), $5, $7);
|
||||||
|
delete[]$3;
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
|
||||||
|
sorrymsg(@1, "Loop statements are not supported");
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| identifier_colon_opt K_loop
|
||||||
|
sequence_of_statements
|
||||||
|
K_end K_loop identifier_opt ';'
|
||||||
|
{
|
||||||
|
if($1 && strcmp($1, $6))
|
||||||
|
errormsg(@1, "Loop statement name doesn't match closing name.\n");
|
||||||
|
if($1) delete[]$1;
|
||||||
|
if($6) delete[]$6;
|
||||||
|
|
||||||
|
BasicLoopStatement* tmp = new BasicLoopStatement($3);
|
||||||
|
FILE_NAME(tmp, @1);
|
||||||
|
|
||||||
|
sorrymsg(@1, "Loop statements are not supported");
|
||||||
|
$$ = tmp;
|
||||||
|
};
|
||||||
|
|
||||||
mode
|
mode
|
||||||
: K_in { $$ = PORT_IN; }
|
: K_in { $$ = PORT_IN; }
|
||||||
| K_out { $$ = PORT_OUT; }
|
| K_out { $$ = PORT_OUT; }
|
||||||
|
|
@ -1278,6 +1338,13 @@ process_sensitivity_list
|
||||||
| name_list
|
| name_list
|
||||||
{ $$ = $1; }
|
{ $$ = $1; }
|
||||||
;
|
;
|
||||||
|
range
|
||||||
|
: simple_expression direction simple_expression
|
||||||
|
{
|
||||||
|
range_t* tmp = new range_t($1, $3, $2);
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
relation
|
relation
|
||||||
: shift_expression
|
: shift_expression
|
||||||
|
|
@ -1392,6 +1459,7 @@ sequential_statement
|
||||||
| signal_assignment_statement { $$ = $1; }
|
| signal_assignment_statement { $$ = $1; }
|
||||||
| case_statement { $$ = $1; }
|
| case_statement { $$ = $1; }
|
||||||
| procedure_call_statement { $$ = $1; }
|
| procedure_call_statement { $$ = $1; }
|
||||||
|
| loop_statement { $$ = $1; }
|
||||||
| K_null ';' { $$ = 0; }
|
| K_null ';' { $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,4 +66,19 @@ class instant_list_t {
|
||||||
application_domain_t domain_;
|
application_domain_t domain_;
|
||||||
std::list<perm_string>* labels_;
|
std::list<perm_string>* labels_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class range_t {
|
||||||
|
public:
|
||||||
|
range_t(Expression* left, Expression* right, bool dir)
|
||||||
|
: left_(left), right_(right), direction_(dir) {}
|
||||||
|
~range_t() { delete left_; delete right_; }
|
||||||
|
void dump(ostream&out, int indent) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Expression *left_, *right_;
|
||||||
|
bool direction_;
|
||||||
|
private: //not implemented
|
||||||
|
range_t(const range_t&);
|
||||||
|
range_t operator=(const range_t&);
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -152,3 +152,46 @@ ProcedureCall::~ProcedureCall()
|
||||||
delete cur;
|
delete cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoopStatement::LoopStatement(list<SequentialStmt*>* stmts)
|
||||||
|
{
|
||||||
|
if (stmts) stmts_.splice(stmts_.end(), *stmts);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoopStatement::~LoopStatement()
|
||||||
|
{
|
||||||
|
while(stmts_.size() > 0) {
|
||||||
|
SequentialStmt* cur = stmts_.front();
|
||||||
|
stmts_.pop_front();
|
||||||
|
delete cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ForLoopStatement::ForLoopStatement(perm_string it, range_t* range, list<SequentialStmt*>* stmts)
|
||||||
|
: LoopStatement(stmts), it_(it), range_(range)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ForLoopStatement::~ForLoopStatement()
|
||||||
|
{
|
||||||
|
delete range_;
|
||||||
|
}
|
||||||
|
|
||||||
|
WhileLoopStatement::WhileLoopStatement(ExpLogical* cond, list<SequentialStmt*>* stmts)
|
||||||
|
: LoopStatement(stmts), cond_(cond)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WhileLoopStatement::~WhileLoopStatement()
|
||||||
|
{
|
||||||
|
delete cond_;
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicLoopStatement::BasicLoopStatement(list<SequentialStmt*>* stmts)
|
||||||
|
: LoopStatement(stmts)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicLoopStatement::~BasicLoopStatement()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,8 +145,60 @@ class ProcedureCall : public SequentialStmt {
|
||||||
int elaborate(Entity*ent, Architecture*arc);
|
int elaborate(Entity*ent, Architecture*arc);
|
||||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||||
void dump(ostream&out, int indent) const;
|
void dump(ostream&out, int indent) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
std::list<named_expr_t*>* param_list_;
|
std::list<named_expr_t*>* param_list_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LoopStatement : public SequentialStmt {
|
||||||
|
public:
|
||||||
|
LoopStatement(list<SequentialStmt*>*);
|
||||||
|
virtual ~LoopStatement();
|
||||||
|
|
||||||
|
int elaborate(Entity*ent, Architecture*arc) = 0;
|
||||||
|
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||||
|
void dump(ostream&out, int indent) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::list<SequentialStmt*> stmts_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WhileLoopStatement : public LoopStatement {
|
||||||
|
public:
|
||||||
|
WhileLoopStatement(ExpLogical*, list<SequentialStmt*>*);
|
||||||
|
~WhileLoopStatement();
|
||||||
|
|
||||||
|
int elaborate(Entity*ent, Architecture*arc);
|
||||||
|
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||||
|
void dump(ostream&out, int indent) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ExpLogical* cond_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ForLoopStatement : public LoopStatement {
|
||||||
|
public:
|
||||||
|
ForLoopStatement(perm_string, range_t*, list<SequentialStmt*>*);
|
||||||
|
~ForLoopStatement();
|
||||||
|
|
||||||
|
int elaborate(Entity*ent, Architecture*arc);
|
||||||
|
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||||
|
void dump(ostream&out, int indent) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
perm_string it_;
|
||||||
|
range_t* range_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BasicLoopStatement : public LoopStatement {
|
||||||
|
public:
|
||||||
|
BasicLoopStatement(list<SequentialStmt*>*);
|
||||||
|
~BasicLoopStatement();
|
||||||
|
|
||||||
|
int elaborate(Entity*ent, Architecture*arc);
|
||||||
|
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||||
|
void dump(ostream&out, int indent) const;
|
||||||
|
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -109,3 +109,32 @@ void ProcedureCall::dump(ostream& out, int indent) const
|
||||||
(*it)->dump(out, indent);
|
(*it)->dump(out, indent);
|
||||||
out << ")" << endl;
|
out << ")" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoopStatement::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
for(list<SequentialStmt*>::const_iterator it = stmts_.begin();
|
||||||
|
it != stmts_.end(); ++it)
|
||||||
|
(*it)->dump(out, indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForLoopStatement::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
out << setw(indent) << "" << "ForLoopStatement at file=" << get_fileline() << endl;
|
||||||
|
out << setw(indent) << "" << it_ << " in ";
|
||||||
|
range_->dump(out, indent);
|
||||||
|
LoopStatement::dump(out, indent+2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WhileLoopStatement::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
out << setw(indent) << "" << "WhileLoopStatement at file=" << get_fileline() << endl;
|
||||||
|
out << setw(indent) << "" << "condition: ";
|
||||||
|
cond_->dump(out, indent);
|
||||||
|
LoopStatement::dump(out, indent+2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicLoopStatement::dump(ostream&out, int indent) const
|
||||||
|
{
|
||||||
|
out << setw(indent) << "" << "BasicLoopStatement at file=" << get_fileline() << endl;
|
||||||
|
LoopStatement::dump(out, indent+2);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,3 +93,19 @@ int ProcedureCall::elaborate(Entity*, Architecture*)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ForLoopStatement::elaborate(Entity*entity, Architecture*arc)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WhileLoopStatement::elaborate(Entity*entity, Architecture*arc)
|
||||||
|
{
|
||||||
|
//TODO:check whether there is any wait statement in the statements (there should be)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BasicLoopStatement::elaborate(Entity*entity, Architecture*arc)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,3 +106,35 @@ int ProcedureCall::emit(ostream&out, Entity*, Architecture*)
|
||||||
<< "type=" << typeid(*this).name() << endl;
|
<< "type=" << typeid(*this).name() << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LoopStatement::emit(ostream&out, Entity*entity, Architecture*arc)
|
||||||
|
{
|
||||||
|
out << " // " << get_fileline() << ": internal error: "
|
||||||
|
<< "I don't know how to emit this sequential statement! "
|
||||||
|
<< "type=" << typeid(*this).name() << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ForLoopStatement::emit(ostream&out, Entity*entity, Architecture*arc)
|
||||||
|
{
|
||||||
|
out << " // " << get_fileline() << ": internal error: "
|
||||||
|
<< "I don't know how to emit this sequential statement! "
|
||||||
|
<< "type=" << typeid(*this).name() << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WhileLoopStatement::emit(ostream&out, Entity*entity, Architecture*arc)
|
||||||
|
{
|
||||||
|
out << " // " << get_fileline() << ": internal error: "
|
||||||
|
<< "I don't know how to emit this sequential statement! "
|
||||||
|
<< "type=" << typeid(*this).name() << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BasicLoopStatement::emit(ostream&out, Entity*entity, Architecture*arc)
|
||||||
|
{
|
||||||
|
out << " // " << get_fileline() << ": internal error: "
|
||||||
|
<< "I don't know how to emit this sequential statement! "
|
||||||
|
<< "type=" << typeid(*this).name() << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue