Parse and elaborate the concatenate operator

in structural contexts, Replace vector<PExpr*>
 and list<PExpr*> with svector<PExpr*>, evaluate
 constant expressions with parameters, handle
 memories as lvalues.

 Parse task declarations, integer types.
This commit is contained in:
steve 1999-05-10 00:16:57 +00:00
parent a416b1b336
commit 5de9b7c9f1
13 changed files with 468 additions and 154 deletions

31
PExpr.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PExpr.h,v 1.7 1999/05/01 02:57:52 steve Exp $"
#ident "$Id: PExpr.h,v 1.8 1999/05/10 00:16:57 steve Exp $"
#endif
# include <string>
@ -51,7 +51,7 @@ class PExpr : public LineInfo {
// This attempts to evaluate a constant expression, and return
// a verinum as a result. If the expression cannot be
// evaluated, return 0.
virtual verinum* eval_const() const;
virtual verinum* eval_const(const Design*des, const string&path) const;
// This method returns true if that expression is the same as
// this expression. This method is used for comparing
@ -61,6 +61,18 @@ class PExpr : public LineInfo {
ostream& operator << (ostream&, const PExpr&);
class PEConcat : public PExpr {
public:
PEConcat(const svector<PExpr*>&p) : parms_(p) { }
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
private:
svector<PExpr*>parms_;
};
class PEEvent : public PExpr {
public:
@ -87,7 +99,10 @@ class PEIdent : public PExpr {
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
verinum* eval_const(const Design*des, const string&path) const;
// XXXX
string name() const { return text_; }
private:
string text_;
@ -114,7 +129,7 @@ class PENumber : public PExpr {
virtual void dump(ostream&) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual verinum* eval_const() const;
virtual verinum* eval_const(const Design*des, const string&path) const;
virtual bool is_the_same(const PExpr*that) const;
@ -160,6 +175,7 @@ class PEBinary : public PExpr {
virtual void dump(ostream&out) const;
virtual NetNet* elaborate_net(Design*des, const string&path) const;
virtual NetExpr*elaborate_expr(Design*des, const string&path) const;
virtual verinum* eval_const(const Design*des, const string&path) const;
private:
char op_;
@ -169,6 +185,15 @@ class PEBinary : public PExpr {
/*
* $Log: PExpr.h,v $
* Revision 1.8 1999/05/10 00:16:57 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.7 1999/05/01 02:57:52 steve
* Handle much more complex event expressions.
*

27
PGate.h
View File

@ -19,10 +19,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: PGate.h,v 1.4 1999/02/15 02:06:15 steve Exp $"
#ident "$Id: PGate.h,v 1.5 1999/05/10 00:16:58 steve Exp $"
#endif
# include <vector>
# include "svector.h"
# include "LineInfo.h"
class PExpr;
class PUdp;
@ -41,7 +41,7 @@ class Module;
class PGate : public LineInfo {
public:
explicit PGate(const string&name, const vector<PExpr*>&pins, long del)
explicit PGate(const string&name, const svector<PExpr*>&pins, long del)
: name_(name), delay_(del), pins_(pins) { }
virtual ~PGate() { }
@ -50,7 +50,7 @@ class PGate : public LineInfo {
long get_delay() const { return delay_; }
unsigned pin_count() const { return pins_.size(); }
unsigned pin_count() const { return pins_.count(); }
const PExpr*pin(unsigned idx) const { return pins_[idx]; }
virtual void dump(ostream&out) const;
@ -62,7 +62,7 @@ class PGate : public LineInfo {
private:
const string name_;
const unsigned long delay_;
const vector<PExpr*> pins_;
svector<PExpr*> pins_;
private: // not implemented
PGate(const PGate&);
@ -76,8 +76,8 @@ class PGate : public LineInfo {
class PGAssign : public PGate {
public:
explicit PGAssign(const vector<PExpr*>&pins)
: PGate("", pins, 0) { assert(pins.size() == 2); }
explicit PGAssign(const svector<PExpr*>&pins)
: PGate("", pins, 0) { assert(pins.count() == 2); }
void dump(ostream&out) const;
virtual void elaborate(Design*des, const string&path) const;
@ -106,7 +106,7 @@ class PGBuiltin : public PGate {
public:
explicit PGBuiltin(Type t, const string&name,
const vector<PExpr*>&pins, long del = 0)
const svector<PExpr*>&pins, long del = 0)
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
{ }
@ -133,7 +133,7 @@ class PGModule : public PGate {
public:
explicit PGModule(const string&type, const string&name,
const vector<PExpr*>&pins)
const svector<PExpr*>&pins)
: PGate(name, pins, 0), type_(type) { }
virtual void dump(ostream&out) const;
@ -148,6 +148,15 @@ class PGModule : public PGate {
/*
* $Log: PGate.h,v $
* Revision 1.5 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.4 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*

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.5 1999/02/03 04:20:11 steve Exp $"
#ident "$Id: Statement.cc,v 1.6 1999/05/10 00:16:58 steve Exp $"
#endif
# include "Statement.h"
@ -47,14 +47,9 @@ PBlock::~PBlock()
delete[]list_;
}
PCallTask::PCallTask(const string&n, const list<PExpr*>&p)
: name_(n), nparms_(p.size()), parms_(nparms_?new PExpr*[nparms_]:0)
PCallTask::PCallTask(const string&n, const svector<PExpr*>&p)
: name_(n), parms_(p)
{
list<PExpr*>::const_iterator s = p.begin();
for (unsigned idx = 0 ; s != p.end() ; s++, idx += 1) {
parms_[idx] = *s;
}
}
PCase::PCase(PExpr*ex, list<PCase::Item*>*l)
@ -104,6 +99,15 @@ PWhile::~PWhile()
/*
* $Log: Statement.cc,v $
* Revision 1.6 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.5 1999/02/03 04:20:11 steve
* Parse and elaborate the Verilog CASE statement.
*

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.7 1999/04/29 02:16:26 steve Exp $"
#ident "$Id: Statement.h,v 1.8 1999/05/10 00:16:58 steve Exp $"
#endif
# include <string>
@ -79,18 +79,21 @@ class Statement : public LineInfo {
class PAssign : public Statement {
public:
explicit PAssign(const string&name, PExpr*ex)
: to_name_(name), expr_(ex) { }
explicit PAssign(PExpr*lval, PExpr*ex)
: lval_(lval), expr_(ex) { }
string lval() const { return to_name_; }
const PExpr* lval() const { return lval_; }
const PExpr* get_expr() const { return expr_; }
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, const string&path) const;
private:
const string to_name_;
PExpr*const expr_;
PExpr* lval_;
PExpr* expr_;
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
Design*des, const string&path) const;
};
/*
@ -125,19 +128,19 @@ class PBlock : public Statement {
class PCallTask : public Statement {
public:
explicit PCallTask(const string&n, const list<PExpr*>&parms);
explicit PCallTask(const string&n, const svector<PExpr*>&parms);
string name() const { return name_; }
unsigned nparms() const { return nparms_; }
unsigned nparms() const { return parms_.count(); }
PExpr*&parm(unsigned idx)
{ assert(idx < nparms_);
{ assert(idx < parms_.count());
return parms_[idx];
}
PExpr* parm(unsigned idx) const
{ assert(idx < nparms_);
{ assert(idx < parms_.count());
return parms_[idx];
}
@ -146,8 +149,7 @@ class PCallTask : public Statement {
private:
const string name_;
const unsigned nparms_;
PExpr**const parms_;
svector<PExpr*> parms_;
};
class PCase : public Statement {
@ -232,8 +234,8 @@ class PEventStatement : public Statement {
class PForStatement : public Statement {
public:
PForStatement(const string&n1, PExpr*e1, PExpr*cond,
const string&n2, PExpr*e2, Statement*st)
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
PExpr*n2, PExpr*e2, Statement*st)
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
statement_(st)
{ }
@ -242,12 +244,12 @@ class PForStatement : public Statement {
virtual void dump(ostream&out, unsigned ind) const;
private:
string name1_;
PExpr* name1_;
PExpr* expr1_;
PExpr*cond_;
string name2_;
PExpr* name2_;
PExpr* expr2_;
Statement*statement_;
@ -276,6 +278,15 @@ class PWhile : public Statement {
/*
* $Log: Statement.h,v $
* Revision 1.8 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.7 1999/04/29 02:16:26 steve
* Parse OR of event expressions.
*

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.22 1999/05/06 02:29:32 steve Exp $"
#ident "$Id: design_dump.cc,v 1.23 1999/05/10 00:16:58 steve Exp $"
#endif
/*
@ -300,6 +300,18 @@ void NetAssign::dump(ostream&o, unsigned ind) const
o << ";" << endl;
}
void NetAssignMem::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "";
o << "/* " << get_line() << " */" << endl;
o << setw(ind) << "";
o << mem_->name() << "[";
index_->dump(o);
o << "] = ";
rval_->dump(o);
o << ";" << endl;
}
/* Dump a block statement */
void NetBlock::dump(ostream&o, unsigned ind) const
{
@ -568,6 +580,15 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.23 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.22 1999/05/06 02:29:32 steve
* Excesss endl.
*

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.24 1999/05/05 03:04:46 steve Exp $"
#ident "$Id: elaborate.cc,v 1.25 1999/05/10 00:16:58 steve Exp $"
#endif
/*
@ -109,10 +109,22 @@ void PWire::elaborate(Design*des, const string&path) const
/* Wires, registers and memories can have a width, expressed
as the msb index and lsb index. */
if (msb && lsb) {
verinum*mval = msb->eval_const();
assert(mval);
verinum*lval = lsb->eval_const();
assert(lval);
verinum*mval = msb->eval_const(des, path);
if (mval == 0) {
cerr << msb->get_line() << ": Unable to evaluate "
"constant expression ``" << *msb << "''." <<
endl;
des->errors += 1;
return;
}
verinum*lval = lsb->eval_const(des, path);
if (mval == 0) {
cerr << lsb->get_line() << ": Unable to evaluate "
"constant expression ``" << *lsb << "''." <<
endl;
des->errors += 1;
return;
}
long mnum = mval->as_long();
long lnum = lval->as_long();
@ -125,7 +137,7 @@ void PWire::elaborate(Design*des, const string&path) const
wid = lnum - mnum + 1;
} else if (msb) {
verinum*val = msb->eval_const();
verinum*val = msb->eval_const(des, path);
assert(val);
assert(val->as_ulong() > 0);
wid = val->as_ulong();
@ -134,9 +146,9 @@ void PWire::elaborate(Design*des, const string&path) const
if (lidx || ridx) {
// If the register has indices, then this is a
// memory. Create the memory object.
verinum*lval = lidx->eval_const();
verinum*lval = lidx->eval_const(des, path);
assert(lval);
verinum*rval = ridx->eval_const();
verinum*rval = ridx->eval_const(des, path);
assert(rval);
long lnum = lval->as_long();
@ -188,8 +200,8 @@ void PGBuiltin::elaborate(Design*des, const string&path) const
gates, then I am expected to make more then one
gate. Figure out how many are desired. */
if (msb_) {
verinum*msb = msb_->eval_const();
verinum*lsb = lsb_->eval_const();
verinum*msb = msb_->eval_const(des, path);
verinum*lsb = lsb_->eval_const(des, path);
if (msb == 0) {
cerr << get_line() << ": Unable to evaluate expression "
@ -563,20 +575,61 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path) const
return osig;
}
/*
* The concatenation operator, as a net, is a wide signal that is
* connected to all the pins of the elaborated expression nets.
*/
NetNet* PEConcat::elaborate_net(Design*des, const string&path) const
{
svector<NetNet*>nets (parms_.count());
unsigned pins = 0;
/* Elaborate the operands of the concatenation. */
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
nets[idx] = parms_[idx]->elaborate_net(des, path);
pins += nets[idx]->pin_count();
}
/* Make the temporary signal that connects to all the
operands, and connect it up. Scan the operands of the
concat operator from least significant to most significant,
which is opposite from how they are given in the list. */
NetNet*osig = new NetNet(des->local_symbol(path),
NetNet::IMPLICIT, pins);
pins = 0;
for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
NetNet*cur = nets[idx-1];
for (unsigned pin = 0 ; pin < cur->pin_count() ; pin += 1) {
connect(osig->pin(pins), cur->pin(pin));
pins += 1;
}
}
osig->local_flag(true);
des->add_signal(osig);
return osig;
}
NetNet* PEIdent::elaborate_net(Design*des, const string&path) const
{
NetNet*sig = des->find_signal(path+"."+text_);
if (msb_ && lsb_) {
verinum*mval = msb_->eval_const();
verinum*mval = msb_->eval_const(des, path);
assert(mval);
verinum*lval = lsb_->eval_const();
verinum*lval = lsb_->eval_const(des, path);
assert(lval);
unsigned midx = sig->sb_to_idx(mval->as_long());
unsigned lidx = sig->sb_to_idx(lval->as_long());
if (midx >= lidx) {
NetTmp*tmp = new NetTmp(midx-lidx+1);
if (tmp->pin_count() > sig->pin_count()) {
cerr << get_line() << ": bit select out of "
<< "range for " << sig->name() << endl;
return sig;
}
for (unsigned idx = lidx ; idx <= midx ; idx += 1)
connect(tmp->pin(idx-lidx), sig->pin(idx));
@ -584,6 +637,7 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path) const
} else {
NetTmp*tmp = new NetTmp(lidx-midx+1);
assert(tmp->pin_count() <= sig->pin_count());
for (unsigned idx = lidx ; idx >= midx ; idx -= 1)
connect(tmp->pin(idx-midx), sig->pin(idx));
@ -591,7 +645,7 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path) const
}
} else if (msb_) {
verinum*mval = msb_->eval_const();
verinum*mval = msb_->eval_const(des, path);
assert(mval);
unsigned idx = sig->sb_to_idx(mval->as_long());
NetTmp*tmp = new NetTmp(1);
@ -751,12 +805,41 @@ NetProc* Statement::elaborate(Design*des, const string&path) const
return cur;
}
NetProc* PAssign::assign_to_memory_(NetMemory*mem, PExpr*ix,
Design*des, const string&path) const
{
NetExpr*rval = expr_->elaborate_expr(des, path);
if (rval == 0) {
cerr << get_line() << ": " << "failed to elaborate expression."
<< endl;
return 0;
}
assert(rval);
NetExpr*idx = ix->elaborate_expr(des, path);
assert(idx);
NetAssignMem*am = new NetAssignMem(mem, idx, rval);
am->set_line(*this);
return am;
}
NetProc* PAssign::elaborate(Design*des, const string&path) const
{
NetNet*reg = des->find_signal(path+"."+lval());
const PEIdent*id = dynamic_cast<const PEIdent*>(lval_);
assert(id);
/* Catch the case where the lvalue is a reference to a memory
item. These are handled differently. */
if (NetMemory*mem = des->find_memory(path+"."+id->name()))
return assign_to_memory_(mem, id->msb_, des, path);
NetNet*reg = des->find_signal(path+"."+id->name());
if (reg == 0) {
cerr << get_line() << ": Could not match signal: " <<
lval() << endl;
id->name() << endl;
return 0;
}
assert(reg);
@ -856,7 +939,7 @@ NetProc* PCallTask::elaborate(Design*des, const string&path) const
NetProc* PDelayStatement::elaborate(Design*des, const string&path) const
{
verinum*num = delay_->eval_const();
verinum*num = delay_->eval_const(des, path);
assert(num);
unsigned long val = num->as_ulong();
@ -897,8 +980,8 @@ NetProc* PEventStatement::elaborate(Design*des, const string&path) const
cerr << get_line() << ": Failed to elaborate expression: ";
expr_[0]->dump(cerr);
cerr << endl;
delete pe;
return 0;
des->errors += 1;
continue;
}
assert(expr);
@ -930,8 +1013,13 @@ NetProc* PEventStatement::elaborate(Design*des, const string&path) const
*/
NetProc* PForStatement::elaborate(Design*des, const string&path) const
{
const PEIdent*id1 = dynamic_cast<const PEIdent*>(name1_);
assert(id1);
const PEIdent*id2 = dynamic_cast<const PEIdent*>(name2_);
assert(id2);
NetBlock*top = new NetBlock(NetBlock::SEQU);
NetNet*sig = des->find_signal(path+"."+name1_);
NetNet*sig = des->find_signal(path+"."+id1->name());
assert(sig);
NetAssign*init = new NetAssign(sig, expr1_->elaborate_expr(des, path));
top->append(init);
@ -940,7 +1028,7 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
body->append(statement_->elaborate(des, path));
sig = des->find_signal(path+"."+name2_);
sig = des->find_signal(path+"."+id2->name());
assert(sig);
NetAssign*step = new NetAssign(sig, expr2_->elaborate_expr(des, path));
body->append(step);
@ -1060,6 +1148,15 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.25 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.24 1999/05/05 03:04:46 steve
* Fix handling of null delay statements.
*

54
eval.cc
View File

@ -17,23 +17,71 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: eval.cc,v 1.1 1998/11/03 23:28:58 steve Exp $"
#ident "$Id: eval.cc,v 1.2 1999/05/10 00:16:58 steve Exp $"
#endif
# include "PExpr.h"
# include "netlist.h"
verinum* PExpr::eval_const() const
verinum* PExpr::eval_const(const Design*, const string&) const
{
return 0;
}
verinum* PENumber::eval_const() const
verinum* PEBinary::eval_const(const Design*des, const string&path) const
{
verinum*l = left_->eval_const(des, path);
if (l == 0) return 0;
verinum*r = right_->eval_const(des, path);
if (r == 0) {
delete l;
return 0;
}
verinum*res;
switch (op_) {
case '-': {
long lv = l->as_long();
long rv = r->as_long();
res = new verinum(lv-rv, l->len());
break;
}
default:
delete l;
delete r;
return 0;
}
return res;
}
verinum* PEIdent::eval_const(const Design*des, const string&path) const
{
assert(msb_ == 0);
NetExpr*expr = des->get_parameter(path + "." + text_);
if (expr == 0) return 0;
NetEConst*eval = dynamic_cast<NetEConst*>(expr);
assert(eval);
return new verinum(eval->value());
}
verinum* PENumber::eval_const(const Design*, const string&) const
{
return new verinum(value());
}
/*
* $Log: eval.cc,v $
* Revision 1.2 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.1 1998/11/03 23:28:58 steve
* Introduce verilog to CVS.
*

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.22 1999/05/01 02:57:53 steve Exp $"
#ident "$Id: netlist.cc,v 1.23 1999/05/10 00:16:58 steve Exp $"
#endif
# include <cassert>
@ -284,6 +284,16 @@ NetAssign::~NetAssign()
{
}
NetAssignMem::NetAssignMem(NetMemory*m, NetExpr*i, NetExpr*r)
: mem_(m), index_(i), rval_(r)
{
}
NetAssignMem::~NetAssignMem()
{
}
/*
* This method looks at the objects connected to me, and searches for
* a signal that I am fully connected to. Return that signal, and the
@ -1040,6 +1050,15 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.23 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.22 1999/05/01 02:57:53 steve
* Handle much more complex event expressions.
*

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.28 1999/05/01 20:43:55 steve Exp $"
#ident "$Id: netlist.h,v 1.29 1999/05/10 00:16:58 steve Exp $"
#endif
/*
@ -614,6 +614,24 @@ class NetAssign : public NetProc, public NetNode, public LineInfo {
NetExpr::REF rval_;
};
/*
* Assignment to memory is handled separately because memory is
* not a node.
*/
class NetAssignMem : public NetProc, public LineInfo {
public:
explicit NetAssignMem(NetMemory*, NetExpr*idx, NetExpr*rv);
~NetAssignMem();
virtual void dump(ostream&, unsigned ind) const;
private:
NetMemory*mem_;
NetExpr::REF index_;
NetExpr::REF rval_;
};
/* A block is stuff line begin-end blocks, that contain and ordered
list of NetProc statements.
@ -1155,6 +1173,15 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.29 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.28 1999/05/01 20:43:55 steve
* Handle wide events, such as @(a) where a has
* many bits in it.

102
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.24 1999/05/08 20:19:20 steve Exp $"
#ident "$Id: parse.y,v 1.25 1999/05/10 00:16:58 steve Exp $"
#endif
# include "parse_misc.h"
@ -41,7 +41,7 @@ extern void lex_end_table();
svector<lgate>*gates;
PExpr*expr;
list<PExpr*>*exprs;
svector<PExpr*>*exprs;
svector<PEEvent*>*event_expr;
@ -88,7 +88,7 @@ extern void lex_end_table();
%type <wires> udp_port_decl udp_port_decls
%type <statement> udp_initial udp_init_opt
%type <text> identifier lpvalue register_variable
%type <text> identifier register_variable
%type <strings> register_variable_list
%type <strings> list_of_variables
@ -102,7 +102,7 @@ extern void lex_end_table();
%type <gates> gate_instance_list
%type <expr> bitsel delay delay_opt expression expr_primary const_expression
%type <expr> lavalue
%type <expr> lavalue lpvalue
%type <exprs> expression_list
%type <exprs> range range_opt
@ -182,12 +182,18 @@ const_expression
yyerror(@1, "XXXX internal error: const_expression.");
$$ = 0;
} else {
$$ = new PENumber(tmp);
PENumber*tmp = new PENumber($1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
}
| STRING
{ $$ = new PEString(*$1);
{ PEString*tmp = new PEString(*$1);
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
delete $1;
$$ = tmp;
}
| IDENTIFIER
{ if (!pform_is_parameter(*$1)) {
@ -204,7 +210,10 @@ const_expression
}
}
| const_expression '-' const_expression
{ $$ = new PEBinary('-', $1, $3);
{ PEBinary*tmp = new PEBinary('-', $1, $3);
tmp->set_file(@2.text);
tmp->set_lineno(@2.first_line);
$$ = tmp;
}
;
@ -307,8 +316,9 @@ expression
| '(' expression ')'
{ $$ = $2; }
| '{' expression_list '}'
{ yyerror(@1, "Sorry, concatenation operator not supported.");
$$ = 0;
{ PEConcat*tmp = new PEConcat(*$2);
delete $2;
$$ = tmp;
}
| '~' expression %prec UNARY_PREC
{ $$ = new PEUnary('~', $2);
@ -363,18 +373,18 @@ expression
expression_list
: expression_list ',' expression
{ list<PExpr*>*tmp = $1;
tmp->push_back($3);
{ svector<PExpr*>*tmp = new svector<PExpr*>(*$1, $3);
delete $1;
$$ = tmp;
}
| expression
{ list<PExpr*>*tmp = new list<PExpr*>;
tmp->push_back($1);
{ svector<PExpr*>*tmp = new svector<PExpr*>(1);
(*tmp)[0] = $1;
$$ = tmp;
}
| expression_list ','
{ list<PExpr*>*tmp = $1;
tmp->push_back(0);
{ svector<PExpr*>*tmp = new svector<PExpr*>(*$1, 0);
delete $1;
$$ = tmp;
}
;
@ -437,13 +447,11 @@ gate_instance
}
| IDENTIFIER range '(' expression_list ')'
{ lgate*tmp = new lgate;
list<PExpr*>*rng = $2;
svector<PExpr*>*rng = $2;
tmp->name = *$1;
tmp->parms = $4;
tmp->range[0] = rng->front();
rng->pop_front();
tmp->range[1] = rng->front();
rng->pop_front();
tmp->range[0] = (*rng)[0];
tmp->range[1] = (*rng)[1];
tmp->file = @1.text;
tmp->lineno = @1.first_line;
delete $1;
@ -566,18 +574,24 @@ list_of_variables
lavalue
: IDENTIFIER
{ PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp;
}
| IDENTIFIER bitsel
{ PEIdent*tmp = new PEIdent(*$1);
tmp->msb_ = $2;
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp;
}
| IDENTIFIER range
{ PEIdent*tmp = new PEIdent(*$1);
yyerror(@3, "Sorry, lvalue bit range not supported.");
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
delete $2;
$$ = tmp;
@ -593,12 +607,21 @@ lavalue
/* An lpvalue is the expression that can go on the left side of a
procedural assignment. This rule handles only procedural assignments. */
lpvalue
: identifier { $$ = $1; }
: identifier
{ PEIdent*tmp = new PEIdent(*$1);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp;
}
| identifier '[' expression ']'
{ yyerror(@2, "Sorry, bit/memory selects "
"not supported in lvalue.");
$$ = $1;
delete $3;
{ PEIdent*tmp = new PEIdent(*$1);
tmp->msb_ = $3;
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
delete $1;
$$ = tmp;
}
| '{' expression_list '}'
{ yyerror(@1, "Sorry, concatenation expressions"
@ -753,9 +776,9 @@ port_type
range
: '[' const_expression ':' const_expression ']'
{ list<PExpr*>*tmp = new list<PExpr*>;
tmp->push_back($2);
tmp->push_back($4);
{ svector<PExpr*>*tmp = new svector<PExpr*> (2);
(*tmp)[0] = $2;
(*tmp)[1] = $4;
$$ = tmp;
}
;
@ -830,9 +853,7 @@ statement
}
| K_for '(' lpvalue '=' expression ';' expression ';'
lpvalue '=' expression ')' statement
{ $$ = new PForStatement(*$3, $5, $7, *$9, $11, $13);
delete $3;
delete $9;
{ $$ = new PForStatement($3, $5, $7, $9, $11, $13);
}
| K_for '(' lpvalue '=' expression ';' expression ';'
error ')' statement
@ -873,18 +894,24 @@ statement
}
}
| lpvalue '=' expression ';'
{ Statement*tmp = pform_make_assignment($1, $3);
{ PAssign*tmp = new PAssign($1,$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| lpvalue K_LE expression ';'
{ $$ = pform_make_assignment($1, $3);
yyerror(@1, "Sorry, non-blocking assignment not implemented.");
{ yyerror(@1, "Sorry, non-blocking assignment not implemented.");
PAssign*tmp = new PAssign($1,$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| lpvalue '=' delay expression ';'
{ $$ = pform_make_assignment($1, $3);
yyerror(@1, "Sorry, assignment timing control not implemented.");
{ yyerror(@1, "Sorry, assignment timing control not implemented.");
PAssign*tmp = new PAssign($1,$3);
tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
}
| K_wait '(' expression ')' statement_opt
{ PEventStatement*tmp;
@ -995,7 +1022,8 @@ udp_sequ_entry
udp_initial
: K_initial IDENTIFIER '=' NUMBER ';'
{ PExpr*etmp = new PENumber($4);
PAssign*atmp = new PAssign(*$2, etmp);
PEIdent*itmp = new PEIdent(*$2);
PAssign*atmp = new PAssign(itmp, etmp);
atmp->set_file(@2.text);
atmp->set_lineno(@2.first_line);
delete $2;

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: pform.cc,v 1.16 1999/05/08 20:19:20 steve Exp $"
#ident "$Id: pform.cc,v 1.17 1999/05/10 00:16:58 steve Exp $"
#endif
# include "pform.h"
@ -186,8 +186,11 @@ void pform_make_udp(string*name, list<string>*parms,
PAssign*pa = dynamic_cast<PAssign*>(init_expr);
assert(pa);
const PEIdent*id = dynamic_cast<const PEIdent*>(pa->lval());
assert(id);
// XXXX
assert(pa->lval() == pins[0]->name);
assert(id->name() == pins[0]->name);
const PENumber*np = dynamic_cast<const PENumber*>(pa->get_expr());
assert(np);
@ -236,14 +239,7 @@ void pform_makegate(PGBuiltin::Type type,
unsigned long delay_val,
const lgate&info)
{
vector<PExpr*>wires (info.parms->size());
for (unsigned idx = 0 ; idx < wires.size() ; idx += 1) {
PExpr*ep = info.parms->front();
info.parms->pop_front();
wires[idx] = ep;
}
PGBuiltin*cur = new PGBuiltin(type, info.name, wires, delay_val);
PGBuiltin*cur = new PGBuiltin(type, info.name, *info.parms, delay_val);
if (info.range[0])
cur->set_range(info.range[0], info.range[1]);
@ -266,10 +262,10 @@ void pform_makegates(PGBuiltin::Type type,
delete gates;
}
void pform_make_modgate(const string&type,
const string&name,
const vector<PExpr*>&wires,
const string&fn, unsigned ln)
static void pform_make_modgate(const string&type,
const string&name,
const svector<PExpr*>&wires,
const string&fn, unsigned ln)
{
if (name == "") {
cerr << fn << ":" << ln << ": Instantiation of " << type
@ -289,15 +285,15 @@ void pform_make_modgates(const string&type, svector<lgate>*gates)
for (unsigned idx = 0 ; idx < gates->count() ; idx += 1) {
lgate cur = (*gates)[idx];
vector<PExpr*>wires (cur.parms? cur.parms->size() : 0);
for (unsigned idx = 0 ; idx < wires.size() ; idx += 1) {
PExpr*ep = cur.parms->front();
cur.parms->pop_front();
wires[idx] = ep;
if (cur.parms) {
svector<PExpr*>wires = *cur.parms;
pform_make_modgate(type, cur.name, wires, cur.file,
cur.lineno);
} else {
svector<PExpr*>wires (0);
pform_make_modgate(type, cur.name, wires, cur.file,
cur.lineno);
}
pform_make_modgate(type, cur.name, wires, cur.file, cur.lineno);
}
delete gates;
@ -305,7 +301,7 @@ void pform_make_modgates(const string&type, svector<lgate>*gates)
void pform_make_pgassign(PExpr*lval, PExpr*rval)
{
vector<PExpr*> wires (2);
svector<PExpr*> wires (2);
wires[0] = lval;
wires[1] = rval;
PGAssign*cur = new PGAssign(wires);
@ -391,9 +387,9 @@ void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r)
cur->ridx = r;
}
static void pform_set_net_range(const string&name, list<PExpr*>*range)
static void pform_set_net_range(const string&name, const svector<PExpr*>*range)
{
assert(range->size() == 2);
assert(range->count() == 2);
PWire*cur = cur_module->get_wire(name);
if (cur == 0) {
@ -402,15 +398,11 @@ static void pform_set_net_range(const string&name, list<PExpr*>*range)
}
if ((cur->msb == 0) && (cur->lsb == 0)){
list<PExpr*>::const_iterator idx = range->begin();
cur->msb = *idx;
idx ++;
cur->lsb = *idx;
cur->msb = (*range)[0];
cur->lsb = (*range)[1];
} else {
list<PExpr*>::const_iterator idx = range->begin();
PExpr*msb = *idx;
idx ++;
PExpr*lsb = *idx;
PExpr*msb = (*range)[0];
PExpr*lsb = (*range)[1];
if (msb == 0) {
VLerror(yylloc, "failed to parse msb of range.");
} else if (lsb == 0) {
@ -419,8 +411,8 @@ static void pform_set_net_range(const string&name, list<PExpr*>*range)
cur->lsb->is_the_same(lsb))) {
VLerror(yylloc, "net ranges are not identical.");
}
delete msb;
delete lsb;
//delete msb;
//delete lsb;
}
}
@ -445,9 +437,9 @@ void pform_set_port_type(list<string>*names, NetNet::PortType pt)
}
}
void pform_set_net_range(list<string>*names, list<PExpr*>*range)
void pform_set_net_range(list<string>*names, const svector<PExpr*>*range)
{
assert(range->size() == 2);
assert(range->count() == 2);
for (list<string>::const_iterator cur = names->begin()
; cur != names->end()
@ -489,17 +481,10 @@ Statement* pform_make_block(PBlock::BL_TYPE type, list<Statement*>*sl)
return bl;
}
Statement* pform_make_assignment(string*text, PExpr*ex)
{
PAssign*st = new PAssign (*text, ex);
delete text;
return st;
}
Statement* pform_make_calltask(string*name, list<PExpr*>*parms)
Statement* pform_make_calltask(string*name, svector<PExpr*>*parms)
{
if (parms == 0)
parms = new list<PExpr*>;
parms = new svector<PExpr*>(0);
PCallTask*ct = new PCallTask(*name, *parms);
delete name;
@ -533,6 +518,15 @@ int pform_parse(const char*path, map<string,Module*>&modules,
/*
* $Log: pform.cc,v $
* Revision 1.17 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.16 1999/05/08 20:19:20 steve
* Parse more things.
*

18
pform.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: pform.h,v 1.12 1999/05/07 04:26:49 steve Exp $"
#ident "$Id: pform.h,v 1.13 1999/05/10 00:16:58 steve Exp $"
#endif
# include "netlist.h"
@ -70,7 +70,7 @@ struct lgate {
}
string name;
list<PExpr*>*parms;
svector<PExpr*>*parms;
PExpr*range[2];
@ -100,7 +100,7 @@ extern void pform_make_udp(string*name, list<string>*parms,
extern void pform_makewire(const string&name, NetNet::Type type = NetNet::IMPLICIT);
extern void pform_makewire(const list<string>*names, NetNet::Type type);
extern void pform_set_port_type(list<string>*names, NetNet::PortType);
extern void pform_set_net_range(list<string>*names, list<PExpr*>*);
extern void pform_set_net_range(list<string>*names, const svector<PExpr*>*);
extern void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r);
extern void pform_set_attrib(const string&name, const string&key,
const string&value);
@ -110,8 +110,7 @@ extern void pform_set_parameter(const string&name, PExpr*expr);
extern bool pform_is_parameter(const string&name);
extern PProcess* pform_make_behavior(PProcess::Type, Statement*);
extern Statement* pform_make_block(PBlock::BL_TYPE, list<Statement*>*);
extern Statement* pform_make_assignment(string*t, PExpr*e);
extern Statement* pform_make_calltask(string*t, list<PExpr*>* =0);
extern Statement* pform_make_calltask(string*t, svector<PExpr*>* =0);
extern list<PWire*>* pform_make_udp_input_ports(list<string>*);
@ -140,6 +139,15 @@ extern void pform_dump(ostream&out, Module*mod);
/*
* $Log: pform.h,v $
* Revision 1.13 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.12 1999/05/07 04:26:49 steve
* Parse more complex continuous assign lvalues.
*

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.15 1999/05/05 03:04:46 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.16 1999/05/10 00:16:58 steve Exp $"
#endif
/*
@ -42,6 +42,20 @@ void PExpr::dump(ostream&out) const
out << typeid(*this).name();
}
void PEConcat::dump(ostream&out) const
{
if (parms_.count() == 0) {
out << "{}";
return;
}
out << "{" << *parms_[0];
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1)
out << ", " << *parms_[idx];
out << "}";
}
void PEEvent::dump(ostream&out) const
{
switch (type_) {
@ -229,7 +243,7 @@ void Statement::dump(ostream&out, unsigned ind) const
void PAssign::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "";
out << to_name_ << " = " << *expr_ << ";";
out << *lval_ << " = " << *expr_ << ";";
out << " /* " << get_line() << " */" << endl;
}
@ -248,12 +262,12 @@ void PCallTask::dump(ostream&out, unsigned ind) const
{
out << setw(ind) << "" << name_;
if (nparms_) {
if (parms_.count() > 0) {
out << "(";
if (parms_[0])
out << *parms_[0];
for (unsigned idx = 1 ; idx < nparms_ ; idx += 1) {
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
out << ", ";
if (parms_[idx])
out << *parms_[idx];
@ -440,6 +454,15 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.16 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.15 1999/05/05 03:04:46 steve
* Fix handling of null delay statements.
*