Parse and elaborate the Verilog CASE statement.

This commit is contained in:
steve 1999-02-03 04:20:11 +00:00
parent a7ad8985ac
commit 8bdd381cdf
8 changed files with 248 additions and 9 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.4 1999/01/25 05:45:56 steve Exp $"
#ident "$Id: Statement.cc,v 1.5 1999/02/03 04:20:11 steve Exp $"
#endif
# include "Statement.h"
@ -57,6 +57,33 @@ PCallTask::PCallTask(const string&n, const list<PExpr*>&p)
}
PCase::PCase(PExpr*ex, list<PCase::Item*>*l)
: expr_(ex)
{
nitems_ = l->size();
items_ = new Item[nitems_];
list<PCase::Item*>::const_iterator cur;
unsigned idx;
for (cur = l->begin(), idx = 0 ; cur != l->end() ; cur ++, idx += 1) {
items_[idx] = *(*cur);
delete (*cur);
}
delete l;
}
PCase::~PCase()
{
delete expr_;
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
if (items_[idx].expr) delete items_[idx].expr;
if (items_[idx].stat) delete items_[idx].stat;
}
delete[]items_;
}
PCondit::~PCondit()
{
delete expr_;
@ -77,6 +104,9 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* Revision 1.5 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.4 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.

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.5 1999/01/25 05:45:56 steve Exp $"
#ident "$Id: Statement.h,v 1.6 1999/02/03 04:20:11 steve Exp $"
#endif
# include <string>
@ -149,6 +149,31 @@ class PCallTask : public Statement {
PExpr**const parms_;
};
class PCase : public Statement {
public:
struct Item {
PExpr*expr;
Statement*stat;
};
PCase(PExpr*ex, list<Item*>*);
~PCase();
virtual NetProc* elaborate(Design*des, const string&path) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
PExpr*expr_;
Item*items_;
unsigned nitems_;
private: // not implemented
PCase(const PCase&);
PCase& operator= (const PCase&);
};
class PCondit : public Statement {
public:
@ -248,6 +273,9 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.6 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.5 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.

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.10 1999/02/01 00:26:48 steve Exp $"
#ident "$Id: design_dump.cc,v 1.11 1999/02/03 04:20:11 steve Exp $"
#endif
/*
@ -303,6 +303,28 @@ void NetBlock::dump(ostream&o, unsigned ind) const
o << setw(ind) << "" << "end" << endl;
}
void NetCase::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "case (" << *expr_ << ")" << endl;
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
o << setw(ind+2) << "";
if (items_[idx].guard)
o << *items_[idx].guard << ":";
else
o << "default:";
if (items_[idx].statement) {
o << endl;
items_[idx].statement->dump(o, ind+6);
} else {
o << " ;" << endl;
}
}
o << setw(ind) << "" << "endcase" << endl;
}
void NetCondit::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "if (";
@ -468,6 +490,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.11 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.10 1999/02/01 00:26:48 steve
* Carry some line info to the netlist,
* Dump line numbers for processes.

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.12 1999/02/01 00:26:49 steve Exp $"
#ident "$Id: elaborate.cc,v 1.13 1999/02/03 04:20:11 steve Exp $"
#endif
/*
@ -650,11 +650,31 @@ NetProc* PBlock::elaborate(Design*des, const string&path) const
return cur;
}
NetProc* PCase::elaborate(Design*des, const string&path) const
{
NetExpr*expr = expr_->elaborate_expr(des, path);
NetCase*res = new NetCase(expr, nitems_);
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
NetExpr*gu = 0;
NetProc*st = 0;
if (items_[idx].expr)
gu = items_[idx].expr->elaborate_expr(des, path);
if (items_[idx].stat)
st = items_[idx].stat->elaborate(des, path);
res->set_case(idx, gu, st);
}
return res;
}
NetProc* PCondit::elaborate(Design*des, const string&path) const
{
NetExpr*expr = expr_->elaborate_expr(des, path);
NetProc*i = if_->elaborate(des, path);
NetProc*e = else_->elaborate(des, path);
NetProc*e = else_? else_->elaborate(des, path) : 0;
NetCondit*res = new NetCondit(expr, i, e);
return res;
@ -851,6 +871,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.13 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.12 1999/02/01 00:26:49 steve
* Carry some line info to the netlist,
* Dump line numbers for processes.

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.14 1998/12/18 05:16:25 steve Exp $"
#ident "$Id: netlist.cc,v 1.15 1999/02/03 04:20:11 steve Exp $"
#endif
# include <cassert>
@ -320,6 +320,34 @@ void NetBlock::append(NetProc*cur)
}
}
NetCase::NetCase(NetExpr*ex, unsigned cnt)
: expr_(ex), nitems_(cnt)
{
assert(expr_);
items_ = new Item[nitems_];
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
items_[idx].guard = 0;
items_[idx].statement = 0;
}
}
NetCase::~NetCase()
{
delete expr_;
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
if (items_[idx].guard) delete items_[idx].guard;
if (items_[idx].statement) delete items_[idx].statement;
}
delete[]items_;
}
void NetCase::set_case(unsigned idx, NetExpr*e, NetProc*p)
{
assert(idx < nitems_);
items_[idx].guard = e;
items_[idx].statement = p;
}
NetTask::~NetTask()
{
delete[]parms_;
@ -845,6 +873,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.15 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.14 1998/12/18 05:16:25 steve
* Parse more UDP input edge descriptions.
*

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.16 1999/02/01 00:26:49 steve Exp $"
#ident "$Id: netlist.h,v 1.17 1999/02/03 04:20:11 steve Exp $"
#endif
/*
@ -531,6 +531,34 @@ 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. */
class NetCase : public NetProc {
public:
NetCase(NetExpr*ex, unsigned cnt);
~NetCase();
void set_case(unsigned idx, NetExpr*ex, NetProc*st);
//virtual void emit_proc(ostream&, struct target_t*) const;
virtual void dump(ostream&, unsigned ind) const;
private:
struct Item {
NetExpr*guard;
NetProc*statement;
};
NetExpr*expr_;
unsigned nitems_;
Item*items_;
};
/* A condit represents a conditional. It has an expression to test,
and a pair of statements to select from. */
class NetCondit : public NetProc {
@ -925,6 +953,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.17 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.16 1999/02/01 00:26:49 steve
* Carry some line info to the netlist,
* Dump line numbers for processes.

48
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.11 1999/01/25 05:45:56 steve Exp $"
#ident "$Id: parse.y,v 1.12 1999/02/03 04:20:11 steve Exp $"
#endif
# include "parse_misc.h"
@ -34,6 +34,9 @@ extern void lex_end_table();
string*text;
list<string>*strings;
PCase::Item*citem;
list<PCase::Item*>*citems;
lgate*gate;
list<lgate>*gates;
@ -89,6 +92,9 @@ extern void lex_end_table();
%type <wire> port
%type <wires> list_of_ports list_of_ports_opt
%type <citem> case_item
%type <citems> case_items
%type <gate> gate_instance
%type <gates> gate_instance_list
@ -123,6 +129,40 @@ bitsel
{ $$ = $2; }
;
case_item
: expression ':' statement_opt
{ PCase::Item*tmp = new PCase::Item;
tmp->expr = $1;
tmp->stat = $3;
$$ = 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;
}
;
case_items
: case_items case_item
{ list<PCase::Item*>*tmp = $1;
tmp->push_back($2);
$$ = tmp;
}
| case_item
{ list<PCase::Item*>*tmp = new list<PCase::Item*>;
tmp->push_back($1);
$$ = tmp;
}
;
const_expression
: NUMBER
{ $$ = new PENumber($1);
@ -546,6 +586,12 @@ statement
{ $$ = pform_make_block(PBlock::BL_SEQ, 0); }
| K_fork K_join
{ $$ = pform_make_block(PBlock::BL_PAR, 0); }
| K_case '(' expression ')' case_items K_endcase
{ PCase*tmp = new PCase($3, $5);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| K_if '(' expression ')' statement_opt
{ PCondit*tmp = new PCondit($3, $5, 0);
$$ = tmp;

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.8 1999/02/01 00:26:49 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.9 1999/02/03 04:20:11 steve Exp $"
#endif
/*
@ -224,6 +224,28 @@ void PCallTask::dump(ostream&out, unsigned ind) const
out << ";" << endl;
}
void PCase::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "case (" << *expr_ << ") /* " <<
get_line() << " */" << endl;
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
if (items_[idx].expr)
out << setw(ind+2) << "" << *items_[idx].expr << ":";
else
out << setw(ind+2) << "" << "default:";
if (items_[idx].stat) {
out << endl;
items_[idx].stat->dump(out, ind+6);
} else {
out << " ;" << endl;
}
}
out << setw(ind) << "" << "endcase" << endl;
}
void PCondit::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << "if (" << *expr_ << ")" << endl;
@ -373,6 +395,9 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.9 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*
* Revision 1.8 1999/02/01 00:26:49 steve
* Carry some line info to the netlist,
* Dump line numbers for processes.