diff --git a/elaborate.cc b/elaborate.cc index 1e78e1342..6f7447543 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -2513,7 +2513,9 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope, if (expr_.count() == 0) { assert(enet); - NexusSet*nset = enet->nex_input(); + /* In this context we do not want all the inputs, so + do not remove outputs that are also inputs. */ + NexusSet*nset = enet->nex_input(false); if (nset == 0) { cerr << get_line() << ": internal error: No NexusSet" << " from statement." << endl; diff --git a/net_nex_input.cc b/net_nex_input.cc index ea62af9ef..dd10df51f 100644 --- a/net_nex_input.cc +++ b/net_nex_input.cc @@ -29,7 +29,7 @@ # include "netlist.h" # include "netmisc.h" -NexusSet* NetExpr::nex_input() +NexusSet* NetExpr::nex_input(bool rem_out) { cerr << get_line() << ": internal error: nex_input not implemented: " @@ -37,7 +37,7 @@ NexusSet* NetExpr::nex_input() return 0; } -NexusSet* NetProc::nex_input() +NexusSet* NetProc::nex_input(bool rem_out) { cerr << get_line() << ": internal error: NetProc::nex_input not implemented" @@ -45,20 +45,20 @@ NexusSet* NetProc::nex_input() return 0; } -NexusSet* NetEBinary::nex_input() +NexusSet* NetEBinary::nex_input(bool rem_out) { - NexusSet*result = left_->nex_input(); - NexusSet*tmp = right_->nex_input(); + NexusSet*result = left_->nex_input(rem_out); + NexusSet*tmp = right_->nex_input(rem_out); result->add(*tmp); delete tmp; return result; } -NexusSet* NetEConcat::nex_input() +NexusSet* NetEConcat::nex_input(bool rem_out) { - NexusSet*result = parms_[0]->nex_input(); + NexusSet*result = parms_[0]->nex_input(rem_out); for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) { - NexusSet*tmp = parms_[idx]->nex_input(); + NexusSet*tmp = parms_[idx]->nex_input(rem_out); result->add(*tmp); delete tmp; } @@ -68,12 +68,12 @@ NexusSet* NetEConcat::nex_input() /* * A constant has not inputs, so always return an empty set. */ -NexusSet* NetEConst::nex_input() +NexusSet* NetEConst::nex_input(bool rem_out) { return new NexusSet; } -NexusSet* NetECReal::nex_input() +NexusSet* NetECReal::nex_input(bool rem_out) { return new NexusSet; } @@ -82,45 +82,45 @@ NexusSet* NetECReal::nex_input() * A parameter by definition has no inputs. It represents a constant * value, even if that value is a constant expression. */ -NexusSet* NetEParam::nex_input() +NexusSet* NetEParam::nex_input(bool rem_out) { return new NexusSet; } -NexusSet* NetEEvent::nex_input() +NexusSet* NetEEvent::nex_input(bool rem_out) { return new NexusSet; } -NexusSet* NetEScope::nex_input() +NexusSet* NetEScope::nex_input(bool rem_out) { return new NexusSet; } -NexusSet* NetESelect::nex_input() +NexusSet* NetESelect::nex_input(bool rem_out) { - NexusSet*result = base_? base_->nex_input() : new NexusSet(); - NexusSet*tmp = expr_->nex_input(); + NexusSet*result = base_? base_->nex_input(rem_out) : new NexusSet(); + NexusSet*tmp = expr_->nex_input(rem_out); result->add(*tmp); delete tmp; return result; } -NexusSet* NetESFunc::nex_input() +NexusSet* NetESFunc::nex_input(bool rem_out) { if (nparms_ == 0) return new NexusSet; - NexusSet*result = parms_[0]->nex_input(); + NexusSet*result = parms_[0]->nex_input(rem_out); for (unsigned idx = 1 ; idx < nparms_ ; idx += 1) { - NexusSet*tmp = parms_[idx]->nex_input(); + NexusSet*tmp = parms_[idx]->nex_input(rem_out); result->add(*tmp); delete tmp; } return result; } -NexusSet* NetESignal::nex_input() +NexusSet* NetESignal::nex_input(bool rem_out) { NexusSet*result = new NexusSet; for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1) @@ -129,27 +129,27 @@ NexusSet* NetESignal::nex_input() return result; } -NexusSet* NetETernary::nex_input() +NexusSet* NetETernary::nex_input(bool rem_out) { NexusSet*tmp; - NexusSet*result = cond_->nex_input(); + NexusSet*result = cond_->nex_input(rem_out); - tmp = true_val_->nex_input(); + tmp = true_val_->nex_input(rem_out); result->add(*tmp); delete tmp; - tmp = false_val_->nex_input(); + tmp = false_val_->nex_input(rem_out); result->add(*tmp); delete tmp; return result; } -NexusSet* NetEUFunc::nex_input() +NexusSet* NetEUFunc::nex_input(bool rem_out) { NexusSet*result = new NexusSet; for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { - NexusSet*tmp = parms_[idx]->nex_input(); + NexusSet*tmp = parms_[idx]->nex_input(rem_out); result->add(*tmp); delete tmp; } @@ -157,21 +157,21 @@ NexusSet* NetEUFunc::nex_input() return result; } -NexusSet* NetEUnary::nex_input() +NexusSet* NetEUnary::nex_input(bool rem_out) { - return expr_->nex_input(); + return expr_->nex_input(rem_out); } -NexusSet* NetAssign_::nex_input() +NexusSet* NetAssign_::nex_input(bool rem_out) { NexusSet*result = new NexusSet; if (word_) { - NexusSet*tmp = word_->nex_input(); + NexusSet*tmp = word_->nex_input(rem_out); result->add(*tmp); delete tmp; } if (base_) { - NexusSet*tmp = base_->nex_input(); + NexusSet*tmp = base_->nex_input(rem_out); result->add(*tmp); delete tmp; } @@ -179,15 +179,15 @@ NexusSet* NetAssign_::nex_input() return result; } -NexusSet* NetAssignBase::nex_input() +NexusSet* NetAssignBase::nex_input(bool rem_out) { - NexusSet*result = rval_->nex_input(); + NexusSet*result = rval_->nex_input(rem_out); /* It is possible that the lval_ can hav nex_input values. In particular, index expressions are statement inputs as well, so should be addressed here. */ for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) { - NexusSet*tmp = cur->nex_input(); + NexusSet*tmp = cur->nex_input(rem_out); result->add(*tmp); delete tmp; } @@ -212,7 +212,7 @@ NexusSet* NetAssignBase::nex_input() * In this example, "t" should not be in the input set because it is * used by the sequence as a temporary value. */ -NexusSet* NetBlock::nex_input() +NexusSet* NetBlock::nex_input(bool rem_out) { if (last_ == 0) return new NexusSet; @@ -232,24 +232,24 @@ NexusSet* NetBlock::nex_input() do { /* Get the inputs for the current statement. */ - NexusSet*tmp = cur->nex_input(); + NexusSet*tmp = cur->nex_input(rem_out); - /* Remove from the input set those bits that are outputs - from previous statements. They aren't really inputs - to the block, just internal intermediate values. */ - tmp->rem(*prev); - - /* Add the corrected set to the accumulated input set. */ + /* Add the current input set to the accumulated input set. */ result->add(*tmp); delete tmp; - /* Add the current outputs to the accumulated output - set, for processing of later statements. */ + /* Add the current outputs to the accumulated output set, + so they can be removed from the input set below. */ cur->nex_output(*prev); cur = cur->next_; } while (cur != last_->next_); + /* Remove from the input set those bits that are outputs + from other statements. They aren't really inputs + to the block, just internal intermediate values. */ + if (rem_out) result->rem(*prev); + return result; } @@ -258,9 +258,9 @@ NexusSet* NetBlock::nex_input() * the inputs to all the guards, and the inputs to all the guarded * statements. */ -NexusSet* NetCase::nex_input() +NexusSet* NetCase::nex_input(bool rem_out) { - NexusSet*result = expr_->nex_input(); + NexusSet*result = expr_->nex_input(rem_out); if (result == 0) return 0; @@ -270,7 +270,7 @@ NexusSet* NetCase::nex_input() if (items_[idx].statement == 0) continue; - NexusSet*tmp = items_[idx].statement->nex_input(); + NexusSet*tmp = items_[idx].statement->nex_input(rem_out); assert(tmp); result->add(*tmp); delete tmp; @@ -279,7 +279,7 @@ NexusSet* NetCase::nex_input() case is special and is identified by a null guard. The default guard obviously has no input. */ if (items_[idx].guard) { - tmp = items_[idx].guard->nex_input(); + tmp = items_[idx].guard->nex_input(rem_out); assert(tmp); result->add(*tmp); delete tmp; @@ -289,24 +289,24 @@ NexusSet* NetCase::nex_input() return result; } -NexusSet* NetCAssign::nex_input() +NexusSet* NetCAssign::nex_input(bool rem_out) { cerr << get_line() << ": internal warning: NetCAssign::nex_input()" << " not implemented." << endl; return new NexusSet; } -NexusSet* NetCondit::nex_input() +NexusSet* NetCondit::nex_input(bool rem_out) { - NexusSet*result = expr_->nex_input(); + NexusSet*result = expr_->nex_input(rem_out); if (if_ != 0) { - NexusSet*tmp = if_->nex_input(); + NexusSet*tmp = if_->nex_input(rem_out); result->add(*tmp); delete tmp; } if (else_ != 0) { - NexusSet*tmp = else_->nex_input(); + NexusSet*tmp = else_->nex_input(rem_out); result->add(*tmp); delete tmp; } @@ -314,16 +314,16 @@ NexusSet* NetCondit::nex_input() return result; } -NexusSet* NetForce::nex_input() +NexusSet* NetForce::nex_input(bool rem_out) { cerr << get_line() << ": internal warning: NetForce::nex_input()" << " not implemented." << endl; return new NexusSet; } -NexusSet* NetForever::nex_input() +NexusSet* NetForever::nex_input(bool rem_out) { - NexusSet*result = statement_->nex_input(); + NexusSet*result = statement_->nex_input(rem_out); return result; } @@ -336,29 +336,29 @@ NexusSet* NetForever::nex_input() * include the input set of the because it does not affect the * result. */ -NexusSet* NetPDelay::nex_input() +NexusSet* NetPDelay::nex_input(bool rem_out) { - NexusSet*result = statement_->nex_input(); + NexusSet*result = statement_->nex_input(rem_out); return result; } -NexusSet* NetRepeat::nex_input() +NexusSet* NetRepeat::nex_input(bool rem_out) { - NexusSet*result = statement_->nex_input(); - NexusSet*tmp = expr_->nex_input(); + NexusSet*result = statement_->nex_input(rem_out); + NexusSet*tmp = expr_->nex_input(rem_out); result->add(*tmp); delete tmp; return result; } -NexusSet* NetSTask::nex_input() +NexusSet* NetSTask::nex_input(bool rem_out) { if (parms_.count() == 0) return new NexusSet; - NexusSet*result = parms_[0]->nex_input(); + NexusSet*result = parms_[0]->nex_input(rem_out); for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) { - NexusSet*tmp = parms_[idx]->nex_input(); + NexusSet*tmp = parms_[idx]->nex_input(rem_out); result->add(*tmp); delete tmp; } @@ -371,79 +371,17 @@ NexusSet* NetSTask::nex_input() * parameters to consider, because the compiler already removed them * and converted them to blocking assignments. */ -NexusSet* NetUTask::nex_input() +NexusSet* NetUTask::nex_input(bool rem_out) { return new NexusSet; } -NexusSet* NetWhile::nex_input() +NexusSet* NetWhile::nex_input(bool rem_out) { - NexusSet*result = proc_->nex_input(); - NexusSet*tmp = cond_->nex_input(); + NexusSet*result = proc_->nex_input(rem_out); + NexusSet*tmp = cond_->nex_input(rem_out); result->add(*tmp); delete tmp; return result; } -/* - * $Log: net_nex_input.cc,v $ - * Revision 1.16 2007/01/16 05:44:15 steve - * Major rework of array handling. Memories are replaced with the - * more general concept of arrays. The NetMemory and NetEMemory - * classes are removed from the ivl core program, and the IVL_LPM_RAM - * lpm type is removed from the ivl_target API. - * - * Revision 1.15 2006/04/16 00:15:43 steve - * Fix part selects in l-values. - * - * Revision 1.14 2005/07/11 16:56:50 steve - * Remove NetVariable and ivl_variable_t structures. - * - * Revision 1.13 2005/01/24 05:28:30 steve - * Remove the NetEBitSel and combine all bit/part select - * behavior into the NetESelect node and IVL_EX_SELECT - * ivl_target expression type. - * - * Revision 1.12 2004/09/04 04:24:15 steve - * PR1026: assignment statements can have sensitivities in the l-values. - * - * Revision 1.11 2003/10/26 04:50:46 steve - * Case with empty statements has no inputs. - * - * Revision 1.10 2003/07/26 03:34:42 steve - * Start handling pad of expressions in code generators. - * - * Revision 1.9 2003/04/22 04:48:29 steve - * Support event names as expressions elements. - * - * Revision 1.8 2003/01/26 21:15:58 steve - * Rework expression parsing and elaboration to - * accommodate real/realtime values and expressions. - * - * Revision 1.7 2002/11/16 05:45:41 steve - * Handle default: case in net_inputs for NetCase. - * - * Revision 1.6 2002/08/18 22:07:16 steve - * Detect temporaries in sequential block synthesis. - * - * Revision 1.5 2002/08/12 01:34:59 steve - * conditional ident string using autoconfig. - * - * Revision 1.4 2002/07/14 23:47:58 steve - * Infinite loop in nex_input of NetBlock objects. - * - * Revision 1.3 2002/06/05 03:44:25 steve - * Add support for memory words in l-value of - * non-blocking assignments, and remove the special - * NetAssignMem_ and NetAssignMemNB classes. - * - * Revision 1.2 2002/04/21 17:43:12 steve - * implement nex_input for behavioral statements. - * - * Revision 1.1 2002/04/21 04:59:08 steve - * Add support for conbinational events by finding - * the inputs to expressions and some statements. - * Get case and assignment statements working. - * - */ - diff --git a/netlist.h b/netlist.h index 2fe5e3984..1cc118439 100644 --- a/netlist.h +++ b/netlist.h @@ -1136,7 +1136,7 @@ class NetExpr : public LineInfo { // Get the Nexus that are the input to this // expression. Normally this descends down to the reference to // a signal that reads from its input. - virtual NexusSet* nex_input() =0; + virtual NexusSet* nex_input(bool rem_out = true) =0; // Return a version of myself that is structural. This is used // for converting expressions to gates. @@ -1178,7 +1178,7 @@ class NetEConst : public NetExpr { virtual NetEConst* dup_expr() const; virtual NetNet*synthesize(Design*); - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); private: verinum value_; @@ -1231,7 +1231,7 @@ class NetECReal : public NetExpr { virtual NetECReal* dup_expr() const; virtual NetNet*synthesize(Design*); - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); private: verireal value_; @@ -1607,7 +1607,7 @@ class NetProc : public virtual LineInfo { // Find the Nexa that are input by the statement. This is used // for example by @* to find the inputs to the process for the // sensitivity list. - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); // Find the nexa that are set by the statement. Add the output // values to the set passed as a parameter. @@ -1716,7 +1716,7 @@ class NetAssign_ { // being outputs. For example foo[idx] = ... is the l-value // (NetAssign_ object) with a foo l-value and the input // expression idx. - NexusSet* nex_input(); + NexusSet* nex_input(bool rem_out = true); // This pointer is for keeping simple lists. NetAssign_* more; @@ -1754,7 +1754,7 @@ class NetAssignBase : public NetProc { void set_delay(NetExpr*); const NetExpr* get_delay() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void nex_output(NexusSet&o); @@ -1841,7 +1841,7 @@ class NetBlock : public NetProc { // for sequential blocks. void emit_recurse(struct target_t*) const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual int match_proc(struct proc_match_t*); @@ -1881,7 +1881,7 @@ class NetCase : public NetProc { const NetExpr*expr(unsigned idx) const { return items_[idx].guard;} const NetProc*stat(unsigned idx) const { return items_[idx].statement; } - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void nex_output(NexusSet&out); bool synth_async(Design*des, NetScope*scope, @@ -1915,7 +1915,7 @@ class NetCAssign : public NetAssignBase { explicit NetCAssign(NetAssign_*lv, NetExpr*rv); ~NetCAssign(); - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void dump(ostream&, unsigned ind) const; virtual bool emit_proc(struct target_t*) const; @@ -1948,7 +1948,7 @@ class NetCondit : public NetProc { bool emit_recurse_if(struct target_t*) const; bool emit_recurse_else(struct target_t*) const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void nex_output(NexusSet&o); bool is_asynchronous(); @@ -2225,7 +2225,7 @@ class NetForce : public NetAssignBase { explicit NetForce(NetAssign_*l, NetExpr*r); ~NetForce(); - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void dump(ostream&, unsigned ind) const; virtual bool emit_proc(struct target_t*) const; @@ -2243,7 +2243,7 @@ class NetForever : public NetProc { void emit_recurse(struct target_t*) const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual bool emit_proc(struct target_t*) const; virtual void dump(ostream&, unsigned ind) const; @@ -2313,7 +2313,7 @@ class NetPDelay : public NetProc { uint64_t delay() const; const NetExpr*expr() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; @@ -2339,7 +2339,7 @@ class NetRepeat : public NetProc { const NetExpr*expr() const; void emit_recurse(struct target_t*) const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual bool emit_proc(struct target_t*) const; virtual void dump(ostream&, unsigned ind) const; @@ -2385,7 +2385,7 @@ class NetSTask : public NetProc { const NetExpr* parm(unsigned idx) const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(ostream&, unsigned ind) const; @@ -2458,7 +2458,7 @@ class NetEUFunc : public NetExpr { virtual void expr_scan(struct expr_scan_t*) const; virtual NetEUFunc*dup_expr() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); private: NetScope*func_; @@ -2485,7 +2485,7 @@ class NetUTask : public NetProc { const NetScope* task() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(ostream&, unsigned ind) const; @@ -2509,7 +2509,7 @@ class NetWhile : public NetProc { void emit_proc_recurse(struct target_t*) const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(ostream&, unsigned ind) const; @@ -2616,7 +2616,7 @@ class NetEBinary : public NetExpr { virtual bool has_width() const; virtual NetEBinary* dup_expr() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; @@ -2860,7 +2860,7 @@ class NetEConcat : public NetExpr { unsigned nparms() const { return parms_.count() ; } NetExpr* parm(unsigned idx) const { return parms_[idx]; } - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual bool has_width() const; virtual bool set_width(unsigned w, bool last_chance =false); virtual NetEConcat* dup_expr() const; @@ -2892,7 +2892,7 @@ class NetEParam : public NetExpr { NetEParam(class Design*des, NetScope*scope, perm_string name); ~NetEParam(); - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual bool set_width(unsigned w, bool last_chance); virtual bool has_width() const; virtual void expr_scan(struct expr_scan_t*) const; @@ -2931,7 +2931,7 @@ class NetESelect : public NetExpr { const NetExpr*sub_expr() const; const NetExpr*select() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual bool set_width(unsigned w, bool last_chance =false); virtual bool has_width() const; virtual void expr_scan(struct expr_scan_t*) const; @@ -2958,7 +2958,7 @@ class NetEEvent : public NetExpr { virtual void expr_scan(struct expr_scan_t*) const; virtual NetEEvent* dup_expr() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void dump(ostream&os) const; @@ -2981,7 +2981,7 @@ class NetEScope : public NetExpr { virtual void expr_scan(struct expr_scan_t*) const; virtual NetEScope* dup_expr() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void dump(ostream&os) const; @@ -3009,7 +3009,7 @@ class NetESFunc : public NetExpr { const NetExpr* parm(unsigned idx) const; virtual ivl_variable_type_t expr_type() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual bool set_width(unsigned, bool last_chance); virtual void dump(ostream&) const; @@ -3048,7 +3048,7 @@ class NetETernary : public NetExpr { virtual NetExpr* eval_tree(int prune_to_width = -1); virtual ivl_variable_type_t expr_type() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; virtual NetNet*synthesize(Design*); @@ -3089,7 +3089,7 @@ class NetEUnary : public NetExpr { virtual NetEConst* eval_tree(int prune_to_width = -1); virtual ivl_variable_type_t expr_type() const; - virtual NexusSet* nex_input(); + virtual NexusSet* nex_input(bool rem_out = true); virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; @@ -3147,7 +3147,7 @@ class NetESignal : public NetExpr { virtual NetESignal* dup_expr() const; NetNet* synthesize(Design*des); - NexusSet* nex_input(); + NexusSet* nex_input(bool rem_out = true); // This is the expression for selecting an array word, if this // signal refers to an array.