diff --git a/README.txt b/README.txt index 778eb40b8..6792eef4e 100644 --- a/README.txt +++ b/README.txt @@ -223,11 +223,6 @@ IVL is in development - as such it still only supports a (growing) subset of verilog. Below is a description of some of the currently unsupported verilog features. - - Lvalue bit ranges, i.e. values being assigned to. Examples: - - regval [3:1] = 3'b0; - regval [7:0] = 8'b0; - - The "?" operator. Example: count = val ? 1 : 0; - Ranges within parameter definitions: @@ -267,12 +262,6 @@ verilog features. - Bit ranges within IF. Example: if (a[2:3]) do = 1; - - List of targets for case statement: - Example: - case (a) // Not Okay - 1, 2, and 3 must be separate lines. - 1, 2, 3: $write("selected 1, 2, 3 (Not Ok)\n"); - endcase - - Forever key word. - Repeat key word. diff --git a/Statement.cc b/Statement.cc index fd2cf6ae0..1ae6be82a 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.8 1999/06/13 23:51:16 steve Exp $" +#ident "$Id: Statement.cc,v 1.9 1999/06/15 05:38:39 steve Exp $" #endif # include "Statement.h" @@ -89,10 +89,8 @@ PCase::PCase(PExpr*ex, svector*l) PCase::~PCase() { delete expr_; - for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) { - if ((*items_)[idx]->expr) delete (*items_)[idx]->expr; + for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) if ((*items_)[idx]->stat) delete (*items_)[idx]->stat; - } delete[]items_; } @@ -117,6 +115,9 @@ PWhile::~PWhile() /* * $Log: Statement.cc,v $ + * Revision 1.9 1999/06/15 05:38:39 steve + * Support case expression lists. + * * Revision 1.8 1999/06/13 23:51:16 steve * l-value part select for procedural assignments. * diff --git a/Statement.h b/Statement.h index 1f2528ea5..b53c475d9 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.10 1999/06/13 23:51:16 steve Exp $" +#ident "$Id: Statement.h,v 1.11 1999/06/15 05:38:39 steve Exp $" #endif # include @@ -180,7 +180,7 @@ class PCase : public Statement { public: struct Item { - PExpr*expr; + svectorexpr; Statement*stat; }; @@ -301,6 +301,9 @@ class PWhile : public Statement { /* * $Log: Statement.h,v $ + * Revision 1.11 1999/06/15 05:38:39 steve + * Support case expression lists. + * * Revision 1.10 1999/06/13 23:51:16 steve * l-value part select for procedural assignments. * diff --git a/elaborate.cc b/elaborate.cc index 461bd59cf..fdbfca040 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.44 1999/06/15 03:44:53 steve Exp $" +#ident "$Id: elaborate.cc,v 1.45 1999/06/15 05:38:39 steve Exp $" #endif /* @@ -1224,6 +1224,9 @@ NetProc* PBlock::elaborate(Design*des, const string&path) const return cur; } +/* + * Elaborate a case statement. + */ NetProc* PCase::elaborate(Design*des, const string&path) const { NetExpr*expr = expr_->elaborate_expr(des, path); @@ -1233,18 +1236,51 @@ NetProc* PCase::elaborate(Design*des, const string&path) const return 0; } - NetCase*res = new NetCase(expr, items_->count()); - + unsigned icount = 0; for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) { - NetExpr*gu = 0; - NetProc*st = 0; - if ((*items_)[idx]->expr) - gu = (*items_)[idx]->expr->elaborate_expr(des, path); + PCase::Item*cur = (*items_)[idx]; - if ((*items_)[idx]->stat) - st = (*items_)[idx]->stat->elaborate(des, path); + if (cur->expr.count() == 0) + icount += 1; + else + icount += cur->expr.count(); + } - res->set_case(idx, gu, st); + NetCase*res = new NetCase(expr, icount); + + unsigned inum = 0; + for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) { + + assert(inum < icount); + PCase::Item*cur = (*items_)[idx]; + + if (cur->expr.count() == 0) { + /* If there are no expressions, then this is the + default case. */ + NetProc*st = 0; + if (cur->stat) + st = cur->stat->elaborate(des, path); + + res->set_case(inum, 0, st); + inum += 1; + + } else for (unsigned e = 0; e < cur->expr.count(); e += 1) { + + /* If there are one or more expressions, then + iterate over the guard expressions, elaborating + a separate case for each. (Yes, the statement + will be elaborated again for each.) */ + NetExpr*gu = 0; + NetProc*st = 0; + assert(cur->expr[e]); + gu = cur->expr[e]->elaborate_expr(des, path); + + if (cur->stat) + st = cur->stat->elaborate(des, path); + + res->set_case(inum, gu, st); + inum += 1; + } } return res; @@ -1527,6 +1563,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.45 1999/06/15 05:38:39 steve + * Support case expression lists. + * * Revision 1.44 1999/06/15 03:44:53 steve * Get rid of the STL vector template. * diff --git a/parse.y b/parse.y index eb99bbeac..68062ee7d 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.41 1999/06/15 02:50:02 steve Exp $" +#ident "$Id: parse.y,v 1.42 1999/06/15 05:38:39 steve Exp $" #endif # include "parse_misc.h" @@ -153,22 +153,18 @@ source_file case_item : expression_list ':' statement_opt { PCase::Item*tmp = new PCase::Item; - if ($1->count() > 1) { - yyerror(@1, "Sorry, case expression lists not supported."); - } - tmp->expr = (*$1)[0]; + tmp->expr = *$1; tmp->stat = $3; + delete $1; $$ = tmp; } | K_default ':' statement_opt { PCase::Item*tmp = new PCase::Item; - tmp->expr = 0; tmp->stat = $3; $$ = tmp; } | K_default statement_opt { PCase::Item*tmp = new PCase::Item; - tmp->expr = 0; tmp->stat = $2; $$ = tmp; } diff --git a/pform_dump.cc b/pform_dump.cc index 018643c4d..39790e012 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.21 1999/06/15 03:44:53 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.22 1999/06/15 05:38:39 steve Exp $" #endif /* @@ -310,14 +310,23 @@ void PCase::dump(ostream&out, unsigned ind) const get_line() << " */" << endl; for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) { - if ((*items_)[idx]->expr) - out << setw(ind+2) << "" << *(*items_)[idx]->expr << ":"; - else + PCase::Item*cur = (*items_)[idx]; + + if (cur->expr.count() == 0) { out << setw(ind+2) << "" << "default:"; - if ((*items_)[idx]->stat) { + } else { + out << setw(ind+2) << "" << *cur->expr[0]; + + for(unsigned e = 1 ; e < cur->expr.count() ; e += 1) + out << ", " << *cur->expr[e]; + + out << ":"; + } + + if (cur->stat) { out << endl; - (*items_)[idx]->stat->dump(out, ind+6); + cur->stat->dump(out, ind+6); } else { out << " ;" << endl; } @@ -480,6 +489,9 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.22 1999/06/15 05:38:39 steve + * Support case expression lists. + * * Revision 1.21 1999/06/15 03:44:53 steve * Get rid of the STL vector template. *