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:
parent
a416b1b336
commit
5de9b7c9f1
31
PExpr.h
31
PExpr.h
|
|
@ -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
27
PGate.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
20
Statement.cc
20
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.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.
|
||||
*
|
||||
|
|
|
|||
43
Statement.h
43
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.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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
137
elaborate.cc
137
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.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
54
eval.cc
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
21
netlist.cc
21
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.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.
|
||||
*
|
||||
|
|
|
|||
29
netlist.h
29
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.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
102
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.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;
|
||||
|
|
|
|||
86
pform.cc
86
pform.cc
|
|
@ -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
18
pform.h
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue