Rework handling of lexical scope
Move the storage of wires (signals) out of the Module class into the PScope base class, and instead of putting the PWires all into the Module object, distribute them into the various lexical scopes (derived from PScope) so that the wire names do not need to carry scope information. This required some rewiring of elaboration of signals, and rewriting of lexical scope handling.
This commit is contained in:
parent
b0e4a6884a
commit
8e704cbf93
19
Module.cc
19
Module.cc
|
|
@ -54,16 +54,6 @@ void Module::add_function(perm_string name, PFunction *func)
|
||||||
funcs_[name] = func;
|
funcs_[name] = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
PWire* Module::add_wire(PWire*wire)
|
|
||||||
{
|
|
||||||
PWire*&ep = wires_[wire->path()];
|
|
||||||
if (ep) return ep;
|
|
||||||
|
|
||||||
assert(ep == 0);
|
|
||||||
ep = wire;
|
|
||||||
return wire;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::add_behavior(PProcess*b)
|
void Module::add_behavior(PProcess*b)
|
||||||
{
|
{
|
||||||
behaviors_.push_back(b);
|
behaviors_.push_back(b);
|
||||||
|
|
@ -111,15 +101,6 @@ unsigned Module::find_port(const char*name) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PWire* Module::get_wire(const pform_name_t&name) const
|
|
||||||
{
|
|
||||||
map<pform_name_t,PWire*>::const_iterator obj = wires_.find(name);
|
|
||||||
if (obj == wires_.end())
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return (*obj).second;
|
|
||||||
}
|
|
||||||
|
|
||||||
PGate* Module::get_gate(perm_string name)
|
PGate* Module::get_gate(perm_string name)
|
||||||
{
|
{
|
||||||
for (list<PGate*>::iterator cur = gates_.begin()
|
for (list<PGate*>::iterator cur = gates_.begin()
|
||||||
|
|
|
||||||
38
Module.h
38
Module.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __Module_H
|
#ifndef __Module_H
|
||||||
#define __Module_H
|
#define __Module_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998-2004 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -18,9 +18,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
|
||||||
#ident "$Id: Module.h,v 1.43 2007/05/24 04:07:11 steve Exp $"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include <list>
|
# include <list>
|
||||||
# include <map>
|
# include <map>
|
||||||
|
|
@ -133,12 +131,6 @@ class Module : public PScope, public LineInfo {
|
||||||
perm_string mod_name() const { return pscope_name(); }
|
perm_string mod_name() const { return pscope_name(); }
|
||||||
|
|
||||||
void add_gate(PGate*gate);
|
void add_gate(PGate*gate);
|
||||||
|
|
||||||
// The add_wire method adds a wire by name, but only if the
|
|
||||||
// wire name doesn't already exist. Either way, the result is
|
|
||||||
// the existing wire or the pointer passed in.
|
|
||||||
PWire* add_wire(PWire*wire);
|
|
||||||
|
|
||||||
void add_behavior(PProcess*behave);
|
void add_behavior(PProcess*behave);
|
||||||
void add_task(perm_string name, PTask*def);
|
void add_task(perm_string name, PTask*def);
|
||||||
void add_function(perm_string name, PFunction*def);
|
void add_function(perm_string name, PFunction*def);
|
||||||
|
|
@ -147,9 +139,6 @@ class Module : public PScope, public LineInfo {
|
||||||
const svector<PEIdent*>& get_port(unsigned idx) const;
|
const svector<PEIdent*>& get_port(unsigned idx) const;
|
||||||
unsigned find_port(const char*name) const;
|
unsigned find_port(const char*name) const;
|
||||||
|
|
||||||
// Find a wire by name. This is used for connecting gates to
|
|
||||||
// existing wires, etc.
|
|
||||||
PWire* get_wire(const pform_name_t&name) const;
|
|
||||||
PGate* get_gate(perm_string name);
|
PGate* get_gate(perm_string name);
|
||||||
|
|
||||||
const list<PGate*>& get_gates() const;
|
const list<PGate*>& get_gates() const;
|
||||||
|
|
@ -164,7 +153,6 @@ class Module : public PScope, public LineInfo {
|
||||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
map<pform_name_t,PWire*> wires_;
|
|
||||||
list<PGate*> gates_;
|
list<PGate*> gates_;
|
||||||
list<PProcess*> behaviors_;
|
list<PProcess*> behaviors_;
|
||||||
map<perm_string,PTask*> tasks_;
|
map<perm_string,PTask*> tasks_;
|
||||||
|
|
@ -178,26 +166,4 @@ class Module : public PScope, public LineInfo {
|
||||||
Module& operator= (const Module&);
|
Module& operator= (const Module&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: Module.h,v $
|
|
||||||
* Revision 1.43 2007/05/24 04:07:11 steve
|
|
||||||
* Rework the heirarchical identifier parse syntax and pform
|
|
||||||
* to handle more general combinations of heirarch and bit selects.
|
|
||||||
*
|
|
||||||
* Revision 1.42 2007/04/19 02:52:53 steve
|
|
||||||
* Add support for -v flag in command file.
|
|
||||||
*
|
|
||||||
* Revision 1.41 2006/09/23 04:57:19 steve
|
|
||||||
* Basic support for specify timing.
|
|
||||||
*
|
|
||||||
* Revision 1.40 2006/04/10 00:37:42 steve
|
|
||||||
* Add support for generate loops w/ wires and gates.
|
|
||||||
*
|
|
||||||
* Revision 1.39 2006/03/30 01:49:07 steve
|
|
||||||
* Fix instance arrays indexed by overridden parameters.
|
|
||||||
*
|
|
||||||
* Revision 1.38 2005/07/11 16:56:50 steve
|
|
||||||
* Remove NetVariable and ivl_variable_t structures.
|
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
14
PGenerate.cc
14
PGenerate.cc
|
|
@ -33,19 +33,9 @@ PGenerate::~PGenerate()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PWire* PGenerate::add_wire(PWire*wire)
|
PWire* PGenerate::get_wire(perm_string name) const
|
||||||
{
|
{
|
||||||
PWire*&ep = wires[wire->path()];
|
map<perm_string,PWire*>::const_iterator obj = wires.find(name);
|
||||||
if (ep) return ep;
|
|
||||||
|
|
||||||
assert(ep == 0);
|
|
||||||
ep = wire;
|
|
||||||
return wire;
|
|
||||||
}
|
|
||||||
|
|
||||||
PWire* PGenerate::get_wire(const pform_name_t&name) const
|
|
||||||
{
|
|
||||||
map<pform_name_t,PWire*>::const_iterator obj = wires.find(name);
|
|
||||||
if (obj == wires.end())
|
if (obj == wires.end())
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,8 @@ class PGenerate : public LineInfo {
|
||||||
PExpr*loop_test;
|
PExpr*loop_test;
|
||||||
PExpr*loop_step;
|
PExpr*loop_step;
|
||||||
|
|
||||||
map<pform_name_t,PWire*>wires;
|
map<perm_string,PWire*>wires;
|
||||||
PWire* add_wire(PWire*);
|
PWire* get_wire(perm_string name) const;
|
||||||
PWire* get_wire(const pform_name_t&name) const;
|
|
||||||
|
|
||||||
list<PGate*> gates;
|
list<PGate*> gates;
|
||||||
void add_gate(PGate*);
|
void add_gate(PGate*);
|
||||||
|
|
|
||||||
|
|
@ -27,3 +27,12 @@ PScope::PScope(perm_string n, PScope*p)
|
||||||
PScope::~PScope()
|
PScope::~PScope()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PWire* PScope::wires_find(perm_string name)
|
||||||
|
{
|
||||||
|
map<perm_string,PWire*>::const_iterator cur = wires.find(name);
|
||||||
|
if (cur == wires.end())
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return (*cur).second;
|
||||||
|
}
|
||||||
|
|
|
||||||
13
PScope.h
13
PScope.h
|
|
@ -24,6 +24,10 @@
|
||||||
# include <map>
|
# include <map>
|
||||||
|
|
||||||
class PEvent;
|
class PEvent;
|
||||||
|
class PWire;
|
||||||
|
|
||||||
|
class Design;
|
||||||
|
class NetScope;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The PScope class is a base representation of an object that
|
* The PScope class is a base representation of an object that
|
||||||
|
|
@ -50,9 +54,18 @@ class PScope {
|
||||||
perm_string pscope_name() const { return name_; }
|
perm_string pscope_name() const { return name_; }
|
||||||
PScope* pscope_parent() { return parent_; }
|
PScope* pscope_parent() { return parent_; }
|
||||||
|
|
||||||
|
// Nets an variables (wires) in the scope
|
||||||
|
map<perm_string,PWire*>wires;
|
||||||
|
PWire* wires_find(perm_string name);
|
||||||
|
|
||||||
// Named events in the scope.
|
// Named events in the scope.
|
||||||
map<perm_string,PEvent*>events;
|
map<perm_string,PEvent*>events;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void dump_wires_(ostream&out, unsigned indent) const;
|
||||||
|
|
||||||
|
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
perm_string name_;
|
||||||
PScope*parent_;
|
PScope*parent_;
|
||||||
|
|
|
||||||
18
PWire.cc
18
PWire.cc
|
|
@ -22,11 +22,11 @@
|
||||||
# include "PExpr.h"
|
# include "PExpr.h"
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
PWire::PWire(const pform_name_t&n,
|
PWire::PWire(perm_string n,
|
||||||
NetNet::Type t,
|
NetNet::Type t,
|
||||||
NetNet::PortType pt,
|
NetNet::PortType pt,
|
||||||
ivl_variable_type_t dt)
|
ivl_variable_type_t dt)
|
||||||
: hname_(n), type_(t), port_type_(pt), data_type_(dt),
|
: name_(n), type_(t), port_type_(pt), data_type_(dt),
|
||||||
signed_(false), isint_(false),
|
signed_(false), isint_(false),
|
||||||
port_msb_(0), port_lsb_(0), port_set_(false),
|
port_msb_(0), port_lsb_(0), port_set_(false),
|
||||||
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0),
|
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0),
|
||||||
|
|
@ -44,9 +44,9 @@ NetNet::Type PWire::get_wire_type() const
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pform_name_t& PWire::path() const
|
perm_string PWire::basename() const
|
||||||
{
|
{
|
||||||
return hname_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PWire::set_wire_type(NetNet::Type t)
|
bool PWire::set_wire_type(NetNet::Type t)
|
||||||
|
|
@ -153,7 +153,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SR_PORT:
|
case SR_PORT:
|
||||||
if (port_set_) {
|
if (port_set_) {
|
||||||
cerr << get_fileline() << ": error: Port ``" << hname_
|
cerr << get_fileline() << ": error: Port ``" << name_
|
||||||
<< "'' has already been declared a port." << endl;
|
<< "'' has already been declared a port." << endl;
|
||||||
error_cnt_ += 1;
|
error_cnt_ += 1;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -165,7 +165,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
||||||
|
|
||||||
case SR_NET:
|
case SR_NET:
|
||||||
if (net_set_) {
|
if (net_set_) {
|
||||||
cerr << get_fileline() << ": error: Net ``" << hname_
|
cerr << get_fileline() << ": error: Net ``" << name_
|
||||||
<< "'' has already been declared." << endl;
|
<< "'' has already been declared." << endl;
|
||||||
error_cnt_ += 1;
|
error_cnt_ += 1;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -178,12 +178,12 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
||||||
case SR_BOTH:
|
case SR_BOTH:
|
||||||
if (port_set_ || net_set_) {
|
if (port_set_ || net_set_) {
|
||||||
if (port_set_) {
|
if (port_set_) {
|
||||||
cerr << get_fileline() << ": error: Port ``" << hname_
|
cerr << get_fileline() << ": error: Port ``" << name_
|
||||||
<< "'' has already been declared a port." << endl;
|
<< "'' has already been declared a port." << endl;
|
||||||
error_cnt_ += 1;
|
error_cnt_ += 1;
|
||||||
}
|
}
|
||||||
if (net_set_) {
|
if (net_set_) {
|
||||||
cerr << get_fileline() << ": error: Net ``" << hname_
|
cerr << get_fileline() << ": error: Net ``" << name_
|
||||||
<< "'' has already been declared." << endl;
|
<< "'' has already been declared." << endl;
|
||||||
error_cnt_ += 1;
|
error_cnt_ += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +202,7 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
||||||
void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||||
{
|
{
|
||||||
if (lidx_ != 0 || ridx_ != 0) {
|
if (lidx_ != 0 || ridx_ != 0) {
|
||||||
cerr << get_fileline() << ": error: Array ``" << hname_
|
cerr << get_fileline() << ": error: Array ``" << name_
|
||||||
<< "'' has already been declared." << endl;
|
<< "'' has already been declared." << endl;
|
||||||
error_cnt_ += 1;
|
error_cnt_ += 1;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
6
PWire.h
6
PWire.h
|
|
@ -56,13 +56,13 @@ enum PWSRType {SR_PORT, SR_NET, SR_BOTH};
|
||||||
class PWire : public LineInfo {
|
class PWire : public LineInfo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PWire(const pform_name_t&hname,
|
PWire(perm_string name,
|
||||||
NetNet::Type t,
|
NetNet::Type t,
|
||||||
NetNet::PortType pt,
|
NetNet::PortType pt,
|
||||||
ivl_variable_type_t dt);
|
ivl_variable_type_t dt);
|
||||||
|
|
||||||
// Return a hierarchical name.
|
// Return a hierarchical name.
|
||||||
const pform_name_t&path() const;
|
perm_string basename() const;
|
||||||
|
|
||||||
NetNet::Type get_wire_type() const;
|
NetNet::Type get_wire_type() const;
|
||||||
bool set_wire_type(NetNet::Type);
|
bool set_wire_type(NetNet::Type);
|
||||||
|
|
@ -90,7 +90,7 @@ class PWire : public LineInfo {
|
||||||
NetNet* elaborate_sig(Design*, NetScope*scope) const;
|
NetNet* elaborate_sig(Design*, NetScope*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pform_name_t hname_;
|
perm_string name_;
|
||||||
NetNet::Type type_;
|
NetNet::Type type_;
|
||||||
NetNet::PortType port_type_;
|
NetNet::PortType port_type_;
|
||||||
ivl_variable_type_t data_type_;
|
ivl_variable_type_t data_type_;
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ class Statement : public LineInfo {
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -166,6 +167,7 @@ class PBlock : public PScope, public Statement {
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const BL_TYPE bl_type_;
|
const BL_TYPE bl_type_;
|
||||||
|
|
@ -217,6 +219,7 @@ class PCase : public Statement {
|
||||||
|
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -252,6 +255,7 @@ class PCondit : public Statement {
|
||||||
|
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -286,6 +290,7 @@ class PDelayStatement : public Statement {
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PExpr*delay_;
|
PExpr*delay_;
|
||||||
|
|
@ -333,6 +338,7 @@ class PEventStatement : public Statement {
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
// This method is used to elaborate, but attach a previously
|
// This method is used to elaborate, but attach a previously
|
||||||
// elaborated statement to the event.
|
// elaborated statement to the event.
|
||||||
|
|
@ -366,6 +372,7 @@ class PForever : public Statement {
|
||||||
|
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -381,6 +388,7 @@ class PForStatement : public Statement {
|
||||||
|
|
||||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||||
|
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||||
virtual void dump(ostream&out, unsigned ind) const;
|
virtual void dump(ostream&out, unsigned ind) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -309,8 +309,14 @@ void NetPow::dump_node(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << "LPM_POW (NetPow): " << name()
|
o << setw(ind) << "" << "LPM_POW (NetPow): " << name()
|
||||||
<< " scope=" << scope_path(scope())
|
<< " scope=" << scope_path(scope())
|
||||||
<< " delay=(" << *rise_time() << "," << *fall_time() << ","
|
<< " delay=(";
|
||||||
<< *decay_time() << ")" << endl;
|
if (rise_time())
|
||||||
|
o << *rise_time() << "," << *fall_time() << ","
|
||||||
|
<< *decay_time();
|
||||||
|
else
|
||||||
|
o << "0,0,0";
|
||||||
|
|
||||||
|
o << ")" << endl;
|
||||||
dump_node_pins(o, ind+4);
|
dump_node_pins(o, ind+4);
|
||||||
dump_obj_attr(o, ind+4);
|
dump_obj_attr(o, ind+4);
|
||||||
}
|
}
|
||||||
|
|
@ -980,7 +986,10 @@ void NetScope::dump(ostream&o) const
|
||||||
o << " MISSING FUNCTION DEFINITION" << endl;
|
o << " MISSING FUNCTION DEFINITION" << endl;
|
||||||
break;
|
break;
|
||||||
case TASK:
|
case TASK:
|
||||||
task_def()->dump(o, 4);
|
if (task_def())
|
||||||
|
task_def()->dump(o, 4);
|
||||||
|
else
|
||||||
|
o << " MISSING TASK DEFINITION" << endl;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
308
elab_sig.cc
308
elab_sig.cc
|
|
@ -28,46 +28,58 @@
|
||||||
# include "PGenerate.h"
|
# include "PGenerate.h"
|
||||||
# include "PTask.h"
|
# include "PTask.h"
|
||||||
# include "PWire.h"
|
# include "PWire.h"
|
||||||
|
# include "Statement.h"
|
||||||
# include "compiler.h"
|
# include "compiler.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netmisc.h"
|
# include "netmisc.h"
|
||||||
# include "util.h"
|
# include "util.h"
|
||||||
# include "ivl_assert.h"
|
# include "ivl_assert.h"
|
||||||
|
|
||||||
/*
|
void Statement::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
* This local function checks if a named signal is connected to a
|
|
||||||
* port. It looks in the array of ports passed, for NetEIdent objects
|
|
||||||
* within the port_t that have a matching name.
|
|
||||||
*/
|
|
||||||
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
|
||||||
NetNet*sig)
|
|
||||||
{
|
{
|
||||||
perm_string name = sig->name();
|
}
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
|
||||||
|
{
|
||||||
|
bool flag = true;
|
||||||
|
|
||||||
Module::port_t*pp = ports[idx];
|
for (map<perm_string,PWire*>::const_iterator wt = wires.begin()
|
||||||
// Skip internally unconnected ports.
|
; wt != wires.end() ; wt ++ ) {
|
||||||
if (pp == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// This port has an internal connection. In this case,
|
PWire*cur = (*wt).second;
|
||||||
// the port has 0 or more NetEIdent objects concatenated
|
NetNet*sig = cur->elaborate_sig(des, scope);
|
||||||
// together that form the port.
|
|
||||||
|
|
||||||
// Note that module ports should not have any hierarchy
|
|
||||||
// in their names: they are in the root of the module
|
|
||||||
// scope by definition.
|
|
||||||
|
|
||||||
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
/* If the signal is an input and is also declared as a
|
||||||
perm_string pname = peek_tail_name(pp->expr[cc]->path());
|
reg, then report an error. */
|
||||||
assert(pp->expr[cc]);
|
|
||||||
if (pname == name)
|
if (sig && (sig->scope() == scope)
|
||||||
return true;
|
&& (scope->type() == NetScope::MODULE)
|
||||||
|
&& (sig->port_type() == NetNet::PINPUT)
|
||||||
|
&& (sig->type() == NetNet::REG)) {
|
||||||
|
|
||||||
|
cerr << cur->get_fileline() << ": error: "
|
||||||
|
<< cur->basename() << " in "
|
||||||
|
<< scope->module_name()
|
||||||
|
<< " declared as input and as a reg type." << endl;
|
||||||
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sig && (sig->scope() == scope)
|
||||||
|
&& (scope->type() == NetScope::MODULE)
|
||||||
|
&& (sig->port_type() == NetNet::PINOUT)
|
||||||
|
&& (sig->type() == NetNet::REG)) {
|
||||||
|
|
||||||
|
cerr << cur->get_fileline() << ": error: "
|
||||||
|
<< cur->basename() << " in "
|
||||||
|
<< scope->module_name()
|
||||||
|
<< " declared as inout and as a reg type." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
@ -81,14 +93,26 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if (pp == 0)
|
if (pp == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
map<pform_name_t,PWire*>::const_iterator wt;
|
// The port has a name and an array of expressions. The
|
||||||
|
// expression are all identifiers that should reference
|
||||||
|
// wires within the scope.
|
||||||
|
map<perm_string,PWire*>::const_iterator wt;
|
||||||
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
||||||
pform_name_t port_path (pp->expr[cc]->path());
|
pform_name_t port_path (pp->expr[cc]->path());
|
||||||
wt = wires_.find(port_path);
|
// A concatenated wire of a port really should not
|
||||||
|
// have any hierarchy.
|
||||||
|
if (port_path.size() != 1) {
|
||||||
|
cerr << get_fileline() << ": internal error: "
|
||||||
|
<< "Port " << port_path << " has a funny name?"
|
||||||
|
<< endl;
|
||||||
|
des->errors += 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (wt == wires_.end()) {
|
wt = wires.find(peek_tail_name(port_path));
|
||||||
|
|
||||||
|
if (wt == wires.end()) {
|
||||||
cerr << get_fileline() << ": error: "
|
cerr << get_fileline() << ": error: "
|
||||||
<< "Port " << pp->expr[cc]->path() << " ("
|
<< "Port " << port_path << " ("
|
||||||
<< (idx+1) << ") of module " << mod_name()
|
<< (idx+1) << ") of module " << mod_name()
|
||||||
<< " is not declared within module." << endl;
|
<< " is not declared within module." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
@ -106,58 +130,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (map<pform_name_t,PWire*>::const_iterator wt = wires_.begin()
|
flag = elaborate_sig_wires_(des, scope) && flag;
|
||||||
; wt != wires_.end() ; wt ++ ) {
|
|
||||||
|
|
||||||
PWire*cur = (*wt).second;
|
|
||||||
NetNet*sig = cur->elaborate_sig(des, scope);
|
|
||||||
|
|
||||||
// If this wire is a signal of the module (as opposed to
|
|
||||||
// a port of a function) and is a port, then check that
|
|
||||||
// the module knows about it. We know that the signal is
|
|
||||||
// the name of a signal within a subscope of a module
|
|
||||||
// (a task, a function, etc.) if the name for the PWire
|
|
||||||
// has hierarchy.
|
|
||||||
|
|
||||||
if (sig && (sig->scope() == scope)
|
|
||||||
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
|
|
||||||
|
|
||||||
if (! signal_is_in_port(ports, sig)) {
|
|
||||||
|
|
||||||
cerr << cur->get_fileline() << ": error: Signal "
|
|
||||||
<< sig->name() << " has a declared direction "
|
|
||||||
<< "but is not a port." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If the signal is an input and is also declared as a
|
|
||||||
reg, then report an error. */
|
|
||||||
|
|
||||||
if (sig && (sig->scope() == scope)
|
|
||||||
&& (sig->port_type() == NetNet::PINPUT)
|
|
||||||
&& (sig->type() == NetNet::REG)) {
|
|
||||||
|
|
||||||
cerr << cur->get_fileline() << ": error: "
|
|
||||||
<< cur->path() << " in module "
|
|
||||||
<< scope->module_name()
|
|
||||||
<< " declared as input and as a reg type." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sig && (sig->scope() == scope)
|
|
||||||
&& (sig->port_type() == NetNet::PINOUT)
|
|
||||||
&& (sig->type() == NetNet::REG)) {
|
|
||||||
|
|
||||||
cerr << cur->get_fileline() << ": error: "
|
|
||||||
<< cur->path() << " in module "
|
|
||||||
<< scope->module_name()
|
|
||||||
<< " declared as inout and as a reg type." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run through all the generate schemes to elaborate the
|
// Run through all the generate schemes to elaborate the
|
||||||
// signals that they hold. Note that the generate schemes hold
|
// signals that they hold. Note that the generate schemes hold
|
||||||
|
|
@ -216,6 +189,18 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
(*cur).second->elaborate_sig(des, tscope);
|
(*cur).second->elaborate_sig(des, tscope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initial and always blocks may contain begin-end and
|
||||||
|
// fork-join blocks that can introduce scopes. Therefore, I
|
||||||
|
// get to scan processes here.
|
||||||
|
|
||||||
|
typedef list<PProcess*>::const_iterator proc_it_t;
|
||||||
|
|
||||||
|
for (proc_it_t cur = behaviors_.begin()
|
||||||
|
; cur != behaviors_.end() ; cur ++ ) {
|
||||||
|
|
||||||
|
(*cur) -> statement() -> elaborate_sig(des, scope);
|
||||||
|
}
|
||||||
|
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -276,7 +261,7 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
// Scan the declared PWires to elaborate the obvious signals
|
// Scan the declared PWires to elaborate the obvious signals
|
||||||
// in the current scope.
|
// in the current scope.
|
||||||
typedef map<pform_name_t,PWire*>::const_iterator wires_it_t;
|
typedef map<perm_string,PWire*>::const_iterator wires_it_t;
|
||||||
for (wires_it_t wt = wires.begin()
|
for (wires_it_t wt = wires.begin()
|
||||||
; wt != wires.end() ; wt ++ ) {
|
; wt != wires.end() ; wt ++ ) {
|
||||||
|
|
||||||
|
|
@ -284,7 +269,7 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
if (debug_elaborate)
|
if (debug_elaborate)
|
||||||
cerr << get_fileline() << ": debug: Elaborate PWire "
|
cerr << get_fileline() << ": debug: Elaborate PWire "
|
||||||
<< cur->path() << " in scope " << scope_path(scope) << endl;
|
<< cur->basename() << " in scope " << scope_path(scope) << endl;
|
||||||
|
|
||||||
cur->elaborate_sig(des, scope);
|
cur->elaborate_sig(des, scope);
|
||||||
}
|
}
|
||||||
|
|
@ -316,6 +301,8 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
perm_string fname = scope->basename();
|
perm_string fname = scope->basename();
|
||||||
assert(scope->type() == NetScope::FUNC);
|
assert(scope->type() == NetScope::FUNC);
|
||||||
|
|
||||||
|
elaborate_sig_wires_(des, scope);
|
||||||
|
|
||||||
/* Make sure the function has at least one input port. If it
|
/* Make sure the function has at least one input port. If it
|
||||||
fails this test, print an error message. Keep going so we
|
fails this test, print an error message. Keep going so we
|
||||||
can find more errors. */
|
can find more errors. */
|
||||||
|
|
@ -416,19 +403,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
name. We know by design that the port name is given
|
name. We know by design that the port name is given
|
||||||
as two components: <func>.<port>. */
|
as two components: <func>.<port>. */
|
||||||
|
|
||||||
pform_name_t path = (*ports_)[idx]->path();
|
perm_string pname = (*ports_)[idx]->basename();
|
||||||
ivl_assert(*this, path.size() == 2);
|
|
||||||
|
|
||||||
perm_string pname = peek_tail_name(path);
|
|
||||||
perm_string ppath = peek_head_name(path);
|
|
||||||
|
|
||||||
if (ppath != scope->basename()) {
|
|
||||||
cerr << get_fileline() << ": internal error: function "
|
|
||||||
<< "port " << (*ports_)[idx]->path()
|
|
||||||
<< " has wrong name for function "
|
|
||||||
<< scope_path(scope) << "." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetNet*tmp = scope->find_signal(pname);
|
NetNet*tmp = scope->find_signal(pname);
|
||||||
if (tmp == 0) {
|
if (tmp == 0) {
|
||||||
|
|
@ -449,6 +424,10 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
assert(def);
|
assert(def);
|
||||||
scope->set_func_def(def);
|
scope->set_func_def(def);
|
||||||
|
|
||||||
|
// Look for further signals in the sub-statement
|
||||||
|
if (statement_)
|
||||||
|
statement_->elaborate_sig(des, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -464,24 +443,12 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
assert(scope->type() == NetScope::TASK);
|
assert(scope->type() == NetScope::TASK);
|
||||||
|
|
||||||
|
elaborate_sig_wires_(des, scope);
|
||||||
|
|
||||||
svector<NetNet*>ports (ports_? ports_->count() : 0);
|
svector<NetNet*>ports (ports_? ports_->count() : 0);
|
||||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||||
|
|
||||||
/* Parse the port name into the task name and the reg
|
perm_string port_name = (*ports_)[idx]->basename();
|
||||||
name. We know by design that the port name is given
|
|
||||||
as two components: <task>.<port>. */
|
|
||||||
|
|
||||||
pform_name_t path = (*ports_)[idx]->path();
|
|
||||||
ivl_assert(*this, path.size() == 2);
|
|
||||||
|
|
||||||
perm_string scope_name = peek_head_name(path);
|
|
||||||
perm_string port_name = peek_tail_name(path);
|
|
||||||
|
|
||||||
/* check that the current scope really does have the
|
|
||||||
name of the first component of the task port name. Do
|
|
||||||
this by looking up the task scope in the parent of
|
|
||||||
the current scope. */
|
|
||||||
ivl_assert(*this, scope->basename() == scope_name);
|
|
||||||
|
|
||||||
/* Find the signal for the port. We know by definition
|
/* Find the signal for the port. We know by definition
|
||||||
that it is in the scope of the task, so look only in
|
that it is in the scope of the task, so look only in
|
||||||
|
|
@ -493,6 +460,7 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
<< "Could not find port " << port_name
|
<< "Could not find port " << port_name
|
||||||
<< " in scope " << scope_path(scope) << endl;
|
<< " in scope " << scope_path(scope) << endl;
|
||||||
scope->dump(cerr);
|
scope->dump(cerr);
|
||||||
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ports[idx] = tmp;
|
ports[idx] = tmp;
|
||||||
|
|
@ -500,6 +468,82 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
NetTaskDef*def = new NetTaskDef(scope, ports);
|
NetTaskDef*def = new NetTaskDef(scope, ports);
|
||||||
scope->set_task_def(def);
|
scope->set_task_def(def);
|
||||||
|
|
||||||
|
// Look for further signals in the sub-statement
|
||||||
|
if (statement_)
|
||||||
|
statement_->elaborate_sig(des, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PBlock::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
{
|
||||||
|
NetScope*my_scope = scope;
|
||||||
|
|
||||||
|
if (pscope_name() != 0) {
|
||||||
|
hname_t use_name (pscope_name());
|
||||||
|
my_scope = scope->child(use_name);
|
||||||
|
if (my_scope == 0) {
|
||||||
|
cerr << get_fileline() << ": internal error: "
|
||||||
|
<< "Unable to find child scope " << pscope_name()
|
||||||
|
<< " in this context?" << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
my_scope = scope;
|
||||||
|
} else {
|
||||||
|
if (debug_elaborate)
|
||||||
|
cerr << get_fileline() << ": debug: "
|
||||||
|
<< "elaborate_sig descending into "
|
||||||
|
<< scope_path(my_scope) << "." << endl;
|
||||||
|
|
||||||
|
elaborate_sig_wires_(des, my_scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// elaborate_sig in the statements included in the
|
||||||
|
// block. There may be named blocks in there.
|
||||||
|
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1)
|
||||||
|
list_[idx] -> elaborate_sig(des, my_scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCase::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
{
|
||||||
|
if (items_ == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) {
|
||||||
|
if ( (*items_)[idx]->stat )
|
||||||
|
(*items_)[idx]->stat ->elaborate_sig(des,scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCondit::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
{
|
||||||
|
if (if_)
|
||||||
|
if_->elaborate_sig(des, scope);
|
||||||
|
if (else_)
|
||||||
|
else_->elaborate_sig(des, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PDelayStatement::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
{
|
||||||
|
if (statement_)
|
||||||
|
statement_->elaborate_sig(des, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PEventStatement::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
{
|
||||||
|
if (statement_)
|
||||||
|
statement_->elaborate_sig(des, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PForever::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
{
|
||||||
|
if (statement_)
|
||||||
|
statement_->elaborate_sig(des, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PForStatement::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
{
|
||||||
|
if (statement_)
|
||||||
|
statement_->elaborate_sig(des, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PGate::elaborate_sig(Design*des, NetScope*scope) const
|
bool PGate::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
@ -516,27 +560,6 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
*/
|
*/
|
||||||
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
|
|
||||||
/* The parser may produce hierarchical names for wires. I here
|
|
||||||
follow the scopes down to the base where I actually want to
|
|
||||||
elaborate the NetNet object. */
|
|
||||||
{ pform_name_t tmp_path = hname_;
|
|
||||||
tmp_path.pop_back();
|
|
||||||
while (! tmp_path.empty()) {
|
|
||||||
name_component_t cur = tmp_path.front();
|
|
||||||
tmp_path.pop_front();
|
|
||||||
|
|
||||||
scope = scope->child( hname_t(cur.name) );
|
|
||||||
|
|
||||||
if (scope == 0) {
|
|
||||||
cerr << get_fileline() << ": internal error: "
|
|
||||||
<< "Bad scope component for name "
|
|
||||||
<< hname_ << endl;
|
|
||||||
assert(scope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NetNet::Type wtype = type_;
|
NetNet::Type wtype = type_;
|
||||||
if (wtype == NetNet::IMPLICIT)
|
if (wtype == NetNet::IMPLICIT)
|
||||||
wtype = NetNet::WIRE;
|
wtype = NetNet::WIRE;
|
||||||
|
|
@ -619,12 +642,12 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if (port_msb_ == 0) {
|
if (port_msb_ == 0) {
|
||||||
if (!gn_io_range_error_flag) {
|
if (!gn_io_range_error_flag) {
|
||||||
cerr << get_fileline()
|
cerr << get_fileline()
|
||||||
<< ": warning: Scalar port ``" << hname_
|
<< ": warning: Scalar port ``" << name_
|
||||||
<< "'' has a vectored net declaration ["
|
<< "'' has a vectored net declaration ["
|
||||||
<< nmsb << ":" << nlsb << "]." << endl;
|
<< nmsb << ":" << nlsb << "]." << endl;
|
||||||
} else {
|
} else {
|
||||||
cerr << get_fileline()
|
cerr << get_fileline()
|
||||||
<< ": error: Scalar port ``" << hname_
|
<< ": error: Scalar port ``" << name_
|
||||||
<< "'' has a vectored net declaration ["
|
<< "'' has a vectored net declaration ["
|
||||||
<< nmsb << ":" << nlsb << "]." << endl;
|
<< nmsb << ":" << nlsb << "]." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
@ -636,7 +659,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if (net_msb_ == 0) {
|
if (net_msb_ == 0) {
|
||||||
cerr << port_msb_->get_fileline()
|
cerr << port_msb_->get_fileline()
|
||||||
<< ": error: Vectored port ``"
|
<< ": error: Vectored port ``"
|
||||||
<< hname_ << "'' [" << pmsb << ":" << plsb
|
<< name_ << "'' [" << pmsb << ":" << plsb
|
||||||
<< "] has a scalar net declaration at "
|
<< "] has a scalar net declaration at "
|
||||||
<< get_fileline() << "." << endl;
|
<< get_fileline() << "." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
|
|
@ -647,7 +670,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if (port_msb_ != 0 && net_msb_ != 0) {
|
if (port_msb_ != 0 && net_msb_ != 0) {
|
||||||
cerr << port_msb_->get_fileline()
|
cerr << port_msb_->get_fileline()
|
||||||
<< ": error: Vectored port ``"
|
<< ": error: Vectored port ``"
|
||||||
<< hname_ << "'' [" << pmsb << ":" << plsb
|
<< name_ << "'' [" << pmsb << ":" << plsb
|
||||||
<< "] has a net declaration [" << nmsb << ":"
|
<< "] has a net declaration [" << nmsb << ":"
|
||||||
<< nlsb << "] at " << net_msb_->get_fileline()
|
<< nlsb << "] at " << net_msb_->get_fileline()
|
||||||
<< " that does not match." << endl;
|
<< " that does not match." << endl;
|
||||||
|
|
@ -687,7 +710,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if ((lexp == 0) || (rexp == 0)) {
|
if ((lexp == 0) || (rexp == 0)) {
|
||||||
cerr << get_fileline() << ": internal error: There is "
|
cerr << get_fileline() << ": internal error: There is "
|
||||||
<< "a problem evaluating indices for ``"
|
<< "a problem evaluating indices for ``"
|
||||||
<< hname_ << "''." << endl;
|
<< name_ << "''." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -698,7 +721,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if ((lcon == 0) || (rcon == 0)) {
|
if ((lcon == 0) || (rcon == 0)) {
|
||||||
cerr << get_fileline() << ": internal error: The indices "
|
cerr << get_fileline() << ": internal error: The indices "
|
||||||
<< "are not constant for array ``"
|
<< "are not constant for array ``"
|
||||||
<< hname_ << "''." << endl;
|
<< name_ << "''." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -748,24 +771,23 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
perm_string name = peek_tail_name(hname_);
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": debug: Create signal "
|
cerr << get_fileline() << ": debug: Create signal "
|
||||||
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name
|
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name_
|
||||||
<< " in scope " << scope_path(scope) << endl;
|
<< " in scope " << scope_path(scope) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NetNet*sig = array_dimensions > 0
|
NetNet*sig = array_dimensions > 0
|
||||||
? new NetNet(scope, name, wtype, msb, lsb, array_s0, array_e0)
|
? new NetNet(scope, name_, wtype, msb, lsb, array_s0, array_e0)
|
||||||
: new NetNet(scope, name, wtype, msb, lsb);
|
: new NetNet(scope, name_, wtype, msb, lsb);
|
||||||
|
|
||||||
ivl_variable_type_t use_data_type = data_type_;
|
ivl_variable_type_t use_data_type = data_type_;
|
||||||
if (use_data_type == IVL_VT_NO_TYPE) {
|
if (use_data_type == IVL_VT_NO_TYPE) {
|
||||||
use_data_type = IVL_VT_LOGIC;
|
use_data_type = IVL_VT_LOGIC;
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": debug: "
|
cerr << get_fileline() << ": debug: "
|
||||||
<< "Signal " << name
|
<< "Signal " << name_
|
||||||
<< " in scope " << scope_path(scope)
|
<< " in scope " << scope_path(scope)
|
||||||
<< " defaults to data type " << use_data_type << endl;
|
<< " defaults to data type " << use_data_type << endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2914,7 +2914,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
||||||
NetNet*sig = des->find_signal(scope, id1->path());
|
NetNet*sig = des->find_signal(scope, id1->path());
|
||||||
if (sig == 0) {
|
if (sig == 0) {
|
||||||
cerr << id1->get_fileline() << ": register ``" << id1->path()
|
cerr << id1->get_fileline() << ": register ``" << id1->path()
|
||||||
<< "'' unknown in this context." << endl;
|
<< "'' unknown in " << scope_path(scope) << "." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -295,10 +295,10 @@ void NetScope::rem_event(NetEvent*ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NetEvent* NetScope::find_event(const char*name)
|
NetEvent* NetScope::find_event(perm_string name)
|
||||||
{
|
{
|
||||||
for (NetEvent*cur = events_; cur ; cur = cur->snext_)
|
for (NetEvent*cur = events_; cur ; cur = cur->snext_)
|
||||||
if (strcmp(cur->name(), name) == 0)
|
if (cur->name() == name)
|
||||||
return cur;
|
return cur;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -337,7 +337,7 @@ void NetScope::rem_signal(NetNet*net)
|
||||||
* is assumed to be the base name of the signal, so no sub-scopes are
|
* is assumed to be the base name of the signal, so no sub-scopes are
|
||||||
* searched.
|
* searched.
|
||||||
*/
|
*/
|
||||||
NetNet* NetScope::find_signal(const char*key)
|
NetNet* NetScope::find_signal(perm_string key)
|
||||||
{
|
{
|
||||||
if (signals_ == 0)
|
if (signals_ == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -3272,7 +3272,7 @@ class NetScope : public Attrib {
|
||||||
|
|
||||||
void add_event(NetEvent*);
|
void add_event(NetEvent*);
|
||||||
void rem_event(NetEvent*);
|
void rem_event(NetEvent*);
|
||||||
NetEvent*find_event(const char*name);
|
NetEvent*find_event(perm_string name);
|
||||||
|
|
||||||
|
|
||||||
/* These methods manage signals. The add_ and rem_signal
|
/* These methods manage signals. The add_ and rem_signal
|
||||||
|
|
@ -3282,7 +3282,7 @@ class NetScope : public Attrib {
|
||||||
|
|
||||||
void add_signal(NetNet*);
|
void add_signal(NetNet*);
|
||||||
void rem_signal(NetNet*);
|
void rem_signal(NetNet*);
|
||||||
NetNet* find_signal(const char*name);
|
NetNet* find_signal(perm_string name);
|
||||||
|
|
||||||
/* The parent and child() methods allow users of NetScope
|
/* The parent and child() methods allow users of NetScope
|
||||||
objects to locate nearby scopes. */
|
objects to locate nearby scopes. */
|
||||||
|
|
|
||||||
427
parse.y
427
parse.y
|
|
@ -26,6 +26,7 @@
|
||||||
# include "pform.h"
|
# include "pform.h"
|
||||||
# include "Statement.h"
|
# include "Statement.h"
|
||||||
# include "PSpec.h"
|
# include "PSpec.h"
|
||||||
|
# include <stack>
|
||||||
# include <cstring>
|
# include <cstring>
|
||||||
# include <sstream>
|
# include <sstream>
|
||||||
|
|
||||||
|
|
@ -49,7 +50,7 @@ static struct {
|
||||||
task/function that is currently in progress. */
|
task/function that is currently in progress. */
|
||||||
static PTask* current_task = 0;
|
static PTask* current_task = 0;
|
||||||
static PFunction* current_function = 0;
|
static PFunction* current_function = 0;
|
||||||
static PBlock* current_block = 0;
|
static stack<PBlock*> current_block_stack;
|
||||||
|
|
||||||
/* Later version of bison (including 1.35) will not compile in stack
|
/* Later version of bison (including 1.35) will not compile in stack
|
||||||
extension if the output is compiled with C++ and either the YYSTYPE
|
extension if the output is compiled with C++ and either the YYSTYPE
|
||||||
|
|
@ -197,7 +198,8 @@ static inline void FILE_NAME(LineInfo*tmp, const struct vlltype&where)
|
||||||
%type <text> udp_input_list udp_sequ_entry udp_comb_entry
|
%type <text> udp_input_list udp_sequ_entry udp_comb_entry
|
||||||
%type <perm_strings> udp_input_declaration_list
|
%type <perm_strings> udp_input_declaration_list
|
||||||
%type <strings> udp_entry_list udp_comb_entry_list udp_sequ_entry_list
|
%type <strings> udp_entry_list udp_comb_entry_list udp_sequ_entry_list
|
||||||
%type <strings> udp_body udp_port_list
|
%type <strings> udp_body
|
||||||
|
%type <perm_strings> udp_port_list
|
||||||
%type <wires> udp_port_decl udp_port_decls
|
%type <wires> udp_port_decl udp_port_decls
|
||||||
%type <statement> udp_initial udp_init_opt
|
%type <statement> udp_initial udp_init_opt
|
||||||
%type <expr> udp_initial_expr_opt
|
%type <expr> udp_initial_expr_opt
|
||||||
|
|
@ -1411,28 +1413,18 @@ list_of_port_declarations
|
||||||
{ svector<Module::port_t*>*tmp
|
{ svector<Module::port_t*>*tmp
|
||||||
= new svector<Module::port_t*>(1);
|
= new svector<Module::port_t*>(1);
|
||||||
(*tmp)[0] = $1;
|
(*tmp)[0] = $1;
|
||||||
/*
|
|
||||||
* Uncommenting this makes lopd always fully specified.
|
|
||||||
* Some wanted an implicit net to not be fully defined.
|
|
||||||
*
|
|
||||||
* pform_set_net_range($1[0].name);
|
|
||||||
*/
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| list_of_port_declarations ',' port_declaration
|
| list_of_port_declarations ',' port_declaration
|
||||||
{ svector<Module::port_t*>*tmp
|
{ svector<Module::port_t*>*tmp
|
||||||
= new svector<Module::port_t*>(*$1, $3);
|
= new svector<Module::port_t*>(*$1, $3);
|
||||||
delete $1;
|
delete $1;
|
||||||
/*
|
|
||||||
* Same as above.
|
|
||||||
*
|
|
||||||
* pform_set_net_range($3[0].name);
|
|
||||||
*/
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| list_of_port_declarations ',' IDENTIFIER
|
| list_of_port_declarations ',' IDENTIFIER
|
||||||
{ Module::port_t*ptmp;
|
{ Module::port_t*ptmp;
|
||||||
ptmp = pform_module_port_reference($3, @3.text,
|
perm_string name = lex_strings.make($3);
|
||||||
|
ptmp = pform_module_port_reference(name, @3.text,
|
||||||
@3.first_line);
|
@3.first_line);
|
||||||
svector<Module::port_t*>*tmp
|
svector<Module::port_t*>*tmp
|
||||||
= new svector<Module::port_t*>(*$1, ptmp);
|
= new svector<Module::port_t*>(*$1, ptmp);
|
||||||
|
|
@ -1440,17 +1432,13 @@ list_of_port_declarations
|
||||||
/* Get the port declaration details, the port type
|
/* Get the port declaration details, the port type
|
||||||
and what not, from context data stored by the
|
and what not, from context data stored by the
|
||||||
last port_declaration rule. */
|
last port_declaration rule. */
|
||||||
pform_module_define_port(@3, $3,
|
pform_module_define_port(@3, name,
|
||||||
port_declaration_context.port_type,
|
port_declaration_context.port_type,
|
||||||
port_declaration_context.port_net_type,
|
port_declaration_context.port_net_type,
|
||||||
port_declaration_context.sign_flag,
|
port_declaration_context.sign_flag,
|
||||||
port_declaration_context.range, 0);
|
port_declaration_context.range, 0);
|
||||||
delete $1;
|
delete $1;
|
||||||
/*
|
delete $3;
|
||||||
* Same as above.
|
|
||||||
*
|
|
||||||
* pform_set_net_range($3);
|
|
||||||
*/
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| list_of_port_declarations ','
|
| list_of_port_declarations ','
|
||||||
|
|
@ -1466,88 +1454,93 @@ list_of_port_declarations
|
||||||
;
|
;
|
||||||
|
|
||||||
port_declaration
|
port_declaration
|
||||||
: attribute_list_opt
|
: attribute_list_opt
|
||||||
K_input net_type_opt signed_opt range_opt IDENTIFIER
|
K_input net_type_opt signed_opt range_opt IDENTIFIER
|
||||||
{ Module::port_t*ptmp;
|
{ Module::port_t*ptmp;
|
||||||
ptmp = pform_module_port_reference($6, @2.text,
|
perm_string name = lex_strings.make($6);
|
||||||
@2.first_line);
|
ptmp = pform_module_port_reference(name, @2.text,
|
||||||
pform_module_define_port(@2, $6, NetNet::PINPUT,
|
@2.first_line);
|
||||||
$3, $4, $5, $1);
|
pform_module_define_port(@2, name, NetNet::PINPUT,
|
||||||
port_declaration_context.port_type = NetNet::PINPUT;
|
$3, $4, $5, $1);
|
||||||
port_declaration_context.port_net_type = $3;
|
port_declaration_context.port_type = NetNet::PINPUT;
|
||||||
port_declaration_context.sign_flag = $4;
|
port_declaration_context.port_net_type = $3;
|
||||||
port_declaration_context.range = $5;
|
port_declaration_context.sign_flag = $4;
|
||||||
delete $1;
|
port_declaration_context.range = $5;
|
||||||
delete $6;
|
delete $1;
|
||||||
$$ = ptmp;
|
delete $6;
|
||||||
}
|
$$ = ptmp;
|
||||||
| attribute_list_opt
|
}
|
||||||
K_inout net_type_opt signed_opt range_opt IDENTIFIER
|
| attribute_list_opt
|
||||||
{ Module::port_t*ptmp;
|
K_inout net_type_opt signed_opt range_opt IDENTIFIER
|
||||||
ptmp = pform_module_port_reference($6, @2.text,
|
{ Module::port_t*ptmp;
|
||||||
@2.first_line);
|
perm_string name = lex_strings.make($6);
|
||||||
pform_module_define_port(@2, $6, NetNet::PINOUT,
|
ptmp = pform_module_port_reference(name, @2.text,
|
||||||
$3, $4, $5, $1);
|
@2.first_line);
|
||||||
port_declaration_context.port_type = NetNet::PINOUT;
|
pform_module_define_port(@2, name, NetNet::PINOUT,
|
||||||
port_declaration_context.port_net_type = $3;
|
$3, $4, $5, $1);
|
||||||
port_declaration_context.sign_flag = $4;
|
port_declaration_context.port_type = NetNet::PINOUT;
|
||||||
port_declaration_context.range = $5;
|
port_declaration_context.port_net_type = $3;
|
||||||
delete $1;
|
port_declaration_context.sign_flag = $4;
|
||||||
delete $6;
|
port_declaration_context.range = $5;
|
||||||
$$ = ptmp;
|
delete $1;
|
||||||
}
|
delete $6;
|
||||||
| attribute_list_opt
|
$$ = ptmp;
|
||||||
K_output net_type_opt signed_opt range_opt IDENTIFIER
|
}
|
||||||
{ Module::port_t*ptmp;
|
| attribute_list_opt
|
||||||
ptmp = pform_module_port_reference($6, @2.text,
|
K_output net_type_opt signed_opt range_opt IDENTIFIER
|
||||||
@2.first_line);
|
{ Module::port_t*ptmp;
|
||||||
pform_module_define_port(@2, $6, NetNet::POUTPUT,
|
perm_string name = lex_strings.make($6);
|
||||||
$3, $4, $5, $1);
|
ptmp = pform_module_port_reference(name, @2.text,
|
||||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
@2.first_line);
|
||||||
port_declaration_context.port_net_type = $3;
|
pform_module_define_port(@2, name, NetNet::POUTPUT,
|
||||||
port_declaration_context.sign_flag = $4;
|
$3, $4, $5, $1);
|
||||||
port_declaration_context.range = $5;
|
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||||
delete $1;
|
port_declaration_context.port_net_type = $3;
|
||||||
delete $6;
|
port_declaration_context.sign_flag = $4;
|
||||||
$$ = ptmp;
|
port_declaration_context.range = $5;
|
||||||
}
|
delete $1;
|
||||||
| attribute_list_opt
|
delete $6;
|
||||||
K_output var_type signed_opt range_opt IDENTIFIER
|
$$ = ptmp;
|
||||||
{ Module::port_t*ptmp;
|
}
|
||||||
ptmp = pform_module_port_reference($6, @2.text,
|
| attribute_list_opt
|
||||||
@2.first_line);
|
K_output var_type signed_opt range_opt IDENTIFIER
|
||||||
pform_module_define_port(@2, $6, NetNet::POUTPUT,
|
{ Module::port_t*ptmp;
|
||||||
$3, $4, $5, $1);
|
perm_string name = lex_strings.make($6);
|
||||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
ptmp = pform_module_port_reference(name, @2.text,
|
||||||
port_declaration_context.port_net_type = $3;
|
@2.first_line);
|
||||||
port_declaration_context.sign_flag = $4;
|
pform_module_define_port(@2, name, NetNet::POUTPUT,
|
||||||
port_declaration_context.range = $5;
|
$3, $4, $5, $1);
|
||||||
delete $1;
|
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||||
delete $6;
|
port_declaration_context.port_net_type = $3;
|
||||||
$$ = ptmp;
|
port_declaration_context.sign_flag = $4;
|
||||||
}
|
port_declaration_context.range = $5;
|
||||||
| attribute_list_opt
|
delete $1;
|
||||||
K_output var_type signed_opt range_opt IDENTIFIER '=' expression
|
delete $6;
|
||||||
{ Module::port_t*ptmp;
|
$$ = ptmp;
|
||||||
ptmp = pform_module_port_reference($6, @2.text,
|
}
|
||||||
@2.first_line);
|
| attribute_list_opt
|
||||||
pform_module_define_port(@2, $6, NetNet::POUTPUT,
|
K_output var_type signed_opt range_opt IDENTIFIER '=' expression
|
||||||
$3, $4, $5, $1);
|
{ Module::port_t*ptmp;
|
||||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
perm_string name = lex_strings.make($6);
|
||||||
port_declaration_context.port_net_type = $3;
|
ptmp = pform_module_port_reference(name, @2.text,
|
||||||
port_declaration_context.sign_flag = $4;
|
@2.first_line);
|
||||||
port_declaration_context.range = $5;
|
pform_module_define_port(@2, name, NetNet::POUTPUT,
|
||||||
|
$3, $4, $5, $1);
|
||||||
|
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||||
|
port_declaration_context.port_net_type = $3;
|
||||||
|
port_declaration_context.sign_flag = $4;
|
||||||
|
port_declaration_context.range = $5;
|
||||||
|
|
||||||
if (! pform_expression_is_constant($8))
|
if (! pform_expression_is_constant($8))
|
||||||
yyerror(@8, "error: register declaration assignment"
|
yyerror(@8, "error: register declaration assignment"
|
||||||
" value must be a constant expression.");
|
" value must be a constant expression.");
|
||||||
pform_make_reginit(@6, $6, $8);
|
pform_make_reginit(@6, name, $8);
|
||||||
|
|
||||||
delete $1;
|
delete $1;
|
||||||
delete $6;
|
delete $6;
|
||||||
$$ = ptmp;
|
$$ = ptmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1849,7 +1842,8 @@ module_item
|
||||||
extension. */
|
extension. */
|
||||||
|
|
||||||
| K_task IDENTIFIER ';'
|
| K_task IDENTIFIER ';'
|
||||||
{ current_task = pform_push_task_scope($2);
|
{ assert(current_task == 0);
|
||||||
|
current_task = pform_push_task_scope($2);
|
||||||
FILE_NAME(current_task, @1);
|
FILE_NAME(current_task, @1);
|
||||||
}
|
}
|
||||||
task_item_list_opt
|
task_item_list_opt
|
||||||
|
|
@ -1863,7 +1857,8 @@ module_item
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_task IDENTIFIER
|
| K_task IDENTIFIER
|
||||||
{ current_task = pform_push_task_scope($2);
|
{ assert(current_task == 0);
|
||||||
|
current_task = pform_push_task_scope($2);
|
||||||
FILE_NAME(current_task, @1);
|
FILE_NAME(current_task, @1);
|
||||||
}
|
}
|
||||||
'(' task_port_decl_list ')' ';'
|
'(' task_port_decl_list ')' ';'
|
||||||
|
|
@ -1883,7 +1878,9 @@ module_item
|
||||||
instead of the module. */
|
instead of the module. */
|
||||||
|
|
||||||
| K_function function_range_or_type_opt IDENTIFIER ';'
|
| K_function function_range_or_type_opt IDENTIFIER ';'
|
||||||
{ current_function = pform_push_function_scope($3); }
|
{ assert(current_function == 0);
|
||||||
|
current_function = pform_push_function_scope($3);
|
||||||
|
}
|
||||||
function_item_list statement
|
function_item_list statement
|
||||||
K_endfunction
|
K_endfunction
|
||||||
{ current_function->set_ports($6);
|
{ current_function->set_ports($6);
|
||||||
|
|
@ -2037,14 +2034,15 @@ generate_block_opt : generate_block | ';' ;
|
||||||
side effect, and all I pass up is the name of the l-value. */
|
side effect, and all I pass up is the name of the l-value. */
|
||||||
|
|
||||||
net_decl_assign
|
net_decl_assign
|
||||||
: IDENTIFIER '=' expression
|
: IDENTIFIER '=' expression
|
||||||
{ net_decl_assign_t*tmp = new net_decl_assign_t;
|
{ net_decl_assign_t*tmp = new net_decl_assign_t;
|
||||||
tmp->next = tmp;
|
tmp->next = tmp;
|
||||||
tmp->name = $1;
|
tmp->name = lex_strings.make($1);
|
||||||
tmp->expr = $3;
|
tmp->expr = $3;
|
||||||
$$ = tmp;
|
delete $1;
|
||||||
}
|
$$ = tmp;
|
||||||
;
|
}
|
||||||
|
;
|
||||||
|
|
||||||
net_decl_assigns
|
net_decl_assigns
|
||||||
: net_decl_assigns ',' net_decl_assign
|
: net_decl_assigns ',' net_decl_assign
|
||||||
|
|
@ -2320,7 +2318,8 @@ port_reference
|
||||||
|
|
||||||
: IDENTIFIER
|
: IDENTIFIER
|
||||||
{ Module::port_t*ptmp;
|
{ Module::port_t*ptmp;
|
||||||
ptmp = pform_module_port_reference($1, @1.text, @1.first_line);
|
perm_string name = lex_strings.make($1);
|
||||||
|
ptmp = pform_module_port_reference(name, @1.text, @1.first_line);
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = ptmp;
|
$$ = ptmp;
|
||||||
}
|
}
|
||||||
|
|
@ -2530,32 +2529,33 @@ function_range_or_type_opt
|
||||||
handle it. The register variable list simply packs them together
|
handle it. The register variable list simply packs them together
|
||||||
so that bit ranges can be assigned. */
|
so that bit ranges can be assigned. */
|
||||||
register_variable
|
register_variable
|
||||||
: IDENTIFIER dimensions_opt
|
: IDENTIFIER dimensions_opt
|
||||||
{ pform_makewire(@1, $1, NetNet::REG,
|
{ perm_string ident_name = lex_strings.make($1);
|
||||||
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
|
pform_makewire(@1, ident_name, NetNet::REG,
|
||||||
if ($2 != 0) {
|
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
|
||||||
index_component_t index;
|
if ($2 != 0) {
|
||||||
if ($2->size() > 1) {
|
index_component_t index;
|
||||||
yyerror(@2, "sorry: only 1 dimensional arrays "
|
if ($2->size() > 1) {
|
||||||
"are currently supported.");
|
yyerror(@2, "sorry: only 1 dimensional arrays "
|
||||||
}
|
"are currently supported.");
|
||||||
index = $2->front();
|
}
|
||||||
pform_set_reg_idx($1, index.msb, index.lsb);
|
index = $2->front();
|
||||||
delete $2;
|
pform_set_reg_idx(ident_name, index.msb, index.lsb);
|
||||||
}
|
delete $2;
|
||||||
$$ = $1;
|
}
|
||||||
}
|
$$ = $1;
|
||||||
| IDENTIFIER '=' expression
|
}
|
||||||
{ pform_makewire(@1, $1, NetNet::REG,
|
| IDENTIFIER '=' expression
|
||||||
NetNet::NOT_A_PORT,
|
{ perm_string ident_name = lex_strings.make($1);
|
||||||
IVL_VT_NO_TYPE, 0);
|
pform_makewire(@1, ident_name, NetNet::REG,
|
||||||
if (! pform_expression_is_constant($3))
|
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
|
||||||
yyerror(@3, "error: register declaration assignment"
|
if (! pform_expression_is_constant($3))
|
||||||
" value must be a constant expression.");
|
yyerror(@3, "error: register declaration assignment"
|
||||||
pform_make_reginit(@1, $1, $3);
|
" value must be a constant expression.");
|
||||||
$$ = $1;
|
pform_make_reginit(@1, ident_name, $3);
|
||||||
}
|
$$ = $1;
|
||||||
;
|
}
|
||||||
|
;
|
||||||
|
|
||||||
register_variable_list
|
register_variable_list
|
||||||
: register_variable
|
: register_variable
|
||||||
|
|
@ -2574,16 +2574,18 @@ register_variable_list
|
||||||
|
|
||||||
real_variable
|
real_variable
|
||||||
: IDENTIFIER dimensions_opt
|
: IDENTIFIER dimensions_opt
|
||||||
{ pform_makewire(@1, $1, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_REAL, 0);
|
{ perm_string name = lex_strings.make($1);
|
||||||
|
pform_makewire(@1, name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_REAL, 0);
|
||||||
if ($2 != 0) {
|
if ($2 != 0) {
|
||||||
yyerror(@2, "sorry: real variables do not currently support arrays.");
|
yyerror(@2, "sorry: real variables do not currently support arrays.");
|
||||||
delete $2;
|
delete $2;
|
||||||
}
|
}
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| IDENTIFIER '=' expression
|
| IDENTIFIER '=' expression
|
||||||
{ pform_makewire(@1, $1, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_REAL, 0);
|
{ perm_string name = lex_strings.make($1);
|
||||||
pform_make_reginit(@1, $1, $3);
|
pform_makewire(@1, name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_REAL, 0);
|
||||||
|
pform_make_reginit(@1, name, $3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -2604,22 +2606,24 @@ real_variable_list
|
||||||
;
|
;
|
||||||
|
|
||||||
net_variable
|
net_variable
|
||||||
: IDENTIFIER dimensions_opt
|
: IDENTIFIER dimensions_opt
|
||||||
{ pform_makewire(@1, $1, NetNet::IMPLICIT,
|
{ perm_string name = lex_strings.make($1);
|
||||||
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
|
pform_makewire(@1, name, NetNet::IMPLICIT,
|
||||||
if ($2 != 0) {
|
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
|
||||||
index_component_t index;
|
if ($2 != 0) {
|
||||||
if ($2->size() > 1) {
|
index_component_t index;
|
||||||
yyerror(@2, "sorry: only 1 dimensional arrays "
|
if ($2->size() > 1) {
|
||||||
"are currently supported.");
|
yyerror(@2, "sorry: only 1 dimensional arrays "
|
||||||
}
|
"are currently supported.");
|
||||||
index = $2->front();
|
}
|
||||||
pform_set_reg_idx($1, index.msb, index.lsb);
|
index = $2->front();
|
||||||
delete $2;
|
pform_set_reg_idx(name, index.msb, index.lsb);
|
||||||
}
|
delete $2;
|
||||||
$$ = $1;
|
}
|
||||||
}
|
$$ = $1;
|
||||||
;
|
}
|
||||||
|
;
|
||||||
|
|
||||||
net_variable_list
|
net_variable_list
|
||||||
: net_variable
|
: net_variable
|
||||||
{ list<perm_string>*tmp = new list<perm_string>;
|
{ list<perm_string>*tmp = new list<perm_string>;
|
||||||
|
|
@ -2970,16 +2974,20 @@ statement
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_begin ':' IDENTIFIER
|
| K_begin ':' IDENTIFIER
|
||||||
{ current_block = pform_push_block_scope($3, PBlock::BL_SEQ);
|
{ PBlock*tmp = pform_push_block_scope($3, PBlock::BL_SEQ);
|
||||||
FILE_NAME(current_block, @1);
|
FILE_NAME(tmp, @1);
|
||||||
|
current_block_stack.push(tmp);
|
||||||
}
|
}
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
statement_list K_end
|
statement_list K_end
|
||||||
{ pform_pop_scope();
|
{ pform_pop_scope();
|
||||||
current_block->set_statement(*$6);
|
assert(! current_block_stack.empty());
|
||||||
|
PBlock*tmp = current_block_stack.top();
|
||||||
|
current_block_stack.pop();
|
||||||
|
tmp->set_statement(*$6);
|
||||||
delete $3;
|
delete $3;
|
||||||
delete $6;
|
delete $6;
|
||||||
$$ = current_block;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_begin K_end
|
| K_begin K_end
|
||||||
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
||||||
|
|
@ -3000,16 +3008,20 @@ statement
|
||||||
code generator can do the right thing. */
|
code generator can do the right thing. */
|
||||||
|
|
||||||
| K_fork ':' IDENTIFIER
|
| K_fork ':' IDENTIFIER
|
||||||
{ current_block = pform_push_block_scope($3, PBlock::BL_PAR);
|
{ PBlock*tmp = pform_push_block_scope($3, PBlock::BL_PAR);
|
||||||
FILE_NAME(current_block, @1);
|
FILE_NAME(tmp, @1);
|
||||||
|
current_block_stack.push(tmp);
|
||||||
}
|
}
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
statement_list K_join
|
statement_list K_join
|
||||||
{ pform_pop_scope();
|
{ pform_pop_scope();
|
||||||
current_block->set_statement(*$6);
|
assert(! current_block_stack.empty());
|
||||||
|
PBlock*tmp = current_block_stack.top();
|
||||||
|
current_block_stack.pop();
|
||||||
|
tmp->set_statement(*$6);
|
||||||
delete $3;
|
delete $3;
|
||||||
delete $6;
|
delete $6;
|
||||||
$$ = current_block;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_fork K_join
|
| K_fork K_join
|
||||||
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
|
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
|
||||||
|
|
@ -3672,35 +3684,32 @@ udp_output_sym
|
||||||
makes for these ports are scoped within the UDP, so there is no
|
makes for these ports are scoped within the UDP, so there is no
|
||||||
hierarchy involved. */
|
hierarchy involved. */
|
||||||
udp_port_decl
|
udp_port_decl
|
||||||
: K_input list_of_identifiers ';'
|
: K_input list_of_identifiers ';'
|
||||||
{ $$ = pform_make_udp_input_ports($2); }
|
{ $$ = pform_make_udp_input_ports($2); }
|
||||||
| K_output IDENTIFIER ';'
|
| K_output IDENTIFIER ';'
|
||||||
{ pform_name_t pname;
|
{ perm_string pname = lex_strings.make($2);
|
||||||
pname.push_back(name_component_t(lex_strings.make($2)));
|
PWire*pp = new PWire(pname, NetNet::IMPLICIT, NetNet::POUTPUT, IVL_VT_LOGIC);
|
||||||
PWire*pp = new PWire(pname, NetNet::IMPLICIT, NetNet::POUTPUT, IVL_VT_LOGIC);
|
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
(*tmp)[0] = pp;
|
||||||
(*tmp)[0] = pp;
|
$$ = tmp;
|
||||||
$$ = tmp;
|
delete $2;
|
||||||
delete $2;
|
}
|
||||||
}
|
| K_reg IDENTIFIER ';'
|
||||||
| K_reg IDENTIFIER ';'
|
{ perm_string pname = lex_strings.make($2);
|
||||||
{ pform_name_t pname;
|
PWire*pp = new PWire(pname, NetNet::REG, NetNet::PIMPLICIT, IVL_VT_LOGIC);
|
||||||
pname.push_back(name_component_t(lex_strings.make($2)));
|
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||||
PWire*pp = new PWire(pname, NetNet::REG, NetNet::PIMPLICIT, IVL_VT_LOGIC);
|
(*tmp)[0] = pp;
|
||||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
$$ = tmp;
|
||||||
(*tmp)[0] = pp;
|
delete $2;
|
||||||
$$ = tmp;
|
}
|
||||||
delete $2;
|
| K_reg K_output IDENTIFIER ';'
|
||||||
}
|
{ perm_string pname = lex_strings.make($3);
|
||||||
| K_reg K_output IDENTIFIER ';'
|
PWire*pp = new PWire(pname, NetNet::REG, NetNet::POUTPUT, IVL_VT_LOGIC);
|
||||||
{ pform_name_t pname;
|
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||||
pname.push_back(name_component_t(lex_strings.make($3)));
|
(*tmp)[0] = pp;
|
||||||
PWire*pp = new PWire(pname, NetNet::REG, NetNet::POUTPUT, IVL_VT_LOGIC);
|
$$ = tmp;
|
||||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
delete $3;
|
||||||
(*tmp)[0] = pp;
|
}
|
||||||
$$ = tmp;
|
|
||||||
delete $3;
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
udp_port_decls
|
udp_port_decls
|
||||||
|
|
@ -3715,19 +3724,19 @@ udp_port_decls
|
||||||
;
|
;
|
||||||
|
|
||||||
udp_port_list
|
udp_port_list
|
||||||
: IDENTIFIER
|
: IDENTIFIER
|
||||||
{ list<string>*tmp = new list<string>;
|
{ list<perm_string>*tmp = new list<perm_string>;
|
||||||
tmp->push_back($1);
|
tmp->push_back(lex_strings.make($1));
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| udp_port_list ',' IDENTIFIER
|
| udp_port_list ',' IDENTIFIER
|
||||||
{ list<string>*tmp = $1;
|
{ list<perm_string>*tmp = $1;
|
||||||
tmp->push_back($3);
|
tmp->push_back(lex_strings.make($3));
|
||||||
delete $3;
|
delete $3;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
udp_reg_opt: K_reg { $$ = true; } | { $$ = false; };
|
udp_reg_opt: K_reg { $$ = true; } | { $$ = false; };
|
||||||
|
|
||||||
|
|
|
||||||
193
pform.cc
193
pform.cc
|
|
@ -89,44 +89,21 @@ static inline void FILE_NAME(LineInfo*tmp, const struct vlltype&where)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scope stack and the following functions handle the processing
|
* The lexical_scope keeps track of the current lexical scope that is
|
||||||
* of scope. As I enter a scope, the push function is called, and as I
|
* being parsed. The lexical scope may stack, so the current scope may
|
||||||
* leave a scope the pop function is called. Entering tasks, functions
|
* have a parent, that is restored when the current scope ends.
|
||||||
* and named blocks causes scope to be pushed and popped. The module
|
|
||||||
* name is not included in this scope stack.
|
|
||||||
*
|
*
|
||||||
* The hier_name function, therefore, converts the name to the scoped
|
* Items that have scoped names are put in the lexical_scope object.
|
||||||
* name within the module currently in progress. It never includes an
|
|
||||||
* instance name.
|
|
||||||
*
|
|
||||||
* The scope stack does not include any scope created by a generate
|
|
||||||
* scheme.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static pform_name_t scope_stack;
|
|
||||||
static PScope* lexical_scope = 0;
|
static PScope* lexical_scope = 0;
|
||||||
|
|
||||||
void pform_push_scope(char*name)
|
|
||||||
{
|
|
||||||
scope_stack.push_back(name_component_t(lex_strings.make(name)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void pform_pop_scope()
|
void pform_pop_scope()
|
||||||
{
|
{
|
||||||
scope_stack.pop_back();
|
|
||||||
lexical_scope = lexical_scope->pscope_parent();
|
lexical_scope = lexical_scope->pscope_parent();
|
||||||
}
|
}
|
||||||
|
|
||||||
static pform_name_t hier_name(const char*tail)
|
|
||||||
{
|
|
||||||
pform_name_t name = scope_stack;
|
|
||||||
name.push_back(name_component_t(lex_strings.make(tail)));
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTask* pform_push_task_scope(char*name)
|
PTask* pform_push_task_scope(char*name)
|
||||||
{
|
{
|
||||||
pform_push_scope(name);
|
|
||||||
perm_string task_name = lex_strings.make(name);
|
perm_string task_name = lex_strings.make(name);
|
||||||
PTask*task = new PTask(task_name, pform_cur_module);
|
PTask*task = new PTask(task_name, pform_cur_module);
|
||||||
|
|
||||||
|
|
@ -139,7 +116,6 @@ PTask* pform_push_task_scope(char*name)
|
||||||
|
|
||||||
PFunction* pform_push_function_scope(char*name)
|
PFunction* pform_push_function_scope(char*name)
|
||||||
{
|
{
|
||||||
pform_push_scope(name);
|
|
||||||
perm_string func_name = lex_strings.make(name);
|
perm_string func_name = lex_strings.make(name);
|
||||||
PFunction*func = new PFunction(func_name, lexical_scope);
|
PFunction*func = new PFunction(func_name, lexical_scope);
|
||||||
|
|
||||||
|
|
@ -152,14 +128,16 @@ PFunction* pform_push_function_scope(char*name)
|
||||||
|
|
||||||
PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
|
PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
|
||||||
{
|
{
|
||||||
pform_push_scope(name);
|
|
||||||
perm_string block_name = lex_strings.make(name);
|
perm_string block_name = lex_strings.make(name);
|
||||||
PBlock*block = new PBlock(block_name, lexical_scope, bt);
|
PBlock*block = new PBlock(block_name, lexical_scope, bt);
|
||||||
|
|
||||||
|
// Make this the current lexical scope
|
||||||
|
lexical_scope = block;
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PWire*get_wire_in_module(const pform_name_t&name)
|
static PWire*get_wire_in_scope(perm_string name)
|
||||||
{
|
{
|
||||||
/* Note that if we are processing a generate, then the
|
/* Note that if we are processing a generate, then the
|
||||||
scope depth will be empty because generate schemes
|
scope depth will be empty because generate schemes
|
||||||
|
|
@ -168,7 +146,7 @@ static PWire*get_wire_in_module(const pform_name_t&name)
|
||||||
if (pform_cur_generate)
|
if (pform_cur_generate)
|
||||||
return pform_cur_generate->get_wire(name);
|
return pform_cur_generate->get_wire(name);
|
||||||
|
|
||||||
return pform_cur_module->get_wire(name);
|
return lexical_scope->wires_find(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_default_nettype(NetNet::Type type,
|
void pform_set_default_nettype(NetNet::Type type,
|
||||||
|
|
@ -297,6 +275,9 @@ void pform_startmodule(const char*name, const char*file, unsigned lineno,
|
||||||
FILE_NAME(pform_cur_module, file, lineno);
|
FILE_NAME(pform_cur_module, file, lineno);
|
||||||
pform_cur_module->library_flag = pform_library_flag;
|
pform_cur_module->library_flag = pform_library_flag;
|
||||||
|
|
||||||
|
ivl_assert(*pform_cur_module, lexical_scope == 0);
|
||||||
|
lexical_scope = pform_cur_module;
|
||||||
|
|
||||||
/* The generate scheme numbering starts with *1*, not
|
/* The generate scheme numbering starts with *1*, not
|
||||||
zero. That's just the way it is, thanks to the standard. */
|
zero. That's just the way it is, thanks to the standard. */
|
||||||
scope_generate_counter = 1;
|
scope_generate_counter = 1;
|
||||||
|
|
@ -323,14 +304,14 @@ void pform_startmodule(const char*name, const char*file, unsigned lineno,
|
||||||
* reference. This is a name without a .X(...), so the internal name
|
* reference. This is a name without a .X(...), so the internal name
|
||||||
* should be generated to be the same as the X.
|
* should be generated to be the same as the X.
|
||||||
*/
|
*/
|
||||||
Module::port_t* pform_module_port_reference(char*name,
|
Module::port_t* pform_module_port_reference(perm_string name,
|
||||||
const char*file,
|
const char*file,
|
||||||
unsigned lineno)
|
unsigned lineno)
|
||||||
{
|
{
|
||||||
Module::port_t*ptmp = new Module::port_t;
|
Module::port_t*ptmp = new Module::port_t;
|
||||||
PEIdent*tmp = new PEIdent(lex_strings.make(name));
|
PEIdent*tmp = new PEIdent(name);
|
||||||
FILE_NAME(tmp, file, lineno);
|
FILE_NAME(tmp, file, lineno);
|
||||||
ptmp->name = lex_strings.make(name);
|
ptmp->name = name;
|
||||||
ptmp->expr = svector<PEIdent*>(1);
|
ptmp->expr = svector<PEIdent*>(1);
|
||||||
ptmp->expr[0] = tmp;
|
ptmp->expr[0] = tmp;
|
||||||
|
|
||||||
|
|
@ -372,6 +353,13 @@ void pform_endmodule(const char*name)
|
||||||
pform_cur_module = 0;
|
pform_cur_module = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The current lexical scope should be this module by now, and
|
||||||
|
// this module should not have a parent lexical scope.
|
||||||
|
ivl_assert(*pform_cur_module, lexical_scope == pform_cur_module);
|
||||||
|
lexical_scope = pform_cur_module->pscope_parent();
|
||||||
|
ivl_assert(*pform_cur_module, lexical_scope == 0);
|
||||||
|
|
||||||
pform_modules[mod_name] = pform_cur_module;
|
pform_modules[mod_name] = pform_cur_module;
|
||||||
pform_cur_module = 0;
|
pform_cur_module = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -583,6 +571,11 @@ PExpr* pform_select_mtm_expr(PExpr*min, PExpr*typ, PExpr*max)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <> inline svector<perm_string>::svector(unsigned size)
|
||||||
|
: nitems_(size), items_(new perm_string[size])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static void process_udp_table(PUdp*udp, list<string>*table,
|
static void process_udp_table(PUdp*udp, list<string>*table,
|
||||||
const char*file, unsigned lineno)
|
const char*file, unsigned lineno)
|
||||||
{
|
{
|
||||||
|
|
@ -650,7 +643,7 @@ static void process_udp_table(PUdp*udp, list<string>*table,
|
||||||
udp->toutput = output;
|
udp->toutput = output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_make_udp(perm_string name, list<string>*parms,
|
void pform_make_udp(perm_string name, list<perm_string>*parms,
|
||||||
svector<PWire*>*decl, list<string>*table,
|
svector<PWire*>*decl, list<string>*table,
|
||||||
Statement*init_expr,
|
Statement*init_expr,
|
||||||
const char*file, unsigned lineno)
|
const char*file, unsigned lineno)
|
||||||
|
|
@ -662,11 +655,10 @@ void pform_make_udp(perm_string name, list<string>*parms,
|
||||||
off with the parameters in the list. If the port is already
|
off with the parameters in the list. If the port is already
|
||||||
in the map, merge the port type. I will rebuild a list
|
in the map, merge the port type. I will rebuild a list
|
||||||
of parameters for the PUdp object. */
|
of parameters for the PUdp object. */
|
||||||
map<string,PWire*> defs;
|
map<perm_string,PWire*> defs;
|
||||||
for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) {
|
||||||
|
|
||||||
pform_name_t pname = (*decl)[idx]->path();
|
perm_string port_name = (*decl)[idx]->basename();
|
||||||
string port_name = peek_tail_name(pname).str();
|
|
||||||
|
|
||||||
if (PWire*cur = defs[port_name]) {
|
if (PWire*cur = defs[port_name]) {
|
||||||
bool rc = true;
|
bool rc = true;
|
||||||
|
|
@ -692,8 +684,8 @@ void pform_make_udp(perm_string name, list<string>*parms,
|
||||||
UDP declaration, and the defs map maps that name to a
|
UDP declaration, and the defs map maps that name to a
|
||||||
PWire* created by an input or output declaration. */
|
PWire* created by an input or output declaration. */
|
||||||
svector<PWire*> pins (parms->size());
|
svector<PWire*> pins (parms->size());
|
||||||
svector<string> pin_names (parms->size());
|
svector<perm_string> pin_names (parms->size());
|
||||||
{ list<string>::iterator cur;
|
{ list<perm_string>::iterator cur;
|
||||||
unsigned idx;
|
unsigned idx;
|
||||||
for (cur = parms->begin(), idx = 0
|
for (cur = parms->begin(), idx = 0
|
||||||
; cur != parms->end()
|
; cur != parms->end()
|
||||||
|
|
@ -827,7 +819,7 @@ void pform_make_udp(perm_string name, list<string>*parms,
|
||||||
|
|
||||||
// Make the port list for the UDP
|
// Make the port list for the UDP
|
||||||
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
|
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
|
||||||
udp->ports[idx] = peek_tail_name(pins[idx]->path());
|
udp->ports[idx] = pins[idx]->basename();
|
||||||
|
|
||||||
process_udp_table(udp, table, file, lineno);
|
process_udp_table(udp, table, file, lineno);
|
||||||
udp->initial = init;
|
udp->initial = init;
|
||||||
|
|
@ -852,10 +844,9 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
|
||||||
svector<PWire*> pins(parms->size() + 1);
|
svector<PWire*> pins(parms->size() + 1);
|
||||||
|
|
||||||
/* Make the PWire for the output port. */
|
/* Make the PWire for the output port. */
|
||||||
pins[0] = new PWire(hier_name(out_name),
|
pins[0] = new PWire(out_name,
|
||||||
synchronous_flag? NetNet::REG : NetNet::WIRE,
|
synchronous_flag? NetNet::REG : NetNet::WIRE,
|
||||||
NetNet::POUTPUT,
|
NetNet::POUTPUT, IVL_VT_LOGIC);
|
||||||
IVL_VT_LOGIC);
|
|
||||||
FILE_NAME(pins[0], file, lineno);
|
FILE_NAME(pins[0], file, lineno);
|
||||||
|
|
||||||
/* Make the PWire objects for the input ports. */
|
/* Make the PWire objects for the input ports. */
|
||||||
|
|
@ -865,10 +856,8 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
|
||||||
; cur != parms->end()
|
; cur != parms->end()
|
||||||
; idx += 1, cur++) {
|
; idx += 1, cur++) {
|
||||||
assert(idx < pins.count());
|
assert(idx < pins.count());
|
||||||
pins[idx] = new PWire(hier_name(*cur),
|
pins[idx] = new PWire(*cur, NetNet::WIRE,
|
||||||
NetNet::WIRE,
|
NetNet::PINPUT, IVL_VT_LOGIC);
|
||||||
NetNet::PINPUT,
|
|
||||||
IVL_VT_LOGIC);
|
|
||||||
FILE_NAME(pins[idx], file, lineno);
|
FILE_NAME(pins[idx], file, lineno);
|
||||||
}
|
}
|
||||||
assert(idx == pins.count());
|
assert(idx == pins.count());
|
||||||
|
|
@ -909,7 +898,7 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
|
||||||
|
|
||||||
// Make the port list for the UDP
|
// Make the port list for the UDP
|
||||||
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
|
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
|
||||||
udp->ports[idx] = peek_tail_name(pins[idx]->path());
|
udp->ports[idx] = pins[idx]->basename();
|
||||||
|
|
||||||
assert(udp);
|
assert(udp);
|
||||||
assert(table);
|
assert(table);
|
||||||
|
|
@ -924,39 +913,18 @@ void pform_make_udp(perm_string name, bool synchronous_flag,
|
||||||
delete init_expr;
|
delete init_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function is used to set the net range for a port that uses
|
|
||||||
* the new (1364-2001) list_of_port_declarations, but omitted a
|
|
||||||
* register/wire/etc. that would have triggered it to be set elsewhere.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Since implicitly defined list of port declarations are no longer
|
|
||||||
* considered fully defined we no longer need this routine to force
|
|
||||||
* them to be fully defined.
|
|
||||||
*
|
|
||||||
void pform_set_net_range(const char* name)
|
|
||||||
{
|
|
||||||
PWire*cur = get_wire_in_module(hier_name(name));
|
|
||||||
if (cur == 0) {
|
|
||||||
VLerror("error: name is not a valid net.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cur->set_net_range();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function attaches a range to a given name. The function is
|
* This function attaches a range to a given name. The function is
|
||||||
* only called by the parser within the scope of the net declaration,
|
* only called by the parser within the scope of the net declaration,
|
||||||
* and the name that I receive only has the tail component.
|
* and the name that I receive only has the tail component.
|
||||||
*/
|
*/
|
||||||
static void pform_set_net_range(const char* name,
|
static void pform_set_net_range(perm_string name,
|
||||||
const svector<PExpr*>*range,
|
const svector<PExpr*>*range,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
ivl_variable_type_t dt,
|
ivl_variable_type_t dt,
|
||||||
PWSRType rt)
|
PWSRType rt)
|
||||||
{
|
{
|
||||||
PWire*cur = get_wire_in_module(hier_name(name));
|
PWire*cur = get_wire_in_scope(name);
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
VLerror("error: name is not a valid net.");
|
VLerror("error: name is not a valid net.");
|
||||||
return;
|
return;
|
||||||
|
|
@ -1271,17 +1239,16 @@ void pform_make_pgassign_list(svector<PExpr*>*alist,
|
||||||
* BTF-B14.
|
* BTF-B14.
|
||||||
*/
|
*/
|
||||||
void pform_make_reginit(const struct vlltype&li,
|
void pform_make_reginit(const struct vlltype&li,
|
||||||
const char*name, PExpr*expr)
|
perm_string name, PExpr*expr)
|
||||||
{
|
{
|
||||||
const pform_name_t sname = hier_name(name);
|
PWire*cur = lexical_scope->wires_find(name);
|
||||||
PWire*cur = pform_cur_module->get_wire(sname);
|
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
VLerror(li, "internal error: reginit to non-register?");
|
VLerror(li, "internal error: reginit to non-register?");
|
||||||
delete expr;
|
delete expr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PEIdent*lval = new PEIdent(sname);
|
PEIdent*lval = new PEIdent(name);
|
||||||
FILE_NAME(lval, li);
|
FILE_NAME(lval, li);
|
||||||
PAssign*ass = new PAssign(lval, expr);
|
PAssign*ass = new PAssign(lval, expr);
|
||||||
FILE_NAME(ass, li);
|
FILE_NAME(ass, li);
|
||||||
|
|
@ -1302,18 +1269,17 @@ void pform_make_reginit(const struct vlltype&li,
|
||||||
* as is done for the old method.
|
* as is done for the old method.
|
||||||
*/
|
*/
|
||||||
void pform_module_define_port(const struct vlltype&li,
|
void pform_module_define_port(const struct vlltype&li,
|
||||||
const char*nm,
|
perm_string name,
|
||||||
NetNet::PortType port_type,
|
NetNet::PortType port_type,
|
||||||
NetNet::Type type,
|
NetNet::Type type,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
svector<PExpr*>*range,
|
svector<PExpr*>*range,
|
||||||
svector<named_pexpr_t*>*attr)
|
svector<named_pexpr_t*>*attr)
|
||||||
{
|
{
|
||||||
pform_name_t name = hier_name(nm);
|
PWire*cur = lexical_scope->wires_find(name);
|
||||||
PWire*cur = pform_cur_module->get_wire(name);
|
|
||||||
if (cur) {
|
if (cur) {
|
||||||
ostringstream msg;
|
ostringstream msg;
|
||||||
msg << nm << " definition conflicts with "
|
msg << name << " definition conflicts with "
|
||||||
<< "definition at " << cur->get_fileline()
|
<< "definition at " << cur->get_fileline()
|
||||||
<< ".";
|
<< ".";
|
||||||
VLerror(msg.str().c_str());
|
VLerror(msg.str().c_str());
|
||||||
|
|
@ -1344,7 +1310,7 @@ void pform_module_define_port(const struct vlltype&li,
|
||||||
cur->attributes[tmp->name] = tmp->parm;
|
cur->attributes[tmp->name] = tmp->parm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pform_cur_module->add_wire(cur);
|
lexical_scope->wires[name] = cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1372,14 +1338,12 @@ void pform_module_define_port(const struct vlltype&li,
|
||||||
* the variable/net. Other forms of pform_makewire ultimately call
|
* the variable/net. Other forms of pform_makewire ultimately call
|
||||||
* this one to create the wire and stash it.
|
* this one to create the wire and stash it.
|
||||||
*/
|
*/
|
||||||
void pform_makewire(const vlltype&li, const char*nm,
|
void pform_makewire(const vlltype&li, perm_string name,
|
||||||
NetNet::Type type, NetNet::PortType pt,
|
NetNet::Type type, NetNet::PortType pt,
|
||||||
ivl_variable_type_t dt,
|
ivl_variable_type_t dt,
|
||||||
svector<named_pexpr_t*>*attr)
|
svector<named_pexpr_t*>*attr)
|
||||||
{
|
{
|
||||||
pform_name_t name = hier_name(nm);
|
PWire*cur = get_wire_in_scope(name);
|
||||||
|
|
||||||
PWire*cur = get_wire_in_module(name);
|
|
||||||
|
|
||||||
// If this is not implicit ("implicit" meaning we don't know
|
// If this is not implicit ("implicit" meaning we don't know
|
||||||
// what the type is yet) then set the type now.
|
// what the type is yet) then set the type now.
|
||||||
|
|
@ -1387,7 +1351,7 @@ void pform_makewire(const vlltype&li, const char*nm,
|
||||||
bool rc = cur->set_wire_type(type);
|
bool rc = cur->set_wire_type(type);
|
||||||
if (rc == false) {
|
if (rc == false) {
|
||||||
ostringstream msg;
|
ostringstream msg;
|
||||||
msg << nm << " definition conflicts with "
|
msg << name << " definition conflicts with "
|
||||||
<< "definition at " << cur->get_fileline()
|
<< "definition at " << cur->get_fileline()
|
||||||
<< ".";
|
<< ".";
|
||||||
VLerror(msg.str().c_str());
|
VLerror(msg.str().c_str());
|
||||||
|
|
@ -1431,9 +1395,9 @@ void pform_makewire(const vlltype&li, const char*nm,
|
||||||
|
|
||||||
if (new_wire_flag) {
|
if (new_wire_flag) {
|
||||||
if (pform_cur_generate)
|
if (pform_cur_generate)
|
||||||
pform_cur_generate->add_wire(cur);
|
pform_cur_generate->wires[name] = cur;
|
||||||
else
|
else
|
||||||
pform_cur_module->add_wire(cur);
|
lexical_scope->wires[name] = cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1493,32 +1457,28 @@ void pform_makewire(const vlltype&li,
|
||||||
SR_NET);
|
SR_NET);
|
||||||
}
|
}
|
||||||
|
|
||||||
perm_string first_name = lex_strings.make(first->name);
|
PWire*cur = get_wire_in_scope(first->name);
|
||||||
pform_name_t name = hier_name(first_name);
|
|
||||||
PWire*cur = get_wire_in_module(name);
|
|
||||||
if (cur != 0) {
|
if (cur != 0) {
|
||||||
PEIdent*lval = new PEIdent(first_name);
|
PEIdent*lval = new PEIdent(first->name);
|
||||||
FILE_NAME(lval, li.text, li.first_line);
|
FILE_NAME(lval, li.text, li.first_line);
|
||||||
PGAssign*ass = pform_make_pgassign(lval, first->expr,
|
PGAssign*ass = pform_make_pgassign(lval, first->expr,
|
||||||
delay, str);
|
delay, str);
|
||||||
FILE_NAME(ass, li.text, li.first_line);
|
FILE_NAME(ass, li.text, li.first_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(first->name);
|
|
||||||
delete first;
|
delete first;
|
||||||
first = next;
|
first = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_port_type(perm_string nm, NetNet::PortType pt,
|
void pform_set_port_type(perm_string name, NetNet::PortType pt,
|
||||||
const char*file, unsigned lineno)
|
const char*file, unsigned lineno)
|
||||||
{
|
{
|
||||||
pform_name_t name = hier_name(nm);
|
PWire*cur = lexical_scope->wires_find(name);
|
||||||
PWire*cur = pform_cur_module->get_wire(name);
|
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT, IVL_VT_NO_TYPE);
|
cur = new PWire(name, NetNet::IMPLICIT, NetNet::PIMPLICIT, IVL_VT_NO_TYPE);
|
||||||
FILE_NAME(cur, file, lineno);
|
FILE_NAME(cur, file, lineno);
|
||||||
pform_cur_module->add_wire(cur);
|
lexical_scope->wires[name] = cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cur->get_port_type()) {
|
switch (cur->get_port_type()) {
|
||||||
|
|
@ -1529,14 +1489,14 @@ void pform_set_port_type(perm_string nm, NetNet::PortType pt,
|
||||||
|
|
||||||
case NetNet::NOT_A_PORT:
|
case NetNet::NOT_A_PORT:
|
||||||
cerr << file << ":" << lineno << ": error: "
|
cerr << file << ":" << lineno << ": error: "
|
||||||
<< "port " << nm << " is not in the port list."
|
<< "port " << name << " is not in the port list."
|
||||||
<< endl;
|
<< endl;
|
||||||
error_count += 1;
|
error_count += 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cerr << file << ":" << lineno << ": error: "
|
cerr << file << ":" << lineno << ": error: "
|
||||||
<< "port " << nm << " already has a port declaration."
|
<< "port " << name << " already has a port declaration."
|
||||||
<< endl;
|
<< endl;
|
||||||
error_count += 1;
|
error_count += 1;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1596,18 +1556,17 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
||||||
for (list<perm_string>::iterator cur = names->begin()
|
for (list<perm_string>::iterator cur = names->begin()
|
||||||
; cur != names->end() ; cur ++ ) {
|
; cur != names->end() ; cur ++ ) {
|
||||||
|
|
||||||
perm_string txt = *cur;
|
perm_string name = *cur;
|
||||||
pform_name_t name = hier_name(txt);
|
|
||||||
|
|
||||||
/* Look for a preexisting wire. If it exists, set the
|
/* Look for a preexisting wire. If it exists, set the
|
||||||
port direction. If not, create it. */
|
port direction. If not, create it. */
|
||||||
PWire*curw = pform_cur_module->get_wire(name);
|
PWire*curw = lexical_scope->wires_find(name);
|
||||||
if (curw) {
|
if (curw) {
|
||||||
curw->set_port_type(pt);
|
curw->set_port_type(pt);
|
||||||
} else {
|
} else {
|
||||||
curw = new PWire(name, NetNet::IMPLICIT_REG, pt, vtype);
|
curw = new PWire(name, NetNet::IMPLICIT_REG, pt, vtype);
|
||||||
FILE_NAME(curw, file, lineno);
|
FILE_NAME(curw, file, lineno);
|
||||||
pform_cur_module->add_wire(curw);
|
lexical_scope->wires[name] = curw;
|
||||||
}
|
}
|
||||||
|
|
||||||
curw->set_signed(signed_flag);
|
curw->set_signed(signed_flag);
|
||||||
|
|
@ -1630,9 +1589,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
||||||
|
|
||||||
void pform_set_attrib(perm_string name, perm_string key, char*value)
|
void pform_set_attrib(perm_string name, perm_string key, char*value)
|
||||||
{
|
{
|
||||||
pform_name_t path = hier_name(name);
|
if (PWire*cur = lexical_scope->wires_find(name)) {
|
||||||
|
|
||||||
if (PWire*cur = pform_cur_module->get_wire(path)) {
|
|
||||||
cur->attributes[key] = new PEString(value);
|
cur->attributes[key] = new PEString(value);
|
||||||
|
|
||||||
} else if (PGate*cur = pform_cur_module->get_gate(name)) {
|
} else if (PGate*cur = pform_cur_module->get_gate(name)) {
|
||||||
|
|
@ -1666,13 +1623,13 @@ void pform_set_type_attrib(perm_string name, const string&key,
|
||||||
* This function attaches a memory index range to an existing
|
* This function attaches a memory index range to an existing
|
||||||
* register. (The named wire must be a register.
|
* register. (The named wire must be a register.
|
||||||
*/
|
*/
|
||||||
void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r)
|
void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r)
|
||||||
{
|
{
|
||||||
PWire*cur = 0;
|
PWire*cur = 0;
|
||||||
if (pform_cur_generate) {
|
if (pform_cur_generate) {
|
||||||
cur = pform_cur_generate->get_wire(hier_name(name));
|
cur = pform_cur_generate->get_wire(name);
|
||||||
} else {
|
} else {
|
||||||
cur = pform_cur_module->get_wire(hier_name(name));
|
cur = lexical_scope->wires_find(name);
|
||||||
}
|
}
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
VLerror("internal error: name is not a valid memory for index.");
|
VLerror("internal error: name is not a valid memory for index.");
|
||||||
|
|
@ -1819,16 +1776,15 @@ void pform_set_port_type(const struct vlltype&li,
|
||||||
delete range;
|
delete range;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pform_set_reg_integer(const char*nm)
|
static void pform_set_reg_integer(perm_string name)
|
||||||
{
|
{
|
||||||
pform_name_t name = hier_name(nm);
|
PWire*cur = lexical_scope->wires_find(name);
|
||||||
PWire*cur = pform_cur_module->get_wire(name);
|
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
cur = new PWire(name, NetNet::INTEGER,
|
cur = new PWire(name, NetNet::INTEGER,
|
||||||
NetNet::NOT_A_PORT,
|
NetNet::NOT_A_PORT,
|
||||||
IVL_VT_LOGIC);
|
IVL_VT_LOGIC);
|
||||||
cur->set_signed(true);
|
cur->set_signed(true);
|
||||||
pform_cur_module->add_wire(cur);
|
lexical_scope->wires[name] = cur;
|
||||||
} else {
|
} else {
|
||||||
bool rc = cur->set_wire_type(NetNet::INTEGER);
|
bool rc = cur->set_wire_type(NetNet::INTEGER);
|
||||||
assert(rc);
|
assert(rc);
|
||||||
|
|
@ -1854,13 +1810,12 @@ void pform_set_reg_integer(list<perm_string>*names)
|
||||||
delete names;
|
delete names;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pform_set_reg_time(const char*nm)
|
static void pform_set_reg_time(perm_string name)
|
||||||
{
|
{
|
||||||
pform_name_t name = hier_name(nm);
|
PWire*cur = lexical_scope->wires_find(name);
|
||||||
PWire*cur = pform_cur_module->get_wire(name);
|
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
||||||
pform_cur_module->add_wire(cur);
|
lexical_scope->wires[name] = cur;
|
||||||
} else {
|
} else {
|
||||||
bool rc = cur->set_wire_type(NetNet::REG);
|
bool rc = cur->set_wire_type(NetNet::REG);
|
||||||
assert(rc);
|
assert(rc);
|
||||||
|
|
@ -1894,9 +1849,7 @@ svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*names)
|
||||||
; cur != names->end()
|
; cur != names->end()
|
||||||
; cur ++ ) {
|
; cur ++ ) {
|
||||||
perm_string txt = *cur;
|
perm_string txt = *cur;
|
||||||
pform_name_t tmp;
|
PWire*pp = new PWire(txt,
|
||||||
tmp.push_back(name_component_t(txt));
|
|
||||||
PWire*pp = new PWire(tmp,
|
|
||||||
NetNet::IMPLICIT,
|
NetNet::IMPLICIT,
|
||||||
NetNet::PINPUT,
|
NetNet::PINPUT,
|
||||||
IVL_VT_LOGIC);
|
IVL_VT_LOGIC);
|
||||||
|
|
|
||||||
15
pform.h
15
pform.h
|
|
@ -95,7 +95,7 @@ struct parmvalue_t {
|
||||||
struct str_pair_t { PGate::strength_t str0, str1; };
|
struct str_pair_t { PGate::strength_t str0, str1; };
|
||||||
|
|
||||||
struct net_decl_assign_t {
|
struct net_decl_assign_t {
|
||||||
char*name;
|
perm_string name;
|
||||||
PExpr*expr;
|
PExpr*expr;
|
||||||
struct net_decl_assign_t*next;
|
struct net_decl_assign_t*next;
|
||||||
};
|
};
|
||||||
|
|
@ -138,19 +138,19 @@ extern void pform_module_set_ports(svector<Module::port_t*>*);
|
||||||
port_definition_list. In this case, we have everything needed to
|
port_definition_list. In this case, we have everything needed to
|
||||||
define the port, all in one place. */
|
define the port, all in one place. */
|
||||||
extern void pform_module_define_port(const struct vlltype&li,
|
extern void pform_module_define_port(const struct vlltype&li,
|
||||||
const char*name,
|
perm_string name,
|
||||||
NetNet::PortType,
|
NetNet::PortType,
|
||||||
NetNet::Type type,
|
NetNet::Type type,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
svector<PExpr*>*range,
|
svector<PExpr*>*range,
|
||||||
svector<named_pexpr_t*>*attr);
|
svector<named_pexpr_t*>*attr);
|
||||||
|
|
||||||
extern Module::port_t* pform_module_port_reference(char*name,
|
extern Module::port_t* pform_module_port_reference(perm_string name,
|
||||||
const char*file,
|
const char*file,
|
||||||
unsigned lineno);
|
unsigned lineno);
|
||||||
extern void pform_endmodule(const char*);
|
extern void pform_endmodule(const char*);
|
||||||
|
|
||||||
extern void pform_make_udp(perm_string name, list<string>*parms,
|
extern void pform_make_udp(perm_string name, list<perm_string>*parms,
|
||||||
svector<PWire*>*decl, list<string>*table,
|
svector<PWire*>*decl, list<string>*table,
|
||||||
Statement*init,
|
Statement*init,
|
||||||
const char*file, unsigned lineno);
|
const char*file, unsigned lineno);
|
||||||
|
|
@ -201,7 +201,7 @@ extern void pform_endgenerate();
|
||||||
* The makewire functions announce to the pform code new wires. These
|
* The makewire functions announce to the pform code new wires. These
|
||||||
* go into a module that is currently opened.
|
* go into a module that is currently opened.
|
||||||
*/
|
*/
|
||||||
extern void pform_makewire(const struct vlltype&li, const char*name,
|
extern void pform_makewire(const struct vlltype&li, perm_string name,
|
||||||
NetNet::Type type,
|
NetNet::Type type,
|
||||||
NetNet::PortType pt,
|
NetNet::PortType pt,
|
||||||
ivl_variable_type_t,
|
ivl_variable_type_t,
|
||||||
|
|
@ -229,7 +229,7 @@ extern void pform_makewire(const struct vlltype&li,
|
||||||
ivl_variable_type_t);
|
ivl_variable_type_t);
|
||||||
|
|
||||||
extern void pform_make_reginit(const struct vlltype&li,
|
extern void pform_make_reginit(const struct vlltype&li,
|
||||||
const char*name, PExpr*expr);
|
perm_string name, PExpr*expr);
|
||||||
|
|
||||||
/* Look up the names of the wires, and set the port type,
|
/* Look up the names of the wires, and set the port type,
|
||||||
i.e. input, output or inout. If the wire does not exist, create
|
i.e. input, output or inout. If the wire does not exist, create
|
||||||
|
|
@ -242,13 +242,12 @@ extern void pform_set_port_type(const struct vlltype&li,
|
||||||
extern void pform_set_port_type(perm_string nm, NetNet::PortType pt,
|
extern void pform_set_port_type(perm_string nm, NetNet::PortType pt,
|
||||||
const char*file, unsigned lineno);
|
const char*file, unsigned lineno);
|
||||||
|
|
||||||
extern void pform_set_net_range(const char* name);
|
|
||||||
extern void pform_set_net_range(list<perm_string>*names,
|
extern void pform_set_net_range(list<perm_string>*names,
|
||||||
svector<PExpr*>*,
|
svector<PExpr*>*,
|
||||||
bool signed_flag,
|
bool signed_flag,
|
||||||
ivl_variable_type_t,
|
ivl_variable_type_t,
|
||||||
PWSRType rt = SR_NET);
|
PWSRType rt = SR_NET);
|
||||||
extern void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r);
|
extern void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r);
|
||||||
extern void pform_set_reg_integer(list<perm_string>*names);
|
extern void pform_set_reg_integer(list<perm_string>*names);
|
||||||
extern void pform_set_reg_time(list<perm_string>*names);
|
extern void pform_set_reg_time(list<perm_string>*names);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ void PWire::dump(ostream&out, unsigned ind) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out << " " << hname_;
|
out << " " << name_;
|
||||||
|
|
||||||
// If the wire has indices, dump them.
|
// If the wire has indices, dump them.
|
||||||
if (lidx_ || ridx_) {
|
if (lidx_ || ridx_) {
|
||||||
|
|
@ -508,6 +508,9 @@ void PBlock::dump(ostream&out, unsigned ind) const
|
||||||
out << " : " << pscope_name();
|
out << " : " << pscope_name();
|
||||||
out << endl;
|
out << endl;
|
||||||
|
|
||||||
|
if (pscope_name() != 0)
|
||||||
|
dump_wires_(out, ind+2);
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1) {
|
||||||
if (list_[idx])
|
if (list_[idx])
|
||||||
list_[idx]->dump(out, ind+2);
|
list_[idx]->dump(out, ind+2);
|
||||||
|
|
@ -703,9 +706,11 @@ void PFunction::dump(ostream&out, unsigned ind) const
|
||||||
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
|
||||||
out << setw(ind) << "";
|
out << setw(ind) << "";
|
||||||
out << "input ";
|
out << "input ";
|
||||||
out << (*ports_)[idx]->path() << ";" << endl;
|
out << (*ports_)[idx]->basename() << ";" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dump_wires_(out, ind);
|
||||||
|
|
||||||
if (statement_)
|
if (statement_)
|
||||||
statement_->dump(out, ind);
|
statement_->dump(out, ind);
|
||||||
else
|
else
|
||||||
|
|
@ -743,9 +748,11 @@ void PTask::dump(ostream&out, unsigned ind) const
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out << (*ports_)[idx]->path() << ";" << endl;
|
out << (*ports_)[idx]->basename() << ";" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dump_wires_(out, ind);
|
||||||
|
|
||||||
if (statement_)
|
if (statement_)
|
||||||
statement_->dump(out, ind);
|
statement_->dump(out, ind);
|
||||||
else
|
else
|
||||||
|
|
@ -870,7 +877,7 @@ void PGenerate::dump(ostream&out, unsigned indent) const
|
||||||
|
|
||||||
out << endl;
|
out << endl;
|
||||||
|
|
||||||
for (map<pform_name_t,PWire*>::const_iterator idx = wires.begin()
|
for (map<perm_string,PWire*>::const_iterator idx = wires.begin()
|
||||||
; idx != wires.end() ; idx++) {
|
; idx != wires.end() ; idx++) {
|
||||||
|
|
||||||
(*idx).second->dump(out, indent+2);
|
(*idx).second->dump(out, indent+2);
|
||||||
|
|
@ -894,6 +901,16 @@ void PGenerate::dump(ostream&out, unsigned indent) const
|
||||||
out << setw(indent) << "" << "endgenerate" << endl;
|
out << setw(indent) << "" << "endgenerate" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PScope::dump_wires_(ostream&out, unsigned indent) const
|
||||||
|
{
|
||||||
|
// Iterate through and display all the wires.
|
||||||
|
for (map<perm_string,PWire*>::const_iterator wire = wires.begin()
|
||||||
|
; wire != wires.end() ; wire ++ ) {
|
||||||
|
|
||||||
|
(*wire).second->dump(out, indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Module::dump(ostream&out) const
|
void Module::dump(ostream&out) const
|
||||||
{
|
{
|
||||||
if (attributes.begin() != attributes.end()) {
|
if (attributes.begin() != attributes.end()) {
|
||||||
|
|
@ -995,12 +1012,7 @@ void Module::dump(ostream&out) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through and display all the wires.
|
// Iterate through and display all the wires.
|
||||||
for (map<pform_name_t,PWire*>::const_iterator wire = wires_.begin()
|
dump_wires_(out, 4);
|
||||||
; wire != wires_.end()
|
|
||||||
; wire ++ ) {
|
|
||||||
|
|
||||||
(*wire).second->dump(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dump the task definitions.
|
// Dump the task definitions.
|
||||||
typedef map<perm_string,PTask*>::const_iterator task_iter_t;
|
typedef map<perm_string,PTask*>::const_iterator task_iter_t;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue