Add support for VHDL's loop statements

This commit is contained in:
Pawel Szostek 2011-07-05 18:31:54 +02:00 committed by Stephen Williams
parent 743cb234c0
commit 60deb775ca
8 changed files with 263 additions and 1 deletions

View File

@ -346,3 +346,10 @@ void named_expr_t::dump(ostream&out, int indent) const
out << setw(indent) << "" << name_ << "=>";
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);
}

View File

@ -140,6 +140,8 @@ const VType*parse_type_by_name(perm_string name)
const VType* vtype;
range_t* range;
std::list<InterfacePort*>* interface_list;
Architecture::Statement* arch_statement;
@ -211,7 +213,7 @@ const VType*parse_type_by_name(perm_string name)
%type <vtype> subtype_indication
%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 <compound_name> prefix selected_name
%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> sequential_statement if_statement signal_assignment_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_list> case_statement_alternative_list
@ -832,6 +837,7 @@ identifier_list
identifier_opt : IDENTIFIER { $$ = $1; } | { $$ = 0; } ;
identifier_colon_opt : IDENTIFIER ':' { $$ = $1; } | { $$ = 0; };
if_statement
: 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
: K_in { $$ = PORT_IN; }
| K_out { $$ = PORT_OUT; }
@ -1278,6 +1338,13 @@ process_sensitivity_list
| name_list
{ $$ = $1; }
;
range
: simple_expression direction simple_expression
{
range_t* tmp = new range_t($1, $3, $2);
$$ = tmp;
}
;
relation
: shift_expression
@ -1392,6 +1459,7 @@ sequential_statement
| signal_assignment_statement { $$ = $1; }
| case_statement { $$ = $1; }
| procedure_call_statement { $$ = $1; }
| loop_statement { $$ = $1; }
| K_null ';' { $$ = 0; }
;

View File

@ -66,4 +66,19 @@ class instant_list_t {
application_domain_t domain_;
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

View File

@ -152,3 +152,46 @@ ProcedureCall::~ProcedureCall()
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()
{
}

View File

@ -145,8 +145,60 @@ class ProcedureCall : public SequentialStmt {
int elaborate(Entity*ent, Architecture*arc);
int emit(ostream&out, Entity*entity, Architecture*arc);
void dump(ostream&out, int indent) const;
private:
perm_string name_;
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

View File

@ -109,3 +109,32 @@ void ProcedureCall::dump(ostream& out, int indent) const
(*it)->dump(out, indent);
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);
}

View File

@ -93,3 +93,19 @@ int ProcedureCall::elaborate(Entity*, Architecture*)
{
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;
}

View File

@ -106,3 +106,35 @@ int ProcedureCall::emit(ostream&out, Entity*, Architecture*)
<< "type=" << typeid(*this).name() << endl;
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;
}