diff --git a/PDelays.cc b/PDelays.cc index c547a2c08..e39a57122 100644 --- a/PDelays.cc +++ b/PDelays.cc @@ -101,7 +101,7 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr) return dex; } -static NetExpr* make_delay_nets(Design*des, NetExpr*expr) +static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr) { if (dynamic_cast (expr)) return expr; @@ -109,7 +109,7 @@ static NetExpr* make_delay_nets(Design*des, NetExpr*expr) if (dynamic_cast (expr)) return expr; - NetNet*sig = expr->synthesize(des); + NetNet*sig = expr->synthesize(des, scope); if (sig == 0) { cerr << expr->get_fileline() << ": error: Expression " << *expr << " is not suitable for delay expression." << endl; @@ -132,17 +132,17 @@ void PDelays::eval_delays(Design*des, NetScope*scope, if (delay_[0]) { rise_time = calculate_val(des, scope, delay_[0]); if (as_nets_flag) - rise_time = make_delay_nets(des, rise_time); + rise_time = make_delay_nets(des, scope, rise_time); if (delay_[1]) { fall_time = calculate_val(des, scope, delay_[1]); if (as_nets_flag) - fall_time = make_delay_nets(des, fall_time); + fall_time = make_delay_nets(des, scope, fall_time); if (delay_[2]) { decay_time = calculate_val(des, scope, delay_[2]); if (as_nets_flag) - decay_time = make_delay_nets(des, decay_time); + decay_time = make_delay_nets(des, scope, decay_time); } else { if (rise_time < fall_time) diff --git a/elab_net.cc b/elab_net.cc index 6cd63c12d..deffb5404 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -355,7 +355,7 @@ static NetNet* compare_eq_constant(Design*des, NetScope*scope, : verinum::V1, 1); NetEConst*ogate = new NetEConst(oval); - NetNet*osig = ogate->synthesize(des); + NetNet*osig = ogate->synthesize(des, scope); osig->data_type(lsig->data_type()); osig->set_line(*lsig); osig->rise_time(rise); @@ -484,7 +484,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope, use of the situation, or 0 if it cannot. */ if (NetEConst*tmp = dynamic_cast(rexp)) { - lsig = lexp->synthesize(des); + lsig = lexp->synthesize(des, scope); if (lsig == 0) return 0; delete lexp; lexp = 0; @@ -492,7 +492,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope, if (real_arg) { verireal vrl(tmp->value().as_double()); NetECReal rlval(vrl); - rsig = rlval.synthesize(des); + rsig = rlval.synthesize(des, scope); delete rexp; rexp = 0; } else { @@ -508,7 +508,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope, if (NetEConst*tmp = dynamic_cast(lexp)) { - rsig = rexp->synthesize(des); + rsig = rexp->synthesize(des, scope); if (rsig == 0) return 0; delete rexp; rexp = 0; @@ -516,7 +516,7 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope, if (real_arg) { verireal vrl(tmp->value().as_double()); NetECReal rlval(vrl); - lsig = rlval.synthesize(des); + lsig = rlval.synthesize(des, scope); delete lexp; lexp = 0; } else { @@ -531,13 +531,13 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope, } if (lsig == 0) { - lsig = lexp->synthesize(des); + lsig = lexp->synthesize(des, scope); if (lsig == 0) return 0; delete lexp; } if (rsig == 0) { - rsig = rexp->synthesize(des); + rsig = rexp->synthesize(des, scope); if (rsig == 0) return 0; delete rexp; } @@ -1737,14 +1737,14 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope, sel_expr = make_sub_expr(sig->lsb(), sel_expr); eval_expr(sel_expr); - sel = sel_expr->synthesize(des); + sel = sel_expr->synthesize(des, scope); } else if (sig->lsb() != 0) { NetExpr*sel_expr = index_tail.msb->elaborate_expr(des, scope, -1,false); sel_expr = make_add_expr(sel_expr, - sig->lsb()); eval_expr(sel_expr); - sel = sel_expr->synthesize(des); + sel = sel_expr->synthesize(des, scope); } else { sel = index_tail.msb->elaborate_net(des, scope, 0, 0, 0, 0); @@ -2188,7 +2188,7 @@ NetNet* PEIdent::elaborate_net_net_idx_up_(Design*des, NetScope*scope, base = make_sub_expr(vwid-offset-wid, base); } - NetPartSelect*sel = new NetPartSelect(sig, base->synthesize(des), wid); + NetPartSelect*sel = new NetPartSelect(sig, base->synthesize(des, scope), wid); sel->set_line(*this); des->add_node(sel); @@ -2281,7 +2281,7 @@ NetNet* PEIdent::elaborate_net_array_(Design*des, NetScope*scope, index_ex = make_add_expr(index_ex, 0-array_base); } - NetNet*index_net = index_ex->synthesize(des); + NetNet*index_net = index_ex->synthesize(des, scope); connect(mux->pin_Address(), index_net->pin(0)); NetNet*tmp = new NetNet(scope, scope->local_symbol(), @@ -3159,7 +3159,7 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope, * on this for now. */ break; } - expr_sig = expr->synthesize(des); + expr_sig = expr->synthesize(des, scope); if (expr_sig == 0 || tru_sig == 0 || fal_sig == 0) return 0; @@ -3355,7 +3355,7 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, drive0, drive1); } - NetNet* sub_sig = expr->synthesize(des); + NetNet* sub_sig = expr->synthesize(des, scope); if (sub_sig == 0) return 0; @@ -3621,7 +3621,7 @@ NetNet* PEUnary::elab_net_unary_real_(Design*des, NetScope*scope, << *this << "."<synthesize(des); + NetNet* sub_sig = expr->synthesize(des, scope); if (sub_sig == 0) return 0; delete expr; diff --git a/elaborate.cc b/elaborate.cc index ad7c273ab..fae8b52e0 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -3472,7 +3472,7 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const // FIXME: Look for constant expressions here? // Get a net form. - condit_sig = tmp->synthesize(des); + condit_sig = tmp->synthesize(des, scope); ivl_assert(*condition, condit_sig); } diff --git a/expr_synth.cc b/expr_synth.cc index df291f6d1..d4b390437 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -26,14 +26,14 @@ # include "netmisc.h" # include "ivl_assert.h" -NetNet* convert_to_real_const(Design*des, NetExpr*expr, NetExpr*obj) +static NetNet* convert_to_real_const(Design*des, NetScope*scope, NetExpr*expr, NetExpr*obj) { NetNet* sig; if (NetEConst*tmp = dynamic_cast(expr)) { verireal vrl(tmp->value().as_double()); NetECReal rlval(vrl); - sig = rlval.synthesize(des); + sig = rlval.synthesize(des, scope); } else { cerr << obj->get_fileline() << ": sorry: Cannot convert " "bit based value (" << *expr << ") to real." << endl; @@ -45,9 +45,10 @@ NetNet* convert_to_real_const(Design*des, NetExpr*expr, NetExpr*obj) } /* Note that lsig, rsig and real_args are references. */ -bool process_binary_args(Design*des, NetExpr*left, NetExpr*right, - NetNet*&lsig, NetNet*&rsig, bool&real_args, - NetExpr*obj) +static bool process_binary_args(Design*des, NetScope*scope, + NetExpr*left, NetExpr*right, + NetNet*&lsig, NetNet*&rsig, bool&real_args, + NetExpr*obj) { if (left->expr_type() == IVL_VT_REAL || right->expr_type() == IVL_VT_REAL) { @@ -56,20 +57,20 @@ bool process_binary_args(Design*des, NetExpr*left, NetExpr*right, /* Currently we will have a runtime assert if both expressions are not real, though we can convert constants. */ if (left->expr_type() == IVL_VT_REAL) { - lsig = left->synthesize(des); + lsig = left->synthesize(des, scope); } else { - lsig = convert_to_real_const(des, left, obj); + lsig = convert_to_real_const(des, scope, left, obj); } if (right->expr_type() == IVL_VT_REAL) { - rsig = right->synthesize(des); + rsig = right->synthesize(des, scope); } else { - rsig = convert_to_real_const(des, right, obj); + rsig = convert_to_real_const(des, scope, right, obj); } } else { real_args = false; - lsig = left->synthesize(des); - rsig = right->synthesize(des); + lsig = left->synthesize(des, scope); + rsig = right->synthesize(des, scope); } @@ -77,7 +78,12 @@ bool process_binary_args(Design*des, NetExpr*left, NetExpr*right, else return false; } -NetNet* NetExpr::synthesize(Design*des) +NetNet* NetExpr::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { cerr << get_fileline() << ": internal error: cannot synthesize expression: " << *this << endl; @@ -88,13 +94,18 @@ NetNet* NetExpr::synthesize(Design*des) /* * Make an LPM_ADD_SUB device from addition operators. */ -NetNet* NetEBAdd::synthesize(Design*des) +NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { assert((op()=='+') || (op()=='-')); NetNet *lsig=0, *rsig=0; bool real_args=false; - if (process_binary_args(des, left_, right_, lsig, rsig, + if (process_binary_args(des, scope, left_, right_, lsig, rsig, real_args, this)) { return 0; } @@ -138,10 +149,15 @@ NetNet* NetEBAdd::synthesize(Design*des) * signals, then just connect a single gate to each bit of the vector * of the expression. */ -NetNet* NetEBBits::synthesize(Design*des) +NetNet* NetEBBits::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { - NetNet*lsig = left_->synthesize(des); - NetNet*rsig = right_->synthesize(des); + NetNet*lsig = left_->synthesize(des, scope); + NetNet*rsig = right_->synthesize(des, scope); if (lsig == 0 || rsig == 0) return 0; @@ -154,9 +170,6 @@ NetNet* NetEBBits::synthesize(Design*des) return 0; } - NetScope*scope = lsig->scope(); - assert(scope); - unsigned width = lsig->vector_width(); if (rsig->vector_width() > width) width = rsig->vector_width(); @@ -205,13 +218,18 @@ NetNet* NetEBBits::synthesize(Design*des) return osig; } -NetNet* NetEBComp::synthesize(Design*des) +NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { NetNet *lsig=0, *rsig=0; unsigned width; bool real_args=false; - if (process_binary_args(des, left_, right_, lsig, rsig, + if (process_binary_args(des, scope, left_, right_, lsig, rsig, real_args, this)) { return 0; } @@ -226,9 +244,6 @@ NetNet* NetEBComp::synthesize(Design*des) rsig = pad_to_width(des, rsig, width); } - NetScope*scope = lsig->scope(); - assert(scope); - NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, 1); osig->set_line(*this); @@ -321,12 +336,17 @@ NetNet* NetEBComp::synthesize(Design*des) return osig; } -NetNet* NetEBPow::synthesize(Design*des) +NetNet* NetEBPow::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { NetNet *lsig=0, *rsig=0; unsigned width; bool real_args=false; - if (process_binary_args(des, left_, right_, lsig, rsig, + if (process_binary_args(des, scope, left_, right_, lsig, rsig, real_args, this)) { return 0; } @@ -334,9 +354,6 @@ NetNet* NetEBPow::synthesize(Design*des) if (real_args) width = 1; else width = expr_width(); - NetScope*scope = lsig->scope(); - assert(scope); - NetPow*powr = new NetPow(scope, scope->local_symbol(), width, lsig->vector_width(), rsig->vector_width()); @@ -359,12 +376,17 @@ NetNet* NetEBPow::synthesize(Design*des) return osig; } -NetNet* NetEBMult::synthesize(Design*des) +NetNet* NetEBMult::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { NetNet *lsig=0, *rsig=0; unsigned width; bool real_args=false; - if (process_binary_args(des, left_, right_, lsig, rsig, + if (process_binary_args(des, scope, left_, right_, lsig, rsig, real_args, this)) { return 0; } @@ -372,9 +394,6 @@ NetNet* NetEBMult::synthesize(Design*des) if (real_args) width = 1; else width = expr_width(); - NetScope*scope = lsig->scope(); - assert(scope); - NetMult*mult = new NetMult(scope, scope->local_symbol(), width, lsig->vector_width(), @@ -398,12 +417,17 @@ NetNet* NetEBMult::synthesize(Design*des) return osig; } -NetNet* NetEBDiv::synthesize(Design*des) +NetNet* NetEBDiv::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { NetNet *lsig=0, *rsig=0; unsigned width; bool real_args=false; - if (process_binary_args(des, left_, right_, lsig, rsig, + if (process_binary_args(des, scope, left_, right_, lsig, rsig, real_args, this)) { return 0; } @@ -411,8 +435,6 @@ NetNet* NetEBDiv::synthesize(Design*des) if (real_args) width = 1; else width = expr_width(); - NetScope*scope = lsig->scope(); - NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, width); osig->set_line(*this); @@ -471,10 +493,15 @@ NetNet* NetEBDiv::synthesize(Design*des) return osig; } -NetNet* NetEBLogic::synthesize(Design*des) +NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { - NetNet*lsig = left_->synthesize(des); - NetNet*rsig = right_->synthesize(des); + NetNet*lsig = left_->synthesize(des, scope); + NetNet*rsig = right_->synthesize(des, scope); if (lsig == 0 || rsig == 0) return 0; @@ -487,9 +514,6 @@ NetNet* NetEBLogic::synthesize(Design*des) return 0; } - NetScope*scope = lsig->scope(); - assert(scope); - NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, 1); osig->data_type(expr_type()); @@ -551,11 +575,16 @@ NetNet* NetEBLogic::synthesize(Design*des) return osig; } -NetNet* NetEBShift::synthesize(Design*des) +NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { eval_expr(right_); - NetNet*lsig = left_->synthesize(des); + NetNet*lsig = left_->synthesize(des, scope); if (lsig == 0) return 0; @@ -571,8 +600,6 @@ NetNet* NetEBShift::synthesize(Design*des) bool right_flag = op_ == 'r' || op_ == 'R'; bool signed_flag = op_ == 'R'; - NetScope*scope = lsig->scope(); - /* Detect the special case where the shift amount is constant. Evaluate the shift amount, and simply reconnect the left operand to the output, but shifted. */ @@ -652,7 +679,7 @@ NetNet* NetEBShift::synthesize(Design*des) return osig; } - NetNet*rsig = right_->synthesize(des); + NetNet*rsig = right_->synthesize(des, scope); if (rsig == 0) return 0; @@ -678,13 +705,18 @@ NetNet* NetEBShift::synthesize(Design*des) return osig; } -NetNet* NetEConcat::synthesize(Design*des) +NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { /* First, synthesize the operands. */ NetNet**tmp = new NetNet*[parms_.count()]; bool flag = true; for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { - tmp[idx] = parms_[idx]->synthesize(des); + tmp[idx] = parms_[idx]->synthesize(des, scope); if (tmp[idx] == 0) flag = false; } @@ -693,8 +725,6 @@ NetNet* NetEConcat::synthesize(Design*des) return 0; assert(tmp[0]); - NetScope*scope = tmp[0]->scope(); - assert(scope); /* Make a NetNet object to carry the output vector. */ perm_string path = scope->local_symbol(); @@ -721,11 +751,13 @@ NetNet* NetEConcat::synthesize(Design*des) return osig; } -NetNet* NetEConst::synthesize(Design*des) +NetNet* NetEConst::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { - NetScope*scope = des->find_root_scope(); - assert(scope); - perm_string path = scope->local_symbol(); unsigned width=expr_width(); @@ -743,11 +775,13 @@ NetNet* NetEConst::synthesize(Design*des) /* * Create a NetLiteral object to represent real valued constants. */ -NetNet* NetECReal::synthesize(Design*des) +NetNet* NetECReal::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { - NetScope*scope = des->find_root_scope(); - assert(scope); - perm_string path = scope->local_symbol(); NetNet*osig = new NetNet(scope, path, NetNet::WIRE, 1); @@ -768,9 +802,14 @@ NetNet* NetECReal::synthesize(Design*des) * The bitwise unary logic operator (there is only one) is turned * into discrete gates just as easily as the binary ones above. */ -NetNet* NetEUBits::synthesize(Design*des) +NetNet* NetEUBits::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { - NetNet*isig = expr_->synthesize(des); + NetNet*isig = expr_->synthesize(des, scope); if (isig == 0) return 0; @@ -782,9 +821,6 @@ NetNet* NetEUBits::synthesize(Design*des) return 0; } - NetScope*scope = isig->scope(); - assert(scope); - unsigned width = isig->vector_width(); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, width); @@ -810,9 +846,14 @@ NetNet* NetEUBits::synthesize(Design*des) return osig; } -NetNet* NetEUReduce::synthesize(Design*des) +NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { - NetNet*isig = expr_->synthesize(des); + NetNet*isig = expr_->synthesize(des, scope); if (isig == 0) return 0; @@ -824,9 +865,6 @@ NetNet* NetEUReduce::synthesize(Design*des) return 0; } - NetScope*scope = isig->scope(); - assert(scope); - NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, 1); osig->data_type(expr_type()); @@ -871,22 +909,25 @@ NetNet* NetEUReduce::synthesize(Design*des) return osig; } -NetNet* NetESelect::synthesize(Design *des) +NetNet* NetESelect::synthesize(Design *des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { - NetNet*sub = expr_->synthesize(des); + NetNet*sub = expr_->synthesize(des, scope); if (sub == 0) return 0; - NetScope*scope = sub->scope(); - NetNet*off = 0; // This handles the case that the NetESelect exists to do an // actual part/bit select. Generate a NetPartSelect object to // do the work, and replace "sub" with the selected output. if (base_ != 0) { - off = base_->synthesize(des); + off = base_->synthesize(des, scope); NetPartSelect*sel = new NetPartSelect(sub, off, expr_width()); sel->set_line(*this); @@ -967,11 +1008,16 @@ NetNet* NetESelect::synthesize(Design *des) * expressions to the B and A inputs. This way, when the select input * is one, the B input, which is the true expression, is selected. */ -NetNet* NetETernary::synthesize(Design *des) +NetNet* NetETernary::synthesize(Design *des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { - NetNet*csig = cond_->synthesize(des), - *tsig = true_val_->synthesize(des), - *fsig = false_val_->synthesize(des); + NetNet*csig = cond_->synthesize(des, scope), + *tsig = true_val_->synthesize(des, scope), + *fsig = false_val_->synthesize(des, scope); if (csig == 0 || tsig == 0 || fsig == 0) return 0; @@ -1025,13 +1071,16 @@ NetNet* NetETernary::synthesize(Design *des) * a bit more work needs to be done. Return a temporary that represents * the selected word. */ -NetNet* NetESignal::synthesize(Design*des) +NetNet* NetESignal::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { if (word_ == 0) return net_; - NetScope*scope = net_->scope(); - NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, net_->vector_width()); tmp->set_line(*this); @@ -1053,7 +1102,7 @@ NetNet* NetESignal::synthesize(Design*des) mux->set_line(*this); des->add_node(mux); - NetNet*index_net = word_->synthesize(des); + NetNet*index_net = word_->synthesize(des, scope); connect(mux->pin_Address(), index_net->pin(0)); connect(tmp->pin(0), mux->pin_Result()); @@ -1061,7 +1110,12 @@ NetNet* NetESignal::synthesize(Design*des) return tmp; } -NetNet* NetESFunc::synthesize(Design*des) +NetNet* NetESFunc::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { cerr << get_fileline() << ": sorry: cannot synthesize system function: " << *this << " in this context" << endl; @@ -1069,14 +1123,19 @@ NetNet* NetESFunc::synthesize(Design*des) return 0; } -NetNet* NetEUFunc::synthesize(Design*des) +NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, + Link::strength_t drive0, + Link::strength_t drive1) { svector eparms (parms_.count()); /* Synthesize the arguments. */ bool errors = false; for (unsigned idx = 0; idx < eparms.count(); idx += 1) { - NetNet*tmp = parms_[idx]->synthesize(des); + NetNet*tmp = parms_[idx]->synthesize(des, scope); if (tmp == 0) { cerr << get_fileline() << ": error: Unable to synthesize " "port " << idx << " of call to " diff --git a/netlist.h b/netlist.h index 7818938e8..e2f34b2d1 100644 --- a/netlist.h +++ b/netlist.h @@ -1535,8 +1535,21 @@ class NetExpr : public LineInfo { 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. - virtual NetNet*synthesize(Design*); + // for converting expressions to gates. The arguments are: + // + // des, scope: The context where this work is done + // + // rise/fall/decay: Attach these delays to the driver for the + // expression output. + // + // drive0/drive1: Attach these strengths tp the driver for + // the expression output. + virtual NetNet*synthesize(Design*des, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); protected: @@ -1574,7 +1587,12 @@ class NetEConst : public NetExpr { virtual void dump(ostream&) const; virtual NetEConst* dup_expr() const; - virtual NetNet*synthesize(Design*); + virtual NetNet*synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); virtual NexusSet* nex_input(bool rem_out = true); private: @@ -1627,7 +1645,12 @@ class NetECReal : public NetExpr { virtual void dump(ostream&) const; virtual NetECReal* dup_expr() const; - virtual NetNet*synthesize(Design*); + virtual NetNet*synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); virtual NexusSet* nex_input(bool rem_out = true); private: @@ -2864,7 +2887,12 @@ class NetEUFunc : public NetExpr { virtual void expr_scan(struct expr_scan_t*) const; virtual NetEUFunc*dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true); - virtual NetNet* synthesize(Design*des); + virtual NetNet* synthesize(Design*des, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); private: NetScope*scope_; @@ -3058,7 +3086,12 @@ class NetEBAdd : public NetEBinary { virtual bool set_width(unsigned w, bool last_chance); virtual NetEBAdd* dup_expr() const; virtual NetExpr* eval_tree(int prune_to_width = -1); - virtual NetNet* synthesize(Design*); + virtual NetNet* synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); private: NetECReal* eval_tree_real_(); @@ -3080,7 +3113,12 @@ class NetEBDiv : public NetEBinary { virtual bool set_width(unsigned w, bool last_chance); virtual NetEBDiv* dup_expr() const; virtual NetExpr* eval_tree(int prune_to_width = -1); - virtual NetNet* synthesize(Design*); + virtual NetNet* synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); }; /* @@ -3107,7 +3145,12 @@ class NetEBBits : public NetEBinary { virtual NetEBBits* dup_expr() const; virtual NetEConst* eval_tree(int prune_to_width = -1); - virtual NetNet* synthesize(Design*); + virtual NetNet* synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); }; /* @@ -3138,7 +3181,12 @@ class NetEBComp : public NetEBinary { virtual NetEBComp* dup_expr() const; virtual NetEConst* eval_tree(int prune_to_width = -1); - virtual NetNet* synthesize(Design*); + virtual NetNet* synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); private: NetEConst* must_be_leeq_(NetExpr*le, const verinum&rv, bool eq_flag); @@ -3169,7 +3217,12 @@ class NetEBLogic : public NetEBinary { virtual bool set_width(unsigned w, bool last_chance); virtual NetEBLogic* dup_expr() const; virtual NetEConst* eval_tree(int prune_to_width = -1); - virtual NetNet* synthesize(Design*); + virtual NetNet* synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); private: }; @@ -3207,7 +3260,12 @@ class NetEBMult : public NetEBinary { virtual bool set_width(unsigned w, bool last_chance); virtual NetEBMult* dup_expr() const; virtual NetExpr* eval_tree(int prune_to_width = -1); - virtual NetNet* synthesize(Design*); + virtual NetNet* synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); private: @@ -3229,7 +3287,12 @@ class NetEBPow : public NetEBinary { virtual bool set_width(unsigned w, bool last_chance); virtual NetEBPow* dup_expr() const; virtual NetExpr* eval_tree(int prune_to_width = -1); - virtual NetNet* synthesize(Design*); + virtual NetNet* synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); private: @@ -3261,7 +3324,12 @@ class NetEBShift : public NetEBinary { virtual NetEBShift* dup_expr() const; virtual NetEConst* eval_tree(int prune_to_width = -1); - virtual NetNet* synthesize(Design*); + virtual NetNet* synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); private: }; @@ -3295,7 +3363,12 @@ class NetEConcat : public NetExpr { virtual bool set_width(unsigned w, bool last_chance =false); virtual NetEConcat* dup_expr() const; virtual NetEConst* eval_tree(int prune_to_width = -1); - virtual NetNet*synthesize(Design*); + virtual NetNet*synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; @@ -3371,7 +3444,12 @@ class NetESelect : public NetExpr { virtual void expr_scan(struct expr_scan_t*) const; virtual NetEConst* eval_tree(int prune_to_width = -1); virtual NetESelect* dup_expr() const; - virtual NetNet*synthesize(Design*des); + virtual NetNet*synthesize(Design*des, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); virtual void dump(ostream&) const; private: @@ -3449,7 +3527,12 @@ class NetESFunc : public NetExpr { virtual void expr_scan(struct expr_scan_t*) const; virtual NetESFunc*dup_expr() const; - virtual NetNet*synthesize(Design*); + virtual NetNet*synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); private: const char* name_; @@ -3486,7 +3569,12 @@ class NetETernary : public NetExpr { 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*); + virtual NetNet*synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); private: NetExpr*cond_; @@ -3543,7 +3631,12 @@ class NetEUBits : public NetEUnary { NetEUBits(char op, NetExpr*ex); ~NetEUBits(); - virtual NetNet* synthesize(Design*); + virtual NetNet* synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); virtual NetExpr* eval_tree(int prune_to_width = -1); virtual ivl_variable_type_t expr_type() const; @@ -3556,7 +3649,12 @@ class NetEUReduce : public NetEUnary { ~NetEUReduce(); virtual bool set_width(unsigned w, bool last_chance); - virtual NetNet* synthesize(Design*); + virtual NetNet* synthesize(Design*, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); virtual NetEUReduce* dup_expr() const; virtual NetEConst* eval_tree(int prune_to_width = -1); virtual ivl_variable_type_t expr_type() const; @@ -3583,7 +3681,12 @@ class NetESignal : public NetExpr { virtual bool set_width(unsigned, bool last_chance); virtual NetESignal* dup_expr() const; - NetNet* synthesize(Design*des); + NetNet* synthesize(Design*des, NetScope*scope, + const NetExpr* rise =0, + const NetExpr* fall =0, + const NetExpr* decay =0, + Link::strength_t drive0 =Link::STRONG, + Link::strength_t drive1 =Link::STRONG); NexusSet* nex_input(bool rem_out = true); // This is the expression for selecting an array word, if this diff --git a/syn-rules.y b/syn-rules.y index 49ea2586b..78c4b4588 100644 --- a/syn-rules.y +++ b/syn-rules.y @@ -1,7 +1,7 @@ %{ /* - * Copyright (c) 2000-2007 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -141,7 +141,7 @@ static void make_DFF_CE(Design*des, NetProcTop*top, NetEvWait*wclk, NetEvProbe*pclk = eclk->probe(0); NetESignal*d = dynamic_cast (asn->rval()); - NetNet*ce = cexp? cexp->synthesize(des) : 0; + NetNet*ce = cexp? cexp->synthesize(des, top->scope()) : 0; if (d == 0) { cerr << asn->get_fileline() << ": internal error: " diff --git a/synth.cc b/synth.cc index e92276d3a..ac2aaeb87 100644 --- a/synth.cc +++ b/synth.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -16,9 +16,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ifdef HAVE_CVS_IDENT -#ident "$Id: synth.cc,v 1.14 2002/08/12 01:35:00 steve Exp $" -#endif # include "config.h" @@ -36,12 +33,13 @@ class do_expr : public proc_match_t { public: - do_expr(Design*d) - : des_(d) { } + do_expr(Design*d, NetScope*s) + : des_(d), scope_(s) { } private: Design*des_; + NetScope*scope_; virtual int assign(NetAssign*); virtual int assign_nb(NetAssignNB*); @@ -55,7 +53,7 @@ int do_expr::assign(NetAssign*stmt) if (dynamic_cast(stmt->rval())) return 0; - NetNet*tmp = stmt->rval()->synthesize(des_); + NetNet*tmp = stmt->rval()->synthesize(des_, scope_); if (tmp == 0) return 0; @@ -70,7 +68,7 @@ int do_expr::assign_nb(NetAssignNB*stmt) if (dynamic_cast(stmt->rval())) return 0; - NetNet*tmp = stmt->rval()->synthesize(des_); + NetNet*tmp = stmt->rval()->synthesize(des_, scope_); if (tmp == 0) return 0; @@ -84,7 +82,7 @@ int do_expr::condit(NetCondit*stmt) { /* synthesize the condition expression, if necessary. */ if (! dynamic_cast(stmt->expr())) { - NetNet*tmp = stmt->expr()->synthesize(des_); + NetNet*tmp = stmt->expr()->synthesize(des_, scope_); if (tmp) { NetESignal*tmpe = new NetESignal(tmp); @@ -144,13 +142,13 @@ void synth_f::process(class Design*des, class NetProcTop*top) void synth_f::proc_always_(class Design*des) { - do_expr expr_pat(des); + do_expr expr_pat(des, top_->scope()); top_->statement()->match_proc(&expr_pat); } void synth_f::proc_initial_(class Design*des) { - do_expr expr_pat(des); + do_expr expr_pat(des, top_->scope()); top_->statement()->match_proc(&expr_pat); } @@ -159,28 +157,3 @@ void synth(Design*des) synth_f synth_obj; des->functor(&synth_obj); } - -/* - * $Log: synth.cc,v $ - * Revision 1.14 2002/08/12 01:35:00 steve - * conditional ident string using autoconfig. - * - * Revision 1.13 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.12 2001/07/25 03:10:49 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - * - * Revision 1.11 2000/11/22 21:18:42 steve - * synthesize the rvalue of <= statements. - * - * Revision 1.10 2000/05/13 20:55:47 steve - * Use yacc based synthesizer. - * - * Revision 1.9 2000/04/16 22:57:34 steve - * Catch expressions that are part of conditionals. - */ - diff --git a/synth2.cc b/synth2.cc index 812dceb03..dbd843759 100644 --- a/synth2.cc +++ b/synth2.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2007 Stephen Williams (steve@icarus.com) + * Copyright (c) 2002-2008 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -60,7 +60,7 @@ bool NetProc::synth_sync(Design*des, NetScope*scope, NetFF*ff, bool NetAssignBase::synth_async(Design*des, NetScope*scope, const NetBus&nex_map, NetBus&nex_out) { - NetNet*rsig = rval_->synthesize(des); + NetNet*rsig = rval_->synthesize(des, scope); assert(rsig); NetNet*lsig = lval_->sig(); @@ -155,7 +155,7 @@ bool NetCase::synth_async(Design*des, NetScope*scope, const NetBus&nex_map, NetBus&nex_out) { /* Synthesize the select expression. */ - NetNet*esig = expr_->synthesize(des); + NetNet*esig = expr_->synthesize(des, scope); unsigned sel_width = esig->vector_width(); assert(sel_width > 0);