Parse and elaborate the Verilog CASE statement.
This commit is contained in:
parent
a7ad8985ac
commit
8bdd381cdf
32
Statement.cc
32
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.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.
|
||||
|
|
|
|||
30
Statement.h
30
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.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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
27
elaborate.cc
27
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.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.
|
||||
|
|
|
|||
33
netlist.cc
33
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.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.
|
||||
*
|
||||
|
|
|
|||
33
netlist.h
33
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.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
48
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.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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue