vhdlpp: prange_t may have the direction determined automatically.

This commit is contained in:
Maciej Suminski 2014-10-08 10:26:37 +02:00
parent 6887c82540
commit 44da7de651
2 changed files with 35 additions and 15 deletions

View File

@ -71,7 +71,7 @@ class instant_list_t {
class prange_t {
public:
prange_t(Expression* left, Expression* right, bool dir)
: left_(left), right_(right), direction_(dir) {}
: left_(left), right_(right), direction_(dir), auto_dir_(false) {}
~prange_t() { delete left_; delete right_; }
void dump(ostream&out, int indent) const;
@ -79,12 +79,16 @@ class prange_t {
inline Expression*lsb() { return direction_? right_: left_; }
inline bool is_downto() const { return direction_; }
inline void set_auto_dir(bool enabled = true) { auto_dir_ = enabled; };
inline bool is_auto_dir() const { return auto_dir_; }
inline Expression*expr_left() { return left_; }
inline Expression*expr_right() { return right_; }
private:
Expression *left_, *right_;
bool direction_;
bool auto_dir_;
private: //not implemented
prange_t(const prange_t&);

View File

@ -213,21 +213,37 @@ int ForLoopStatement::emit(ostream&out, Entity*ent, Architecture*arc)
out << "begin : " << scope_name << endl;
out << "longint \\" << it_ << " ;" << endl;
out << "for (\\" << it_ << " = ";
if (range_->is_downto()) {
range_->msb()->emit(out, ent, arc);
out << " ; \\" << it_ << " >= ";
range_->lsb()->emit(out, ent, arc);
} else {
range_->lsb()->emit(out, ent, arc);
out << " ; \\" << it_ << " <= ";
range_->msb()->emit(out, ent, arc);
}
range_->expr_left()->emit(out, ent, arc);
out << "; \\" << it_ << " = \\" << it_;
if (range_->is_downto())
out << " - 1";
else
out << " + 1";
// Determining the loop direction at the runtime
if (range_->is_auto_dir() || true) {
out << " ;\n(";
range_->expr_left()->emit(out, ent, arc);
out << " < ";
range_->expr_right()->emit(out, ent, arc);
out << " ? \\" << it_ << " <= ";
range_->expr_right()->emit(out, ent, arc);
out << " : \\" << it_ << " >= ";
range_->expr_right()->emit(out, ent, arc);
out << ");\n\\" << it_ << " = \\" << it_ << " + (";
range_->expr_left()->emit(out, ent, arc);
out << " < ";
range_->expr_right()->emit(out, ent, arc);
out << " ? 1 : -1)";
} else {
if (range_->is_downto())
out << " ; \\" << it_ << " >= ";
else
out << " ; \\" << it_ << " <= ";
range_->expr_right()->emit(out, ent, arc);
out << "; \\" << it_ << " = \\" << it_;
if (range_->is_downto())
out << " - 1";
else
out << " + 1";
}
out << ") begin" << endl;