Add memories to the parse and elaboration phases.
This commit is contained in:
parent
bd40e5dfe1
commit
5895d3c98d
14
PExpr.h
14
PExpr.h
|
|
@ -19,11 +19,12 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: PExpr.h,v 1.4 1998/11/11 00:01:51 steve Exp $"
|
||||
#ident "$Id: PExpr.h,v 1.5 1999/04/19 01:59:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include "verinum.h"
|
||||
# include "LineInfo.h"
|
||||
|
||||
class Design;
|
||||
class NetNet;
|
||||
|
|
@ -38,7 +39,7 @@ class NetExpr;
|
|||
* up a netlist interpretation of the expression.
|
||||
*/
|
||||
|
||||
class PExpr {
|
||||
class PExpr : public LineInfo {
|
||||
public:
|
||||
virtual ~PExpr();
|
||||
|
||||
|
|
@ -63,7 +64,7 @@ class PEIdent : public PExpr {
|
|||
|
||||
public:
|
||||
explicit PEIdent(const string&s)
|
||||
: text_(s), msb_(0), lsb_(0) { }
|
||||
: text_(s), msb_(0), lsb_(0), idx_(0) { }
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path) const;
|
||||
|
|
@ -77,6 +78,10 @@ class PEIdent : public PExpr {
|
|||
// Use these to support bit- and part-select operators.
|
||||
PExpr*msb_;
|
||||
PExpr*lsb_;
|
||||
|
||||
// If this is a reference to a memory, this is the index
|
||||
// expression.
|
||||
PExpr*idx_;
|
||||
};
|
||||
|
||||
class PENumber : public PExpr {
|
||||
|
|
@ -146,6 +151,9 @@ class PEBinary : public PExpr {
|
|||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* Revision 1.5 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.4 1998/11/11 00:01:51 steve
|
||||
* Check net ranges in declarations.
|
||||
*
|
||||
|
|
|
|||
13
PWire.h
13
PWire.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: PWire.h,v 1.2 1998/11/23 00:20:22 steve Exp $"
|
||||
#ident "$Id: PWire.h,v 1.3 1999/04/19 01:59:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -37,7 +37,8 @@ class PWire {
|
|||
|
||||
public:
|
||||
PWire(const string&n, NetNet::Type t =NetNet::IMPLICIT)
|
||||
: name(n), type(t), port_type(NetNet::NOT_A_PORT), msb(0), lsb(0)
|
||||
: name(n), type(t), port_type(NetNet::NOT_A_PORT), msb(0),
|
||||
lsb(0), lidx(0), ridx(0)
|
||||
{ }
|
||||
|
||||
string name;
|
||||
|
|
@ -47,6 +48,11 @@ class PWire {
|
|||
PExpr*msb;
|
||||
PExpr*lsb;
|
||||
|
||||
// If this wire is actually a memory, these indices will give
|
||||
// me the size and address range of the memory.
|
||||
PExpr*lidx;
|
||||
PExpr*ridx;
|
||||
|
||||
map<string,string> attributes;
|
||||
|
||||
// Write myself to the specified stream.
|
||||
|
|
@ -61,6 +67,9 @@ class PWire {
|
|||
|
||||
/*
|
||||
* $Log: PWire.h,v $
|
||||
* Revision 1.3 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.2 1998/11/23 00:20:22 steve
|
||||
* NetAssign handles lvalues as pin links
|
||||
* instead of a signal pointer,
|
||||
|
|
|
|||
|
|
@ -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.16 1999/03/15 02:43:32 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.17 1999/04/19 01:59:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -57,6 +57,12 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
|||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetMemory::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << name_ << "[" << width_ << "] " <<
|
||||
"[" << idxh_ << ":" << idxl_ << "]" << endl;
|
||||
}
|
||||
|
||||
|
||||
/* Dump a NetNode and its pins. Dump what I know about the netnode on
|
||||
the first line, then list all the pins, with the name of the
|
||||
|
|
@ -463,6 +469,13 @@ void NetESignal::dump(ostream&o) const
|
|||
o << name();
|
||||
}
|
||||
|
||||
void NetEMemory::dump(ostream&o) const
|
||||
{
|
||||
o << mem_->name() << "[";
|
||||
idx_->dump(o);
|
||||
o << "]";
|
||||
}
|
||||
|
||||
void NetESignal::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Expression Node: " << name() << endl;
|
||||
|
|
@ -500,6 +513,15 @@ void Design::dump(ostream&o) const
|
|||
} while (cur != signals_->sig_next_);
|
||||
}
|
||||
|
||||
o << "ELABORATED MEMORIES:" << endl;
|
||||
{
|
||||
map<string,NetMemory*>::const_iterator pp;
|
||||
for (pp = memories_.begin()
|
||||
; pp != memories_.end() ; pp ++) {
|
||||
(*pp).second->dump(o, 0);
|
||||
}
|
||||
}
|
||||
|
||||
o << "ELABORATED NODES:" << endl;
|
||||
|
||||
// dump the nodes,
|
||||
|
|
@ -521,6 +543,9 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.17 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.16 1999/03/15 02:43:32 steve
|
||||
* Support more operators, especially logical.
|
||||
*
|
||||
|
|
|
|||
68
elaborate.cc
68
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.18 1999/03/15 02:43:32 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.19 1999/04/19 01:59:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -91,7 +91,13 @@ static void do_assign(Design*des, const string&path,
|
|||
static const map<string,Module*>* modlist = 0;
|
||||
static const map<string,PUdp*>* udplist = 0;
|
||||
|
||||
/* Elaborate a source wire. Generally pretty easy. */
|
||||
/*
|
||||
* Elaborate a source wire. The "wire" is the declaration of wires,
|
||||
* registers, ports and memories. The parser has already merged the
|
||||
* multiple properties of a wire (i.e. "input wire") so come the
|
||||
* elaboration this creates an object in the design that represent the
|
||||
* defined item.
|
||||
*/
|
||||
void PWire::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetNet::Type wtype = type;
|
||||
|
|
@ -100,6 +106,8 @@ void PWire::elaborate(Design*des, const string&path) const
|
|||
|
||||
unsigned wid = 1;
|
||||
|
||||
/* 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);
|
||||
|
|
@ -123,10 +131,29 @@ void PWire::elaborate(Design*des, const string&path) const
|
|||
wid = val->as_ulong();
|
||||
}
|
||||
|
||||
NetNet*sig = new NetNet(path + "." + name, wtype, wid);
|
||||
sig->port_type(port_type);
|
||||
sig->set_attributes(attributes);
|
||||
des->add_signal(sig);
|
||||
if (lidx || ridx) {
|
||||
// If the register has indices, then this is a
|
||||
// memory. Create the memory object.
|
||||
verinum*lval = lidx->eval_const();
|
||||
assert(lval);
|
||||
verinum*rval = ridx->eval_const();
|
||||
assert(rval);
|
||||
|
||||
long lnum = lval->as_long();
|
||||
long rnum = rval->as_long();
|
||||
delete lval;
|
||||
delete rval;
|
||||
NetMemory*sig = new NetMemory(path+"."+name, wid, lnum, rnum);
|
||||
sig->set_attributes(attributes);
|
||||
des->add_memory(sig);
|
||||
|
||||
} else {
|
||||
|
||||
NetNet*sig = new NetNet(path + "." + name, wtype, wid);
|
||||
sig->port_type(port_type);
|
||||
sig->set_attributes(attributes);
|
||||
des->add_signal(sig);
|
||||
}
|
||||
}
|
||||
|
||||
void PGate::elaborate(Design*des, const string&path) const
|
||||
|
|
@ -667,7 +694,26 @@ NetExpr*PEIdent::elaborate_expr(Design*des, const string&path) const
|
|||
return node;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
if (NetMemory*mem = des->find_memory(name)) {
|
||||
assert(msb_ != 0);
|
||||
assert(lsb_ == 0);
|
||||
assert(idx_ == 0);
|
||||
NetExpr*i = msb_->elaborate_expr(des, path);
|
||||
if (i == 0) {
|
||||
cerr << get_line() << ": Unable to exaborate "
|
||||
"index expression `" << *msb_ << "'" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEMemory*node = new NetEMemory(mem, i);
|
||||
return node;
|
||||
}
|
||||
|
||||
cerr << get_line() << ": Unable to bind wire/reg/memory "
|
||||
"`" << path << "." << text_ << "'" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -709,6 +755,11 @@ NetProc* PAssign::elaborate(Design*des, const string&path) const
|
|||
assert(expr_);
|
||||
|
||||
NetExpr*rval = expr_->elaborate_expr(des, path);
|
||||
if (rval == 0) {
|
||||
cerr << get_line() << ": " << "failed to elaborate expression."
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
assert(rval);
|
||||
|
||||
NetAssign*cur = new NetAssign(reg, rval);
|
||||
|
|
@ -977,6 +1028,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.19 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.18 1999/03/15 02:43:32 steve
|
||||
* Support more operators, especially logical.
|
||||
*
|
||||
|
|
|
|||
19
emit.cc
19
emit.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: emit.cc,v 1.6 1999/02/08 02:49:56 steve Exp $"
|
||||
#ident "$Id: emit.cc,v 1.7 1999/04/19 01:59:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -173,6 +173,15 @@ void Design::emit(ostream&o, struct target_t*tgt) const
|
|||
}
|
||||
|
||||
|
||||
// emit memories
|
||||
{
|
||||
map<string,NetMemory*>::const_iterator mi;
|
||||
for (mi = memories_.begin() ; mi != memories_.end() ; mi++) {
|
||||
tgt->memory(o, (*mi).second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// emit nodes
|
||||
{
|
||||
NetNode*cur = nodes_->node_next_;
|
||||
|
|
@ -205,6 +214,11 @@ void NetEIdent::expr_scan(struct expr_scan_t*tgt) const
|
|||
tgt->expr_ident(this);
|
||||
}
|
||||
|
||||
void NetEMemory::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_memory(this);
|
||||
}
|
||||
|
||||
void NetESignal::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_signal(this);
|
||||
|
|
@ -234,6 +248,9 @@ void emit(ostream&o, const Design*des, const char*type)
|
|||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.7 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.6 1999/02/08 02:49:56 steve
|
||||
* Turn the NetESignal into a NetNode so
|
||||
* that it can connect to the netlist.
|
||||
|
|
|
|||
60
netlist.cc
60
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.19 1999/03/15 02:43:32 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.20 1999/04/19 01:59:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <cassert>
|
||||
|
|
@ -240,6 +240,26 @@ NetNode::~NetNode()
|
|||
design_->del_node(this);
|
||||
}
|
||||
|
||||
NetNet::NetNet(const string&n, Type t, unsigned npins)
|
||||
: NetObj(n, npins), sig_next_(0), sig_prev_(0), design_(0),
|
||||
type_(t), port_type_(NOT_A_PORT), msb_(npins-1), lsb_(0),
|
||||
local_flag_(false)
|
||||
{
|
||||
ivalue_ = new verinum::V[npins];
|
||||
for (unsigned idx = 0 ; idx < npins ; idx += 1)
|
||||
ivalue_[idx] = verinum::Vz;
|
||||
}
|
||||
|
||||
NetNet::NetNet(const string&n, Type t, long ms, long ls)
|
||||
: NetObj(n, ((ms>ls)?ms-ls:ls-ms) + 1), sig_next_(0),
|
||||
sig_prev_(0), design_(0), type_(t), port_type_(NOT_A_PORT),
|
||||
msb_(ms), lsb_(ls), local_flag_(false)
|
||||
{
|
||||
ivalue_ = new verinum::V[pin_count()];
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1)
|
||||
ivalue_[idx] = verinum::Vz;
|
||||
}
|
||||
|
||||
NetNet::~NetNet()
|
||||
{
|
||||
if (design_)
|
||||
|
|
@ -477,6 +497,27 @@ void NetEConst::set_width(unsigned w)
|
|||
expr_width(w);
|
||||
}
|
||||
|
||||
NetEMemory::NetEMemory(NetMemory*m, NetExpr*i)
|
||||
: mem_(m), idx_(i)
|
||||
{
|
||||
}
|
||||
|
||||
NetEMemory::~NetEMemory()
|
||||
{
|
||||
}
|
||||
|
||||
void NetMemory::set_attributes(const map<string,string>&attr)
|
||||
{
|
||||
assert(attributes_.size() == 0);
|
||||
attributes_ = attr;
|
||||
}
|
||||
|
||||
void NetEMemory::set_width(unsigned w)
|
||||
{
|
||||
assert(w == mem_->width());
|
||||
expr_width(w);
|
||||
}
|
||||
|
||||
NetESignal::NetESignal(NetNet*n)
|
||||
: NetExpr(n->pin_count()), NetNode(n->name(), n->pin_count())
|
||||
{
|
||||
|
|
@ -854,6 +895,20 @@ NetNet* Design::find_signal(const string&name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Design::add_memory(NetMemory*mem)
|
||||
{
|
||||
memories_[mem->name()] = mem;
|
||||
}
|
||||
|
||||
NetMemory* Design::find_memory(const string&key)
|
||||
{
|
||||
map<string,NetMemory*>::const_iterator cur = memories_.find(key);
|
||||
if (cur == memories_.end())
|
||||
return 0;
|
||||
|
||||
return (*cur).second;
|
||||
}
|
||||
|
||||
void Design::add_node(NetNode*net)
|
||||
{
|
||||
assert(net->design_ == 0);
|
||||
|
|
@ -961,6 +1016,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
|||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.20 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.19 1999/03/15 02:43:32 steve
|
||||
* Support more operators, especially logical.
|
||||
*
|
||||
|
|
|
|||
77
netlist.h
77
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.22 1999/03/15 02:43:32 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.23 1999/04/19 01:59:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -218,27 +218,13 @@ class NetNet : public NetObj {
|
|||
|
||||
enum PortType { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT };
|
||||
|
||||
explicit NetNet(const string&n, Type t, unsigned npins =1)
|
||||
: NetObj(n, npins), sig_next_(0), sig_prev_(0), design_(0),
|
||||
type_(t), port_type_(NOT_A_PORT), msb_(npins-1), lsb_(0),
|
||||
local_flag_(false)
|
||||
{ ivalue_ = new verinum::V[npins];
|
||||
for (unsigned idx = 0 ; idx < npins ; idx += 1)
|
||||
ivalue_[idx] = verinum::Vz;
|
||||
}
|
||||
explicit NetNet(const string&n, Type t, unsigned npins =1);
|
||||
|
||||
explicit NetNet(const string&n, Type t, long ms, long ls)
|
||||
: NetObj(n, ((ms>ls)?ms-ls:ls-ms) + 1), sig_next_(0),
|
||||
sig_prev_(0), design_(0), type_(t), port_type_(NOT_A_PORT),
|
||||
msb_(ms), lsb_(ls), local_flag_(false)
|
||||
{ ivalue_ = new verinum::V[pin_count()];
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1)
|
||||
ivalue_[idx] = verinum::Vz;
|
||||
}
|
||||
explicit NetNet(const string&n, Type t, long ms, long ls);
|
||||
|
||||
virtual ~NetNet();
|
||||
|
||||
// Every signal has a name, even if it is null.
|
||||
|
||||
Type type() const { return type_; }
|
||||
void type(Type t) { type_ = t; }
|
||||
|
||||
|
|
@ -282,6 +268,34 @@ class NetNet : public NetObj {
|
|||
verinum::V*ivalue_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class represents the declared memory object. The parser
|
||||
* creates one of these for each declared memory in the elaborated
|
||||
* design. A reference to one of these is handled by the NetEMemory
|
||||
* object, which is derived from NetExpr.
|
||||
*/
|
||||
class NetMemory {
|
||||
|
||||
public:
|
||||
NetMemory(const string&n, long w, long s, long e)
|
||||
: name_(n), width_(w), idxh_(s), idxl_(e) { }
|
||||
|
||||
const string&name() const { return name_; }
|
||||
unsigned width() const { return width_; }
|
||||
|
||||
void set_attributes(const map<string,string>&a);
|
||||
|
||||
void dump(ostream&o, unsigned lm) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
unsigned width_;
|
||||
long idxh_;
|
||||
long idxl_;
|
||||
|
||||
map<string,string> attributes_;
|
||||
};
|
||||
|
||||
/* =========
|
||||
* There are cases where expressions need to be represented. The
|
||||
* NetExpr class is the root of a heirarchy that serves that purpose.
|
||||
|
|
@ -897,6 +911,24 @@ class NetEIdent : public NetExpr {
|
|||
string name_;
|
||||
};
|
||||
|
||||
/*
|
||||
* A reference to a memory is represented by this expression.
|
||||
*/
|
||||
class NetEMemory : public NetExpr {
|
||||
|
||||
public:
|
||||
NetEMemory(NetMemory*mem, NetExpr*idx);
|
||||
virtual ~NetEMemory();
|
||||
|
||||
virtual void set_width(unsigned);
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
private:
|
||||
NetMemory*mem_;
|
||||
NetExpr::REF idx_;
|
||||
};
|
||||
|
||||
/*
|
||||
* When a signal shows up in an expression, this type represents
|
||||
* it. From this the expression can get any kind of access to the
|
||||
|
|
@ -953,6 +985,10 @@ class Design {
|
|||
void del_signal(NetNet*);
|
||||
NetNet*find_signal(const string&name);
|
||||
|
||||
// Memories
|
||||
void add_memory(NetMemory*);
|
||||
NetMemory* find_memory(const string&name);
|
||||
|
||||
// NODES
|
||||
void add_node(NetNode*);
|
||||
void del_node(NetNode*);
|
||||
|
|
@ -988,6 +1024,8 @@ class Design {
|
|||
// List all the signals in the design.
|
||||
NetNet*signals_;
|
||||
|
||||
map<string,NetMemory*> memories_;
|
||||
|
||||
// List the nodes in the design
|
||||
NetNode*nodes_;
|
||||
|
||||
|
|
@ -1048,6 +1086,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.23 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.22 1999/03/15 02:43:32 steve
|
||||
* Support more operators, especially logical.
|
||||
*
|
||||
|
|
|
|||
72
parse.y
72
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.16 1999/03/16 04:44:45 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.17 1999/04/19 01:59:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -87,7 +87,7 @@ extern void lex_end_table();
|
|||
%type <statement> udp_initial udp_init_opt
|
||||
|
||||
%type <text> identifier lvalue register_variable
|
||||
%type <strings> list_of_register_variables
|
||||
%type <strings> register_variable_list
|
||||
%type <strings> list_of_variables
|
||||
|
||||
%type <wire> port
|
||||
|
|
@ -194,7 +194,10 @@ delay
|
|||
}
|
||||
}
|
||||
| '#' IDENTIFIER
|
||||
{ $$ = new PEIdent(*$2);
|
||||
{ PEIdent*tmp = new PEIdent(*$2);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = tmp;
|
||||
delete $2;
|
||||
}
|
||||
;
|
||||
|
|
@ -317,7 +320,10 @@ expr_primary
|
|||
delete $1;
|
||||
}
|
||||
| identifier
|
||||
{ $$ = new PEIdent(*$1);
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
delete $1;
|
||||
}
|
||||
| SYSTEM_IDENTIFIER
|
||||
|
|
@ -326,12 +332,16 @@ expr_primary
|
|||
}
|
||||
| identifier '[' expression ']'
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
tmp->msb_ = $3;
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier '[' expression ':' expression ']'
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
tmp->msb_ = $3;
|
||||
tmp->lsb_ = $5;
|
||||
delete $1;
|
||||
|
|
@ -447,20 +457,6 @@ list_of_ports_opt
|
|||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
list_of_register_variables
|
||||
: register_variable
|
||||
{ list<string>*tmp = new list<string>;
|
||||
tmp->push_back(*$1);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| list_of_register_variables ',' register_variable
|
||||
{ list<string>*tmp = $1;
|
||||
tmp->push_back(*$3);
|
||||
delete $3;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
list_of_variables
|
||||
: IDENTIFIER
|
||||
{ list<string>*tmp = new list<string>;
|
||||
|
|
@ -508,14 +504,13 @@ module_item
|
|||
}
|
||||
delete $3;
|
||||
}
|
||||
| K_reg range_opt list_of_register_variables ';'
|
||||
{ pform_makewire($3, NetNet::REG);
|
||||
if ($2) {
|
||||
pform_set_net_range($3, $2);
|
||||
delete $2;
|
||||
}
|
||||
| K_reg range register_variable_list ';'
|
||||
{ pform_set_net_range($3, $2);
|
||||
delete $2;
|
||||
delete $3;
|
||||
}
|
||||
| K_reg register_variable_list ';'
|
||||
{ delete $2; }
|
||||
| K_parameter parameter_assign_list ';'
|
||||
| gatetype delay_opt gate_instance_list ';'
|
||||
{ pform_makegates($1, $2, $3);
|
||||
|
|
@ -629,13 +624,36 @@ range_opt
|
|||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
/* The register_variable rule is matched only when I am parsing
|
||||
variables in a "reg" definition. I therefore know that I am
|
||||
creating registers and I do not need to let the containing rule
|
||||
handle it. The register variable list simply packs them together
|
||||
so that bit ranges can be assigned. */
|
||||
register_variable
|
||||
: IDENTIFIER
|
||||
{ $$ = $1; }
|
||||
| IDENTIFIER '[' error ']'
|
||||
{ yyerror(@1, "Sorry, register regions not implemented.");
|
||||
{ pform_makewire(*$1, NetNet::REG);
|
||||
$$ = $1;
|
||||
}
|
||||
| IDENTIFIER '[' const_expression ':' const_expression ']'
|
||||
{ pform_makewire(*$1, NetNet::REG);
|
||||
pform_set_reg_idx(*$1, $3, $5);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
register_variable_list
|
||||
: register_variable
|
||||
{ list<string>*tmp = new list<string>;
|
||||
tmp->push_back(*$1);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| register_variable_list ',' register_variable
|
||||
{ list<string>*tmp = $1;
|
||||
tmp->push_back(*$3);
|
||||
delete $3;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
statement
|
||||
|
|
|
|||
19
pform.cc
19
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.10 1999/02/21 17:01:57 steve Exp $"
|
||||
#ident "$Id: pform.cc,v 1.11 1999/04/19 01:59:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "pform.h"
|
||||
|
|
@ -385,6 +385,20 @@ void pform_set_type_attrib(const string&name, const string&key,
|
|||
(*udp).second ->attributes[key] = value;
|
||||
}
|
||||
|
||||
void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r)
|
||||
{
|
||||
PWire*cur = cur_module->get_wire(name);
|
||||
if (cur == 0) {
|
||||
VLerror("name is not a valid net.");
|
||||
return;
|
||||
}
|
||||
|
||||
assert(cur->lidx == 0);
|
||||
assert(cur->ridx == 0);
|
||||
cur->lidx = l;
|
||||
cur->ridx = r;
|
||||
}
|
||||
|
||||
static void pform_set_net_range(const string&name, list<PExpr*>*range)
|
||||
{
|
||||
assert(range->size() == 2);
|
||||
|
|
@ -514,6 +528,9 @@ int pform_parse(const char*path, map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: pform.cc,v $
|
||||
* Revision 1.11 1999/04/19 01:59:37 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.10 1999/02/21 17:01:57 steve
|
||||
* Add support for module parameters.
|
||||
*
|
||||
|
|
|
|||
8
pform.h
8
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.8 1999/02/21 17:01:57 steve Exp $"
|
||||
#ident "$Id: pform.h,v 1.9 1999/04/19 01:59:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -97,10 +97,11 @@ extern void pform_make_udp(string*name, list<string>*parms,
|
|||
* The makewire functions announce to the pform code new wires. These
|
||||
* go into a module that is currently opened.
|
||||
*/
|
||||
extern void pform_makewire(const string&name, NetNet::Type type);
|
||||
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_reg_idx(const string&name, PExpr*l, PExpr*r);
|
||||
extern void pform_set_attrib(const string&name, const string&key,
|
||||
const string&value);
|
||||
extern void pform_set_type_attrib(const string&name, const string&key,
|
||||
|
|
@ -139,6 +140,9 @@ extern void pform_dump(ostream&out, Module*mod);
|
|||
|
||||
/*
|
||||
* $Log: pform.h,v $
|
||||
* Revision 1.9 1999/04/19 01:59:37 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.8 1999/02/21 17:01:57 steve
|
||||
* Add support for module parameters.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.11 1999/02/21 17:01:57 steve Exp $"
|
||||
#ident "$Id: pform_dump.cc,v 1.12 1999/04/19 01:59:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -119,7 +119,17 @@ void PWire::dump(ostream&out) const
|
|||
out << " [" << *msb << ":" << *lsb << "]";
|
||||
}
|
||||
|
||||
out << " " << name << ";" << endl;
|
||||
out << " " << name;
|
||||
|
||||
// If the wire has indices, dump them.
|
||||
if (lidx || ridx) {
|
||||
out << "[";
|
||||
if (lidx) out << *lidx;
|
||||
if (ridx) out << ":" << *ridx;
|
||||
out << "]";
|
||||
}
|
||||
|
||||
out << ";" << endl;
|
||||
for (map<string,string>::const_iterator idx = attributes.begin()
|
||||
; idx != attributes.end()
|
||||
; idx ++) {
|
||||
|
|
@ -414,6 +424,9 @@ void PUdp::dump(ostream&out) const
|
|||
|
||||
/*
|
||||
* $Log: pform_dump.cc,v $
|
||||
* Revision 1.12 1999/04/19 01:59:37 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.11 1999/02/21 17:01:57 steve
|
||||
* Add support for module parameters.
|
||||
*
|
||||
|
|
|
|||
12
t-vvm.cc
12
t-vvm.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: t-vvm.cc,v 1.14 1999/03/15 02:43:32 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.15 1999/04/19 01:59:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -41,6 +41,7 @@ class target_vvm : public target_t {
|
|||
public:
|
||||
virtual void start_design(ostream&os, const Design*);
|
||||
virtual void signal(ostream&os, const NetNet*);
|
||||
virtual void memory(ostream&os, const NetMemory*);
|
||||
virtual void logic(ostream&os, const NetLogic*);
|
||||
virtual void bufz(ostream&os, const NetBUFZ*);
|
||||
virtual void udp(ostream&os, const NetUDP*);
|
||||
|
|
@ -332,6 +333,12 @@ void target_vvm::signal(ostream&os, const NetNet*sig)
|
|||
}
|
||||
}
|
||||
|
||||
void target_vvm::memory(ostream&os, const NetMemory*mem)
|
||||
{
|
||||
os << "static vvm_bitset_t<" << mem->width() << "> " <<
|
||||
mangle(mem->name()) << "[" << "];" << endl;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method handles writing output functions for gates that have a
|
||||
* single output (at pin 0). This writes the output_fun method into
|
||||
|
|
@ -883,6 +890,9 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.15 1999/04/19 01:59:37 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.14 1999/03/15 02:43:32 steve
|
||||
* Support more operators, especially logical.
|
||||
*
|
||||
|
|
|
|||
17
target.cc
17
target.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: target.cc,v 1.5 1999/02/08 02:49:56 steve Exp $"
|
||||
#ident "$Id: target.cc,v 1.6 1999/04/19 01:59:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -35,6 +35,12 @@ void target_t::signal(ostream&os, const NetNet*)
|
|||
{
|
||||
}
|
||||
|
||||
void target_t::memory(ostream&os, const NetMemory*)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
"Unhandled memory." << endl;
|
||||
}
|
||||
|
||||
void target_t::logic(ostream&os, const NetLogic*)
|
||||
{
|
||||
}
|
||||
|
|
@ -146,6 +152,12 @@ void expr_scan_t::expr_ident(const NetEIdent*)
|
|||
"unhandled expr_ident." << endl;
|
||||
}
|
||||
|
||||
void expr_scan_t::expr_memory(const NetEMemory*)
|
||||
{
|
||||
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
|
||||
"unhandled expr_memory." << endl;
|
||||
}
|
||||
|
||||
void expr_scan_t::expr_signal(const NetESignal*)
|
||||
{
|
||||
cerr << "expr_scan_t (" << typeid(*this).name() << "): "
|
||||
|
|
@ -166,6 +178,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
|
|||
|
||||
/*
|
||||
* $Log: target.cc,v $
|
||||
* Revision 1.6 1999/04/19 01:59:37 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.5 1999/02/08 02:49:56 steve
|
||||
* Turn the NetESignal into a NetNode so
|
||||
* that it can connect to the netlist.
|
||||
|
|
|
|||
9
target.h
9
target.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: target.h,v 1.5 1999/02/08 02:49:56 steve Exp $"
|
||||
#ident "$Id: target.h,v 1.6 1999/04/19 01:59:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -58,6 +58,9 @@ struct target_t {
|
|||
/* Output a signal (called for each signal) */
|
||||
virtual void signal(ostream&os, const NetNet*);
|
||||
|
||||
/* Output a memory (called for each memory object) */
|
||||
virtual void memory(ostream&os, const NetMemory*);
|
||||
|
||||
/* Output a gate (called for each gate) */
|
||||
virtual void logic(ostream&os, const NetLogic*);
|
||||
virtual void bufz(ostream&os, const NetBUFZ*);
|
||||
|
|
@ -94,6 +97,7 @@ struct expr_scan_t {
|
|||
virtual ~expr_scan_t();
|
||||
virtual void expr_const(const NetEConst*);
|
||||
virtual void expr_ident(const NetEIdent*);
|
||||
virtual void expr_memory(const NetEMemory*);
|
||||
virtual void expr_signal(const NetESignal*);
|
||||
virtual void expr_unary(const NetEUnary*);
|
||||
virtual void expr_binary(const NetEBinary*);
|
||||
|
|
@ -116,6 +120,9 @@ extern const struct target *target_table[];
|
|||
|
||||
/*
|
||||
* $Log: target.h,v $
|
||||
* Revision 1.6 1999/04/19 01:59:37 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.5 1999/02/08 02:49:56 steve
|
||||
* Turn the NetESignal into a NetNode so
|
||||
* that it can connect to the netlist.
|
||||
|
|
|
|||
Loading…
Reference in New Issue