diff --git a/Makefile.in b/Makefile.in index 1a177aa13..9bcd535f4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -108,8 +108,8 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \ net_design.o netdarray.o \ - netenum.o netstruct.o net_event.o net_expr.o net_func.o net_func_eval.o \ - net_link.o net_modulo.o \ + netenum.o netstruct.o netvector.o net_event.o net_expr.o net_func.o \ + net_func_eval.o net_link.o net_modulo.o \ net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \ net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \ pform_disciplines.o pform_dump.o pform_pclass.o pform_string_type.o \ diff --git a/design_dump.cc b/design_dump.cc index af1483e65..926ee780f 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -29,6 +29,7 @@ # include "compiler.h" # include "discipline.h" # include "netdarray.h" +# include "netvector.h" # include "ivl_assert.h" # include "PExpr.h" @@ -140,6 +141,12 @@ ostream& operator << (ostream&o, ivl_switch_type_t val) return o; } +ostream& netvector_t::debug_dump(std::ostream&o) const +{ + o << type_ << packed_dims_; + return o; +} + static inline void dump_scope_path(ostream&o, const NetScope*scope) { const NetScope*parent = scope->parent(); @@ -235,7 +242,6 @@ void NetNet::dump_net(ostream&o, unsigned ind) const o << " pin_count=" << pin_count(); if (local_flag_) o << " (local)"; - o << " " << data_type_; if (signed_) o << " signed"; switch (port_type_) { @@ -261,6 +267,10 @@ void NetNet::dump_net(ostream&o, unsigned ind) const if (ivl_discipline_t dis = get_discipline()) o << " discipline=" << dis->name(); + if (netvector_t*varray = dynamic_cast(net_type_)) + o << " vector " << varray->packed_dims() + << " of " << *varray; + if (netdarray_t*darray = darray_type()) o << " dynamic array of " << darray->data_type(); diff --git a/elab_expr.cc b/elab_expr.cc index d377e3b61..b7c890268 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -27,6 +27,7 @@ # include "pform.h" # include "netlist.h" # include "netenum.h" +# include "netvector.h" # include "discipline.h" # include "netmisc.h" # include "netdarray.h" @@ -2382,6 +2383,10 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode) expr_width_ = net->vector_width(); min_width_ = expr_width_; signed_flag_ = net->get_signed(); + if (debug_elaborate) { + cerr << get_fileline() << ": PEIdent::test_width: " + << net->name() << " is a net, width=" << expr_width_ << endl; + } return expr_width_; } @@ -4503,9 +4508,9 @@ NetNet* Design::find_discipline_reference(ivl_discipline_t dis, NetScope*scope) if (gnd) return gnd; string name = string(dis->name()) + "$gnd"; - gnd = new NetNet(scope, lex_strings.make(name), NetNet::WIRE, 1); + netvector_t*gnd_vec = new netvector_t(IVL_VT_REAL,0,0); + gnd = new NetNet(scope, lex_strings.make(name), NetNet::WIRE, gnd_vec); gnd->set_discipline(dis); - gnd->data_type(IVL_VT_REAL); discipline_references_[dis->name()] = gnd; if (debug_elaborate) diff --git a/elab_net.cc b/elab_net.cc index ba1b68316..465a6de4b 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -24,6 +24,7 @@ # include "netlist.h" # include "netmisc.h" # include "netstruct.h" +# include "netvector.h" # include "compiler.h" # include @@ -98,12 +99,12 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope, concat operator from most significant to least significant, which is the order they are given in the concat list. */ + netvector_t*tmp2_vec = new netvector_t(nets[0]->data_type(),width-1,0); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, width); + NetNet::IMPLICIT, tmp2_vec); /* Assume that the data types of the nets are all the same, so we can take the data type of any, the first will do. */ - osig->data_type(nets[0]->data_type()); osig->local_flag(true); osig->set_line(*this); @@ -154,8 +155,6 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope, assert(width == 0); } - osig->data_type(nets[0]->data_type()); - osig->local_flag(true); return osig; } @@ -655,11 +654,12 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, return 0; } + netvector_t*tmp2_vec = new netvector_t(sig->data_type(), + sig->vector_width()-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - sig->type(), sig->vector_width()); + sig->type(), tmp2_vec); tmp->set_line(*this); tmp->local_flag(true); - tmp->data_type( sig->data_type() ); connect(sig->pin(widx), tmp->pin(0)); sig = tmp; } @@ -683,10 +683,11 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, << " wid=" << subnet_wid <<"]" << endl; + netvector_t*tmp2_vec = new netvector_t(sig->data_type(), + subnet_wid-1,0); NetNet*subsig = new NetNet(sig->scope(), sig->scope()->local_symbol(), - NetNet::WIRE, subnet_wid); - subsig->data_type( sig->data_type() ); + NetNet::WIRE, tmp2_vec); subsig->local_flag(true); subsig->set_line(*this); @@ -800,10 +801,10 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const unsigned swid = abs(midx - lidx) + 1; ivl_assert(*this, swid > 0 && swid < sig->vector_width()); + netvector_t*tmp2_vec = new netvector_t(sig->data_type(),swid-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, swid); + NetNet::WIRE, tmp2_vec); tmp->port_type(sig->port_type()); - tmp->data_type(sig->data_type()); tmp->set_line(*this); tmp->local_flag(true); NetNode*ps = 0; diff --git a/elab_sig.cc b/elab_sig.cc index 5eb3915a2..7310e411d 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -36,6 +36,7 @@ # include "netmisc.h" # include "netenum.h" # include "netstruct.h" +# include "netvector.h" # include "netdarray.h" # include "netparray.h" # include "util.h" @@ -485,6 +486,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const } NetNet*ret_sig = 0; + netvector_t*ret_vec = 0; /* Create the signals/variables of the return value and write them into the function scope. */ @@ -522,48 +524,49 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const list packed; packed.push_back(netrange_t(mnum, lnum)); - ret_sig = new NetNet(scope, fname, NetNet::REG, packed); + ret_vec = new netvector_t(packed, IVL_VT_LOGIC); + ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); ret_sig->set_scalar(false); } else { - ret_sig = new NetNet(scope, fname, NetNet::REG); + ret_vec = new netvector_t(IVL_VT_LOGIC); + ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); ret_sig->set_scalar(true); } ret_sig->set_line(*this); ret_sig->set_signed(return_type_.type == PTF_REG_S); ret_sig->port_type(NetNet::POUTPUT); - ret_sig->data_type(IVL_VT_LOGIC); break; case PTF_INTEGER: - ret_sig = new NetNet(scope, fname, NetNet::REG, integer_width); + ret_vec = new netvector_t(IVL_VT_LOGIC, integer_width-1,0); + ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); ret_sig->set_line(*this); ret_sig->set_signed(true); ret_sig->set_isint(true); ret_sig->set_scalar(false); ret_sig->port_type(NetNet::POUTPUT); - ret_sig->data_type(IVL_VT_LOGIC); break; case PTF_TIME: - ret_sig = new NetNet(scope, fname, NetNet::REG, 64); + ret_vec = new netvector_t(IVL_VT_LOGIC, 64-1,0); + ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); ret_sig->set_line(*this); ret_sig->set_signed(false); ret_sig->set_isint(false); ret_sig->set_scalar(false); ret_sig->port_type(NetNet::POUTPUT); - ret_sig->data_type(IVL_VT_LOGIC); break; case PTF_REAL: case PTF_REALTIME: - ret_sig = new NetNet(scope, fname, NetNet::REG, 1); + ret_vec = new netvector_t(IVL_VT_REAL); + ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); ret_sig->set_line(*this); ret_sig->set_signed(true); ret_sig->set_isint(false); ret_sig->set_scalar(true); ret_sig->port_type(NetNet::POUTPUT); - ret_sig->data_type(IVL_VT_REAL); break; case PTF_ATOM2: @@ -598,13 +601,13 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const use_wid = mnum - lnum + 1; } - ret_sig = new NetNet(scope, fname, NetNet::REG, use_wid); + ret_vec = new netvector_t(IVL_VT_BOOL, use_wid-1, 0); + ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); ret_sig->set_line(*this); ret_sig->set_signed(return_type_.type == PTF_ATOM2_S? true : false); ret_sig->set_isint(true); ret_sig->set_scalar(false); ret_sig->port_type(NetNet::POUTPUT); - ret_sig->data_type(IVL_VT_BOOL); break; case PTF_STRING: @@ -1272,23 +1275,24 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const cerr << " in scope " << scope_path(scope) << endl; } - sig = new NetNet(scope, name_, wtype, packed_dimensions, unpacked_dimensions); + ivl_variable_type_t use_data_type = data_type_; + if (use_data_type == IVL_VT_NO_TYPE) { + use_data_type = IVL_VT_LOGIC; + if (debug_elaborate) { + cerr << get_fileline() << ": debug: " + << "Signal " << name_ + << " in scope " << scope_path(scope) + << " defaults to data type " << use_data_type << endl; + } + } + + netvector_t*vec = new netvector_t(packed_dimensions, use_data_type); + packed_dimensions.clear(); + sig = new NetNet(scope, name_, wtype, packed_dimensions, unpacked_dimensions, vec); + } if (wtype == NetNet::WIRE) sig->devirtualize_pins(); - - ivl_variable_type_t use_data_type = data_type_; - if (use_data_type == IVL_VT_NO_TYPE) { - use_data_type = IVL_VT_LOGIC; - if (debug_elaborate) { - cerr << get_fileline() << ": debug: " - << "Signal " << name_ - << " in scope " << scope_path(scope) - << " defaults to data type " << use_data_type << endl; - } - } - - sig->data_type(use_data_type); sig->set_line(*this); sig->port_type(port_type_); sig->set_signed(get_signed()); diff --git a/elaborate.cc b/elaborate.cc index 60dc888da..41a8328ff 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -35,6 +35,7 @@ # include "PGenerate.h" # include "PSpec.h" # include "netlist.h" +# include "netvector.h" # include "netmisc.h" # include "util.h" # include "parse_api.h" @@ -75,8 +76,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const if (debug_elaborate) { cerr << get_fileline() << ": debug: PGAssign: elaborated l-value" - << " width=" << lval->vector_width() - << ", type=" << lval->data_type() << endl; + << " width=" << lval->vector_width() << endl; } NetExpr*rval_expr = elaborate_rval_expr(des, scope, lval->data_type(), @@ -164,11 +164,12 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const NetPartSelect::VP); des->add_node(tmp); tmp->set_line(*this); + netvector_t*osig_vec = new netvector_t(rval->data_type(), + lval->vector_width()-1,0); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::TRI, lval->vector_width()); + NetNet::TRI, osig_vec); osig->set_line(*this); osig->local_flag(true); - osig->data_type(rval->data_type()); connect(osig->pin(0), tmp->pin(0)); rval = osig; need_driver_flag = false; @@ -190,10 +191,11 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const connect(rval->pin(0), driver->pin(1)); + netvector_t*tmp_vec = new netvector_t(rval->data_type(), + rval->vector_width()-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, rval->vector_width()); + NetNet::WIRE, tmp_vec); tmp->set_line(*this); - tmp->data_type(rval->data_type()); tmp->local_flag(true); connect(driver->pin(0), tmp->pin(0)); @@ -868,10 +870,11 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const des->add_node(rep); connect(rep->pin(1), sig->pin(0)); + netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC, + instance_width-1,0); sig = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, instance_width); + NetNet::WIRE, osig_vec); sig->set_line(*this); - sig->data_type(IVL_VT_LOGIC); sig->local_flag(true); connect(rep->pin(0), sig->pin(0)); @@ -948,12 +951,12 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const unsigned dev = gdx*gate_count; connect(cur[dev+idx]->pin(0), cc->pin(gdx+1)); + netvector_t*tmp2_vec = new netvector_t(IVL_VT_LOGIC); NetNet*tmp2 = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, 1); + NetNet::WIRE, tmp2_vec); tmp2->set_line(*this); tmp2->local_flag(true); - tmp2->data_type(IVL_VT_LOGIC); connect(cc->pin(gdx+1), tmp2->pin(0)); } @@ -965,11 +968,11 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const tmp1->set_line(*this); des->add_node(tmp1); connect(tmp1->pin(1), sig->pin(0)); + netvector_t*tmp2_vec = new netvector_t(sig->data_type()); NetNet*tmp2 = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, 1); + NetNet::WIRE, tmp2_vec); tmp2->set_line(*this); tmp2->local_flag(true); - tmp2->data_type(sig->data_type()); connect(tmp1->pin(0), tmp2->pin(0)); unsigned use_idx = idx - gate_count + 1; unsigned dev = gdx*gate_count; @@ -1432,11 +1435,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const des->add_node(tmp); connect(tmp->pin(1), sig->pin(0)); + netvector_t*tmp2_vec = new netvector_t(sig->data_type(), + sig->vector_width()-1,0); NetNet*tmp2 = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, sig->vector_width()); + NetNet::WIRE, tmp2_vec); tmp2->local_flag(true); tmp2->set_line(*this); - tmp2->data_type(sig->data_type()); connect(tmp->pin(0), tmp2->pin(0)); sig = tmp2; } @@ -2382,11 +2386,11 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const if (delay || event_) { unsigned wid = count_lval_width(lv); + netvector_t*tmp2_vec = new netvector_t(rv->expr_type(),wid-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::REG, wid); + NetNet::REG, tmp2_vec); tmp->local_flag(true); tmp->set_line(*this); - tmp->data_type(rv->expr_type()); NetESignal*sig = new NetESignal(tmp); diff --git a/expr_synth.cc b/expr_synth.cc index fa0a69f2c..bd8ac62d4 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -24,6 +24,7 @@ # include # include "netlist.h" +# include "netvector.h" # include "netmisc.h" # include "ivl_assert.h" @@ -118,10 +119,10 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope, NetExpr*root) } perm_string path = lsig->scope()->local_symbol(); - NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width); + netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); + NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); - osig->data_type(expr_type()); osig->set_signed(has_sign()); perm_string oname = osig->scope()->local_symbol(); @@ -173,11 +174,11 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope, NetExpr*root) rsig = pad_to_width(des, rsig, width, *this); assert(lsig->vector_width() == rsig->vector_width()); + netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, width); + NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); - osig->data_type(expr_type()); perm_string oname = scope->local_symbol(); NetLogic*gate; @@ -243,11 +244,11 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root) rsig = pad_to_width(des, rsig, width, *this); } + netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, 1); + NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); - osig->data_type(IVL_VT_LOGIC); // Test if the comparison is signed. // @@ -390,10 +391,10 @@ NetNet* NetEBPow::synthesize(Design*des, NetScope*scope, NetExpr*root) connect(powr->pin_DataA(), lsig->pin(0)); connect(powr->pin_DataB(), rsig->pin(0)); + netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, width); + NetNet::IMPLICIT, osig_vec); osig->set_line(*this); - osig->data_type(expr_type()); osig->set_signed(has_sign()); osig->local_flag(true); @@ -427,10 +428,10 @@ NetNet* NetEBMult::synthesize(Design*des, NetScope*scope, NetExpr*root) connect(mult->pin_DataA(), lsig->pin(0)); connect(mult->pin_DataB(), rsig->pin(0)); + netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, width); + NetNet::IMPLICIT, osig_vec); osig->set_line(*this); - osig->data_type(expr_type()); osig->set_signed(has_sign()); osig->local_flag(true); @@ -452,10 +453,10 @@ NetNet* NetEBDiv::synthesize(Design*des, NetScope*scope, NetExpr*root) if (real_args) width = 1; else width = expr_width(); + netvector_t*osig_vec = new netvector_t(lsig->data_type(), width-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, width); + NetNet::IMPLICIT, osig_vec); osig->set_line(*this); - osig->data_type(lsig->data_type()); osig->set_signed(has_sign()); osig->local_flag(true); @@ -530,10 +531,10 @@ NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, NetExpr*root) return 0; } + netvector_t*osig_tmp = new netvector_t(expr_type()); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, 1); + NetNet::IMPLICIT, osig_tmp); osig->set_line(*this); - osig->data_type(expr_type()); osig->local_flag(true); NetLogic*olog; @@ -597,10 +598,10 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root) if (shift == 0) return lsig; + netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1,0); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, expr_width()); + NetNet::IMPLICIT, osig_vec); osig->set_line(*this); - osig->data_type(expr_type()); osig->local_flag(true); // ushift is the amount of pad created by the shift. @@ -618,10 +619,10 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root) psel->set_line(*this); des->add_node(psel); + netvector_t*psig_vec = new netvector_t(expr_type(), part_width-1, 0); NetNet*psig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, part_width); + NetNet::IMPLICIT, psig_vec); psig->set_line(*this); - psig->data_type(expr_type()); psig->local_flag(true); connect(psig->pin(0), psel->pin(0)); @@ -646,10 +647,11 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root) znum); des->add_node(zcon); + netvector_t*zsig_vec = new netvector_t(osig->data_type(), + znum.len()-1, 0); NetNet*zsig = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, znum.len()); + NetNet::WIRE, zsig_vec); zsig->set_line(*this); - zsig->data_type(osig->data_type()); zsig->local_flag(true); connect(zcon->pin(0), zsig->pin(0)); @@ -676,10 +678,10 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root) if (rsig == 0) return 0; + netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, expr_width()); + NetNet::IMPLICIT, osig_vec); osig->set_line(*this); - osig->data_type(expr_type()); osig->local_flag(true); NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(), @@ -739,10 +741,10 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root) /* Make a NetNet object to carry the output vector. */ perm_string path = scope->local_symbol(); - NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width()); + netvector_t*osig_vec = new netvector_t(data_type, expr_width()-1, 0); + NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); - osig->data_type(data_type); NetConcat*concat = new NetConcat(scope, scope->local_symbol(), osig->vector_width(), @@ -785,10 +787,10 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope, NetExpr*) return 0; } - NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width); + netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); + NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); - osig->data_type(expr_type()); osig->set_signed(has_sign()); NetConst*con = new NetConst(scope, scope->local_symbol(), value()); @@ -806,10 +808,10 @@ NetNet* NetECReal::synthesize(Design*des, NetScope*scope, NetExpr*) { perm_string path = scope->local_symbol(); - NetNet*osig = new NetNet(scope, path, NetNet::WIRE, 1); + netvector_t*osig_vec = new netvector_t(IVL_VT_REAL); + NetNet*osig = new NetNet(scope, path, NetNet::WIRE, osig_vec); osig->set_line(*this); osig->local_flag(true); - osig->data_type(IVL_VT_REAL); osig->set_signed(has_sign()); NetLiteral*con = new NetLiteral(scope, scope->local_symbol(), value_); @@ -839,10 +841,10 @@ NetNet* NetEUBits::synthesize(Design*des, NetScope*scope, NetExpr*root) } unsigned width = isig->vector_width(); + netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, width); + NetNet::IMPLICIT, osig_vec); osig->set_line(*this); - osig->data_type(expr_type()); osig->local_flag(true); perm_string oname = scope->local_symbol(); @@ -882,11 +884,12 @@ NetNet* NetEUnary::synthesize(Design*des, NetScope*scope, NetExpr*root) if (expr_->has_sign() == false) return sub; + netvector_t*sig_vec = new netvector_t(sub->data_type(), + sub->vector_width()-1, 0); NetNet*sig = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, sub->vector_width()); + NetNet::WIRE, sig_vec); sig->set_line(*this); sig->local_flag(true); - sig->data_type(sub->data_type()); NetAbs*tmp = new NetAbs(scope, scope->local_symbol(), sub->vector_width()); tmp->set_line(*this); @@ -956,10 +959,10 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root) gate->set_line(*this); des->add_node(gate); + netvector_t*osig_vec = new netvector_t(expr_type()); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, 1); + NetNet::IMPLICIT, osig_vec); osig->set_line(*this); - osig->data_type(expr_type()); osig->local_flag(true); connect(gate->pin(0), osig->pin(0)); @@ -1063,10 +1066,11 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root) des->add_node(sel); ivl_assert(*this, select_width > 0); + netvector_t*tmp_vec = new netvector_t(sub->data_type(), + select_width-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, select_width); + NetNet::WIRE, tmp_vec); tmp->set_line(*this); - tmp->data_type(sub->data_type()); tmp->local_flag(true); connect(sel->pin(0), tmp->pin(0)); @@ -1090,10 +1094,10 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root) connect(cat->pin(concat_count), above->pin(0)); } + tmp_vec = new netvector_t(sub->data_type(), expr_width()-1, 0); tmp = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, expr_width()); + NetNet::WIRE, tmp_vec); tmp->set_line(*this); - tmp->data_type(sub->data_type()); tmp->local_flag(true); connect(cat->pin(0), tmp->pin(0)); } @@ -1111,9 +1115,10 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root) sel->set_line(*this); des->add_node(sel); + netvector_t*tmp_vec = new netvector_t(sub->data_type(), + expr_width()-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, expr_width()); - tmp->data_type(sub->data_type()); + NetNet::IMPLICIT, tmp_vec); tmp->local_flag(true); tmp->set_line(*this); sub = tmp; @@ -1134,10 +1139,10 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root) // extension or 0 extension, depending on the has_sign() mode // of the expression. + netvector_t*net_vec = new netvector_t(expr_type(), expr_width()-1, 0); NetNet*net = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, expr_width()); + NetNet::IMPLICIT, net_vec); net->set_line(*this); - net->data_type(expr_type()); net->local_flag(true); if (has_sign()) { NetSignExtend*pad = new NetSignExtend(scope, @@ -1165,10 +1170,10 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root) con->set_line(*this); des->add_node(con); + netvector_t*tmp_vec = new netvector_t(expr_type(), pad_width-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, pad_width); + NetNet::IMPLICIT, tmp_vec); tmp->set_line(*this); - tmp->data_type(expr_type()); tmp->local_flag(true); connect(tmp->pin(0), con->pin(0)); @@ -1220,9 +1225,9 @@ NetNet* NetETernary::synthesize(Design *des, NetScope*scope, NetExpr*root) ivl_assert(*this, csig->vector_width() == 1); unsigned width=expr_width(); - NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, width); + netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); + NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, osig_vec); osig->set_line(*this); - osig->data_type(expr_type()); osig->local_flag(true); /* Make sure the types match. */ @@ -1265,11 +1270,12 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root) if (word_ == 0) return net_; + netvector_t*tmp_vec = new netvector_t(net_->data_type(), + net_->vector_width()-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::IMPLICIT, net_->vector_width()); + NetNet::IMPLICIT, tmp_vec); tmp->set_line(*this); tmp->local_flag(true); - tmp->data_type(net_->data_type()); // For NetExpr objects, the word index is already converted to // a canonical (lsb==0) address. Just use the index directly. @@ -1354,12 +1360,12 @@ NetNet* NetESFunc::synthesize(Design*des, NetScope*scope, NetExpr*root) net->set_line(*this); des->add_node(net); + netvector_t*osig_vec = new netvector_t(def->type, def->wid-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, def->wid); + NetNet::WIRE, osig_vec); osig->set_line(*this); osig->local_flag(true); osig->set_signed(def->type==IVL_VT_REAL? true : false); - osig->data_type(def->type); connect(net->pin(0), osig->pin(0)); @@ -1422,11 +1428,12 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root) des->add_node(net); /* Create an output signal and connect it to the function. */ + netvector_t*osig_vec = new netvector_t(result_sig_->expr_type(), + result_sig_->vector_width()-1, 0); NetNet*osig = new NetNet(scope_, scope_->local_symbol(), NetNet::WIRE, - result_sig_->vector_width()); + osig_vec); osig->set_line(*this); osig->local_flag(true); - osig->data_type(result_sig_->expr_type()); connect(net->pin(0), osig->pin(0)); /* Connect the pins to the arguments. */ diff --git a/netlist.cc b/netlist.cc index 57e9e3be1..1906b0030 100644 --- a/netlist.cc +++ b/netlist.cc @@ -30,6 +30,7 @@ # include "netdarray.h" # include "netenum.h" # include "netstruct.h" +# include "netvector.h" # include "ivl_assert.h" @@ -465,7 +466,7 @@ PortType::Enum PortType::merged( Enum lhs, Enum rhs ) NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins) : NetObj(s, n, 1), - type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), + type_(t), port_type_(NOT_A_PORT), signed_(false), isint_(false), is_scalar_(false), local_flag_(false), net_type_(0), discipline_(0), eref_count_(0), lref_count_(0), @@ -513,40 +514,6 @@ void NetNet::initialize_dir_(Link::DIR dir) } } -NetNet::NetNet(NetScope*s, perm_string n, Type t, - const list&packed) -: NetObj(s, n, 1), type_(t), - port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false), - isint_(false), is_scalar_(false), local_flag_(false), - net_type_(0), discipline_(0), - eref_count_(0), lref_count_(0) -{ - packed_dims_ = packed; - calculate_slice_widths_from_packed_dims_(); - assert(s); - - Link::DIR dir = Link::PASSIVE; - - switch (t) { - case REG: - case IMPLICIT_REG: - dir = Link::OUTPUT; - break; - case SUPPLY0: - dir = Link::OUTPUT; - break; - case SUPPLY1: - dir = Link::OUTPUT; - break; - default: - break; - } - - initialize_dir_(dir); - - s->add_signal(this); -} - static unsigned calculate_count(const list&unpacked) { unsigned long sum = 1; @@ -577,15 +544,19 @@ template static unsigned calculate_count(T*type) void NetNet::calculate_slice_widths_from_packed_dims_(void) { - if (packed_dims_.empty()) { + netvector_t*vec = dynamic_cast (net_type_); + ivl_assert(*this, vec==0 || packed_dims_.empty()); + + const std::list&use_packed = vec? vec->packed_dims() : packed_dims_; + if (use_packed.empty()) { slice_wids_.clear(); return; } - slice_wids_.resize(packed_dims_.size()); + slice_wids_.resize(use_packed.size()); - slice_wids_[0] = netrange_width(packed_dims_); - list::const_iterator cur = packed_dims_.begin(); + slice_wids_[0] = netrange_width(use_packed); + list::const_iterator cur = use_packed.begin(); for (size_t idx = 1 ; idx < slice_wids_.size() ; idx += 1) { slice_wids_[idx] = slice_wids_[idx-1] / cur->width(); } @@ -598,14 +569,23 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, nettype_base_t*net_type) : NetObj(s, n, calculate_count(unpacked)), type_(t), port_type_(NOT_A_PORT), - data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false), + signed_(false), isint_(false), is_scalar_(false), local_flag_(false), net_type_(net_type), discipline_(0), unpacked_dims_(unpacked.size()), eref_count_(0), lref_count_(0) { packed_dims_ = packed; - if (net_type) - packed_dims_.push_back(netrange_t(calculate_count(net_type)-1, 0)); + // Special case: This is an enum, so it is its own packed vector. + if (netenum_t*et = dynamic_cast(net_type)) { + ivl_assert(*this, packed_dims_.empty()); + packed_dims_.push_back(netrange_t(calculate_count(et)-1, 0)); + } + // Special case: netstruct types are like another packed + // dimension. + if (netstruct_t*st = dynamic_cast(net_type)) { + packed_dims_.push_back(netrange_t(calculate_count(st)-1, 0)); + } + calculate_slice_widths_from_packed_dims_(); size_t idx = 0; for (list::const_iterator cur = unpacked.begin() @@ -650,7 +630,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, NetNet::NetNet(NetScope*s, perm_string n, Type t, netstruct_t*ty) : NetObj(s, n, 1), type_(t), port_type_(NOT_A_PORT), - data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false), + signed_(false), isint_(false), is_scalar_(false), local_flag_(false), net_type_(ty), discipline_(0), eref_count_(0), lref_count_(0) @@ -682,7 +662,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, netstruct_t*ty) NetNet::NetNet(NetScope*s, perm_string n, Type t, netdarray_t*ty) : NetObj(s, n, 1), type_(t), port_type_(NOT_A_PORT), - data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false), + signed_(false), isint_(false), is_scalar_(false), local_flag_(false), net_type_(ty), discipline_(0), eref_count_(0), lref_count_(0) @@ -709,6 +689,37 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, netdarray_t*ty) s->add_signal(this); } +NetNet::NetNet(NetScope*s, perm_string n, Type t, netvector_t*ty) +: NetObj(s, n, 1), + type_(t), port_type_(NOT_A_PORT), + signed_(false), isint_(false), + is_scalar_(false), local_flag_(false), net_type_(ty), + discipline_(0), + eref_count_(0), lref_count_(0) +{ + calculate_slice_widths_from_packed_dims_(); + Link::DIR dir = Link::PASSIVE; + + switch (t) { + case REG: + case IMPLICIT_REG: + dir = Link::OUTPUT; + break; + case SUPPLY0: + dir = Link::OUTPUT; + break; + case SUPPLY1: + dir = Link::OUTPUT; + break; + default: + break; + } + + initialize_dir_(dir); + + s->add_signal(this); +} + NetNet::~NetNet() { if (eref_count_ > 0) { @@ -785,22 +796,27 @@ void NetNet::set_module_port_index(unsigned idx) assert( port_index_ >= 0 ); } -ivl_variable_type_t NetNet::data_type() const +const std::list& NetNet::packed_dims() const { - return data_type_; + if (netvector_t*vec = dynamic_cast (net_type_)) { + ivl_assert(*this, packed_dims_.empty()); + return vec->packed_dims(); + } + + return packed_dims_; } -void NetNet::data_type(ivl_variable_type_t t) +ivl_variable_type_t NetNet::data_type() const { - data_type_ = t; + if (net_type_==0) + return IVL_VT_LOGIC; + else + return net_type_->base_type(); } bool NetNet::get_signed() const { - if (data_type_ == IVL_VT_REAL) - return true; - else - return signed_; + return signed_; } void NetNet::set_signed(bool flag) @@ -875,9 +891,9 @@ void NetNet::set_discipline(ivl_discipline_t dis) bool NetNet::sb_is_valid(const list&indices, long sb) const { - ivl_assert(*this, indices.size()+1 == packed_dims_.size()); - assert(packed_dims_.size() == 1); - const netrange_t&rng = packed_dims_.back(); + ivl_assert(*this, indices.size()+1 == packed_dims().size()); + assert(packed_dims().size() == 1); + const netrange_t&rng = packed_dims().back(); if (rng.get_msb() >= rng.get_lsb()) return (sb <= rng.get_msb()) && (sb >= rng.get_lsb()); else @@ -886,9 +902,9 @@ bool NetNet::sb_is_valid(const list&indices, long sb) const long NetNet::sb_to_idx(const list&indices, long sb) const { - ivl_assert(*this, indices.size()+1 == packed_dims_.size()); + ivl_assert(*this, indices.size()+1 == packed_dims().size()); - list::const_iterator pcur = packed_dims_.end(); + list::const_iterator pcur = packed_dims().end(); -- pcur; long acc_off; @@ -924,8 +940,8 @@ long NetNet::sb_to_idx(const list&indices, long sb) const bool NetNet::sb_to_slice(const list&indices, long sb, long&loff, unsigned long&lwid) const { - ivl_assert(*this, indices.size() < packed_dims_.size()); - return prefix_to_slice(packed_dims_, indices, sb, loff, lwid); + ivl_assert(*this, indices.size() < packed_dims().size()); + return prefix_to_slice(packed_dims(), indices, sb, loff, lwid); } unsigned NetNet::unpacked_count() const diff --git a/netlist.h b/netlist.h index bd5af11b0..5b3da68c3 100644 --- a/netlist.h +++ b/netlist.h @@ -80,6 +80,7 @@ class netdarray_t; class netparray_t; class netenum_t; class netstruct_t; +class netvector_t; struct target; struct functor_t; @@ -605,8 +606,6 @@ class NetNet : public NetObj, public PortType { // the base vector, and the [s0:e0] define the array // dimensions. If s0==e0, then this is not an array after // all. - explicit NetNet(NetScope*s, perm_string n, Type t, - const std::list&packed); explicit NetNet(NetScope*s, perm_string n, Type t, const std::list&packed, const std::list&unpacked, @@ -615,7 +614,7 @@ class NetNet : public NetObj, public PortType { // This form builds a NetNet from its record/enum definition. explicit NetNet(NetScope*s, perm_string n, Type t, netstruct_t*type); explicit NetNet(NetScope*s, perm_string n, Type t, netdarray_t*type); - //explicit NetNet(NetScope*s, perm_string n, Type t, netparray_t*type); + explicit NetNet(NetScope*s, perm_string n, Type t, netvector_t*type); virtual ~NetNet(); @@ -631,7 +630,6 @@ class NetNet : public NetObj, public PortType { void set_module_port_index(unsigned idx); ivl_variable_type_t data_type() const; - void data_type(ivl_variable_type_t t); /* If a NetNet is signed, then its value is to be treated as signed. Otherwise, it is unsigned. */ @@ -658,7 +656,7 @@ class NetNet : public NetObj, public PortType { for the vector. These are arranged as a list where the first range in the list (front) is the left-most range in the verilog declaration. */ - const std::list& packed_dims() const { return packed_dims_; } + const std::list& packed_dims() const; const std::vector& unpacked_dims() const { return unpacked_dims_; } @@ -733,7 +731,6 @@ class NetNet : public NetObj, public PortType { private: Type type_ : 5; PortType port_type_ : 3; - ivl_variable_type_t data_type_ : 3; bool signed_ : 1; bool isint_ : 1; // original type of integer bool is_scalar_ : 1; diff --git a/netmisc.cc b/netmisc.cc index da0504494..b63fb445a 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -21,6 +21,7 @@ # include # include "netlist.h" +# include "netvector.h" # include "netmisc.h" # include "PExpr.h" # include "pform_types.h" @@ -30,10 +31,11 @@ NetNet* sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig) { + netvector_t*zero_vec = new netvector_t(sig->data_type(), + sig->vector_width()-1, 0); NetNet*zero_net = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, sig->vector_width()); + NetNet::WIRE, zero_vec); zero_net->set_line(*sig); - zero_net->data_type(sig->data_type()); zero_net->local_flag(true); if (sig->data_type() == IVL_VT_REAL) { @@ -62,10 +64,11 @@ NetNet* sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig) connect(zero_net->pin(0), adder->pin_DataA()); connect(adder->pin_DataB(), sig->pin(0)); + netvector_t*tmp_vec = new netvector_t(sig->data_type(), + sig->vector_width()-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, sig->vector_width()); + NetNet::WIRE, tmp_vec); tmp->set_line(*sig); - tmp->data_type(sig->data_type()); tmp->local_flag(true); connect(adder->pin_Result(), tmp->pin(0)); @@ -78,9 +81,9 @@ NetNet* cast_to_int2(Design*des, NetScope*scope, NetNet*src, unsigned wid) if (src->data_type() == IVL_VT_BOOL) return src; - NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid); + netvector_t*tmp_vec = new netvector_t(IVL_VT_BOOL, wid-1, 0); + NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*src); - tmp->data_type(IVL_VT_BOOL); tmp->local_flag(true); NetCastInt2*cast = new NetCastInt2(scope, scope->local_symbol(), wid); @@ -98,9 +101,9 @@ NetNet* cast_to_int4(Design*des, NetScope*scope, NetNet*src, unsigned wid) if (src->data_type() != IVL_VT_REAL) return src; - NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid); + netvector_t*tmp_vec = new netvector_t(IVL_VT_LOGIC, wid-1, 0); + NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*src); - tmp->data_type(IVL_VT_LOGIC); tmp->local_flag(true); NetCastInt4*cast = new NetCastInt4(scope, scope->local_symbol(), wid); @@ -118,9 +121,9 @@ NetNet* cast_to_real(Design*des, NetScope*scope, NetNet*src) if (src->data_type() == IVL_VT_REAL) return src; - NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE); + netvector_t*tmp_vec = new netvector_t(IVL_VT_REAL); + NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*src); - tmp->data_type(IVL_VT_REAL); tmp->local_flag(true); NetCastReal*cast = new NetCastReal(scope, scope->local_symbol(), src->get_signed()); @@ -630,9 +633,9 @@ NetNet* make_const_x(Design*des, NetScope*scope, unsigned long wid) NetConst*res = new NetConst(scope, scope->local_symbol(), xxx); des->add_node(res); - NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid); + netvector_t*sig_vec = new netvector_t(IVL_VT_LOGIC, wid-1, 0); + NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, sig_vec); sig->local_flag(true); - sig->data_type(IVL_VT_LOGIC); connect(sig->pin(0), res->pin(0)); return sig; diff --git a/netstruct.cc b/netstruct.cc index 2db490eee..0f6982a78 100644 --- a/netstruct.cc +++ b/netstruct.cc @@ -66,3 +66,16 @@ long netstruct_t::packed_width(void) const return res; } + +ivl_variable_type_t netstruct_t::base_type() const +{ + if (! packed_) + return IVL_VT_NO_TYPE; + + for (size_t idx = 0 ; idx < members_.size() ; idx += 1) { + if (members_[idx].data_type() != IVL_VT_BOOL) + return members_[idx].data_type(); + } + + return IVL_VT_BOOL; +} diff --git a/netstruct.h b/netstruct.h index 02ff90cb6..25aaf70e4 100644 --- a/netstruct.h +++ b/netstruct.h @@ -55,6 +55,10 @@ class netstruct_t : public LineInfo, public nettype_base_t { // the record is not packed. long packed_width() const; + // Return the base type of the packed record, or + // IVL_VT_NO_TYPE if the record is not packed. + ivl_variable_type_t base_type() const; + private: bool packed_; std::vectormembers_; diff --git a/nettypes.cc b/nettypes.cc index 9d31c81c2..023e28c64 100644 --- a/nettypes.cc +++ b/nettypes.cc @@ -31,6 +31,11 @@ long nettype_base_t::packed_width(void) const return 0; } +ivl_variable_type_t nettype_base_t::base_type() const +{ + return IVL_VT_NO_TYPE; +} + unsigned long netrange_width(const list&packed) { unsigned wid = 1; diff --git a/nettypes.h b/nettypes.h index 3292ffc8c..3a452ecfc 100644 --- a/nettypes.h +++ b/nettypes.h @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +# include "ivl_target.h" # include # include # include @@ -31,6 +32,9 @@ class nettype_base_t { public: virtual ~nettype_base_t() =0; virtual long packed_width(void) const; + + // Some types have a base variable type. + virtual ivl_variable_type_t base_type() const; }; class netrange_t { diff --git a/netvector.cc b/netvector.cc new file mode 100644 index 000000000..20c65f07b --- /dev/null +++ b/netvector.cc @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012 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 + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +# include "netvector.h" + +netvector_t::netvector_t(ivl_variable_type_t type, long msb, long lsb) +: type_(type) +{ + packed_dims_.push_back(netrange_t(msb,lsb)); +} + +netvector_t::netvector_t(ivl_variable_type_t type) +: type_(type) +{ +} + +netvector_t::~netvector_t() +{ +} + +ivl_variable_type_t netvector_t::base_type() const +{ + return type_; +} + +long netvector_t::packed_width() const +{ + netrange_width(packed_dims_); +} diff --git a/netvector.h b/netvector.h new file mode 100644 index 000000000..868b3b17a --- /dev/null +++ b/netvector.h @@ -0,0 +1,72 @@ +#ifndef __netvector_H +#define __netvector_H +/* + * Copyright (c) 2012 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 + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +# include "nettypes.h" +# include "ivl_target.h" +# include +# include + +class netvector_t : public nettype_base_t { + + public: + explicit netvector_t(const std::list&packed, + ivl_variable_type_t type); + + // special case: there is a single packed dimension and we + // know it in the form [:]. This step saves me + // creating a netrange_t for this single item. + explicit netvector_t(ivl_variable_type_t type, long msb, long lsb); + + // Special case: scaler object--no packed dimenions at all. + explicit netvector_t(ivl_variable_type_t type); + + ~netvector_t(); + + ivl_variable_type_t base_type() const; + const std::list&packed_dims() const; + + long packed_width() const; + + std::ostream& debug_dump(std::ostream&) const; + + private: + std::list packed_dims_; + ivl_variable_type_t type_; + +}; + +inline netvector_t::netvector_t(const std::list&packed, + ivl_variable_type_t type) +: packed_dims_(packed), type_(type) +{ +} + +inline const std::list& netvector_t::packed_dims() const +{ + return packed_dims_; +} + +inline static std::ostream& operator << (std::ostream&out, const netvector_t&obj) +{ + return obj.debug_dump(out); +} + +#endif diff --git a/pad_to_width.cc b/pad_to_width.cc index 8004c046b..96ecdfdd3 100644 --- a/pad_to_width.cc +++ b/pad_to_width.cc @@ -20,6 +20,7 @@ # include "config.h" # include "netlist.h" +# include "netvector.h" # include "netmisc.h" @@ -77,19 +78,20 @@ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid, const LineInfo&info) connect(cc->pin(2), con->pin(0)); // Make a NetNet for the NetConst to NetConcat link. + netvector_t*tmp_vec = new netvector_t(net->data_type(), + wid - net->vector_width() - 1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, wid - net->vector_width()); + NetNet::WIRE, tmp_vec); tmp->set_line(info); - tmp->data_type( net->data_type() ); tmp->local_flag(true); connect(cc->pin(2), tmp->pin(0)); // Create a NetNet of the output width and connect it to the // NetConcat node output pin. + tmp_vec = new netvector_t(net->data_type(), wid-1, 0); tmp = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, wid); + NetNet::WIRE, tmp_vec); tmp->set_line(info); - tmp->data_type( net->data_type() ); tmp->local_flag(true); connect(cc->pin(0), tmp->pin(0)); @@ -109,10 +111,10 @@ NetNet*pad_to_width_signed(Design*des, NetNet*net, unsigned wid, se->set_line(info); des->add_node(se); - NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, wid); + netvector_t*tmp_vec = new netvector_t(net->data_type(), wid-1, 0); + NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(info); tmp->local_flag(true); - tmp->data_type(net->data_type()); tmp->set_signed(true); connect(tmp->pin(0), se->pin(0)); @@ -132,10 +134,10 @@ NetNet*crop_to_width(Design*des, NetNet*net, unsigned wid) ps->set_line(*net); des->add_node(ps); + netvector_t*tmp_vec = new netvector_t(net->data_type(), wid-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), - NetNet::WIRE, wid); + NetNet::WIRE, tmp_vec); tmp->set_line(*net); - tmp->data_type(net->data_type()); tmp->local_flag(true); connect(ps->pin(0), tmp->pin(0)); diff --git a/synth2.cc b/synth2.cc index b62a05e9f..f1e8d6371 100644 --- a/synth2.cc +++ b/synth2.cc @@ -21,6 +21,7 @@ # include "functor.h" # include "netlist.h" +# include "netvector.h" # include "netmisc.h" # include "compiler.h" # include @@ -221,10 +222,10 @@ bool NetCase::synth_async(Design*des, NetScope*scope, continue; } + netvector_t*isig_vec = new netvector_t(mux_data_type, mux_width-1, 0); isig = new NetNet(scope, scope->local_symbol(), - NetNet::TRI, mux_width); + NetNet::TRI, isig_vec); isig->local_flag(true); - isig->data_type(mux_data_type); connect(mux->pin_Data(idx), isig->pin(0));