Generate code for vhdl for loops.
This commit is contained in:
parent
f0e61a1db7
commit
677a22d353
|
|
@ -1098,53 +1098,61 @@ loop_statement
|
|||
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;
|
||||
{ perm_string loop_name = $1? lex_strings.make($1) : perm_string() ;
|
||||
if ($8 && !$1) {
|
||||
errormsg(@8, "Loop statement closing name %s for un-named statement\n", $8);
|
||||
} else if($8 && loop_name != $8) {
|
||||
errormsg(@1, "Loop statement name %s doesn't match closing name %s.\n", loop_name.str(), $8);
|
||||
}
|
||||
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.\n");
|
||||
}
|
||||
WhileLoopStatement* tmp = new WhileLoopStatement(cond, $5);
|
||||
FILE_NAME(tmp, @1);
|
||||
ExpLogical* cond = dynamic_cast<ExpLogical*>($3);
|
||||
if(!cond) {
|
||||
errormsg(@3, "Iteration condition is not a correct logical expression.\n");
|
||||
}
|
||||
WhileLoopStatement* tmp = new WhileLoopStatement(loop_name, cond, $5);
|
||||
FILE_NAME(tmp, @1);
|
||||
|
||||
sorrymsg(@1, "Loop statements are not supported.\n");
|
||||
$$ = tmp;
|
||||
sorrymsg(@1, "Loop statements are not supported.\n");
|
||||
$$ = 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);
|
||||
| identifier_colon_opt
|
||||
K_for IDENTIFIER K_in range
|
||||
K_loop sequence_of_statements K_end K_loop identifier_opt ';'
|
||||
{ perm_string loop_name = $1? lex_strings.make($1) : perm_string() ;
|
||||
perm_string index_name = lex_strings.make($3);
|
||||
if ($10 && !$1) {
|
||||
errormsg(@10, "Loop statement closing name %s for un-named statement\n", $10);
|
||||
} else if($10 && loop_name != $10) {
|
||||
errormsg(@1, "Loop statement name %s doesn't match closing name %s.\n", loop_name.str(), $10);
|
||||
}
|
||||
if($1) delete[] $1;
|
||||
delete[] $3;
|
||||
if($10) delete[] $10;
|
||||
|
||||
sorrymsg(@1, "Loop statements are not supported.\n");
|
||||
$$ = tmp;
|
||||
ForLoopStatement* tmp = new ForLoopStatement(loop_name, index_name, $5, $7);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = 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);
|
||||
| identifier_colon_opt
|
||||
K_loop sequence_of_statements K_end K_loop identifier_opt ';'
|
||||
{ perm_string loop_name = $1? lex_strings.make($1) : perm_string() ;
|
||||
if ($6 && !$1) {
|
||||
errormsg(@6, "Loop statement closing name %s for un-named statement\n", $6);
|
||||
} else if($6 && loop_name != $6) {
|
||||
errormsg(@1, "Loop statement name %s doesn't match closing name %s.\n", loop_name.str(), $6);
|
||||
}
|
||||
if($1) delete[]$1;
|
||||
if($6) delete[]$6;
|
||||
|
||||
sorrymsg(@1, "Loop statements are not supported.\n");
|
||||
$$ = tmp;
|
||||
BasicLoopStatement* tmp = new BasicLoopStatement(loop_name, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
|
||||
sorrymsg(@1, "Loop statements are not supported.\n");
|
||||
$$ = tmp;
|
||||
};
|
||||
|
||||
mode
|
||||
|
|
|
|||
|
|
@ -77,9 +77,12 @@ class range_t {
|
|||
Expression*msb() { return direction_? left_ : right_; }
|
||||
Expression*lsb() { return direction_? right_: left_; }
|
||||
|
||||
inline bool is_downto() const { return direction_; }
|
||||
|
||||
private:
|
||||
Expression *left_, *right_;
|
||||
bool direction_;
|
||||
|
||||
private: //not implemented
|
||||
range_t(const range_t&);
|
||||
range_t operator=(const range_t&);
|
||||
|
|
|
|||
|
|
@ -153,7 +153,8 @@ ProcedureCall::~ProcedureCall()
|
|||
}
|
||||
}
|
||||
|
||||
LoopStatement::LoopStatement(list<SequentialStmt*>* stmts)
|
||||
LoopStatement::LoopStatement(perm_string name, list<SequentialStmt*>* stmts)
|
||||
: name_(name)
|
||||
{
|
||||
if (stmts) stmts_.splice(stmts_.end(), *stmts);
|
||||
}
|
||||
|
|
@ -167,8 +168,8 @@ LoopStatement::~LoopStatement()
|
|||
}
|
||||
}
|
||||
|
||||
ForLoopStatement::ForLoopStatement(perm_string it, range_t* range, list<SequentialStmt*>* stmts)
|
||||
: LoopStatement(stmts), it_(it), range_(range)
|
||||
ForLoopStatement::ForLoopStatement(perm_string scope_name, perm_string it, range_t* range, list<SequentialStmt*>* stmts)
|
||||
: LoopStatement(scope_name, stmts), it_(it), range_(range)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -188,8 +189,8 @@ VariableSeqAssignment::~VariableSeqAssignment()
|
|||
delete rval_;
|
||||
}
|
||||
|
||||
WhileLoopStatement::WhileLoopStatement(ExpLogical* cond, list<SequentialStmt*>* stmts)
|
||||
: LoopStatement(stmts), cond_(cond)
|
||||
WhileLoopStatement::WhileLoopStatement(perm_string lname, ExpLogical* cond, list<SequentialStmt*>* stmts)
|
||||
: LoopStatement(lname, stmts), cond_(cond)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -198,8 +199,8 @@ WhileLoopStatement::~WhileLoopStatement()
|
|||
delete cond_;
|
||||
}
|
||||
|
||||
BasicLoopStatement::BasicLoopStatement(list<SequentialStmt*>* stmts)
|
||||
: LoopStatement(stmts)
|
||||
BasicLoopStatement::BasicLoopStatement(perm_string lname, list<SequentialStmt*>* stmts)
|
||||
: LoopStatement(lname, stmts)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,28 @@ class SequentialStmt : public LineInfo {
|
|||
virtual void dump(ostream&out, int indent) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* The LoopStatement is an abstract base class for the various loop
|
||||
* statements.
|
||||
*/
|
||||
class LoopStatement : public SequentialStmt {
|
||||
public:
|
||||
LoopStatement(perm_string block_name, list<SequentialStmt*>*);
|
||||
virtual ~LoopStatement();
|
||||
|
||||
inline perm_string loop_name() const { return name_; }
|
||||
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
protected:
|
||||
int elaborate_substatements(Entity*ent, Architecture*arc);
|
||||
int emit_substatements(std::ostream&out, Entity*ent, Architecture*arc);
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
std::list<SequentialStmt*> stmts_;
|
||||
};
|
||||
|
||||
class IfSequential : public SequentialStmt {
|
||||
|
||||
public:
|
||||
|
|
@ -151,19 +173,6 @@ class ProcedureCall : public SequentialStmt {
|
|||
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 VariableSeqAssignment : public SequentialStmt {
|
||||
public:
|
||||
VariableSeqAssignment(Expression*sig, Expression*rval);
|
||||
|
|
@ -181,7 +190,8 @@ class VariableSeqAssignment : public SequentialStmt {
|
|||
|
||||
class WhileLoopStatement : public LoopStatement {
|
||||
public:
|
||||
WhileLoopStatement(ExpLogical*, list<SequentialStmt*>*);
|
||||
WhileLoopStatement(perm_string loop_name,
|
||||
ExpLogical*, list<SequentialStmt*>*);
|
||||
~WhileLoopStatement();
|
||||
|
||||
int elaborate(Entity*ent, Architecture*arc);
|
||||
|
|
@ -194,7 +204,8 @@ class WhileLoopStatement : public LoopStatement {
|
|||
|
||||
class ForLoopStatement : public LoopStatement {
|
||||
public:
|
||||
ForLoopStatement(perm_string, range_t*, list<SequentialStmt*>*);
|
||||
ForLoopStatement(perm_string loop_name,
|
||||
perm_string index, range_t*, list<SequentialStmt*>*);
|
||||
~ForLoopStatement();
|
||||
|
||||
int elaborate(Entity*ent, Architecture*arc);
|
||||
|
|
@ -208,12 +219,11 @@ class ForLoopStatement : public LoopStatement {
|
|||
|
||||
class BasicLoopStatement : public LoopStatement {
|
||||
public:
|
||||
BasicLoopStatement(list<SequentialStmt*>*);
|
||||
~BasicLoopStatement();
|
||||
BasicLoopStatement(perm_string lname, 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
|
||||
|
|
|
|||
|
|
@ -25,6 +25,25 @@ int SequentialStmt::elaborate(Entity*, Architecture*)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int LoopStatement::elaborate_substatements(Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
for (list<SequentialStmt*>::iterator cur = stmts_.begin()
|
||||
; cur != stmts_.end() ; ++cur) {
|
||||
errors += (*cur)->elaborate(ent, arc);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int ForLoopStatement::elaborate(Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
errors += elaborate_substatements(ent, arc);
|
||||
return errors;
|
||||
}
|
||||
|
||||
int IfSequential::elaborate(Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
|
|
@ -94,11 +113,6 @@ int ProcedureCall::elaborate(Entity*, Architecture*)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ForLoopStatement::elaborate(Entity*, Architecture*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VariableSeqAssignment::elaborate(Entity*ent, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,12 @@
|
|||
|
||||
# include "sequential.h"
|
||||
# include "expression.h"
|
||||
# include "architec.h"
|
||||
# include "compiler.h"
|
||||
# include <iostream>
|
||||
# include <cstdio>
|
||||
# include <typeinfo>
|
||||
# include <ivl_assert.h>
|
||||
|
||||
int SequentialStmt::emit(ostream&out, Entity*, Architecture*)
|
||||
{
|
||||
|
|
@ -120,20 +124,69 @@ int ProcedureCall::emit(ostream&out, Entity*, Architecture*)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int LoopStatement::emit(ostream&out, Entity*, Architecture*)
|
||||
int LoopStatement::emit_substatements(ostream&out, Entity*ent, 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 errors = 0;
|
||||
for (list<SequentialStmt*>::iterator cur = stmts_.begin()
|
||||
; cur != stmts_.end() ; ++cur) {
|
||||
SequentialStmt*tmp = *cur;
|
||||
errors += tmp->emit(out, ent, arc);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
int ForLoopStatement::emit(ostream&out, Entity*, Architecture*)
|
||||
int ForLoopStatement::emit(ostream&out, Entity*ent, 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 errors = 0;
|
||||
ivl_assert(*this, range_);
|
||||
|
||||
int64_t start_val;
|
||||
bool start_rc = range_->msb()->evaluate(arc, start_val);
|
||||
|
||||
int64_t finish_val;
|
||||
bool finish_rc = range_->lsb()->evaluate(arc, finish_val);
|
||||
|
||||
ivl_assert(*this, start_rc);
|
||||
ivl_assert(*this, finish_rc);
|
||||
|
||||
if (range_->is_downto() && start_val < finish_val) {
|
||||
out << "begin /* Degenerate loop at " << get_fileline() << " */ end" << endl;
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (!range_->is_downto() && start_val > finish_val) {
|
||||
out << "begin /* Degenerate loop at " << get_fileline() << " */ end" << endl;
|
||||
return errors;
|
||||
}
|
||||
|
||||
perm_string scope_name = loop_name();
|
||||
if (scope_name.nil()) {
|
||||
char buf[80];
|
||||
snprintf(buf, sizeof buf, "__%p", this);
|
||||
scope_name = lex_strings.make(buf);
|
||||
}
|
||||
|
||||
out << "begin : " << scope_name << endl;
|
||||
out << "longint \\" << it_ << " ;" << endl;
|
||||
out << "for (\\" << it_ << " = " << start_val << " ; ";
|
||||
if (range_->is_downto())
|
||||
out << "\\" << it_ << " >= " << finish_val;
|
||||
else
|
||||
out << "\\" << it_ << " <= " << finish_val;
|
||||
out << "; \\" << it_ << " = \\" << it_;
|
||||
if (range_->is_downto())
|
||||
out << " - 1";
|
||||
else
|
||||
out << " + 1";
|
||||
|
||||
out << ") begin" << endl;
|
||||
|
||||
errors += emit_substatements(out, ent, arc);
|
||||
|
||||
out << "end" << endl;
|
||||
out << "end /* " << scope_name << " */" << endl;
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int WhileLoopStatement::emit(ostream&out, Entity*, Architecture*)
|
||||
|
|
|
|||
Loading…
Reference in New Issue