Full case support

This commit is contained in:
steve 1999-09-29 18:36:02 +00:00
parent 3a415fb04c
commit a64a33e65a
11 changed files with 228 additions and 43 deletions

View File

@ -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<PExpr*>&p)
{
}
PCase::PCase(PExpr*ex, svector<PCase::Item*>*l)
: expr_(ex), items_(l)
PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*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.
*

View File

@ -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 <string>
@ -200,13 +200,14 @@ class PCase : public Statement {
Statement*stat;
};
PCase(PExpr*ex, svector<Item*>*);
PCase(NetCase::TYPE, PExpr*ex, svector<Item*>*);
~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<Item*>*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.
*

View File

@ -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.
*

View File

@ -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<string,Module*>&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.
*

View File

@ -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 <cassert>
@ -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.
*

View File

@ -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.
*

10
parse.y
View File

@ -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

View File

@ -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.
*

View File

@ -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 <iostream>
@ -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.
*

View File

@ -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 <vector>
@ -133,13 +133,6 @@ template <unsigned WIDTH> 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<WIDTH>&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 <unsigned WIDTH> 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.
*

View File

@ -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<LW>&l,
}
}
/*
* This function return true if all the bits are the same. Even x and
* z bites are compared for equality.
*/
template <unsigned LW, unsigned RW>
vvm_bitset_t<1> vvm_binop_eeq(const vvm_bitset_t<LW>&l,
const vvm_bitset_t<RW>&r)
@ -277,6 +281,112 @@ vvm_bitset_t<1> vvm_binop_eeq(const vvm_bitset_t<LW>&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 <unsigned LW, unsigned RW>
vvm_bitset_t<1> vvm_binop_xeq(const vvm_bitset_t<LW>&l,
const vvm_bitset_t<RW>&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 <unsigned LW, unsigned RW>
vvm_bitset_t<1> vvm_binop_zeq(const vvm_bitset_t<LW>&l,
const vvm_bitset_t<RW>&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 <unsigned LW, unsigned RW>
vvm_bitset_t<1> vvm_binop_ne(const vvm_bitset_t<LW>&l,
const vvm_bitset_t<RW>&r)
@ -411,6 +521,9 @@ vvm_bitset_t<W> vvm_ternary(vvm_bit_t c, const vvm_bitset_t<W>&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.
*