diff --git a/design_dump.cc b/design_dump.cc index d79a0c67f..327e795bc 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: design_dump.cc,v 1.49 1999/10/08 02:00:35 steve Exp $" +#ident "$Id: design_dump.cc,v 1.50 1999/10/10 01:59:54 steve Exp $" #endif /* @@ -153,6 +153,12 @@ void NetBUFZ::dump_node(ostream&o, unsigned ind) const dump_node_pins(o, ind+4); } +void NetCaseCmp::dump_node(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << "case compare === : " << name() << endl; + dump_node_pins(o, ind+4); +} + void NetConst::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "constant " << value_ << ": " << name() << endl; @@ -789,6 +795,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.50 1999/10/10 01:59:54 steve + * Structural case equals device. + * * Revision 1.49 1999/10/08 02:00:35 steve * Fix dump of sase statements. * diff --git a/elaborate.cc b/elaborate.cc index 356ee142e..5b63d567b 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: elaborate.cc,v 1.115 1999/10/09 21:30:16 steve Exp $" +#ident "$Id: elaborate.cc,v 1.116 1999/10/10 01:59:54 steve Exp $" #endif /* @@ -720,6 +720,76 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path, des->add_signal(osig); break; + case 'a': // && (logical AND) + gate = new NetLogic(des->local_symbol(path), 3, NetLogic::AND); + + // The first OR gate returns 1 if the left value is true... + if (lsig->pin_count() > 1) { + gate_t = new NetLogic(des->local_symbol(path), + 1+lsig->pin_count(), NetLogic::OR); + for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) + connect(gate_t->pin(idx+1), lsig->pin(idx)); + connect(gate->pin(1), gate_t->pin(0)); + des->add_node(gate_t); + } else { + connect(gate->pin(1), lsig->pin(0)); + } + + // The second OR gate returns 1 if the right value is true... + if (rsig->pin_count() > 1) { + gate_t = new NetLogic(des->local_symbol(path), + 1+rsig->pin_count(), NetLogic::OR); + for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1) + connect(gate_t->pin(idx+1), rsig->pin(idx)); + connect(gate->pin(2), gate_t->pin(0)); + des->add_node(gate_t); + } else { + connect(gate->pin(2), rsig->pin(0)); + } + + // The output is the AND of the two logic values. + osig = new NetNet(des->local_symbol(path), NetNet::WIRE); + osig->local_flag(true); + connect(gate->pin(0), osig->pin(0)); + des->add_signal(osig); + gate->rise_time(rise); + gate->fall_time(fall); + gate->decay_time(decay); + des->add_node(gate); + break; + + case 'E': // === (Case equals) + + // The comparison generates gates to bitwise compare + // each pair, and AND all the comparison results. + assert(lsig->pin_count() == rsig->pin_count()); + osig = new NetNet(des->local_symbol(path), NetNet::WIRE); + osig->local_flag(true); + gate = new NetLogic(des->local_symbol(path), + 1+lsig->pin_count(), + NetLogic::AND); + connect(gate->pin(0), osig->pin(0)); + for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) { + gate_t = new NetCaseCmp(des->local_symbol(path)); + connect(gate_t->pin(1), lsig->pin(idx)); + connect(gate_t->pin(2), rsig->pin(idx)); + connect(gate_t->pin(0), gate->pin(idx+1)); + des->add_node(gate_t); + + // Attach a label to this intermediate wire + NetNet*tmp = new NetNet(des->local_symbol(path), + NetNet::WIRE); + tmp->local_flag(true); + connect(gate_t->pin(0), tmp->pin(0)); + des->add_signal(tmp); + } + des->add_signal(osig); + gate->rise_time(rise); + gate->fall_time(fall); + gate->decay_time(decay); + des->add_node(gate); + break; + case 'e': // == assert(lsig->pin_count() == rsig->pin_count()); osig = new NetNet(des->local_symbol(path), NetNet::WIRE); @@ -2614,6 +2684,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.116 1999/10/10 01:59:54 steve + * Structural case equals device. + * * Revision 1.115 1999/10/09 21:30:16 steve * Support parameters in continuous assignments. * diff --git a/emit.cc b/emit.cc index cb1d5f531..33ead0613 100644 --- a/emit.cc +++ b/emit.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: emit.cc,v 1.23 1999/09/22 16:57:23 steve Exp $" +#ident "$Id: emit.cc,v 1.24 1999/10/10 01:59:54 steve Exp $" #endif /* @@ -60,6 +60,11 @@ void NetAssignNB::emit_node(ostream&o, struct target_t*tgt) const tgt->net_assign_nb(o, this); } +void NetCaseCmp::emit_node(ostream&o, struct target_t*tgt) const +{ + tgt->net_case_cmp(o, this); +} + void NetConst::emit_node(ostream&o, struct target_t*tgt) const { tgt->net_const(o, this); @@ -352,6 +357,9 @@ bool emit(ostream&o, const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.24 1999/10/10 01:59:54 steve + * Structural case equals device. + * * Revision 1.23 1999/09/22 16:57:23 steve * Catch parallel blocks in vvm emit. * diff --git a/netlist.cc b/netlist.cc index 06ee9f9d3..a29e4f6ca 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.cc,v 1.75 1999/10/07 05:25:34 steve Exp $" +#ident "$Id: netlist.cc,v 1.76 1999/10/10 01:59:55 steve Exp $" #endif # include @@ -599,6 +599,18 @@ void NetCase::set_case(unsigned idx, NetExpr*e, NetProc*p) items_[idx].guard->set_width(expr_->expr_width()); } +NetCaseCmp::NetCaseCmp(const string&n) +: NetNode(n, 3) +{ + pin(0).set_dir(Link::OUTPUT); + pin(1).set_dir(Link::INPUT); + pin(2).set_dir(Link::INPUT); +} + +NetCaseCmp::~NetCaseCmp() +{ +} + NetCondit::NetCondit(NetExpr*ex, NetProc*i, NetProc*e) : expr_(ex), if_(i), else_(e) { @@ -631,6 +643,16 @@ NetProc* NetCondit::else_clause() return else_; } +NetConst::NetConst(const string&n, verinum::V v) +: NetNode(n, 1), value_(v) +{ + pin(0).set_dir(Link::OUTPUT); +} + +NetConst::~NetConst() +{ +} + NetFuncDef::NetFuncDef(const string&n, const svector&po) : name_(n), statement_(0), ports_(po) { @@ -1732,6 +1754,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.76 1999/10/10 01:59:55 steve + * Structural case equals device. + * * Revision 1.75 1999/10/07 05:25:34 steve * Add non-const bit select in l-value of assignment. * diff --git a/netlist.h b/netlist.h index 675beaffc..f98cec311 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: netlist.h,v 1.78 1999/10/07 05:25:34 steve Exp $" +#ident "$Id: netlist.h,v 1.79 1999/10/10 01:59:55 steve Exp $" #endif /* @@ -431,11 +431,33 @@ class NetBUFZ : public NetNode { virtual void emit_node(ostream&, struct target_t*) const; }; +/* + * This node is used to represent case equality in combinational + * logic. Although this is not normally synthesizeable, it makes sense + * to support an abstract gate that can compare x and z. + * + * This pins are assigned as: + * + * 0 -- Output (always returns 0 or 1) + * 1 -- Input + * 2 -- Input + */ +class NetCaseCmp : public NetNode { + + public: + explicit NetCaseCmp(const string&n); + ~NetCaseCmp(); + + virtual void dump_node(ostream&, unsigned ind) const; + virtual void emit_node(ostream&, struct target_t*) const; +}; + + class NetConst : public NetNode { public: - explicit NetConst(const string&n, verinum::V v) - : NetNode(n, 1), value_(v) { pin(0).set_dir(Link::OUTPUT); } + explicit NetConst(const string&n, verinum::V v); + ~NetConst(); verinum::V value() const { return value_; } @@ -1711,6 +1733,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.79 1999/10/10 01:59:55 steve + * Structural case equals device. + * * Revision 1.78 1999/10/07 05:25:34 steve * Add non-const bit select in l-value of assignment. * diff --git a/pform_dump.cc b/pform_dump.cc index e58277da9..a358b3a47 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pform_dump.cc,v 1.44 1999/09/30 02:43:02 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.45 1999/10/10 01:59:55 steve Exp $" #endif /* @@ -132,6 +132,9 @@ void PEBinary::dump(ostream&out) const { out << "(" << *left_ << ")"; switch (op_) { + case 'a': + out << "&&"; + break; case 'e': out << "=="; break; @@ -672,6 +675,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.45 1999/10/10 01:59:55 steve + * Structural case equals device. + * * Revision 1.44 1999/09/30 02:43:02 steve * Elaborate ~^ and ~| operators. * diff --git a/t-vvm.cc b/t-vvm.cc index 2c612f600..885f97cca 100644 --- a/t-vvm.cc +++ b/t-vvm.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: t-vvm.cc,v 1.61 1999/10/08 02:00:48 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.62 1999/10/10 01:59:55 steve Exp $" #endif # include @@ -55,6 +55,7 @@ class target_vvm : public target_t { virtual void bufz(ostream&os, const NetBUFZ*); virtual void udp(ostream&os, const NetUDP*); virtual void net_assign_nb(ostream&os, const NetAssignNB*); + virtual void net_case_cmp(ostream&os, const NetCaseCmp*); virtual void net_const(ostream&os, const NetConst*); virtual void net_esignal(ostream&os, const NetESignal*); virtual void net_event(ostream&os, const NetNEvent*); @@ -1008,6 +1009,22 @@ void target_vvm::net_assign_nb(ostream&os, const NetAssignNB*net) delayed << "}" << endl; } +void target_vvm::net_case_cmp(ostream&os, const NetCaseCmp*gate) +{ + os << "static void " << mangle(gate->name()) << + "_output_fun(vvm_simulation*, vvm_bit_t);" << endl; + + assert(gate->pin_count() == 3); + os << "static vvm_eeq" << "<" << gate->rise_time() << "> " + << mangle(gate->name()) << "(&" << mangle(gate->name()) << + "_output_fun);" << endl; + + emit_gate_outputfun_(gate); + + start_code << " " << mangle(gate->name()) << + ".start(&sim);" << endl; +} + /* * The NetConst is a synthetic device created to represent constant * values. I represent them in the output as a vvm_bufz object that @@ -1727,6 +1744,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.62 1999/10/10 01:59:55 steve + * Structural case equals device. + * * Revision 1.61 1999/10/08 02:00:48 steve * vvm supports unary | operator. * diff --git a/target.cc b/target.cc index 7f9b5573c..524eafc29 100644 --- a/target.cc +++ b/target.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: target.cc,v 1.20 1999/09/22 16:57:24 steve Exp $" +#ident "$Id: target.cc,v 1.21 1999/10/10 01:59:55 steve Exp $" #endif # include "target.h" @@ -85,6 +85,12 @@ void target_t::net_assign_nb(ostream&os, const NetAssignNB*) "Unhandled non-blocking assignment node." << endl; } +void target_t::net_case_cmp(ostream&os, const NetCaseCmp*) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled case compare node." << endl; +} + void target_t::net_const(ostream&os, const NetConst*) { cerr << "target (" << typeid(*this).name() << "): " @@ -269,6 +275,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.21 1999/10/10 01:59:55 steve + * Structural case equals device. + * * Revision 1.20 1999/09/22 16:57:24 steve * Catch parallel blocks in vvm emit. * diff --git a/target.h b/target.h index f80d643a9..688a3d380 100644 --- a/target.h +++ b/target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: target.h,v 1.19 1999/09/22 16:57:24 steve Exp $" +#ident "$Id: target.h,v 1.20 1999/10/10 01:59:55 steve Exp $" #endif # include "netlist.h" @@ -74,6 +74,7 @@ struct target_t { virtual void udp(ostream&os, const NetUDP*); virtual void net_assign(ostream&os, const NetAssign*); virtual void net_assign_nb(ostream&os, const NetAssignNB*); + virtual void net_case_cmp(ostream&os, const NetCaseCmp*); virtual void net_const(ostream&os, const NetConst*); virtual void net_esignal(ostream&os, const NetESignal*); virtual void net_event(ostream&os, const NetNEvent*); @@ -136,6 +137,9 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.20 1999/10/10 01:59:55 steve + * Structural case equals device. + * * Revision 1.19 1999/09/22 16:57:24 steve * Catch parallel blocks in vvm emit. * diff --git a/vvm/vvm_gates.h b/vvm/vvm_gates.h index e1946ba3f..f38571b1e 100644 --- a/vvm/vvm_gates.h +++ b/vvm/vvm_gates.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm_gates.h,v 1.13 1999/10/09 19:24:36 steve Exp $" +#ident "$Id: vvm_gates.h,v 1.14 1999/10/10 01:59:55 steve Exp $" #endif # include "vvm.h" @@ -346,6 +346,47 @@ template class vvm_xor { vvm_out_event::action_t output_; }; +/* + * This gate has only 3 pins, the output at pin 0 and two inputs. The + * output is 1 or 0 if the two inputs are exactly equal or not. + */ +template class vvm_eeq { + + public: + explicit vvm_eeq(vvm_out_event::action_t o) + : output_(o) { } + + void init(unsigned idx, vvm_bit_t val) + { input_[idx-1] = val; } + + void start(vvm_simulation*sim) + { vvm_event*ev = new vvm_out_event(sim, compute_(), output_); + if (DELAY > 0) + sim->insert_event(DELAY, ev); + else + sim->active_event(ev); + } + + void set(vvm_simulation*sim, unsigned idx, vvm_bit_t val) + { if (input_[idx-1] == val) + return; + input_[idx-1] = val; + start(sim); + } + + private: + + vvm_bit_t compute_() const + { vvm_bit_t outval = V0; + if (input_[0] == input_[1]) + outval = V1; + return outval; + } + + vvm_bit_t input_[2]; + vvm_out_event::action_t output_; +}; + /* * A Sequential UDP has a more complex truth table, and handles * edges. Pin 0 is an output, and all the remaining pins are @@ -496,6 +537,9 @@ template class vvm_pevent { /* * $Log: vvm_gates.h,v $ + * Revision 1.14 1999/10/10 01:59:55 steve + * Structural case equals device. + * * Revision 1.13 1999/10/09 19:24:36 steve * NOR device. *