diff --git a/Statement.cc b/Statement.cc index 98b25a717..b6f71d5ce 100644 --- a/Statement.cc +++ b/Statement.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Statement.cc,v 1.15 1999/09/22 02:00:48 steve Exp $" +#ident "$Id: Statement.cc,v 1.16 1999/09/29 18:36:02 steve Exp $" #endif # include "Statement.h" @@ -108,8 +108,8 @@ PCallTask::PCallTask(const string&n, const svector&p) { } -PCase::PCase(PExpr*ex, svector*l) -: expr_(ex), items_(l) +PCase::PCase(NetCase::TYPE t, PExpr*ex, svector*l) +: type_(t), expr_(ex), items_(l) { } @@ -163,6 +163,9 @@ PWhile::~PWhile() /* * $Log: Statement.cc,v $ + * Revision 1.16 1999/09/29 18:36:02 steve + * Full case support + * * Revision 1.15 1999/09/22 02:00:48 steve * assignment with blocking event delay. * diff --git a/Statement.h b/Statement.h index 1c11a7d1c..6ecf730ca 100644 --- a/Statement.h +++ b/Statement.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: Statement.h,v 1.19 1999/09/22 02:00:48 steve Exp $" +#ident "$Id: Statement.h,v 1.20 1999/09/29 18:36:02 steve Exp $" #endif # include @@ -200,13 +200,14 @@ class PCase : public Statement { Statement*stat; }; - PCase(PExpr*ex, svector*); + PCase(NetCase::TYPE, PExpr*ex, svector*); ~PCase(); virtual NetProc* elaborate(Design*des, const string&path) const; virtual void dump(ostream&out, unsigned ind) const; private: + NetCase::TYPE type_; PExpr*expr_; svector*items_; @@ -346,6 +347,9 @@ class PWhile : public Statement { /* * $Log: Statement.h,v $ + * Revision 1.20 1999/09/29 18:36:02 steve + * Full case support + * * Revision 1.19 1999/09/22 02:00:48 steve * assignment with blocking event delay. * diff --git a/design_dump.cc b/design_dump.cc index b367ead57..8f99a3462 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.43 1999/09/21 00:13:40 steve Exp $" +#ident "$Id: design_dump.cc,v 1.44 1999/09/29 18:36:03 steve Exp $" #endif /* @@ -406,7 +406,14 @@ void NetBlock::dump(ostream&o, unsigned ind) const void NetCase::dump(ostream&o, unsigned ind) const { - o << setw(ind) << "" << "case (" << *expr_ << ")" << endl; + switch (type_) { + case EQ: + o << setw(ind) << "" << "case (" << *expr_ << ")" << endl; + case EQX: + o << setw(ind) << "" << "casex (" << *expr_ << ")" << endl; + case EQZ: + o << setw(ind) << "" << "casez (" << *expr_ << ")" << endl; + } for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) { o << setw(ind+2) << ""; @@ -761,6 +768,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.44 1999/09/29 18:36:03 steve + * Full case support + * * Revision 1.43 1999/09/21 00:13:40 steve * Support parameters that reference other paramters. * diff --git a/elaborate.cc b/elaborate.cc index d8cd5bed7..069f4f72c 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.101 1999/09/29 00:42:50 steve Exp $" +#ident "$Id: elaborate.cc,v 1.102 1999/09/29 18:36:03 steve Exp $" #endif /* @@ -1845,7 +1845,8 @@ NetProc* PCase::elaborate(Design*des, const string&path) const icount += cur->expr.count(); } - NetCase*res = new NetCase(expr, icount); + NetCase*res = new NetCase(type_, expr, icount); + res->set_line(*this); unsigned inum = 0; for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) { @@ -2572,6 +2573,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.102 1999/09/29 18:36:03 steve + * Full case support + * * Revision 1.101 1999/09/29 00:42:50 steve * Allow expanding of additive operators. * diff --git a/netlist.cc b/netlist.cc index 721fa4bd7..474e88b46 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.70 1999/09/28 03:11:29 steve Exp $" +#ident "$Id: netlist.cc,v 1.71 1999/09/29 18:36:03 steve Exp $" #endif # include @@ -292,6 +292,11 @@ unsigned NetNet::sb_to_idx(long sb) const return lsb_ - sb; } +NetProc::NetProc() +: next_(0) +{ +} + NetProc::~NetProc() { } @@ -511,8 +516,8 @@ void NetBlock::append(NetProc*cur) } } -NetCase::NetCase(NetExpr*ex, unsigned cnt) -: expr_(ex), nitems_(cnt) +NetCase::NetCase(NetCase::TYPE c, NetExpr*ex, unsigned cnt) +: type_(c), expr_(ex), nitems_(cnt) { assert(expr_); items_ = new Item[nitems_]; @@ -531,6 +536,11 @@ NetCase::~NetCase() delete[]items_; } +NetCase::TYPE NetCase::type() const +{ + return type_; +} + void NetCase::set_case(unsigned idx, NetExpr*e, NetProc*p) { assert(idx < nitems_); @@ -1647,6 +1657,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*)) /* * $Log: netlist.cc,v $ + * Revision 1.71 1999/09/29 18:36:03 steve + * Full case support + * * Revision 1.70 1999/09/28 03:11:29 steve * Get the bit widths of unary operators that return one bit. * diff --git a/netlist.h b/netlist.h index 3128b91bd..758e99330 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.73 1999/09/28 03:11:30 steve Exp $" +#ident "$Id: netlist.h,v 1.74 1999/09/29 18:36:03 steve Exp $" #endif /* @@ -583,10 +583,10 @@ class NetUDP : public NetNode { * linked into the netlist. However, elaborating a process may cause * special nodes to be created to handle things like events. */ -class NetProc { +class NetProc : public LineInfo { public: - explicit NetProc() : next_(0) { } + explicit NetProc(); virtual ~NetProc(); // This method is called to emit the statement to the @@ -613,7 +613,7 @@ class NetProc { * should know that this is not a guarantee. */ -class NetAssign_ : public NetProc, public NetNode, public LineInfo { +class NetAssign_ : public NetProc, public NetNode { protected: NetAssign_(const string&n, unsigned w); @@ -675,7 +675,7 @@ class NetAssignNB : public NetAssign_ { * regular assign, and the NetAssignMem_ base class takes care of all * the common stuff. */ -class NetAssignMem_ : public NetProc, public LineInfo { +class NetAssignMem_ : public NetProc { public: explicit NetAssignMem_(NetMemory*, NetExpr*idx, NetExpr*rv); @@ -743,18 +743,27 @@ class NetBlock : public NetProc { NetProc*last_; }; -/* A CASE statement in the verilog source leads, eventually, to one of - these. This is different from a simple conditional because of the - way the comparisons are performed. Also, it is likely that the - target may be able to optimize differently. */ +/* + * A CASE statement in the verilog source leads, eventually, to one of + * these. This is different from a simple conditional because of the + * way the comparisons are performed. Also, it is likely that the + * target may be able to optimize differently. + * + * Case cane be one of three types: + * EQ -- All bits must exactly match + * EQZ -- z bits are don't care + * EQX -- x and z bits are don't care. + */ class NetCase : public NetProc { public: - NetCase(NetExpr*ex, unsigned cnt); + enum TYPE { EQ, EQX, EQZ }; + NetCase(TYPE c, NetExpr*ex, unsigned cnt); ~NetCase(); void set_case(unsigned idx, NetExpr*ex, NetProc*st); + TYPE type() const; const NetExpr*expr() const { return expr_; } unsigned nitems() const { return nitems_; } @@ -766,6 +775,8 @@ class NetCase : public NetProc { private: + TYPE type_; + struct Item { NetExpr*guard; NetProc*statement; @@ -1689,6 +1700,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.74 1999/09/29 18:36:03 steve + * Full case support + * * Revision 1.73 1999/09/28 03:11:30 steve * Get the bit widths of unary operators that return one bit. * diff --git a/parse.y b/parse.y index 607c1f5a6..deb6a41b1 100644 --- a/parse.y +++ b/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: parse.y,v 1.67 1999/09/25 02:57:30 steve Exp $" +#ident "$Id: parse.y,v 1.68 1999/09/29 18:36:04 steve Exp $" #endif # include "parse_misc.h" @@ -1490,23 +1490,21 @@ statement $$ = tmp; } | K_case '(' expression ')' case_items K_endcase - { PCase*tmp = new PCase($3, $5); + { PCase*tmp = new PCase(NetCase::EQ, $3, $5); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); $$ = tmp; } | K_casex '(' expression ')' case_items K_endcase - { PCase*tmp = new PCase($3, $5); + { PCase*tmp = new PCase(NetCase::EQX, $3, $5); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); - yywarn(@1, "casex not properly supported, using case."); $$ = tmp; } | K_casez '(' expression ')' case_items K_endcase - { PCase*tmp = new PCase($3, $5); + { PCase*tmp = new PCase(NetCase::EQZ, $3, $5); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); - yywarn(@1, "casez not properly supported, using case."); $$ = tmp; } | K_case '(' expression ')' error K_endcase diff --git a/pform_dump.cc b/pform_dump.cc index 83de5d216..60e63cf45 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.39 1999/09/17 02:06:26 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.40 1999/09/29 18:36:04 steve Exp $" #endif /* @@ -361,8 +361,19 @@ void PCallTask::dump(ostream&out, unsigned ind) const void PCase::dump(ostream&out, unsigned ind) const { - out << setw(ind) << "" << "case (" << *expr_ << ") /* " << - get_line() << " */" << endl; + out << setw(ind) << ""; + switch (type_) { + case NetCase::EQ: + out << "case"; + break; + case NetCase::EQX: + out << "casex"; + break; + case NetCase::EQZ: + out << "casez"; + break; + } + out << " (" << *expr_ << ") /* " << get_line() << " */" << endl; for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) { PCase::Item*cur = (*items_)[idx]; @@ -645,6 +656,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.40 1999/09/29 18:36:04 steve + * Full case support + * * Revision 1.39 1999/09/17 02:06:26 steve * Handle unconnected module ports. * diff --git a/t-vvm.cc b/t-vvm.cc index 62e795355..edf24fbdd 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.51 1999/09/29 00:42:25 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.52 1999/09/29 18:36:04 steve Exp $" #endif # include @@ -1198,6 +1198,19 @@ bool target_vvm::proc_block(ostream&os, const NetBlock*net) */ void target_vvm::proc_case(ostream&os, const NetCase*net) { + string test_func = ""; + switch (net->type()) { + case NetCase::EQ: + test_func = "vvm_binop_eeq"; + break; + case NetCase::EQX: + test_func = "vvm_binop_xeq"; + break; + case NetCase::EQZ: + test_func = "vvm_binop_zeq"; + break; + } + os << " /* case (" << *net->expr() << ") */" << endl; string expr = emit_proc_rval(os, 8, net->expr()); @@ -1223,8 +1236,8 @@ void target_vvm::proc_case(ostream&os, const NetCase*net) thread_step_ += 1; - os << " if (" << expr << ".eequal(" << guard << - ")) {" << endl; + os << " if (V1 == " << test_func << "(" << guard << "," + << expr << ")[0]) {" << endl; os << " step_ = &" << thread_class_ << "::step_" << thread_step_ << "_;" << endl; os << " return true;" << endl; @@ -1563,6 +1576,9 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.52 1999/09/29 18:36:04 steve + * Full case support + * * Revision 1.51 1999/09/29 00:42:25 steve * Comment on where binary operator came from. * diff --git a/vvm/vvm.h b/vvm/vvm.h index 7c57ce5b2..424c371fd 100644 --- a/vvm/vvm.h +++ b/vvm/vvm.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm.h,v 1.11 1999/09/28 01:13:15 steve Exp $" +#ident "$Id: vvm.h,v 1.12 1999/09/29 18:36:04 steve Exp $" #endif # include @@ -133,13 +133,6 @@ template class vvm_bitset_t : public vvm_bits_t { unsigned get_width() const { return WIDTH; } vvm_bit_t get_bit(unsigned idx) const { return bits_[idx]; } - bool eequal(const vvm_bitset_t&that) const - { for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) - if (bits_[idx] != that.bits_[idx]) - return false; - return true; - } - unsigned as_unsigned() const { unsigned result = 0; for (unsigned idx = WIDTH ; idx > 0 ; idx -= 1) { @@ -289,6 +282,9 @@ template class vvm_signal_t : public vvm_monitor_t { /* * $Log: vvm.h,v $ + * Revision 1.12 1999/09/29 18:36:04 steve + * Full case support + * * Revision 1.11 1999/09/28 01:13:15 steve * Support in vvm > and >= behavioral operators. * diff --git a/vvm/vvm_func.h b/vvm/vvm_func.h index 08ade4967..58f1e2aa4 100644 --- a/vvm/vvm_func.h +++ b/vvm/vvm_func.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvm_func.h,v 1.10 1999/09/28 01:13:16 steve Exp $" +#ident "$Id: vvm_func.h,v 1.11 1999/09/29 18:36:04 steve Exp $" #endif # include "vvm.h" @@ -239,6 +239,10 @@ vvm_bitset_t<1> vvm_binop_eq(const vvm_bitset_t&l, } } +/* + * This function return true if all the bits are the same. Even x and + * z bites are compared for equality. + */ template vvm_bitset_t<1> vvm_binop_eeq(const vvm_bitset_t&l, const vvm_bitset_t&r) @@ -277,6 +281,112 @@ vvm_bitset_t<1> vvm_binop_eeq(const vvm_bitset_t&l, return result; } +/* + * This function return true if all the bits are the same. The x and z + * bits are don't care, s don't make the result false. + */ +template +vvm_bitset_t<1> vvm_binop_xeq(const vvm_bitset_t&l, + const vvm_bitset_t&r) +{ + vvm_bitset_t<1> result; + result[0] = V1; + + if (LW <= RW) { + for (unsigned idx = 0 ; idx < LW ; idx += 1) { + if ((l[idx] == Vz) || (r[idx] == Vz)) + continue; + if ((l[idx] == Vx) || (r[idx] == Vx)) + continue; + if (l[idx] != r[idx]) { + result[0] = V0; + return result; + } + } + for (unsigned idx = LW ; idx < RW ; idx += 1) { + if ((r[idx] == Vx) || (r[idx] == Vz)) + continue; + if (r[idx] != V0) { + result[0] = V0; + return result; + } + } + + } else { + for (unsigned idx = 0 ; idx < RW ; idx += 1) { + if ((l[idx] == Vz) || (r[idx] == Vz)) + continue; + if ((l[idx] == Vx) || (r[idx] == Vx)) + continue; + if (l[idx] != r[idx]) { + result[0] = V0; + return result; + } + } + for (unsigned idx = RW ; idx < LW ; idx += 1) { + if ((l[idx] == Vx) || (l[idx] == Vz)) + continue; + if (l[idx] != V0) { + result[0] = V0; + return result; + } + } + } + + return result; +} + +/* + * This function return true if all the bits are the same. The z + * bits are don't care, so don't make the result false. + */ +template +vvm_bitset_t<1> vvm_binop_zeq(const vvm_bitset_t&l, + const vvm_bitset_t&r) +{ + vvm_bitset_t<1> result; + result[0] = V1; + + if (LW <= RW) { + for (unsigned idx = 0 ; idx < LW ; idx += 1) { + if ((l[idx] == Vz) || (r[idx] == Vz)) + continue; + if (l[idx] != r[idx]) { + result[0] = V0; + return result; + } + } + for (unsigned idx = LW ; idx < RW ; idx += 1) { + if (r[idx] == Vz) + continue; + if (r[idx] != V0) { + result[0] = V0; + return result; + } + } + + } else { + for (unsigned idx = 0 ; idx < RW ; idx += 1) { + if ((l[idx] == Vz) || (r[idx] == Vz)) + continue; + if (l[idx] != r[idx]) { + result[0] = V0; + return result; + } + } + for (unsigned idx = RW ; idx < LW ; idx += 1) { + if (l[idx] == Vz) + continue; + if (l[idx] != V0) { + result[0] = V0; + return result; + } + } + } + + return result; +} + template vvm_bitset_t<1> vvm_binop_ne(const vvm_bitset_t&l, const vvm_bitset_t&r) @@ -411,6 +521,9 @@ vvm_bitset_t vvm_ternary(vvm_bit_t c, const vvm_bitset_t&t, /* * $Log: vvm_func.h,v $ + * Revision 1.11 1999/09/29 18:36:04 steve + * Full case support + * * Revision 1.10 1999/09/28 01:13:16 steve * Support in vvm > and >= behavioral operators. *