diff --git a/vhdlpp/architec.cc b/vhdlpp/architec.cc index b034d4346..b3e5cfc4f 100644 --- a/vhdlpp/architec.cc +++ b/vhdlpp/architec.cc @@ -48,6 +48,12 @@ SignalAssignment::SignalAssignment(ExpName*name, list&rv) rval_.splice(rval_.end(), rv); } +SignalAssignment::SignalAssignment(ExpName*name, Expression*rv) +: lval_(name) +{ + rval_.push_back(rv); +} + SignalAssignment::~SignalAssignment() { for (list::iterator cur = rval_.begin() diff --git a/vhdlpp/architec.h b/vhdlpp/architec.h index d4d23258a..80a0c7140 100644 --- a/vhdlpp/architec.h +++ b/vhdlpp/architec.h @@ -95,8 +95,10 @@ class SignalAssignment : public Architecture::Statement { public: SignalAssignment(ExpName*target, std::list&rval); + SignalAssignment(ExpName*target, Expression*rval); ~SignalAssignment(); + virtual int elaborate(Entity*ent, Architecture*arc); virtual int emit(ostream&out, Entity*entity, Architecture*arc); virtual void dump(ostream&out, int ident =0) const; @@ -137,6 +139,7 @@ class ProcessStatement : public Architecture::Statement { private: int rewrite_as_always_edge_(Entity*ent, Architecture*arc); + int extract_anyedge_(Entity*ent, Architecture*arc);; private: perm_string iname_; diff --git a/vhdlpp/architec_elaborate.cc b/vhdlpp/architec_elaborate.cc index 6573ad751..0bc44a8b2 100644 --- a/vhdlpp/architec_elaborate.cc +++ b/vhdlpp/architec_elaborate.cc @@ -42,7 +42,7 @@ int Architecture::Statement::elaborate(Entity*, Architecture*) return 0; } -int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc) +int ComponentInstantiation::elaborate(Entity*, Architecture*arc) { int errors = 0; @@ -75,7 +75,7 @@ int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc) * always-@(n-edge ) version of the same statement. This makes * for a more natural translation to verilog, if it comes to that. */ -int ProcessStatement::rewrite_as_always_edge_(Entity*ent, Architecture*arc) +int ProcessStatement::rewrite_as_always_edge_(Entity*, Architecture*) { // If thare are multiple sensitivity expressions, I give up. if (sensitivity_list_.size() != 1) @@ -93,6 +93,10 @@ int ProcessStatement::rewrite_as_always_edge_(Entity*ent, Architecture*arc) if (stmt == 0) return -1; + // If the "if" statement has a false clause, then give up. + if (stmt->false_size() != 0) + return -1; + const Expression*ce_raw = stmt->peek_condition(); // We expect the condition to be 'event AND ='1'. @@ -145,31 +149,58 @@ int ProcessStatement::rewrite_as_always_edge_(Entity*ent, Architecture*arc) // And we can convert it to: // always @(edge ) ... - // Replace the sensitivity expression with an edge expression. + // Replace the sensitivity expression with an edge + // expression. The ExpEdge expression signals that this is an + // always-@(edge) statement. ExpEdge*edge = new ExpEdge(op2b->value()=='1'? ExpEdge::POSEDGE : ExpEdge::NEGEDGE, se); assert(sensitivity_list_.size() == 1); sensitivity_list_.pop_front(); sensitivity_list_.push_front(edge); + // Replace the statement with the body of the always + // statement, which is the true clause of the top "if" + // statement. There should be no "else" clause. assert(statements_list_.size() == 1); statements_list_.pop_front(); stmt->extract_true(statements_list_); - std::list tmp; - stmt->extract_false(tmp); - assert(tmp.size() == 0); - delete stmt; return 0; } +/* + * Change the "process () " into "always @() ..." + */ +int ProcessStatement::extract_anyedge_(Entity*, Architecture*) +{ + + vector se; + while (! sensitivity_list_.empty()) { + se.push_back(sensitivity_list_.front()); + sensitivity_list_.pop_front(); + } + + for (size_t idx = 0 ; idx < se.size() ; idx += 1) { + ExpEdge*edge = new ExpEdge(ExpEdge::ANYEDGE, se[idx]); + FILE_NAME(edge, se[idx]); + sensitivity_list_.push_back(edge); + } + + return 0; +} + int ProcessStatement::elaborate(Entity*ent, Architecture*arc) { int errors = 0; - rewrite_as_always_edge_(ent, arc); + if (rewrite_as_always_edge_(ent, arc) >= 0) { + + } else if (extract_anyedge_(ent, arc) >= 0) { + + } else { + } for (list::iterator cur = statements_list_.begin() ; cur != statements_list_.end() ; ++cur) { @@ -178,3 +209,27 @@ int ProcessStatement::elaborate(Entity*ent, Architecture*arc) return errors; } + +int SignalAssignment::elaborate(Entity*ent, Architecture*arc) +{ + int errors = 0; + + // Elaborate the l-value expression. + errors += lval_->elaborate_lval(ent, arc); + + // The elaborate_lval should have resolved the type of the + // l-value expression. We'll use that type to elaborate the + // r-value. + const VType*lval_type = lval_->peek_type(); + if (lval_type == 0) { + if (errors == 0) errors += 1; + return errors; + } + + for (list::const_iterator cur = rval_.begin() + ; cur != rval_.end() ; ++cur) { + (*cur)->elaborate_expr(ent, arc, lval_type); + } + + return errors; +} diff --git a/vhdlpp/debug.cc b/vhdlpp/debug.cc index a8b6caf2b..ef709c3e3 100644 --- a/vhdlpp/debug.cc +++ b/vhdlpp/debug.cc @@ -193,7 +193,7 @@ void ExpBitstring::dump(ostream&out, int indent) const for (size_t idx = value_.size() ; idx > 0 ; idx -= 1) { out << value_[idx-1]; } - out << "\""; + out << "\"" << endl; } void ExpCharacter::dump(ostream&out, int indent) const @@ -202,6 +202,25 @@ void ExpCharacter::dump(ostream&out, int indent) const << " at " << get_fileline() << endl; } +void ExpConditional::dump(ostream&out, int indent) const +{ + out << setw(indent) << "" << "Conditional expression at "<< get_fileline() << endl; + out << setw(indent) << "" << " when:" << endl; + cond_->dump(out, indent+4); + + out << setw(indent) << "" << " do:" << endl; + for (list::const_iterator cur = true_clause_.begin() + ; cur != true_clause_.end() ; ++cur) { + (*cur)->dump(out, indent+4); + } + + out << setw(indent) << "" << " else:" << endl; + for (list::const_iterator cur = else_clause_.begin() + ; cur != else_clause_.end() ; ++cur) { + (*cur)->dump(out, indent+4); + } +} + void ExpEdge::dump(ostream&out, int indent) const { out << setw(indent) << ""; diff --git a/vhdlpp/expression.cc b/vhdlpp/expression.cc index af95ba537..76f089bcb 100644 --- a/vhdlpp/expression.cc +++ b/vhdlpp/expression.cc @@ -192,6 +192,28 @@ ExpCharacter::~ExpCharacter() { } +ExpConditional::ExpConditional(Expression*co, list*tru, list*els) +: cond_(co) +{ + if (tru) true_clause_.splice(true_clause_.end(), *tru); + if (els) else_clause_.splice(else_clause_.end(), *els); +} + +ExpConditional::~ExpConditional() +{ + delete cond_; + while (! true_clause_.empty()) { + Expression*tmp = true_clause_.front(); + true_clause_.pop_front(); + delete tmp; + } + while (! else_clause_.empty()) { + Expression*tmp = else_clause_.front(); + else_clause_.pop_front(); + delete tmp; + } +} + ExpEdge::ExpEdge(ExpEdge::fun_t typ, Expression*op) : ExpUnary(op), fun_(typ) { diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index 018b7e2a6..654101608 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -22,12 +22,14 @@ # include "StringHeap.h" # include "LineInfo.h" # include +# include # include class Entity; class Architecture; class ScopeBase; class VType; +class VTypePrimitive; class ExpName; @@ -101,6 +103,11 @@ class Expression : public LineInfo { Expression& operator = (const Expression&); }; +static inline void FILE_NAME(Expression*tgt, const LineInfo*src) +{ + tgt->set_line(*src); +} + class ExpUnary : public Expression { public: @@ -128,6 +135,8 @@ class ExpBinary : public Expression { const Expression* peek_operand1(void) const { return operand1_; } const Expression* peek_operand2(void) const { return operand2_; } + const VType*probe_type(Entity*ent, Architecture*arc) const; + protected: int elaborate_exprs(Entity*, Architecture*, const VType*); @@ -153,10 +162,14 @@ class ExpArithmetic : public ExpBinary { ExpArithmetic(ExpArithmetic::fun_t op, Expression*op1, Expression*op2); ~ExpArithmetic(); + int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype); int emit(ostream&out, Entity*ent, Architecture*arc); virtual bool evaluate(ScopeBase*scope, int64_t&val) const; void dump(ostream&out, int indent = 0) const; + private: + int emit_concat_(ostream&out, Entity*ent, Architecture*arc); + private: fun_t fun_; }; @@ -170,6 +183,7 @@ class ExpAttribute : public Expression { inline perm_string peek_attribute() const { return name_; } inline const ExpName* peek_base() const { return base_; } + int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype); int emit(ostream&out, Entity*ent, Architecture*arc); void dump(ostream&out, int indent = 0) const; @@ -184,6 +198,7 @@ class ExpBitstring : public Expression { explicit ExpBitstring(const char*); ~ExpBitstring(); + int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype); int emit(ostream&out, Entity*ent, Architecture*arc); void dump(ostream&out, int indent = 0) const; @@ -204,10 +219,37 @@ class ExpCharacter : public Expression { char value() const { return value_; } + private: + int emit_primitive_bit_(ostream&out, Entity*ent, Architecture*arc, + const VTypePrimitive*etype); + private: char value_; }; +/* + * The conditional expression represents the VHDL when-else + * expressions. Note that by the VHDL syntax rules, these cannot show + * up other then at the root of an expression. + */ +class ExpConditional : public Expression { + + public: + ExpConditional(Expression*cond, std::list*tru, + std::list*els); + ~ExpConditional(); + + const VType*probe_type(Entity*ent, Architecture*arc) const; + int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype); + int emit(ostream&out, Entity*ent, Architecture*arc); + void dump(ostream&out, int indent = 0) const; + + private: + Expression*cond_; + std::list true_clause_; + std::list else_clause_; +}; + /* * This is a special expression type that represents posedge/negedge * expressions in sensitivity lists. @@ -256,6 +298,7 @@ class ExpLogical : public ExpBinary { inline fun_t logic_fun() const { return fun_; } + int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype); int emit(ostream&out, Entity*ent, Architecture*arc); void dump(ostream&out, int indent = 0) const; diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index 0b3082fff..775a18ed0 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -77,6 +77,23 @@ int Expression::elaborate_expr(Entity*, Architecture*, const VType*) return 1; } +const VType* ExpBinary::probe_type(Entity*ent, Architecture*arc) const +{ + const VType*t1 = operand1_->probe_type(ent, arc); + const VType*t2 = operand2_->probe_type(ent, arc); + + if (t1 == 0) + return t2; + if (t2 == 0) + return t1; + + if (t1 == t2) + return t1; + + cerr << get_fileline() << ": internal error: I don't know how to resolve types of generic binary expressions." << endl; + return 0; +} + int ExpBinary::elaborate_exprs(Entity*ent, Architecture*arc, const VType*ltype) { int errors = 0; @@ -86,6 +103,33 @@ int ExpBinary::elaborate_exprs(Entity*ent, Architecture*arc, const VType*ltype) return errors; } +int ExpArithmetic::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype) +{ + int errors = 0; + + if (ltype == 0) { + ltype = probe_type(ent, arc); + } + + assert(ltype != 0); + errors += elaborate_exprs(ent, arc, ltype); + return errors; +} + +int ExpAttribute::elaborate_expr(Entity*ent, Architecture*arc, const VType*) +{ + int errors = 0; + const VType*sub_type = base_->probe_type(ent, arc); + errors += base_->elaborate_expr(ent, arc, sub_type); + return errors; +} + +int ExpBitstring::elaborate_expr(Entity*, Architecture*, const VType*) +{ + int errors = 0; + return errors; +} + int ExpCharacter::elaborate_expr(Entity*, Architecture*, const VType*ltype) { assert(ltype != 0); @@ -93,6 +137,52 @@ int ExpCharacter::elaborate_expr(Entity*, Architecture*, const VType*ltype) return 0; } +const VType* ExpConditional::probe_type(Entity*, Architecture*) const +{ + return 0; +} + +int ExpConditional::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype) +{ + int errors = 0; + + if (ltype == 0) + ltype = probe_type(ent, arc); + + assert(ltype); + + set_type(ltype); + + /* Note that the type for the condition expression need not + have anything to do with the type of this expression. */ + errors += cond_->elaborate_expr(ent, arc, 0); + + for (list::const_iterator cur = true_clause_.begin() + ; cur != true_clause_.end() ; ++cur) { + errors += (*cur)->elaborate_expr(ent, arc, ltype); + } + + for (list::const_iterator cur = else_clause_.begin() + ; cur != else_clause_.end() ; ++cur) { + errors += (*cur)->elaborate_expr(ent, arc, ltype); + } + + return errors; +} + +int ExpLogical::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype) +{ + int errors = 0; + + if (ltype == 0) { + ltype = probe_type(ent, arc); + } + + assert(ltype != 0); + errors += elaborate_exprs(ent, arc, ltype); + return errors; +} + const VType* ExpName::probe_type(Entity*ent, Architecture*arc) const { if (const InterfacePort*cur = ent->find_port(name_)) diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index 2557196e4..0712af26d 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -21,6 +21,7 @@ # include "vtype.h" # include # include +# include using namespace std; @@ -77,6 +78,9 @@ int ExpArithmetic::emit(ostream&out, Entity*ent, Architecture*arc) { int errors = 0; + if (fun_ == CONCAT) + return emit_concat_(out, ent, arc); + errors += emit_operand1(out, ent, arc); switch (fun_) { @@ -111,43 +115,70 @@ int ExpArithmetic::emit(ostream&out, Entity*ent, Architecture*arc) return errors; } -int ExpBitstring::emit(ostream&out, Entity*, Architecture*) +int ExpArithmetic::emit_concat_(ostream&out, Entity*ent, Architecture*arc) { int errors = 0; - errors += 1; + out << "{"; + errors += emit_operand1(out, ent, arc); + out << ", "; + errors += emit_operand2(out, ent, arc); + out << "}"; return errors; } -int ExpCharacter::emit(ostream&out, Entity*, Architecture*) +int ExpBitstring::emit(ostream&out, Entity*, Architecture*) +{ + int errors = 0; + + out << value_.size() << "'b"; + for (size_t idx = 0 ; idx < value_.size() ; idx += 1) + out << value_[value_.size()-idx-1]; + + return errors; +} + +int ExpCharacter::emit_primitive_bit_(ostream&out, Entity*ent, Architecture*arc, + const VTypePrimitive*etype) +{ + switch (etype->type()) { + case VTypePrimitive::BOOLEAN: + case VTypePrimitive::BIT: + switch (value_) { + case '0': + case '1': + out << "1'b" << value_; + return 0; + default: + break; + } + break; + + case VTypePrimitive::STDLOGIC: + switch (value_) { + case '0': + case '1': + out << "1'b" << value_; + return 0; + default: + break; + } + + default: + return 1; + } +} + +int ExpCharacter::emit(ostream&out, Entity*ent, Architecture*arc) { const VType*etype = peek_type(); if (const VTypePrimitive*use_type = dynamic_cast(etype)) { - switch (use_type->type()) { - case VTypePrimitive::BOOLEAN: - case VTypePrimitive::BIT: - switch (value_) { - case '0': - case '1': - out << "1'b" << value_; - return 0; - default: - break; - } - break; + return emit_primitive_bit_(out, ent, arc, use_type); + } - case VTypePrimitive::STDLOGIC: - switch (value_) { - case '0': - case '1': - out << "1'b" << value_; - return 0; - default: - break; - } - - default: - return 1; + if (const VTypeArray*array = dynamic_cast(etype)) { + if (const VTypePrimitive*use_type = dynamic_cast(array->element_type())) { + return emit_primitive_bit_(out, ent, arc, use_type); } } @@ -160,6 +191,36 @@ bool ExpCharacter::is_primary(void) const return true; } +int ExpConditional::emit(ostream&out, Entity*ent, Architecture*arc) +{ + int errors = 0; + out << "("; + errors += cond_->emit(out, ent, arc); + out << ")? ("; + + if (true_clause_.size() > 1) { + cerr << get_fileline() << ": sorry: Multiple expressions not supported here." << endl; + errors += 1; + } + + Expression*tmp = true_clause_.front(); + errors += tmp->emit(out, ent, arc); + + out << ") : ("; + + if (else_clause_.size() > 1) { + cerr << get_fileline() << ": sorry: Multiple expressions not supported here." << endl; + errors += 1; + } + + tmp = else_clause_.front(); + errors += tmp->emit(out, ent, arc); + + out << ")"; + + return errors; +} + int ExpEdge::emit(ostream&out, Entity*ent, Architecture*arc) { int errors = 0; @@ -170,9 +231,7 @@ int ExpEdge::emit(ostream&out, Entity*ent, Architecture*arc) case POSEDGE: out << "posedge "; break; - default: - out << "INVALIDedge "; - errors += 1; + case ANYEDGE: break; } errors += emit_operand1(out, ent, arc); diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index c78a2e226..6504c1056 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -126,6 +126,9 @@ const VType*parse_type_by_name(perm_string name) SequentialStmt* sequ; std::list*sequ_list; + IfSequential::Elsif*elsif; + std::list*elsif_list; + named_expr_t*named_expr; std::list*named_expr_list; entity_aspect_t* entity_aspect; @@ -213,6 +216,9 @@ const VType*parse_type_by_name(perm_string name) %type sequence_of_statements if_statement_else %type sequential_statement if_statement signal_assignment_statement +%type if_statement_elsif +%type if_statement_elsif_list if_statement_elsif_list_opt + %% /* The design_file is the root for the VHDL parse. */ @@ -346,7 +352,7 @@ block_declarative_item | component_declaration | constant_declaration - { sorrymsg(@1, "constant declarations not supported here.\n"); } + | use_clause_lib /* Various error handling rules for block_declarative_item... */ @@ -453,14 +459,17 @@ concurrent_signal_assignment_statement delete $3; } | name LEQ waveform K_when expression K_else waveform ';' - { ExpName*name = dynamic_cast ($1); - assert(name); - SignalAssignment*tmp = new SignalAssignment(name, *$3); - FILE_NAME(tmp, @1); - - $$ = tmp; + { ExpConditional*tmp = new ExpConditional($5, $3, $7); + FILE_NAME(tmp, @3); delete $3; - sorrymsg(@4, "Conditional signal assignment not supported here.\n"); + delete $7; + + ExpName*name = dynamic_cast ($1); + assert(name); + SignalAssignment*tmpa = new SignalAssignment(name, tmp); + FILE_NAME(tmpa, @1); + + $$ = tmpa; } | name LEQ error ';' { errormsg(@2, "Syntax error in signal assignment waveform.\n"); @@ -776,8 +785,11 @@ if_statement : K_if expression K_then sequence_of_statements if_statement_elsif_list_opt if_statement_else K_end K_if ';' - { IfSequential*tmp = new IfSequential($2, $4, $6); + { IfSequential*tmp = new IfSequential($2, $4, $5, $6); FILE_NAME(tmp, @1); + delete $4; + delete $5; + delete $6; $$ = tmp; } @@ -804,21 +816,34 @@ if_statement ; if_statement_elsif_list_opt - : if_statement_elsif_list - | + : if_statement_elsif_list { $$ = $1; } + | { $$ = 0; } ; if_statement_elsif_list : if_statement_elsif_list if_statement_elsif + { list*tmp = $1; + tmp->push_back($2); + $$ = tmp; + } | if_statement_elsif + { list*tmp = new list; + tmp->push_back($1); + $$ = tmp; + } ; if_statement_elsif : K_elsif expression K_then sequence_of_statements - { sorrymsg(@1, "elsif sub-statements are not supported.\n"); } + { IfSequential::Elsif*tmp = new IfSequential::Elsif($2, $4); + FILE_NAME(tmp, @1); + delete $4; + $$ = tmp; + } | K_elsif expression K_then error { errormsg(@4, "Too many errors in elsif sub-statements.\n"); yyerrok; + $$ = 0; } ; diff --git a/vhdlpp/sequential.cc b/vhdlpp/sequential.cc index d9dcddf45..4d04ea757 100644 --- a/vhdlpp/sequential.cc +++ b/vhdlpp/sequential.cc @@ -29,10 +29,12 @@ SequentialStmt::~SequentialStmt() } IfSequential::IfSequential(Expression*cond, std::list*tr, + std::list*el, std::list*fa) { cond_ = cond; if (tr) if_.splice(if_.end(), *tr); + if (el) elsif_.splice(elsif_.end(), *el); if (fa) else_.splice(else_.end(), *fa); } @@ -44,6 +46,11 @@ IfSequential::~IfSequential() if_.pop_front(); delete cur; } + while (elsif_.size() > 0) { + IfSequential::Elsif*cur = elsif_.front(); + elsif_.pop_front(); + delete cur; + } while (else_.size() > 0) { SequentialStmt*cur = else_.front(); else_.pop_front(); @@ -68,6 +75,22 @@ void IfSequential::extract_false(std::list&that) } } +IfSequential::Elsif::Elsif(Expression*cond, std::list*tr) +: cond_(cond) +{ + if (tr) if_.splice(if_.end(), *tr); +} + +IfSequential::Elsif::~Elsif() +{ + delete cond_; + while (if_.size() > 0) { + SequentialStmt*cur = if_.front(); + if_.pop_front(); + delete cur; + } +} + SignalSeqAssignment::SignalSeqAssignment(Expression*sig, std::list*wav) { lval_ = sig; diff --git a/vhdlpp/sequential.h b/vhdlpp/sequential.h index e216edf21..45c9b1ab6 100644 --- a/vhdlpp/sequential.h +++ b/vhdlpp/sequential.h @@ -40,8 +40,25 @@ class SequentialStmt : public LineInfo { class IfSequential : public SequentialStmt { + public: + class Elsif : public LineInfo { + public: + Elsif(Expression*cond, std::list*tr); + ~Elsif(); + + void dump(ostream&out, int indent) const; + + private: + Expression*cond_; + std::listif_; + private: // not implemented + Elsif(const Elsif&); + Elsif& operator =(const Elsif&); + }; + public: IfSequential(Expression*cond, std::list*tr, + std::list*elsif, std::list*fa); ~IfSequential(); @@ -52,6 +69,8 @@ class IfSequential : public SequentialStmt { const Expression*peek_condition() const { return cond_; } + size_t false_size() const { return else_.size(); } + // These method extract (and remove) the sub-statements from // the true or false clause. void extract_true(std::list&that); @@ -60,6 +79,7 @@ class IfSequential : public SequentialStmt { private: Expression*cond_; std::list if_; + std::list elsif_; std::list else_; }; diff --git a/vhdlpp/sequential_debug.cc b/vhdlpp/sequential_debug.cc index 8dc688878..e8434b2ef 100644 --- a/vhdlpp/sequential_debug.cc +++ b/vhdlpp/sequential_debug.cc @@ -42,6 +42,10 @@ void IfSequential::dump(ostream&out, int indent) const ; cur != if_.end() ; ++cur) (*cur)->dump(out, indent+4); + for (list::const_iterator cur = elsif_.begin() + ; cur != elsif_.end() ; ++cur) + (*cur)->dump(out, indent); + out << setw(indent+3) << "" << "FALSE clause (" << else_.size() << "):" << endl; for (list::const_iterator cur = else_.begin() ; cur != else_.end() ; ++cur) @@ -49,6 +53,18 @@ void IfSequential::dump(ostream&out, int indent) const } +void IfSequential::Elsif::dump(ostream&out, int indent) const +{ + out << setw(indent+3) << "" << "Elsif Condition at " << get_fileline() << ":" << endl; + cond_->dump(out, indent+4); + + out << setw(indent+3) << "" << "ELSIF TRUE clause (" << if_.size() << "):" << endl; + for (list::const_iterator cur = if_.begin() + ; cur != if_.end() ; ++cur) + (*cur)->dump(out, indent+4); + +} + void SignalSeqAssignment::dump(ostream&out, int indent) const { out << setw(indent) << "" << "SignalSeqAssignment at file=" << get_fileline() << endl;