Merge branch 'pscope'
This commit is contained in:
commit
11a33a0907
|
|
@ -111,7 +111,7 @@ parse.o parse_misc.o pform.o pform_dump.o pform_types.o \
|
||||||
set_width.o symbol_search.o sync.o sys_funcs.o \
|
set_width.o symbol_search.o sync.o sys_funcs.o \
|
||||||
verinum.o verireal.o target.o targets.o \
|
verinum.o verireal.o target.o targets.o \
|
||||||
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
|
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
|
||||||
PExpr.o PGate.o PGenerate.o PSpec.o \
|
PExpr.o PGate.o PGenerate.o PScope.o PSpec.o \
|
||||||
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
|
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
|
||||||
$(FF) $(TT)
|
$(FF) $(TT)
|
||||||
|
|
||||||
|
|
|
||||||
21
Module.cc
21
Module.cc
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
/* n is a permallocated string. */
|
/* n is a permallocated string. */
|
||||||
Module::Module(perm_string n)
|
Module::Module(perm_string n)
|
||||||
: name_(n)
|
: PScope(n, 0)
|
||||||
{
|
{
|
||||||
library_flag = false;
|
library_flag = false;
|
||||||
default_nettype = NetNet::NONE;
|
default_nettype = NetNet::NONE;
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
50
Module.h
50
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>
|
||||||
|
|
@ -28,10 +26,10 @@
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include "HName.h"
|
# include "HName.h"
|
||||||
# include "named.h"
|
# include "named.h"
|
||||||
|
# include "PScope.h"
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "pform_types.h"
|
# include "pform_types.h"
|
||||||
class PEvent;
|
|
||||||
class PExpr;
|
class PExpr;
|
||||||
class PEIdent;
|
class PEIdent;
|
||||||
class PGate;
|
class PGate;
|
||||||
|
|
@ -50,7 +48,7 @@ class NetScope;
|
||||||
* therefore the handle for grasping the described circuit.
|
* therefore the handle for grasping the described circuit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Module : public LineInfo {
|
class Module : public PScope, public LineInfo {
|
||||||
|
|
||||||
/* The module ports are in general a vector of port_t
|
/* The module ports are in general a vector of port_t
|
||||||
objects. Each port has a name and an ordered list of
|
objects. Each port has a name and an ordered list of
|
||||||
|
|
@ -113,9 +111,6 @@ class Module : public LineInfo {
|
||||||
named array of PEident pointers. */
|
named array of PEident pointers. */
|
||||||
svector<port_t*> ports;
|
svector<port_t*> ports;
|
||||||
|
|
||||||
/* Keep a table of named events declared in the module. */
|
|
||||||
map<perm_string,PEvent*>events;
|
|
||||||
|
|
||||||
map<perm_string,PExpr*> attributes;
|
map<perm_string,PExpr*> attributes;
|
||||||
|
|
||||||
/* These are the timescale for this module. The default is
|
/* These are the timescale for this module. The default is
|
||||||
|
|
@ -132,15 +127,10 @@ class Module : public LineInfo {
|
||||||
|
|
||||||
list<PSpecPath*> specify_paths;
|
list<PSpecPath*> specify_paths;
|
||||||
|
|
||||||
perm_string mod_name() const { return name_; }
|
// The mod_name() is the name of the module type.
|
||||||
|
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);
|
||||||
|
|
@ -149,9 +139,6 @@ class Module : 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;
|
||||||
|
|
@ -166,9 +153,6 @@ class Module : public LineInfo {
|
||||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
|
||||||
|
|
||||||
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_;
|
||||||
|
|
@ -182,26 +166,4 @@ class Module : 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
|
||||||
|
|
|
||||||
34
PFunction.cc
34
PFunction.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-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
|
||||||
|
|
@ -16,16 +16,13 @@
|
||||||
* 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: PFunction.cc,v 1.7 2004/05/31 23:34:36 steve Exp $"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
||||||
#include "PTask.h"
|
#include "PTask.h"
|
||||||
|
|
||||||
PFunction::PFunction(perm_string name)
|
PFunction::PFunction(perm_string name, PScope*parent)
|
||||||
: name_(name), ports_(0), statement_(0)
|
: PScope(name, parent), ports_(0), statement_(0)
|
||||||
{
|
{
|
||||||
return_type_.type = PTF_NONE;
|
return_type_.type = PTF_NONE;
|
||||||
}
|
}
|
||||||
|
|
@ -51,28 +48,3 @@ void PFunction::set_return(PTaskFuncArg t)
|
||||||
{
|
{
|
||||||
return_type_ = t;
|
return_type_ = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: PFunction.cc,v $
|
|
||||||
* Revision 1.7 2004/05/31 23:34:36 steve
|
|
||||||
* Rewire/generalize parsing an elaboration of
|
|
||||||
* function return values to allow for better
|
|
||||||
* speed and more type support.
|
|
||||||
*
|
|
||||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
|
||||||
* conditional ident string using autoconfig.
|
|
||||||
*
|
|
||||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
|
||||||
* Create a config.h.in file to hold all the config
|
|
||||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
|
||||||
*
|
|
||||||
* Revision 1.4 2001/01/13 22:20:08 steve
|
|
||||||
* Parse parameters within nested scopes.
|
|
||||||
*
|
|
||||||
* Revision 1.3 2000/02/23 02:56:53 steve
|
|
||||||
* Macintosh compilers do not support ident.
|
|
||||||
*
|
|
||||||
* Revision 1.2 1999/08/25 22:22:41 steve
|
|
||||||
* elaborate some aspects of functions.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
|
||||||
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*);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
# include "PScope.h"
|
||||||
|
|
||||||
|
PScope::PScope(perm_string n, PScope*p)
|
||||||
|
: name_(n), parent_(p)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
#ifndef __PScope_H
|
||||||
|
#define __PScope_H
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
|
||||||
|
*
|
||||||
|
* This source code is free software; you can redistribute it
|
||||||
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
* General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
# include "StringHeap.h"
|
||||||
|
# include "pform_types.h"
|
||||||
|
# include <map>
|
||||||
|
|
||||||
|
class PEvent;
|
||||||
|
class PWire;
|
||||||
|
|
||||||
|
class Design;
|
||||||
|
class NetScope;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The PScope class is a base representation of an object that
|
||||||
|
* represents lexical scope. For example, a module, a function/task, a
|
||||||
|
* named block is derived from a PScope.
|
||||||
|
*
|
||||||
|
* NOTE: This is note the same concept as the "scope" of an elaborated
|
||||||
|
* hierarchy. That is represented by NetScope objects after elaboration.
|
||||||
|
*/
|
||||||
|
class PScope {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// When created, a scope has a name and a parent. The name is
|
||||||
|
// the name of the definition. For example, if this is a
|
||||||
|
// module declaration, the name is the name after the "module"
|
||||||
|
// keyword, and if this is a task scope, the name is the task
|
||||||
|
// name. The parent is the lexical parent of this scope. Since
|
||||||
|
// modules do not nest in Verilog, the parent must be nil for
|
||||||
|
// modules. Scopes for tasks and functions point to their
|
||||||
|
// containing module.
|
||||||
|
PScope(perm_string name, PScope*parent);
|
||||||
|
virtual ~PScope();
|
||||||
|
|
||||||
|
perm_string pscope_name() const { return name_; }
|
||||||
|
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.
|
||||||
|
map<perm_string,PEvent*>events;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void dump_wires_(ostream&out, unsigned indent) const;
|
||||||
|
|
||||||
|
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
perm_string name_;
|
||||||
|
PScope*parent_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
9
PTask.cc
9
PTask.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-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
|
||||||
|
|
@ -16,16 +16,13 @@
|
||||||
* 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: PTask.cc,v 1.7 2002/08/12 01:34:58 steve Exp $"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
||||||
# include "PTask.h"
|
# include "PTask.h"
|
||||||
|
|
||||||
PTask::PTask()
|
PTask::PTask(perm_string name, PScope*parent)
|
||||||
: ports_(0), statement_(0)
|
: PScope(name, parent), ports_(0), statement_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
73
PTask.h
73
PTask.h
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef __PTask_H
|
#ifndef __PTask_H
|
||||||
#define __PTask_H
|
#define __PTask_H
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 1999-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,11 +18,9 @@
|
||||||
* 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: PTask.h,v 1.14 2007/03/06 05:22:49 steve Exp $"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
|
# include "PScope.h"
|
||||||
# include "svector.h"
|
# include "svector.h"
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
@ -50,10 +48,10 @@ struct PTaskFuncArg {
|
||||||
/*
|
/*
|
||||||
* The PTask holds the parsed definitions of a task.
|
* The PTask holds the parsed definitions of a task.
|
||||||
*/
|
*/
|
||||||
class PTask : public LineInfo {
|
class PTask : public PScope, public LineInfo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PTask();
|
explicit PTask(perm_string name, PScope*parent);
|
||||||
~PTask();
|
~PTask();
|
||||||
|
|
||||||
void set_ports(svector<PWire *>*p);
|
void set_ports(svector<PWire *>*p);
|
||||||
|
|
@ -89,10 +87,10 @@ class PTask : public LineInfo {
|
||||||
*
|
*
|
||||||
* The output value is not elaborated until elaborate_sig.
|
* The output value is not elaborated until elaborate_sig.
|
||||||
*/
|
*/
|
||||||
class PFunction : public LineInfo {
|
class PFunction : public PScope, public LineInfo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PFunction(perm_string name);
|
explicit PFunction(perm_string name, PScope*parent);
|
||||||
~PFunction();
|
~PFunction();
|
||||||
|
|
||||||
void set_ports(svector<PWire *>*p);
|
void set_ports(svector<PWire *>*p);
|
||||||
|
|
@ -110,68 +108,9 @@ class PFunction : public LineInfo {
|
||||||
void dump(ostream&, unsigned) const;
|
void dump(ostream&, unsigned) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
perm_string name_;
|
|
||||||
PTaskFuncArg return_type_;
|
PTaskFuncArg return_type_;
|
||||||
svector<PWire *> *ports_;
|
svector<PWire *> *ports_;
|
||||||
Statement *statement_;
|
Statement *statement_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: PTask.h,v $
|
|
||||||
* Revision 1.14 2007/03/06 05:22:49 steve
|
|
||||||
* Support signed function return values.
|
|
||||||
*
|
|
||||||
* Revision 1.13 2004/05/31 23:34:36 steve
|
|
||||||
* Rewire/generalize parsing an elaboration of
|
|
||||||
* function return values to allow for better
|
|
||||||
* speed and more type support.
|
|
||||||
*
|
|
||||||
* Revision 1.12 2002/08/12 01:34:58 steve
|
|
||||||
* conditional ident string using autoconfig.
|
|
||||||
*
|
|
||||||
* Revision 1.11 2001/11/22 06:20:59 steve
|
|
||||||
* Use NetScope instead of string for scope path.
|
|
||||||
*
|
|
||||||
* Revision 1.10 2001/01/13 22:20:08 steve
|
|
||||||
* Parse parameters within nested scopes.
|
|
||||||
*
|
|
||||||
* Revision 1.9 2000/07/30 18:25:43 steve
|
|
||||||
* Rearrange task and function elaboration so that the
|
|
||||||
* NetTaskDef and NetFuncDef functions are created during
|
|
||||||
* signal enaboration, and carry these objects in the
|
|
||||||
* NetScope class instead of the extra, useless map in
|
|
||||||
* the Design class.
|
|
||||||
*
|
|
||||||
* Revision 1.8 2000/03/08 04:36:53 steve
|
|
||||||
* Redesign the implementation of scopes and parameters.
|
|
||||||
* I now generate the scopes and notice the parameters
|
|
||||||
* in a separate pass over the pform. Once the scopes
|
|
||||||
* are generated, I can process overrides and evalutate
|
|
||||||
* paremeters before elaboration begins.
|
|
||||||
*
|
|
||||||
* Revision 1.7 2000/02/23 02:56:53 steve
|
|
||||||
* Macintosh compilers do not support ident.
|
|
||||||
*
|
|
||||||
* Revision 1.6 1999/09/30 21:28:34 steve
|
|
||||||
* Handle mutual reference of tasks by elaborating
|
|
||||||
* task definitions in two passes, like functions.
|
|
||||||
*
|
|
||||||
* Revision 1.5 1999/09/01 20:46:19 steve
|
|
||||||
* Handle recursive functions and arbitrary function
|
|
||||||
* references to other functions, properly pass
|
|
||||||
* function parameters and save function results.
|
|
||||||
*
|
|
||||||
* Revision 1.4 1999/08/25 22:22:41 steve
|
|
||||||
* elaborate some aspects of functions.
|
|
||||||
*
|
|
||||||
* Revision 1.3 1999/07/31 19:14:47 steve
|
|
||||||
* Add functions up to elaboration (Ed Carter)
|
|
||||||
*
|
|
||||||
* Revision 1.2 1999/07/24 02:11:19 steve
|
|
||||||
* Elaborate task input ports.
|
|
||||||
*
|
|
||||||
* Revision 1.1 1999/07/03 02:12:51 steve
|
|
||||||
* Elaborate user defined tasks.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
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_;
|
||||||
|
|
|
||||||
16
Statement.cc
16
Statement.cc
|
|
@ -86,18 +86,13 @@ PAssignNB::~PAssignNB()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PBlock::PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st)
|
PBlock::PBlock(perm_string n, PScope*parent, BL_TYPE t)
|
||||||
: name_(n), bl_type_(t), list_(st)
|
: PScope(n, parent), bl_type_(t)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PBlock::PBlock(BL_TYPE t, const svector<Statement*>&st)
|
|
||||||
: bl_type_(t), list_(st)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PBlock::PBlock(BL_TYPE t)
|
PBlock::PBlock(BL_TYPE t)
|
||||||
: bl_type_(t)
|
: PScope(perm_string(),0), bl_type_(t)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,6 +102,11 @@ PBlock::~PBlock()
|
||||||
delete list_[idx];
|
delete list_[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PBlock::set_statement(const svector<Statement*>&st)
|
||||||
|
{
|
||||||
|
list_ = st;
|
||||||
|
}
|
||||||
|
|
||||||
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
|
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
|
||||||
: path_(n), parms_(p)
|
: path_(n), parms_(p)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
18
Statement.h
18
Statement.h
|
|
@ -27,6 +27,7 @@
|
||||||
# include "StringHeap.h"
|
# include "StringHeap.h"
|
||||||
# include "PDelays.h"
|
# include "PDelays.h"
|
||||||
# include "PExpr.h"
|
# include "PExpr.h"
|
||||||
|
# include "PScope.h"
|
||||||
# include "HName.h"
|
# include "HName.h"
|
||||||
# include "LineInfo.h"
|
# include "LineInfo.h"
|
||||||
class PExpr;
|
class PExpr;
|
||||||
|
|
@ -83,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -147,25 +149,27 @@ class PAssignNB : public PAssign_ {
|
||||||
* statements before constructing this object, so it knows a priori
|
* statements before constructing this object, so it knows a priori
|
||||||
* what is contained.
|
* what is contained.
|
||||||
*/
|
*/
|
||||||
class PBlock : public Statement {
|
class PBlock : public PScope, public Statement {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum BL_TYPE { BL_SEQ, BL_PAR };
|
enum BL_TYPE { BL_SEQ, BL_PAR };
|
||||||
|
|
||||||
explicit PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st);
|
// If the block has a name, it is a scope and also has a parent.
|
||||||
explicit PBlock(BL_TYPE t, const svector<Statement*>&st);
|
explicit PBlock(perm_string n, PScope*parent, BL_TYPE t);
|
||||||
|
// If it doesn't have a name, it's not a scope
|
||||||
explicit PBlock(BL_TYPE t);
|
explicit PBlock(BL_TYPE t);
|
||||||
~PBlock();
|
~PBlock();
|
||||||
|
|
||||||
BL_TYPE bl_type() const { return bl_type_; }
|
BL_TYPE bl_type() const { return bl_type_; }
|
||||||
|
|
||||||
|
void set_statement(const svector<Statement*>&st);
|
||||||
|
|
||||||
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:
|
||||||
perm_string name_;
|
|
||||||
const BL_TYPE bl_type_;
|
const BL_TYPE bl_type_;
|
||||||
svector<Statement*>list_;
|
svector<Statement*>list_;
|
||||||
};
|
};
|
||||||
|
|
@ -215,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:
|
||||||
|
|
@ -250,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:
|
||||||
|
|
@ -284,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_;
|
||||||
|
|
@ -331,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.
|
||||||
|
|
@ -364,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:
|
||||||
|
|
@ -379,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);
|
||||||
}
|
}
|
||||||
|
|
@ -987,7 +993,10 @@ void NetScope::dump(ostream&o) const
|
||||||
o << " MISSING FUNCTION DEFINITION" << endl;
|
o << " MISSING FUNCTION DEFINITION" << endl;
|
||||||
break;
|
break;
|
||||||
case TASK:
|
case TASK:
|
||||||
|
if (task_def())
|
||||||
task_def()->dump(o, 4);
|
task_def()->dump(o, 4);
|
||||||
|
else
|
||||||
|
o << " MISSING TASK DEFINITION" << endl;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -794,8 +794,8 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
NetScope*my_scope = scope;
|
NetScope*my_scope = scope;
|
||||||
|
|
||||||
if (name_ != 0) {
|
if (pscope_name() != 0) {
|
||||||
hname_t use_name(name_);
|
hname_t use_name(pscope_name());
|
||||||
if (scope->child(use_name)) {
|
if (scope->child(use_name)) {
|
||||||
cerr << get_fileline() << ": error: block/scope name "
|
cerr << get_fileline() << ": error: block/scope name "
|
||||||
<< use_name << " already used in this context."
|
<< use_name << " already used in this context."
|
||||||
|
|
|
||||||
314
elab_sig.cc
314
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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 flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
|
|
@ -81,15 +93,27 @@ 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 " << 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;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -98,7 +122,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||||
if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) {
|
if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) {
|
||||||
cerr << get_fileline() << ": error: "
|
cerr << get_fileline() << ": error: "
|
||||||
<< "Port " << pp->expr[cc]->path() << " ("
|
<< "Port " << pp->expr[cc]->path() << " ("
|
||||||
<< (idx+1) << ") of module " << name_
|
<< (idx+1) << ") of module " << mod_name()
|
||||||
<< " has no direction declaration."
|
<< " has no direction declaration."
|
||||||
<< endl;
|
<< 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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
elaborate.cc
10
elaborate.cc
|
|
@ -1866,12 +1866,12 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
|
||||||
: NetBlock::SEQU;
|
: NetBlock::SEQU;
|
||||||
|
|
||||||
NetScope*nscope = 0;
|
NetScope*nscope = 0;
|
||||||
if (name_.str() != 0) {
|
if (pscope_name() != 0) {
|
||||||
nscope = scope->child(hname_t(name_));
|
nscope = scope->child(hname_t(pscope_name()));
|
||||||
if (nscope == 0) {
|
if (nscope == 0) {
|
||||||
cerr << get_fileline() << ": internal error: "
|
cerr << get_fileline() << ": internal error: "
|
||||||
"unable to find block scope " << scope_path(scope)
|
"unable to find block scope " << scope_path(scope)
|
||||||
<< "<" << name_ << ">" << endl;
|
<< "<" << pscope_name() << ">" << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1889,7 +1889,7 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
|
||||||
// statement. There is no need to keep the block node. Also,
|
// statement. There is no need to keep the block node. Also,
|
||||||
// don't elide named blocks, because they might be referenced
|
// don't elide named blocks, because they might be referenced
|
||||||
// elsewhere.
|
// elsewhere.
|
||||||
if ((list_.count() == 1) && (name_.str() == 0)) {
|
if ((list_.count() == 1) && (pscope_name() == 0)) {
|
||||||
assert(list_[0]);
|
assert(list_[0]);
|
||||||
NetProc*tmp = list_[0]->elaborate(des, nscope);
|
NetProc*tmp = list_[0]->elaborate(des, nscope);
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
@ -2934,7 +2934,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;
|
||||||
|
|
|
||||||
|
|
@ -3275,7 +3275,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
|
||||||
|
|
@ -3285,7 +3285,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. */
|
||||||
|
|
|
||||||
182
parse.y
182
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>
|
||||||
|
|
||||||
|
|
@ -45,6 +46,12 @@ static struct {
|
||||||
svector<PExpr*>* range;
|
svector<PExpr*>* range;
|
||||||
} port_declaration_context;
|
} port_declaration_context;
|
||||||
|
|
||||||
|
/* The task and function rules need to briefly hold the pointer to the
|
||||||
|
task/function that is currently in progress. */
|
||||||
|
static PTask* current_task = 0;
|
||||||
|
static PFunction* current_function = 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
|
||||||
or YYLTYPE are provided by the source code. However, I can get the
|
or YYLTYPE are provided by the source code. However, I can get the
|
||||||
|
|
@ -191,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
|
||||||
|
|
@ -1405,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);
|
||||||
|
|
@ -1434,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 ','
|
||||||
|
|
@ -1463,9 +1457,10 @@ 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);
|
||||||
|
ptmp = pform_module_port_reference(name, @2.text,
|
||||||
@2.first_line);
|
@2.first_line);
|
||||||
pform_module_define_port(@2, $6, NetNet::PINPUT,
|
pform_module_define_port(@2, name, NetNet::PINPUT,
|
||||||
$3, $4, $5, $1);
|
$3, $4, $5, $1);
|
||||||
port_declaration_context.port_type = NetNet::PINPUT;
|
port_declaration_context.port_type = NetNet::PINPUT;
|
||||||
port_declaration_context.port_net_type = $3;
|
port_declaration_context.port_net_type = $3;
|
||||||
|
|
@ -1478,9 +1473,10 @@ port_declaration
|
||||||
| attribute_list_opt
|
| attribute_list_opt
|
||||||
K_inout net_type_opt signed_opt range_opt IDENTIFIER
|
K_inout 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);
|
||||||
|
ptmp = pform_module_port_reference(name, @2.text,
|
||||||
@2.first_line);
|
@2.first_line);
|
||||||
pform_module_define_port(@2, $6, NetNet::PINOUT,
|
pform_module_define_port(@2, name, NetNet::PINOUT,
|
||||||
$3, $4, $5, $1);
|
$3, $4, $5, $1);
|
||||||
port_declaration_context.port_type = NetNet::PINOUT;
|
port_declaration_context.port_type = NetNet::PINOUT;
|
||||||
port_declaration_context.port_net_type = $3;
|
port_declaration_context.port_net_type = $3;
|
||||||
|
|
@ -1493,9 +1489,10 @@ port_declaration
|
||||||
| attribute_list_opt
|
| attribute_list_opt
|
||||||
K_output net_type_opt signed_opt range_opt IDENTIFIER
|
K_output 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);
|
||||||
|
ptmp = pform_module_port_reference(name, @2.text,
|
||||||
@2.first_line);
|
@2.first_line);
|
||||||
pform_module_define_port(@2, $6, NetNet::POUTPUT,
|
pform_module_define_port(@2, name, NetNet::POUTPUT,
|
||||||
$3, $4, $5, $1);
|
$3, $4, $5, $1);
|
||||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||||
port_declaration_context.port_net_type = $3;
|
port_declaration_context.port_net_type = $3;
|
||||||
|
|
@ -1508,9 +1505,10 @@ port_declaration
|
||||||
| attribute_list_opt
|
| attribute_list_opt
|
||||||
K_output var_type signed_opt range_opt IDENTIFIER
|
K_output var_type 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);
|
||||||
|
ptmp = pform_module_port_reference(name, @2.text,
|
||||||
@2.first_line);
|
@2.first_line);
|
||||||
pform_module_define_port(@2, $6, NetNet::POUTPUT,
|
pform_module_define_port(@2, name, NetNet::POUTPUT,
|
||||||
$3, $4, $5, $1);
|
$3, $4, $5, $1);
|
||||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||||
port_declaration_context.port_net_type = $3;
|
port_declaration_context.port_net_type = $3;
|
||||||
|
|
@ -1523,9 +1521,10 @@ port_declaration
|
||||||
| attribute_list_opt
|
| attribute_list_opt
|
||||||
K_output var_type signed_opt range_opt IDENTIFIER '=' expression
|
K_output var_type signed_opt range_opt IDENTIFIER '=' expression
|
||||||
{ Module::port_t*ptmp;
|
{ Module::port_t*ptmp;
|
||||||
ptmp = pform_module_port_reference($6, @2.text,
|
perm_string name = lex_strings.make($6);
|
||||||
|
ptmp = pform_module_port_reference(name, @2.text,
|
||||||
@2.first_line);
|
@2.first_line);
|
||||||
pform_module_define_port(@2, $6, NetNet::POUTPUT,
|
pform_module_define_port(@2, name, NetNet::POUTPUT,
|
||||||
$3, $4, $5, $1);
|
$3, $4, $5, $1);
|
||||||
port_declaration_context.port_type = NetNet::POUTPUT;
|
port_declaration_context.port_type = NetNet::POUTPUT;
|
||||||
port_declaration_context.port_net_type = $3;
|
port_declaration_context.port_net_type = $3;
|
||||||
|
|
@ -1535,7 +1534,7 @@ port_declaration
|
||||||
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;
|
||||||
|
|
@ -1843,33 +1842,33 @@ module_item
|
||||||
extension. */
|
extension. */
|
||||||
|
|
||||||
| K_task IDENTIFIER ';'
|
| K_task IDENTIFIER ';'
|
||||||
{ pform_push_scope($2); }
|
{ assert(current_task == 0);
|
||||||
|
current_task = pform_push_task_scope($2);
|
||||||
|
FILE_NAME(current_task, @1);
|
||||||
|
}
|
||||||
task_item_list_opt
|
task_item_list_opt
|
||||||
statement_or_null
|
statement_or_null
|
||||||
K_endtask
|
K_endtask
|
||||||
{ PTask*tmp = new PTask;
|
{ current_task->set_ports($5);
|
||||||
perm_string tmp2 = lex_strings.make($2);
|
current_task->set_statement($6);
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
tmp->set_ports($5);
|
|
||||||
tmp->set_statement($6);
|
|
||||||
pform_set_task(tmp2, tmp);
|
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
|
current_task = 0;
|
||||||
delete $2;
|
delete $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_task IDENTIFIER
|
| K_task IDENTIFIER
|
||||||
{ pform_push_scope($2); }
|
{ assert(current_task == 0);
|
||||||
|
current_task = pform_push_task_scope($2);
|
||||||
|
FILE_NAME(current_task, @1);
|
||||||
|
}
|
||||||
'(' task_port_decl_list ')' ';'
|
'(' task_port_decl_list ')' ';'
|
||||||
task_item_list_opt
|
task_item_list_opt
|
||||||
statement_or_null
|
statement_or_null
|
||||||
K_endtask
|
K_endtask
|
||||||
{ PTask*tmp = new PTask;
|
{ current_task->set_ports($5);
|
||||||
perm_string tmp2 = lex_strings.make($2);
|
current_task->set_statement($9);
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
tmp->set_ports($5);
|
|
||||||
tmp->set_statement($9);
|
|
||||||
pform_set_task(tmp2, tmp);
|
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
|
current_task = 0;
|
||||||
delete $2;
|
delete $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1879,17 +1878,16 @@ 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 ';'
|
||||||
{ pform_push_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
|
||||||
{ perm_string name = lex_strings.make($3);
|
{ current_function->set_ports($6);
|
||||||
PFunction *tmp = new PFunction(name);
|
current_function->set_statement($7);
|
||||||
FILE_NAME(tmp, @1);
|
current_function->set_return($2);
|
||||||
tmp->set_ports($6);
|
|
||||||
tmp->set_statement($7);
|
|
||||||
tmp->set_return($2);
|
|
||||||
pform_set_function(name, tmp);
|
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
|
current_function = 0;
|
||||||
delete $3;
|
delete $3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2039,8 +2037,9 @@ 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;
|
||||||
|
delete $1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -2319,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,7 +2530,8 @@ function_range_or_type_opt
|
||||||
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);
|
||||||
|
pform_makewire(@1, ident_name, NetNet::REG,
|
||||||
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
|
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
|
||||||
if ($2 != 0) {
|
if ($2 != 0) {
|
||||||
index_component_t index;
|
index_component_t index;
|
||||||
|
|
@ -2539,19 +2540,19 @@ register_variable
|
||||||
"are currently supported.");
|
"are currently supported.");
|
||||||
}
|
}
|
||||||
index = $2->front();
|
index = $2->front();
|
||||||
pform_set_reg_idx($1, index.msb, index.lsb);
|
pform_set_reg_idx(ident_name, index.msb, index.lsb);
|
||||||
delete $2;
|
delete $2;
|
||||||
}
|
}
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| IDENTIFIER '=' expression
|
| IDENTIFIER '=' expression
|
||||||
{ pform_makewire(@1, $1, NetNet::REG,
|
{ perm_string ident_name = lex_strings.make($1);
|
||||||
NetNet::NOT_A_PORT,
|
pform_makewire(@1, ident_name, NetNet::REG,
|
||||||
IVL_VT_NO_TYPE, 0);
|
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
|
||||||
if (! pform_expression_is_constant($3))
|
if (! pform_expression_is_constant($3))
|
||||||
yyerror(@3, "error: register declaration assignment"
|
yyerror(@3, "error: register declaration assignment"
|
||||||
" value must be a constant expression.");
|
" value must be a constant expression.");
|
||||||
pform_make_reginit(@1, $1, $3);
|
pform_make_reginit(@1, ident_name, $3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -2573,7 +2574,8 @@ 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;
|
||||||
|
|
@ -2581,8 +2583,9 @@ real_variable
|
||||||
$$ = $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,7 +2607,8 @@ 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);
|
||||||
|
pform_makewire(@1, name, NetNet::IMPLICIT,
|
||||||
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
|
NetNet::NOT_A_PORT, IVL_VT_NO_TYPE, 0);
|
||||||
if ($2 != 0) {
|
if ($2 != 0) {
|
||||||
index_component_t index;
|
index_component_t index;
|
||||||
|
|
@ -2613,12 +2617,13 @@ net_variable
|
||||||
"are currently supported.");
|
"are currently supported.");
|
||||||
}
|
}
|
||||||
index = $2->front();
|
index = $2->front();
|
||||||
pform_set_reg_idx($1, index.msb, index.lsb);
|
pform_set_reg_idx(name, index.msb, index.lsb);
|
||||||
delete $2;
|
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>;
|
||||||
|
|
@ -2962,19 +2967,24 @@ statement
|
||||||
the declarations. The scope is popped at the end of the block. */
|
the declarations. The scope is popped at the end of the block. */
|
||||||
|
|
||||||
| K_begin statement_list K_end
|
| K_begin statement_list K_end
|
||||||
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ, *$2);
|
{ PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
|
tmp->set_statement(*$2);
|
||||||
delete $2;
|
delete $2;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_begin ':' IDENTIFIER
|
| K_begin ':' IDENTIFIER
|
||||||
{ pform_push_scope($3); }
|
{ PBlock*tmp = pform_push_block_scope($3, PBlock::BL_SEQ);
|
||||||
|
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();
|
||||||
PBlock*tmp = new PBlock(lex_strings.make($3),
|
assert(! current_block_stack.empty());
|
||||||
PBlock::BL_SEQ, *$6);
|
PBlock*tmp = current_block_stack.top();
|
||||||
FILE_NAME(tmp, @1);
|
current_block_stack.pop();
|
||||||
|
tmp->set_statement(*$6);
|
||||||
delete $3;
|
delete $3;
|
||||||
delete $6;
|
delete $6;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
|
@ -2998,13 +3008,17 @@ statement
|
||||||
code generator can do the right thing. */
|
code generator can do the right thing. */
|
||||||
|
|
||||||
| K_fork ':' IDENTIFIER
|
| K_fork ':' IDENTIFIER
|
||||||
{ pform_push_scope($3); }
|
{ PBlock*tmp = pform_push_block_scope($3, PBlock::BL_PAR);
|
||||||
|
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();
|
||||||
PBlock*tmp = new PBlock(lex_strings.make($3),
|
assert(! current_block_stack.empty());
|
||||||
PBlock::BL_PAR, *$6);
|
PBlock*tmp = current_block_stack.top();
|
||||||
FILE_NAME(tmp, @1);
|
current_block_stack.pop();
|
||||||
|
tmp->set_statement(*$6);
|
||||||
delete $3;
|
delete $3;
|
||||||
delete $6;
|
delete $6;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
|
|
@ -3039,8 +3053,9 @@ statement
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| K_fork statement_list K_join
|
| K_fork statement_list K_join
|
||||||
{ PBlock*tmp = new PBlock(PBlock::BL_PAR, *$2);
|
{ PBlock*tmp = new PBlock(PBlock::BL_PAR);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
|
tmp->set_statement(*$2);
|
||||||
delete $2;
|
delete $2;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
@ -3672,8 +3687,7 @@ 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;
|
||||||
|
|
@ -3681,8 +3695,7 @@ udp_port_decl
|
||||||
delete $2;
|
delete $2;
|
||||||
}
|
}
|
||||||
| K_reg IDENTIFIER ';'
|
| K_reg 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::REG, NetNet::PIMPLICIT, IVL_VT_LOGIC);
|
PWire*pp = new PWire(pname, NetNet::REG, NetNet::PIMPLICIT, IVL_VT_LOGIC);
|
||||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||||
(*tmp)[0] = pp;
|
(*tmp)[0] = pp;
|
||||||
|
|
@ -3690,8 +3703,7 @@ udp_port_decl
|
||||||
delete $2;
|
delete $2;
|
||||||
}
|
}
|
||||||
| K_reg K_output IDENTIFIER ';'
|
| K_reg K_output IDENTIFIER ';'
|
||||||
{ pform_name_t pname;
|
{ perm_string pname = lex_strings.make($3);
|
||||||
pname.push_back(name_component_t(lex_strings.make($3)));
|
|
||||||
PWire*pp = new PWire(pname, NetNet::REG, NetNet::POUTPUT, IVL_VT_LOGIC);
|
PWire*pp = new PWire(pname, NetNet::REG, 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;
|
||||||
|
|
@ -3713,14 +3725,14 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
230
pform.cc
230
pform.cc
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
# include "ivl_assert.h"
|
# include "ivl_assert.h"
|
||||||
|
|
||||||
|
|
||||||
map<perm_string,Module*> pform_modules;
|
map<perm_string,Module*> pform_modules;
|
||||||
map<perm_string,PUdp*> pform_primitives;
|
map<perm_string,PUdp*> pform_primitives;
|
||||||
|
|
||||||
|
|
@ -88,40 +89,55 @@ 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 PScope* lexical_scope = 0;
|
||||||
static pform_name_t scope_stack;
|
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
static pform_name_t hier_name(const char*tail)
|
PTask* pform_push_task_scope(char*name)
|
||||||
{
|
{
|
||||||
pform_name_t name = scope_stack;
|
perm_string task_name = lex_strings.make(name);
|
||||||
name.push_back(name_component_t(lex_strings.make(tail)));
|
PTask*task = new PTask(task_name, pform_cur_module);
|
||||||
return name;
|
|
||||||
|
// Add the task to the current module
|
||||||
|
pform_cur_module->add_task(task->pscope_name(), task);
|
||||||
|
// Make this the current lexical scope
|
||||||
|
lexical_scope = task;
|
||||||
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PWire*get_wire_in_module(const pform_name_t&name)
|
PFunction* pform_push_function_scope(char*name)
|
||||||
|
{
|
||||||
|
perm_string func_name = lex_strings.make(name);
|
||||||
|
PFunction*func = new PFunction(func_name, lexical_scope);
|
||||||
|
|
||||||
|
// Add the task to the current module
|
||||||
|
pform_cur_module->add_function(func->pscope_name(), func);
|
||||||
|
// Make this the current lexical scope
|
||||||
|
lexical_scope = func;
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
|
||||||
|
{
|
||||||
|
perm_string block_name = lex_strings.make(name);
|
||||||
|
PBlock*block = new PBlock(block_name, lexical_scope, bt);
|
||||||
|
|
||||||
|
// Make this the current lexical scope
|
||||||
|
lexical_scope = block;
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
@ -130,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,
|
||||||
|
|
@ -259,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;
|
||||||
|
|
@ -285,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;
|
||||||
|
|
||||||
|
|
@ -334,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;
|
||||||
}
|
}
|
||||||
|
|
@ -545,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)
|
||||||
{
|
{
|
||||||
|
|
@ -612,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)
|
||||||
|
|
@ -624,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;
|
||||||
|
|
@ -654,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()
|
||||||
|
|
@ -789,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;
|
||||||
|
|
@ -814,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. */
|
||||||
|
|
@ -827,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());
|
||||||
|
|
@ -871,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);
|
||||||
|
|
@ -886,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;
|
||||||
|
|
@ -1233,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);
|
||||||
|
|
@ -1264,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());
|
||||||
|
|
@ -1306,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1334,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.
|
||||||
|
|
@ -1349,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());
|
||||||
|
|
@ -1393,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1455,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()) {
|
||||||
|
|
@ -1491,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;
|
||||||
|
|
@ -1558,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);
|
||||||
|
|
@ -1590,22 +1587,9 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_task(perm_string name, PTask*task)
|
|
||||||
{
|
|
||||||
pform_cur_module->add_task(name, task);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void pform_set_function(perm_string name, PFunction*func)
|
|
||||||
{
|
|
||||||
pform_cur_module->add_function(name, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)) {
|
||||||
|
|
@ -1639,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.");
|
||||||
|
|
@ -1792,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);
|
||||||
|
|
@ -1827,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);
|
||||||
|
|
@ -1867,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);
|
||||||
|
|
|
||||||
22
pform.h
22
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);
|
||||||
|
|
@ -167,9 +167,12 @@ extern void pform_make_udp(perm_string name,
|
||||||
* name string onto the scope hierarchy. The pop pulls it off and
|
* name string onto the scope hierarchy. The pop pulls it off and
|
||||||
* deletes it. Thus, the string pushed must be allocated.
|
* deletes it. Thus, the string pushed must be allocated.
|
||||||
*/
|
*/
|
||||||
extern void pform_push_scope(char*name);
|
|
||||||
extern void pform_pop_scope();
|
extern void pform_pop_scope();
|
||||||
|
|
||||||
|
extern PTask*pform_push_task_scope(char*name);
|
||||||
|
extern PFunction*pform_push_function_scope(char*name);
|
||||||
|
extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt);
|
||||||
|
|
||||||
|
|
||||||
extern verinum* pform_verinum_with_size(verinum*s, verinum*val,
|
extern verinum* pform_verinum_with_size(verinum*s, verinum*val,
|
||||||
const char*file, unsigned loneno);
|
const char*file, unsigned loneno);
|
||||||
|
|
@ -198,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,
|
||||||
|
|
@ -226,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
|
||||||
|
|
@ -239,17 +242,14 @@ 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);
|
||||||
extern void pform_set_task(perm_string name, PTask*);
|
|
||||||
extern void pform_set_function(perm_string name, PFunction*);
|
|
||||||
|
|
||||||
/* pform_set_attrib and pform_set_type_attrib exist to support the
|
/* pform_set_attrib and pform_set_type_attrib exist to support the
|
||||||
$attribute syntax, which can only set string values to
|
$attribute syntax, which can only set string values to
|
||||||
|
|
|
||||||
|
|
@ -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_) {
|
||||||
|
|
@ -504,10 +504,13 @@ void PAssignNB::dump(ostream&out, unsigned ind) const
|
||||||
void PBlock::dump(ostream&out, unsigned ind) const
|
void PBlock::dump(ostream&out, unsigned ind) const
|
||||||
{
|
{
|
||||||
out << setw(ind) << "" << "begin";
|
out << setw(ind) << "" << "begin";
|
||||||
if (name_ != 0)
|
if (pscope_name() != 0)
|
||||||
out << " : " << 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);
|
||||||
|
|
@ -697,15 +700,17 @@ void PFunction::dump(ostream&out, unsigned ind) const
|
||||||
out << "] ";
|
out << "] ";
|
||||||
}
|
}
|
||||||
|
|
||||||
out << name_ << ";" << endl;
|
out << pscope_name() << ";" << endl;
|
||||||
|
|
||||||
if (ports_)
|
if (ports_)
|
||||||
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()) {
|
||||||
|
|
@ -911,7 +928,7 @@ void Module::dump(ostream&out) const
|
||||||
out << " *) ";
|
out << " *) ";
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "module " << name_ << ";" << endl;
|
out << "module " << mod_name() << ";" << endl;
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||||
port_t*cur = ports[idx];
|
port_t*cur = ports[idx];
|
||||||
|
|
@ -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