Merge branch 'master' of github.com:steveicarus/iverilog
This commit is contained in:
commit
4b3ef8a314
|
|
@ -13,6 +13,7 @@ tags
|
|||
TAGS
|
||||
cscope.*
|
||||
*.patch
|
||||
*.orig
|
||||
|
||||
# Object files and libraries
|
||||
*.[oa]
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <map>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
2
Attrib.h
2
Attrib.h
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "StringHeap.h"
|
||||
|
|
|
|||
5
COPYING
5
COPYING
|
|
@ -2,7 +2,8 @@
|
|||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
|
@ -305,7 +306,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||
|
||||
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
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
|
|
|
|||
12
HName.cc
12
HName.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2012 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
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -31,21 +31,19 @@ hname_t::hname_t()
|
|||
}
|
||||
|
||||
hname_t::hname_t(perm_string text)
|
||||
: name_(text)
|
||||
{
|
||||
name_ = text;
|
||||
number_ = INT_MIN;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text, int num)
|
||||
: name_(text), number_(num)
|
||||
{
|
||||
name_ = text;
|
||||
number_ = num;
|
||||
}
|
||||
|
||||
hname_t::hname_t(const hname_t&that)
|
||||
: name_(that.name_), number_(that.number_)
|
||||
{
|
||||
name_ = that.name_;
|
||||
number_ = that.number_;
|
||||
}
|
||||
|
||||
hname_t& hname_t::operator = (const hname_t&that)
|
||||
|
|
|
|||
2
HName.h
2
HName.h
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <iostream>
|
||||
|
|
|
|||
30
Makefile.in
30
Makefile.in
|
|
@ -12,9 +12,8 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Library 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
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
|
@ -87,7 +86,7 @@ GIT = @GIT@
|
|||
ifeq (@srcdir@,.)
|
||||
INCLUDE_PATH = -I. -Ilibmisc
|
||||
else
|
||||
INCLUDE_PATH = -I. -Ilibmisc -I$(srcdir) -I$(srcdir)/libmisc
|
||||
INCLUDE_PATH = -I. -I$(srcdir) -I$(srcdir)/libmisc
|
||||
endif
|
||||
|
||||
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@
|
||||
|
|
@ -95,6 +94,7 @@ CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
|||
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
CTARGETFLAGS = @CTARGETFLAGS@
|
||||
|
||||
# Source files in the libmisc directory
|
||||
M = LineInfo.o StringHeap.o
|
||||
|
|
@ -104,17 +104,20 @@ FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
|
|||
|
||||
O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
||||
elab_expr.o elaborate_analog.o elab_lval.o elab_net.o \
|
||||
elab_scope.o elab_sig.o elab_sig_analog.o emit.o eval.o eval_attrib.o \
|
||||
elab_scope.o elab_sig.o elab_sig_analog.o elab_type.o \
|
||||
emit.o eval.o eval_attrib.o \
|
||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||
load_module.o netlist.o netmisc.o net_analog.o net_assign.o net_design.o \
|
||||
netenum.o netstruct.o net_event.o net_expr.o net_func.o net_link.o net_modulo.o \
|
||||
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
|
||||
net_design.o netclass.o netdarray.o \
|
||||
netenum.o netparray.o netstruct.o netvector.o net_event.o net_expr.o net_func.o \
|
||||
net_func_eval.o net_link.o net_modulo.o \
|
||||
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
|
||||
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
|
||||
pform_disciplines.o pform_dump.o pform_pclass.o pform_struct_type.o \
|
||||
pform_types.o \
|
||||
pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
|
||||
pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
|
||||
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PGate.o \
|
||||
PGenerate.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
|
||||
PGenerate.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
|
||||
Statement.o AStatement.o $M $(FF) $(TT)
|
||||
|
||||
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
|
||||
|
|
@ -170,8 +173,8 @@ endif
|
|||
rm -rf autom4te.cache
|
||||
|
||||
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c
|
||||
cppcheck --enable=all -f --suppressions $(srcdir)/cppcheck.sup \
|
||||
$(INCLUDE_PATH) $^
|
||||
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
|
||||
|
||||
cppcheck-all:
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) cppcheck && ) true
|
||||
|
|
@ -226,6 +229,7 @@ iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
|
|||
-e 's;@IVCXX@;$(CXX);' \
|
||||
-e 's;@IVCFLAGS@;$(CFLAGS);' \
|
||||
-e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@IVCTARGETFLAGS@;$(CTARGETFLAGS);' \
|
||||
-e 's;@INCLUDEDIR@;$(includedir);' \
|
||||
-e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||
chmod +x $@
|
||||
|
|
@ -377,7 +381,7 @@ uninstall:
|
|||
do rm -f "$(DESTDIR)$(bindir)/$$f"; done
|
||||
for f in ivl_target.h vpi_user.h _pli_types.h sv_vpi_user.h acc_user.h veriuser.h; \
|
||||
do rm -f "$(DESTDIR)$(includedir)/$$f"; done
|
||||
-test X$(suffix) = X || rmdir "$(DESTDIR)/$(includedir)"
|
||||
-test X$(suffix) = X || rmdir "$(DESTDIR)$(includedir)"
|
||||
rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
|
||||
|
||||
|
||||
|
|
|
|||
23
Module.cc
23
Module.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -27,11 +27,12 @@
|
|||
list<Module::named_expr_t> Module::user_defparms;
|
||||
|
||||
/* n is a permallocated string. */
|
||||
Module::Module(perm_string n)
|
||||
: PScopeExtra(n)
|
||||
Module::Module(LexicalScope*parent, perm_string n)
|
||||
: PScopeExtra(n, parent)
|
||||
{
|
||||
library_flag = false;
|
||||
is_cell = false;
|
||||
program_block = false;
|
||||
uc_drive = UCD_NONE;
|
||||
timescale_warn_done = false;
|
||||
time_unit = 0;
|
||||
|
|
@ -89,6 +90,22 @@ unsigned Module::find_port(const char*name) const
|
|||
return ports.size();
|
||||
}
|
||||
|
||||
perm_string Module::get_port_name(unsigned idx) const
|
||||
{
|
||||
|
||||
assert(idx < ports.size());
|
||||
if (ports[idx] == 0) {
|
||||
/* It is possible to have undeclared ports. These
|
||||
are ports that are skipped in the declaration,
|
||||
for example like so: module foo(x ,, y); The
|
||||
port between x and y is unnamed and thus
|
||||
inaccessible to binding by name. */
|
||||
return perm_string::literal("");
|
||||
}
|
||||
return ports[idx]->name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PGate* Module::get_gate(perm_string name)
|
||||
{
|
||||
|
|
|
|||
27
Module.h
27
Module.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __Module_H
|
||||
#define __Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2010,2012 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
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ class Module : public PScopeExtra, public LineInfo {
|
|||
public:
|
||||
/* The name passed here is the module name, not the instance
|
||||
name. This make must be a permallocated string. */
|
||||
explicit Module(perm_string name);
|
||||
explicit Module(LexicalScope*parent, perm_string name);
|
||||
~Module();
|
||||
|
||||
/* Initially false. This is set to true if the module has been
|
||||
|
|
@ -76,13 +76,18 @@ class Module : public PScopeExtra, public LineInfo {
|
|||
|
||||
bool is_cell;
|
||||
|
||||
/* This is true if the module represents a program block
|
||||
instead of a module/cell. Program blocks have content
|
||||
restrictions and slightly modify scheduling semantics. */
|
||||
bool program_block;
|
||||
|
||||
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
|
||||
UCDriveType uc_drive;
|
||||
|
||||
/* specparams are simpler than other params, in that they have
|
||||
no type information. They are merely constant
|
||||
expressions. */
|
||||
map<perm_string,PExpr*>specparams;
|
||||
/* specparams are simpler than other parameters, in that they
|
||||
can have a range, but not an explicit type. The restrictions
|
||||
are enforced by the parser. */
|
||||
map<perm_string,param_expr_t>specparams;
|
||||
|
||||
/* The module also has defparam assignments which don't create
|
||||
new parameters within the module, but may be used to set
|
||||
|
|
@ -116,6 +121,10 @@ class Module : public PScopeExtra, public LineInfo {
|
|||
the module definition. These are used at elaboration time. */
|
||||
list<PGenerate*> generate_schemes;
|
||||
|
||||
/* Nested modules are placed here, and are not elaborated
|
||||
unless they are instantiated, implicitly or explicitly. */
|
||||
std::map<perm_string,Module*> nested_modules;
|
||||
|
||||
list<PSpecPath*> specify_paths;
|
||||
|
||||
// The mod_name() is the name of the module type.
|
||||
|
|
@ -127,6 +136,9 @@ class Module : public PScopeExtra, public LineInfo {
|
|||
const vector<PEIdent*>& get_port(unsigned idx) const;
|
||||
unsigned find_port(const char*name) const;
|
||||
|
||||
// Return port name ("" for undeclared port)
|
||||
perm_string get_port_name(unsigned idx) const;
|
||||
|
||||
PGate* get_gate(perm_string name);
|
||||
|
||||
const list<PGate*>& get_gates() const;
|
||||
|
|
@ -140,6 +152,7 @@ class Module : public PScopeExtra, public LineInfo {
|
|||
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
void dump_specparams_(ostream&out, unsigned indent) const;
|
||||
list<PGate*> gates_;
|
||||
|
||||
private: // Not implemented
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PClass.h"
|
||||
|
|
|
|||
7
PClass.h
7
PClass.h
|
|
@ -16,12 +16,13 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PScope.h"
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* SystemVerilog supports class declarations with their own lexical
|
||||
|
|
@ -35,6 +36,10 @@ class PClass : public PScopeExtra, public LineInfo {
|
|||
explicit PClass (perm_string name, LexicalScope*parent);
|
||||
~PClass();
|
||||
|
||||
void dump(std::ostream&out, unsigned indent) const;
|
||||
|
||||
public:
|
||||
class_type_t*type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "svector.h"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
2
PEvent.h
2
PEvent.h
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
|
|
|
|||
30
PExpr.cc
30
PExpr.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -281,6 +281,14 @@ PExpr* PEEvent::expr() const
|
|||
return expr_;
|
||||
}
|
||||
|
||||
PENull::PENull(void)
|
||||
{
|
||||
}
|
||||
|
||||
PENull::~PENull()
|
||||
{
|
||||
}
|
||||
|
||||
PEFNumber::PEFNumber(verireal*v)
|
||||
: value_(v)
|
||||
{
|
||||
|
|
@ -363,7 +371,7 @@ bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
|
|||
|
||||
const NetExpr*ex1, *ex2;
|
||||
|
||||
scope = symbol_search(0, des, scope, path_, net, par, eve, ex1, ex2);
|
||||
scope = symbol_search(this, des, scope, path_, net, par, eve, ex1, ex2);
|
||||
|
||||
if (scope)
|
||||
return scope->is_auto();
|
||||
|
|
@ -371,6 +379,24 @@ bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
|
|||
return false;
|
||||
}
|
||||
|
||||
PENew::PENew(PExpr*size_expr)
|
||||
: size_(size_expr)
|
||||
{
|
||||
}
|
||||
|
||||
PENew::~PENew()
|
||||
{
|
||||
delete size_;
|
||||
}
|
||||
|
||||
PENewClass::PENewClass(void)
|
||||
{
|
||||
}
|
||||
|
||||
PENewClass::~PENewClass()
|
||||
{
|
||||
}
|
||||
|
||||
PENumber::PENumber(verinum*vp)
|
||||
: value_(vp)
|
||||
{
|
||||
|
|
|
|||
83
PExpr.h
83
PExpr.h
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <string>
|
||||
|
|
@ -49,6 +49,7 @@ class PExpr : public LineInfo {
|
|||
static const unsigned NO_FLAGS = 0x0;
|
||||
static const unsigned NEED_CONST = 0x1;
|
||||
static const unsigned SYS_TASK_ARG = 0x2;
|
||||
static const unsigned ANNOTATABLE = 0x4;
|
||||
|
||||
PExpr();
|
||||
virtual ~PExpr();
|
||||
|
|
@ -120,6 +121,13 @@ class PExpr : public LineInfo {
|
|||
// to be propagated down to any context-dependant operands.
|
||||
void cast_signed(bool flag) { signed_flag_ = flag; }
|
||||
|
||||
// This is the more generic form of the elaborate_expr method
|
||||
// below. The plan is to replace the simpler elaborate_expr
|
||||
// method with this version, which can handle more advanced
|
||||
// types. But for now, this is only implemented in special cases.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
// Procedural elaboration of the expression. The expr_width is
|
||||
// the required width of the expression.
|
||||
//
|
||||
|
|
@ -304,13 +312,15 @@ class PEIdent : public PExpr {
|
|||
NetScope*scope,
|
||||
bool is_force) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
||||
// Elaborate the PEIdent as a port to a module. This method
|
||||
// only applies to Ident expressions.
|
||||
NetNet* elaborate_port(Design*des, NetScope*sc) const;
|
||||
NetNet* elaborate_subport(Design*des, NetScope*sc) const;
|
||||
|
||||
verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
|
||||
|
|
@ -363,9 +373,14 @@ class PEIdent : public PExpr {
|
|||
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
|
||||
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
|
||||
index_component_t::ctype_t) const;
|
||||
bool elaborate_lval_net_class_member_(Design*, NetScope*,
|
||||
NetAssign_*,
|
||||
const perm_string&) const;
|
||||
bool elaborate_lval_net_packed_member_(Design*, NetScope*,
|
||||
NetAssign_*,
|
||||
const perm_string&) const;
|
||||
bool elaborate_lval_darray_bit_(Design*, NetScope*,
|
||||
NetAssign_*) const;
|
||||
|
||||
private:
|
||||
NetExpr*elaborate_expr_param_(Design*des,
|
||||
|
|
@ -438,6 +453,59 @@ class PEIdent : public PExpr {
|
|||
long&midx, long&lidx) const;
|
||||
};
|
||||
|
||||
class PENew : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PENew (PExpr*s);
|
||||
~PENew();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
||||
private:
|
||||
PExpr*size_;
|
||||
};
|
||||
|
||||
class PENewClass : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PENewClass ();
|
||||
~PENewClass();
|
||||
virtual void dump(ostream&) const;
|
||||
// Class objects don't have a useful width, but the expression
|
||||
// is IVL_VT_CLASS.
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
// Note that class (new) expressions only appear in context
|
||||
// that uses this form of the elaborate_expr method. In fact,
|
||||
// the type argument is going to be a netclas_t object.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class PENull : public PExpr {
|
||||
public:
|
||||
explicit PENull();
|
||||
~PENull();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
};
|
||||
|
||||
class PENumber : public PExpr {
|
||||
|
||||
public:
|
||||
|
|
@ -716,8 +784,17 @@ class PECallFunction : public PExpr {
|
|||
|
||||
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
||||
|
||||
|
||||
NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const;
|
||||
|
||||
NetExpr*elaborate_expr_method_(Design*des, NetScope*scope,
|
||||
unsigned expr_wid) const;
|
||||
#if 0
|
||||
NetExpr*elaborate_expr_string_method_(Design*des, NetScope*scope) const;
|
||||
NetExpr*elaborate_expr_enum_method_(Design*des, NetScope*scope,
|
||||
unsigned expr_wid) const;
|
||||
#endif
|
||||
|
||||
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
|
@ -725,6 +802,8 @@ class PECallFunction : public PExpr {
|
|||
unsigned expr_wid) const;
|
||||
unsigned test_width_sfunc_(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
unsigned test_width_method_(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
12
PGate.cc
12
PGate.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -260,7 +260,7 @@ const char* PGBuiltin::gate_name() const
|
|||
}
|
||||
|
||||
PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
|
||||
: PGate(name, pins), overrides_(0), pins_(0),
|
||||
: PGate(name, pins), bound_type_(0), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = type;
|
||||
|
|
@ -268,12 +268,18 @@ PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
|
|||
|
||||
PGModule::PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins)
|
||||
: PGate(name, 0), overrides_(0), pins_(pins),
|
||||
: PGate(name, 0), bound_type_(0), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::PGModule(Module*type, perm_string name)
|
||||
: PGate(name, 0), bound_type_(type), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PGModule::~PGModule()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
6
PGate.h
6
PGate.h
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "svector.h"
|
||||
|
|
@ -201,6 +201,9 @@ class PGModule : public PGate {
|
|||
explicit PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins);
|
||||
|
||||
// If the module type is known by design, then use this
|
||||
// constructor.
|
||||
explicit PGModule(Module*type, perm_string name);
|
||||
|
||||
~PGModule();
|
||||
|
||||
|
|
@ -223,6 +226,7 @@ class PGModule : public PGate {
|
|||
perm_string get_type() const;
|
||||
|
||||
private:
|
||||
Module*bound_type_;
|
||||
perm_string type_;
|
||||
list<PExpr*>*overrides_;
|
||||
named<PExpr*>*pins_;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PGenerate.h"
|
||||
|
|
|
|||
11
PGenerate.h
11
PGenerate.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __PGenerate_H
|
||||
#define __PGenerate_H
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2006-2010,2012 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
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
|
|
@ -80,6 +80,10 @@ class PGenerate : public LineInfo, public LexicalScope {
|
|||
// test value.
|
||||
std::valarray<PExpr*> item_test;
|
||||
|
||||
// defparam assignments found in this scope.
|
||||
typedef pair<pform_name_t,PExpr*> named_expr_t;
|
||||
list<named_expr_t>defparms;
|
||||
|
||||
list<PGate*> gates;
|
||||
void add_gate(PGate*);
|
||||
|
||||
|
|
@ -87,9 +91,6 @@ class PGenerate : public LineInfo, public LexicalScope {
|
|||
map<perm_string,PTask*> tasks;
|
||||
map<perm_string,PFunction*>funcs;
|
||||
|
||||
// genvars declared within this scheme.
|
||||
map<perm_string,LineInfo*> genvars;
|
||||
|
||||
// Generate schemes can contain further generate schemes.
|
||||
list<PGenerate*> generate_schemes;
|
||||
// PGenerate*parent;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Picture Elements, Inc.
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PPackage.h"
|
||||
|
||||
PPackage::PPackage(perm_string name, LexicalScope*parent)
|
||||
: PScopeExtra(name, parent)
|
||||
{
|
||||
}
|
||||
|
||||
PPackage::~PPackage()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef __PPackage_H
|
||||
#define __PPackage_H
|
||||
/*
|
||||
* Copyright (c) 2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PScope.h"
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
|
||||
/*
|
||||
* SystemVerilog supports class declarations with their own lexical
|
||||
* scope, etc. The parser arranges for these to be created and
|
||||
* collected.
|
||||
*/
|
||||
|
||||
class PPackage : public PScopeExtra, public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PPackage (perm_string name, LexicalScope*parent);
|
||||
~PPackage();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PScope.h"
|
||||
|
|
|
|||
12
PScope.h
12
PScope.h
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
|
|
@ -30,6 +30,7 @@ class PExpr;
|
|||
class PFunction;
|
||||
class AProcess;
|
||||
class PProcess;
|
||||
class PClass;
|
||||
class PTask;
|
||||
class PWire;
|
||||
|
||||
|
|
@ -165,8 +166,13 @@ class PScopeExtra : public PScope {
|
|||
~PScopeExtra();
|
||||
|
||||
/* Task definitions within this module */
|
||||
map<perm_string,PTask*> tasks;
|
||||
map<perm_string,PFunction*> funcs;
|
||||
std::map<perm_string,PTask*> tasks;
|
||||
std::map<perm_string,PFunction*> funcs;
|
||||
/* class definitions within this module. */
|
||||
std::map<perm_string,PClass*> classes;
|
||||
|
||||
protected:
|
||||
void dump_classes_(ostream&out, unsigned indent) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
2
PSpec.cc
2
PSpec.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PSpec.h"
|
||||
|
|
|
|||
2
PSpec.h
2
PSpec.h
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
|
|
|
|||
2
PTask.cc
2
PTask.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
2
PTask.h
2
PTask.h
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
|
|
|
|||
2
PUdp.cc
2
PUdp.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PUdp.h"
|
||||
|
|
|
|||
2
PUdp.h
2
PUdp.h
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <map>
|
||||
|
|
|
|||
25
PWire.cc
25
PWire.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -29,7 +29,7 @@ PWire::PWire(perm_string n,
|
|||
: name_(n), type_(t), port_type_(pt), data_type_(dt),
|
||||
signed_(false), isint_(false),
|
||||
port_set_(false), net_set_(false), is_scalar_(false),
|
||||
error_cnt_(0), lidx_(0), ridx_(0), enum_type_(0), struct_type_(0),
|
||||
error_cnt_(0), set_data_type_(0),
|
||||
discipline_(0)
|
||||
{
|
||||
if (t == NetNet::INTEGER) {
|
||||
|
|
@ -242,30 +242,21 @@ void PWire::set_range(const list<pform_range_t>&rlist, PWSRType type)
|
|||
}
|
||||
}
|
||||
|
||||
void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||
void PWire::set_unpacked_idx(const list<pform_range_t>&ranges)
|
||||
{
|
||||
if (lidx_ != 0 || ridx_ != 0) {
|
||||
if (! unpacked_.empty()) {
|
||||
cerr << get_fileline() << ": error: Array ``" << name_
|
||||
<< "'' has already been declared." << endl;
|
||||
error_cnt_ += 1;
|
||||
} else {
|
||||
lidx_ = ldx;
|
||||
ridx_ = rdx;
|
||||
unpacked_ = ranges;
|
||||
}
|
||||
}
|
||||
|
||||
void PWire::set_enumeration(enum_type_t*enum_type)
|
||||
void PWire::set_data_type(data_type_t*type)
|
||||
{
|
||||
assert(enum_type_ == 0);
|
||||
assert(struct_type_ == 0);
|
||||
enum_type_ = enum_type;
|
||||
}
|
||||
|
||||
void PWire::set_struct_type(struct_type_t*type)
|
||||
{
|
||||
assert(enum_type_ == 0);
|
||||
assert(struct_type_ == 0);
|
||||
struct_type_ = type;
|
||||
assert(set_data_type_ == 0);
|
||||
set_data_type_ = type;
|
||||
}
|
||||
|
||||
void PWire::set_discipline(ivl_discipline_t d)
|
||||
|
|
|
|||
18
PWire.h
18
PWire.h
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -33,6 +33,7 @@ class ostream;
|
|||
|
||||
class PExpr;
|
||||
class Design;
|
||||
class netdarray_t;
|
||||
|
||||
/*
|
||||
* The different type of PWire::set_range() calls.
|
||||
|
|
@ -78,10 +79,9 @@ class PWire : public LineInfo {
|
|||
void set_range_scalar(PWSRType type);
|
||||
void set_range(const std::list<pform_range_t>&ranges, PWSRType type);
|
||||
|
||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||
void set_unpacked_idx(const std::list<pform_range_t>&ranges);
|
||||
|
||||
void set_enumeration(enum_type_t*enum_type);
|
||||
void set_struct_type(struct_type_t*type);
|
||||
void set_data_type(data_type_t*type);
|
||||
|
||||
void set_discipline(ivl_discipline_t);
|
||||
ivl_discipline_t get_discipline(void) const;
|
||||
|
|
@ -115,12 +115,12 @@ class PWire : public LineInfo {
|
|||
unsigned error_cnt_;
|
||||
|
||||
// If this wire is actually a memory, these indices will give
|
||||
// me the size and address range of the memory.
|
||||
PExpr*lidx_;
|
||||
PExpr*ridx_;
|
||||
// me the size and address ranges of the memory.
|
||||
std::list<pform_range_t>unpacked_;
|
||||
|
||||
enum_type_t*enum_type_;
|
||||
struct_type_t*struct_type_;
|
||||
// This is the complex type of the wire. the data_type_ may
|
||||
// modify how this is interpreted.
|
||||
data_type_t*set_data_type_;
|
||||
|
||||
ivl_discipline_t discipline_;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ on a UNIX-like system:
|
|||
- termcap
|
||||
The readline library in turn uses termcap.
|
||||
|
||||
If you are building from CVS, you will also need software to generate
|
||||
If you are building from git, you will also need software to generate
|
||||
the configure scripts.
|
||||
|
||||
- autoconf 2.53
|
||||
|
|
|
|||
11
Statement.cc
11
Statement.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2008,2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2008,2010,2012 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
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -114,6 +114,13 @@ PBlock::~PBlock()
|
|||
delete list_[idx];
|
||||
}
|
||||
|
||||
void PBlock::set_join_type(PBlock::BL_TYPE type)
|
||||
{
|
||||
assert(bl_type_ == BL_PAR);
|
||||
assert(type==BL_PAR || type==BL_JOIN_NONE || type==BL_JOIN_ANY);
|
||||
bl_type_ = type;
|
||||
}
|
||||
|
||||
void PBlock::set_statement(const vector<Statement*>&st)
|
||||
{
|
||||
list_ = st;
|
||||
|
|
|
|||
18
Statement.h
18
Statement.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __Statement_H
|
||||
#define __Statement_H
|
||||
/*
|
||||
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2008,2012 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
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <string>
|
||||
|
|
@ -106,6 +106,10 @@ class PAssign_ : public Statement {
|
|||
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, unsigned lv_width,
|
||||
ivl_variable_type_t type) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const;
|
||||
|
||||
NetExpr* elaborate_rval_obj_(Design*, NetScope*,
|
||||
ivl_variable_type_t type) const;
|
||||
|
||||
PExpr* delay_;
|
||||
PEventStatement*event_;
|
||||
|
|
@ -165,7 +169,7 @@ class PAssignNB : public PAssign_ {
|
|||
class PBlock : public PScope, public Statement {
|
||||
|
||||
public:
|
||||
enum BL_TYPE { BL_SEQ, BL_PAR };
|
||||
enum BL_TYPE { BL_SEQ, BL_PAR, BL_JOIN_NONE, BL_JOIN_ANY };
|
||||
|
||||
// If the block has a name, it is a scope and also has a parent.
|
||||
explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t);
|
||||
|
|
@ -175,6 +179,10 @@ class PBlock : public PScope, public Statement {
|
|||
|
||||
BL_TYPE bl_type() const { return bl_type_; }
|
||||
|
||||
// If the bl_type() is BL_PAR, it is possible to replace it
|
||||
// with JOIN_NONE or JOIN_ANY. This is to help the parser.
|
||||
void set_join_type(BL_TYPE);
|
||||
|
||||
void set_statement(const std::vector<Statement*>&st);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
|
@ -183,7 +191,7 @@ class PBlock : public PScope, public Statement {
|
|||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
const BL_TYPE bl_type_;
|
||||
BL_TYPE bl_type_;
|
||||
std::vector<Statement*>list_;
|
||||
};
|
||||
|
||||
|
|
@ -203,6 +211,8 @@ class PCallTask : public Statement {
|
|||
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
||||
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
|
||||
|
||||
NetProc*elaborate_method_(Design*des, NetScope*scope) const;
|
||||
|
||||
pform_name_t path_;
|
||||
vector<PExpr*> parms_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# undef HAVE_INTTYPES_H
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
2
async.cc
2
async.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
#
|
||||
# This shell script exists to run autoconf on source distributions
|
||||
# that are pulled from CVS. The configure scripts are not included
|
||||
# in CVS, and there are several configure.in files, so it is easiest
|
||||
# to just run this script to autoconf wherever needed.
|
||||
# that are pulled from git The configure script is not included
|
||||
# in git, so it is easiest to just run this script whenever needed
|
||||
# to generate the configure script.
|
||||
#
|
||||
echo "Autoconf in root..."
|
||||
autoconf -f
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Library 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
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <vpi_user.h>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <list>
|
||||
|
|
@ -177,6 +177,11 @@ static inline bool gn_system_verilog(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline bool gn_modules_nest(void)
|
||||
{
|
||||
return gn_system_verilog();
|
||||
}
|
||||
|
||||
/* The bits of these GN_KEYWORDS_* constants define non-intersecting
|
||||
sets of keywords. The compiler enables groups of keywords by setting
|
||||
lexor_keyword_mask with the OR of the bits for the keywords to be
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __config_H /* -*- c++ -*- */
|
||||
#define __config_H
|
||||
/*
|
||||
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2012 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
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
@ -53,6 +53,8 @@
|
|||
/* These two are needed by the lxt and lxt2 files (copied from GTKWave). */
|
||||
# undef HAVE_ALLOCA_H
|
||||
# undef HAVE_FSEEKO
|
||||
/* And this is needed by the fst files (copied from GTKWave). */
|
||||
# undef HAVE_LIBPTHREAD
|
||||
|
||||
/*
|
||||
* Define this if you want to compile vvp with memory freeing and
|
||||
|
|
|
|||
27
configure.in
27
configure.in
|
|
@ -36,7 +36,7 @@ then
|
|||
echo ""
|
||||
echo "*** Warning: No suitable gperf found. ***"
|
||||
echo " The gperf package is essential for building ivl from"
|
||||
echo " CVS sources, or modifying the parse engine of ivl itself."
|
||||
echo " git sources, or modifying the parse engine of ivl itself."
|
||||
echo " You can get away without it when simply building from"
|
||||
echo " snapshots or major releases."
|
||||
echo ""
|
||||
|
|
@ -91,6 +91,20 @@ fi
|
|||
|
||||
AC_LANG(C++)
|
||||
|
||||
AC_ARG_WITH([m32], [AC_HELP_STRING([--with-m32], [Compile 32-bit on x86_64])],
|
||||
[ with_m32=yes ],[ with_m32=no ])
|
||||
|
||||
AS_IF( [test "x$with_m32" = xyes],
|
||||
[ AC_MSG_NOTICE([Compiling for 32-bit environment - needs gcc on x86_64])
|
||||
LDTARGETFLAGS="-m elf_i386"
|
||||
CTARGETFLAGS="-m32"
|
||||
],
|
||||
[])
|
||||
|
||||
CFLAGS="$CTARGETFLAGS $CFLAGS"
|
||||
CXXFLAGS="$CTARGETFLAGS $CXXFLAGS"
|
||||
LDFLAGS="$CTARGETFLAGS $LDFLAGS"
|
||||
|
||||
# Check that we are using either the GNU compilers or the Sun compilers
|
||||
# but not a mixture of the two (not currently supported).
|
||||
AC_CHECK_DECL(__SUNPRO_CC, using_sunpro_cc=1, using_sunpro_cc=0)
|
||||
|
|
@ -111,7 +125,11 @@ else
|
|||
fi
|
||||
fi
|
||||
|
||||
iverilog_temp_cxxflags="$CXXFLAGS"
|
||||
CXXFLAGS="-DHAVE_DECL_BASENAME $CXXFLAGS"
|
||||
|
||||
AC_CHECK_HEADERS(getopt.h inttypes.h libiberty.h iosfwd sys/wait.h)
|
||||
CXXFLAGS="$iverilog_temp_cxxflags"
|
||||
|
||||
AC_CHECK_SIZEOF(unsigned long long)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
|
|
@ -178,6 +196,11 @@ if test -z "$DLLIB" ; then
|
|||
AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
|
||||
fi
|
||||
AC_SUBST(DLLIB)
|
||||
AC_SUBST(LDRELOCFLAGS)
|
||||
|
||||
AC_SUBST(CTARGETFLAGS)
|
||||
AC_SUBST(LDTARGETFLAGS)
|
||||
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
|
|
@ -302,6 +325,4 @@ AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
|
|||
fi
|
||||
AC_MSG_RESULT(ok)
|
||||
|
||||
# XXX disable tgt-fpga for the moment
|
||||
|
||||
AC_OUTPUT(Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
// These are correct and are used to find the base (zero) pin.
|
||||
thisSubtraction:netlist.h:4169
|
||||
thisSubtraction:netlist.h:4178
|
||||
thisSubtraction:netlist.h:4430
|
||||
thisSubtraction:netlist.h:4439
|
||||
|
|
|
|||
189
cprop.cc
189
cprop.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2010,2012 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
|
||||
|
|
@ -14,18 +14,19 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <algorithm>
|
||||
# include <vector>
|
||||
# include <cstdlib>
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "functor.h"
|
||||
# include "compiler.h"
|
||||
# include "ivl_assert.h"
|
||||
# include <vector>
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -42,11 +43,14 @@ struct cprop_functor : public functor_t {
|
|||
virtual void signal(Design*des, NetNet*obj);
|
||||
virtual void lpm_add_sub(Design*des, NetAddSub*obj);
|
||||
virtual void lpm_compare(Design*des, NetCompare*obj);
|
||||
virtual void lpm_compare_eq_(Design*des, NetCompare*obj);
|
||||
virtual void lpm_concat(Design*des, NetConcat*obj);
|
||||
virtual void lpm_ff(Design*des, NetFF*obj);
|
||||
virtual void lpm_logic(Design*des, NetLogic*obj);
|
||||
virtual void lpm_mux(Design*des, NetMux*obj);
|
||||
};
|
||||
virtual void lpm_part_select(Design*des, NetPartSelect*obj);
|
||||
|
||||
void lpm_compare_eq_(Design*des, NetCompare*obj);
|
||||
};
|
||||
|
||||
void cprop_functor::signal(Design*, NetNet*)
|
||||
{
|
||||
|
|
@ -74,6 +78,45 @@ void cprop_functor::lpm_compare_eq_(Design*, NetCompare*)
|
|||
{
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_concat(Design*des, NetConcat*obj)
|
||||
{
|
||||
verinum result (verinum::Vz, obj->width());
|
||||
unsigned off = 0;
|
||||
|
||||
for (unsigned idx = 1 ; idx < obj->pin_count() ; idx += 1) {
|
||||
Nexus*nex = obj->pin(idx).nexus();
|
||||
// If there are non-constant drivers, then give up.
|
||||
if (! nex->drivers_constant())
|
||||
return;
|
||||
|
||||
verinum tmp = nex->driven_vector();
|
||||
result.set(off, tmp);
|
||||
off += tmp.len();
|
||||
}
|
||||
|
||||
if (debug_optimizer)
|
||||
cerr << obj->get_fileline() << ": cprop_functor::lpm_concat: "
|
||||
<< "Replace NetConcat with " << result << "." << endl;
|
||||
|
||||
|
||||
NetScope*scope = obj->scope();
|
||||
|
||||
// Create a NetConst object to carry the result. Give it the
|
||||
// same name as the Concat object that we are replacing, and
|
||||
// link the NetConst to the NetConcat object. Then delete the
|
||||
// concat that is now replaced.
|
||||
NetConst*result_obj = new NetConst(scope, obj->name(), result);
|
||||
result_obj->set_line(*obj);
|
||||
des->add_node(result_obj);
|
||||
connect(obj->pin(0), result_obj->pin(0));
|
||||
|
||||
// Note that this will leave the const inputs to dangle. They
|
||||
// will be reaped by other passes of cprop_functor.
|
||||
delete obj;
|
||||
|
||||
count += 1;
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_ff(Design*, NetFF*obj)
|
||||
{
|
||||
// Look for and count unlinked FF outputs. Note that if the
|
||||
|
|
@ -150,6 +193,142 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
|||
count += 1;
|
||||
}
|
||||
|
||||
static bool compare_base(NetPartSelect*a, NetPartSelect*b)
|
||||
{
|
||||
return a->base() < b->base();
|
||||
}
|
||||
|
||||
/*
|
||||
* This optimization searches for Nexa that are driven only by
|
||||
* NetPartSelect(PV) outputs. These might turn from Verilog input that
|
||||
* looks like this:
|
||||
* wire [7:0] foo
|
||||
* assign foo[7:4] = a;
|
||||
* assign foo[3:0] = b;
|
||||
* The idea is to convert the part selects of the above to a single
|
||||
* concatenation that looks like this:
|
||||
* assign foo = {a, b};
|
||||
*/
|
||||
void cprop_functor::lpm_part_select(Design*des, NetPartSelect*obj)
|
||||
{
|
||||
if (obj->dir() != NetPartSelect::PV)
|
||||
return;
|
||||
|
||||
NetScope*scope = obj->scope();
|
||||
Nexus*nex = obj->pin(1).nexus();
|
||||
vector<NetPartSelect*> obj_set;
|
||||
|
||||
for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) {
|
||||
|
||||
// If this is an input (or passive) then ignore it.
|
||||
if (cur->get_dir() != Link::OUTPUT)
|
||||
continue;
|
||||
|
||||
// Check to see if this is the output of a
|
||||
// NetPartSelect::PV. If not, then give up on the blend.
|
||||
NetPins*tmp_obj = cur->get_obj();
|
||||
unsigned tmp_pin = cur->get_pin();
|
||||
|
||||
NetPartSelect*cur_obj = dynamic_cast<NetPartSelect*> (tmp_obj);
|
||||
if (cur_obj == 0)
|
||||
return;
|
||||
|
||||
if (cur_obj->dir() != NetPartSelect::PV)
|
||||
return;
|
||||
|
||||
if (tmp_pin != 1)
|
||||
return;
|
||||
|
||||
obj_set.push_back(cur_obj);
|
||||
}
|
||||
|
||||
if (obj_set.size() < 2)
|
||||
return;
|
||||
|
||||
if (debug_optimizer)
|
||||
cerr << obj->get_fileline() << ": cprop::lpm_part_select: "
|
||||
<< "Found " << obj_set.size() << " NetPartSelect(PV) objects."
|
||||
<< endl;
|
||||
|
||||
// Sort by increasing base offset.
|
||||
sort(obj_set.begin(), obj_set.end(), compare_base);
|
||||
|
||||
// Check and make sure there are no overlaps. If there are,
|
||||
// then give up on this optimization.
|
||||
for (size_t idx = 1 ; idx < obj_set.size() ; idx += 1) {
|
||||
unsigned top = obj_set[idx-1]->base() + obj_set[idx-1]->width();
|
||||
if (top > obj_set[idx]->base()) {
|
||||
if (debug_optimizer)
|
||||
cerr << obj->get_fileline() << ": cprop::lpm_part_select: "
|
||||
<< "Range [" << obj_set[idx-1]->base()
|
||||
<< " " << top << ") overlaps PV starting at "
|
||||
<< obj_set[idx]->base() << ". Give up." << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the tail runs off the end of the target. If so it
|
||||
// should be possible to replace it with a bit select to
|
||||
// shorten the object for the target, but for now just give up.
|
||||
unsigned sig_width = nex->vector_width();
|
||||
if (obj_set.back()->base() + obj_set.back()->width() > sig_width) {
|
||||
if (debug_optimizer)
|
||||
cerr << obj->get_fileline() << ": cprop::lpm_part_select: "
|
||||
<< "Range [" << obj_set.back()->base()
|
||||
<< ":" << (obj_set.back()->base() + obj_set.back()->width() - 1)
|
||||
<< "] runs off the end of target." << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Figure out how many components we are going to need.
|
||||
unsigned part_count = 0;
|
||||
unsigned off = 0;
|
||||
for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) {
|
||||
if (obj_set[idx]->base() > off) {
|
||||
off = obj_set[idx]->base();
|
||||
part_count += 1;
|
||||
}
|
||||
off += obj_set[idx]->width();
|
||||
part_count += 1;
|
||||
}
|
||||
|
||||
if (off < sig_width)
|
||||
part_count += 1;
|
||||
|
||||
NetConcat*concat = new NetConcat(scope, scope->local_symbol(),
|
||||
sig_width, part_count);
|
||||
concat->set_line(*obj);
|
||||
des->add_node(concat);
|
||||
connect(concat->pin(0), obj->pin(1));
|
||||
|
||||
off = 0;
|
||||
size_t concat_pin = 1;
|
||||
for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) {
|
||||
NetPartSelect*cobj = obj_set[idx];
|
||||
if (cobj->base() > off) {
|
||||
NetNet*zzz = make_const_z(des, scope, cobj->base()-off);
|
||||
connect(concat->pin(concat_pin), zzz->pin(0));
|
||||
concat_pin += 1;
|
||||
off = cobj->base();
|
||||
}
|
||||
connect(concat->pin(concat_pin), cobj->pin(0));
|
||||
concat_pin += 1;
|
||||
off += cobj->width();
|
||||
}
|
||||
if (off < sig_width) {
|
||||
NetNet*zzz = make_const_z(des, scope, sig_width-off);
|
||||
connect(concat->pin(concat_pin), zzz->pin(0));
|
||||
concat_pin += 1;
|
||||
}
|
||||
ivl_assert(*obj, concat_pin == concat->pin_count());
|
||||
|
||||
for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) {
|
||||
delete obj_set[idx];
|
||||
}
|
||||
|
||||
count += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This functor looks to see if the constant is connected to nothing
|
||||
* but signals. If that is the case, delete the dangling constant and
|
||||
|
|
|
|||
150
design_dump.cc
150
design_dump.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -28,6 +28,8 @@
|
|||
# include "netlist.h"
|
||||
# include "compiler.h"
|
||||
# include "discipline.h"
|
||||
# include "netdarray.h"
|
||||
# include "netvector.h"
|
||||
# include "ivl_assert.h"
|
||||
# include "PExpr.h"
|
||||
|
||||
|
|
@ -40,6 +42,12 @@ static ostream& operator<< (ostream&o, NetBlock::Type t)
|
|||
case NetBlock::PARA:
|
||||
o << "fork";
|
||||
break;
|
||||
case NetBlock::PARA_JOIN_NONE:
|
||||
o << "fork-join_none";
|
||||
break;
|
||||
case NetBlock::PARA_JOIN_ANY:
|
||||
o << "fork-join_any";
|
||||
break;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
|
@ -98,6 +106,12 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
|
|||
case IVL_VT_STRING:
|
||||
o << "string";
|
||||
break;
|
||||
case IVL_VT_DARRAY:
|
||||
o << "darray";
|
||||
break;
|
||||
case IVL_VT_CLASS:
|
||||
o << "class";
|
||||
break;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
|
@ -130,6 +144,24 @@ ostream& operator << (ostream&o, ivl_switch_type_t val)
|
|||
return o;
|
||||
}
|
||||
|
||||
ostream& ivl_type_s::debug_dump(ostream&o) const
|
||||
{
|
||||
o << typeid(*this).name();
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& netdarray_t::debug_dump(ostream&o) const
|
||||
{
|
||||
o << "dynamic array of " << *element_type();
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& netvector_t::debug_dump(ostream&o) const
|
||||
{
|
||||
o << type_ << (signed_? " signed" : " unsigned") << packed_dims_;
|
||||
return o;
|
||||
}
|
||||
|
||||
static inline void dump_scope_path(ostream&o, const NetScope*scope)
|
||||
{
|
||||
const NetScope*parent = scope->parent();
|
||||
|
|
@ -187,11 +219,30 @@ void NetDelaySrc::dump(ostream&o, unsigned ind) const
|
|||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
ostream&operator<<(ostream&out, const list<NetNet::range_t>&rlist)
|
||||
static inline ostream&operator<<(ostream&out, const netrange_t&that)
|
||||
{
|
||||
for (list<NetNet::range_t>::const_iterator cur = rlist.begin()
|
||||
if (that.defined())
|
||||
out << "[" << that.get_msb() << ":" << that.get_lsb() << "]";
|
||||
else
|
||||
out << "[]";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
ostream&operator<<(ostream&out, const list<netrange_t>&rlist)
|
||||
{
|
||||
for (list<netrange_t>::const_iterator cur = rlist.begin()
|
||||
; cur != rlist.end() ; ++cur) {
|
||||
out << "[" << cur->msb << ":" << cur->lsb << "]";
|
||||
out << *cur;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
ostream&operator<<(ostream&out, const vector<netrange_t>&rlist)
|
||||
{
|
||||
for (vector<netrange_t>::const_iterator cur = rlist.begin()
|
||||
; cur != rlist.end() ; ++cur) {
|
||||
out << *cur;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
|
@ -200,12 +251,10 @@ ostream&operator<<(ostream&out, const list<NetNet::range_t>&rlist)
|
|||
void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << type() << ": " << name()
|
||||
<< "[" << s0_ << ":" << e0_ << " count=" << pin_count() << "]";
|
||||
<< unpacked_dims_ << " unpacked dims=" << unpacked_dimensions();
|
||||
o << " pin_count=" << pin_count();
|
||||
if (local_flag_)
|
||||
o << " (local)";
|
||||
o << " " << data_type_;
|
||||
if (signed_)
|
||||
o << " signed";
|
||||
switch (port_type_) {
|
||||
case NetNet::NOT_A_PORT:
|
||||
break;
|
||||
|
|
@ -229,7 +278,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
|||
if (ivl_discipline_t dis = get_discipline())
|
||||
o << " discipline=" << dis->name();
|
||||
|
||||
o << " packed dims: " << packed_dims_;
|
||||
if (net_type_) o << " " << *net_type_;
|
||||
|
||||
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
|
||||
if (scope())
|
||||
|
|
@ -470,9 +519,7 @@ void NetCaseCmp::dump_node(ostream&o, unsigned ind) const
|
|||
|
||||
void NetConst::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "constant " << width_ << "'b";
|
||||
for (unsigned idx = width_ ; idx > 0 ; idx -= 1)
|
||||
o << value_[idx-1];
|
||||
o << setw(ind) << "" << "constant " << value_;
|
||||
o << ": " << name();
|
||||
if (rise_time())
|
||||
o << " #(" << *rise_time()
|
||||
|
|
@ -808,6 +855,9 @@ void NetAssign_::dump_lval(ostream&o) const
|
|||
{
|
||||
if (sig_) {
|
||||
o << sig_->name();
|
||||
if (! member_.nil()) {
|
||||
o << "." << member_;
|
||||
}
|
||||
if (word_) {
|
||||
o << "[word=" << *word_ << "]";
|
||||
}
|
||||
|
|
@ -1059,7 +1109,7 @@ void NetFuncDef::dump(ostream&o, unsigned ind) const
|
|||
if (result_sig_) {
|
||||
o << setw(ind+2) << "" << "Return signal: ";
|
||||
if (result_sig_->get_signed()) o << "+";
|
||||
o << result_sig_->name() << result_sig_->packed_dims() << endl;
|
||||
o << result_sig_->name() << endl;
|
||||
}
|
||||
o << setw(ind+2) << "" << "Arguments: ";
|
||||
if (port_count() == 0) o << "<none>";
|
||||
|
|
@ -1081,7 +1131,7 @@ void NetFuncDef::dump(ostream&o, unsigned ind) const
|
|||
break;
|
||||
}
|
||||
if (port(idx)->get_signed()) o << "+";
|
||||
o << port(idx)->name() << port(idx)->packed_dims() << endl;
|
||||
o << port(idx)->name() << endl;
|
||||
}
|
||||
if (statement_)
|
||||
statement_->dump(o, ind+2);
|
||||
|
|
@ -1127,6 +1177,9 @@ void NetScope::dump(ostream&o) const
|
|||
print_type(o);
|
||||
if (is_auto()) o << " (automatic)";
|
||||
if (is_cell()) o << " (cell)";
|
||||
if (nested_module()) o << " (nested)";
|
||||
if (program_block()) o << " (program)";
|
||||
|
||||
o << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
|
||||
|
|
@ -1141,7 +1194,10 @@ void NetScope::dump(ostream&o) const
|
|||
map<perm_string,param_expr_t>::const_iterator pp;
|
||||
for (pp = parameters.begin()
|
||||
; pp != parameters.end() ; ++ pp ) {
|
||||
o << " parameter ";
|
||||
if ((*pp).second.is_annotatable)
|
||||
o << " specparam ";
|
||||
else
|
||||
o << " parameter ";
|
||||
|
||||
o << pp->second.type << " ";
|
||||
|
||||
|
|
@ -1188,12 +1244,6 @@ void NetScope::dump(ostream&o) const
|
|||
|
||||
o << ";" << endl;
|
||||
}
|
||||
|
||||
for (pp = localparams.begin()
|
||||
; pp != localparams.end() ; ++ pp ) {
|
||||
o << " localparam " << (*pp).first << " = " <<
|
||||
*(*pp).second.val << ";" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump the saved defparam assignments here. */
|
||||
|
|
@ -1245,27 +1295,6 @@ void NetScope::dump(ostream&o) const
|
|||
cur->second->dump_net(o, 4);
|
||||
}
|
||||
|
||||
// Dump specparams
|
||||
typedef map<perm_string,spec_val_t>::const_iterator specparam_it_t;
|
||||
for (specparam_it_t cur = specparams.begin()
|
||||
; cur != specparams.end() ; ++ cur ) {
|
||||
o << " specparam " << (*cur).first
|
||||
<< " = ";
|
||||
spec_val_t value = (*cur).second;
|
||||
switch (value.type) {
|
||||
case IVL_VT_REAL:
|
||||
o << "R:" << value.real_val;
|
||||
break;
|
||||
case IVL_VT_BOOL:
|
||||
o << "I:" << value.integer;
|
||||
break;
|
||||
default:
|
||||
o << "<bad type>";
|
||||
break;
|
||||
}
|
||||
o << endl;
|
||||
}
|
||||
|
||||
switch (type_) {
|
||||
case FUNC:
|
||||
if (func_def())
|
||||
|
|
@ -1293,12 +1322,12 @@ void NetSTask::dump(ostream&o, unsigned ind) const
|
|||
{
|
||||
o << setw(ind) << "" << name_;
|
||||
|
||||
if (parms_.count() > 0) {
|
||||
if (! parms_.empty()) {
|
||||
o << "(";
|
||||
if (parms_[0])
|
||||
parms_[0]->dump(o);
|
||||
|
||||
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
o << ", ";
|
||||
if (parms_[idx])
|
||||
parms_[idx]->dump(o);
|
||||
|
|
@ -1428,7 +1457,7 @@ void NetEConcat::dump(ostream&o) const
|
|||
else
|
||||
o << "{";
|
||||
|
||||
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_[idx])
|
||||
o << ", " << *parms_[idx];
|
||||
else
|
||||
|
|
@ -1481,6 +1510,21 @@ void NetENetenum::dump(ostream&o) const
|
|||
o << "<netenum=" << netenum_ << ">";
|
||||
}
|
||||
|
||||
void NetENew::dump(ostream&o) const
|
||||
{
|
||||
o << "new <type>";
|
||||
}
|
||||
|
||||
void NetENull::dump(ostream&o) const
|
||||
{
|
||||
o << "<null>";
|
||||
}
|
||||
|
||||
void NetEProperty::dump(ostream&o) const
|
||||
{
|
||||
o << net_->name() << ".<" << pidx_ << ">";
|
||||
}
|
||||
|
||||
void NetEScope::dump(ostream&o) const
|
||||
{
|
||||
o << "<scope=" << scope_path(scope_) << ">";
|
||||
|
|
@ -1502,7 +1546,14 @@ void NetESelect::dump(ostream&o) const
|
|||
else
|
||||
o << "(0)";
|
||||
|
||||
o << "+:" << expr_width() << "]>";
|
||||
o << "+:" << expr_width() << "]";
|
||||
if (ivl_type_t nt = net_type()) {
|
||||
o << " net_type=(" << *nt << ")";
|
||||
} else {
|
||||
o << " expr_type=" << expr_type();
|
||||
}
|
||||
|
||||
o << ">";
|
||||
}
|
||||
|
||||
void NetESFunc::dump(ostream&o) const
|
||||
|
|
@ -1521,7 +1572,8 @@ void NetESignal::dump(ostream&o) const
|
|||
o << "+";
|
||||
o << name();
|
||||
if (word_) o << "[word=" << *word_ << "]";
|
||||
o << sig()->packed_dims();
|
||||
vector<netrange_t>tmp = net_->net_type()->slice_dimensions();
|
||||
o << tmp;
|
||||
}
|
||||
|
||||
void NetETernary::dump(ostream&o) const
|
||||
|
|
@ -1533,9 +1585,9 @@ void NetETernary::dump(ostream&o) const
|
|||
void NetEUFunc::dump(ostream&o) const
|
||||
{
|
||||
o << func_->basename() << "(";
|
||||
if (parms_.count() > 0) {
|
||||
if (! parms_.empty()) {
|
||||
parms_[0]->dump(o);
|
||||
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
o << ", ";
|
||||
parms_[idx]->dump(o);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "discipline.h"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
2
dosify.c
2
dosify.c
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Library 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
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Library 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
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "cfparse.h"
|
||||
|
|
@ -195,7 +195,6 @@ int yywrap()
|
|||
void switch_to_command_file(const char *file)
|
||||
{
|
||||
char path[4096];
|
||||
char *cp;
|
||||
|
||||
if (cmdfile_stack_ptr >= MAX_CMDFILE_DEPTH) {
|
||||
fprintf(stderr, "Error: command files nested too deeply (%d) "
|
||||
|
|
@ -213,6 +212,7 @@ void switch_to_command_file(const char *file)
|
|||
* file name.
|
||||
*/
|
||||
if (file[0] != '/') {
|
||||
char *cp;
|
||||
strcpy(path, current_file);
|
||||
cp = strrchr(path, '/');
|
||||
if (cp == 0) strcpy(path, file); /* A base file. */
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "globals.h"
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <stddef.h>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <string.h>
|
||||
|
|
|
|||
28
dup_expr.cc
28
dup_expr.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -110,10 +110,10 @@ NetEBShift* NetEBShift::dup_expr() const
|
|||
|
||||
NetEConcat* NetEConcat::dup_expr() const
|
||||
{
|
||||
NetEConcat*dup = new NetEConcat(parms_.count(), repeat_);
|
||||
NetEConcat*dup = new NetEConcat(parms_.size(), repeat_, expr_type_);
|
||||
ivl_assert(*this, dup);
|
||||
dup->set_line(*this);
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1)
|
||||
if (parms_[idx]) {
|
||||
NetExpr*tmp = parms_[idx]->dup_expr();
|
||||
ivl_assert(*this, tmp);
|
||||
|
|
@ -177,6 +177,24 @@ NetENetenum* NetENetenum::dup_expr() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetENew* NetENew::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetENull* NetENull::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEProperty* NetEProperty::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEScope* NetEScope::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
|
|
@ -232,9 +250,9 @@ NetETernary* NetETernary::dup_expr() const
|
|||
NetEUFunc* NetEUFunc::dup_expr() const
|
||||
{
|
||||
NetEUFunc*tmp;
|
||||
svector<NetExpr*> tmp_parms (parms_.count());
|
||||
vector<NetExpr*> tmp_parms (parms_.size());
|
||||
|
||||
for (unsigned idx = 0 ; idx < tmp_parms.count() ; idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < tmp_parms.size() ; idx += 1) {
|
||||
ivl_assert(*this, parms_[idx]);
|
||||
tmp_parms[idx] = parms_[idx]->dup_expr();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
866
elab_expr.cc
866
elab_expr.cc
File diff suppressed because it is too large
Load Diff
310
elab_lval.cc
310
elab_lval.cc
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / 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
|
||||
|
|
@ -14,7 +15,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -23,6 +24,7 @@
|
|||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "netstruct.h"
|
||||
# include "netclass.h"
|
||||
# include "compiler.h"
|
||||
# include <cstdlib>
|
||||
# include <iostream>
|
||||
|
|
@ -163,12 +165,17 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
the search with "a.b". */
|
||||
if (reg == 0 && path_.size() >= 2) {
|
||||
pform_name_t use_path = path_;
|
||||
method_name = peek_tail_name(use_path);
|
||||
perm_string tmp_name = peek_tail_name(use_path);
|
||||
use_path.pop_back();
|
||||
symbol_search(this, des, scope, use_path, reg, par, eve);
|
||||
|
||||
if (reg && reg->struct_type() == 0) {
|
||||
method_name = perm_string();
|
||||
if (reg && reg->struct_type()) {
|
||||
method_name = tmp_name;
|
||||
|
||||
} else if (reg && reg->class_type()) {
|
||||
method_name = tmp_name;
|
||||
|
||||
} else {
|
||||
reg = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -185,7 +192,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
ivl_assert(*this, reg);
|
||||
// We are processing the tail of a string of names. For
|
||||
// example, the verilog may be "a.b.c", so we are processing
|
||||
// "c" at this point.
|
||||
// "c" at this point. (Note that if method_name is not nil,
|
||||
// then this is "a.b.c.method" and "a.b.c" is a struct or class.)
|
||||
const name_component_t&name_tail = path_.back();
|
||||
|
||||
// Use the last index to determine what kind of select
|
||||
|
|
@ -202,7 +210,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
// slice. This is, in fact, an error in l-values. Detect the
|
||||
// situation by noting if the index count is less than the
|
||||
// array dimensions (unpacked).
|
||||
if (reg->array_dimensions() > name_tail.index.size()) {
|
||||
if (reg->unpacked_dimensions() > name_tail.index.size()) {
|
||||
cerr << get_fileline() << ": error: Cannot assign to array "
|
||||
<< path_ << ". Did you forget a word index?" << endl;
|
||||
des->errors += 1;
|
||||
|
|
@ -228,7 +236,17 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
return lv;
|
||||
}
|
||||
|
||||
if (reg->array_dimensions() > 0)
|
||||
if (reg->class_type() && !method_name.nil() && gn_system_verilog()) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_class_member_(des, scope, lv, method_name);
|
||||
return lv;
|
||||
}
|
||||
|
||||
// Past this point, we should have taken care of the cases
|
||||
// where the name is a member/method of a struct/class.
|
||||
ivl_assert(*this, method_name.nil());
|
||||
|
||||
if (reg->unpacked_dimensions() > 0)
|
||||
return elaborate_lval_net_word_(des, scope, reg);
|
||||
|
||||
// This must be after the array word elaboration above!
|
||||
|
|
@ -257,9 +275,15 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
|
||||
|
||||
if (use_sel == index_component_t::SEL_BIT) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_bit_(des, scope, lv);
|
||||
return lv;
|
||||
if (reg->darray_type()) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_darray_bit_(des, scope, lv);
|
||||
return lv;
|
||||
} else {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_bit_(des, scope, lv);
|
||||
return lv;
|
||||
}
|
||||
}
|
||||
|
||||
ivl_assert(*this, use_sel == index_component_t::SEL_NONE);
|
||||
|
|
@ -278,6 +302,15 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
|||
const name_component_t&name_tail = path_.back();
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
|
||||
if (name_tail.index.size() < reg->unpacked_dimensions()) {
|
||||
cerr << get_fileline() << ": error: Array " << reg->name()
|
||||
<< " needs " << reg->unpacked_dimensions() << " indices,"
|
||||
<< " but got only " << name_tail.index.size() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make sure there are enough indices to address an array element.
|
||||
const index_component_t&index_head = name_tail.index.front();
|
||||
if (index_head.sel == index_component_t::SEL_PART) {
|
||||
cerr << get_fileline() << ": error: cannot perform a part "
|
||||
|
|
@ -286,47 +319,47 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
|||
return 0;
|
||||
}
|
||||
|
||||
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
|
||||
ivl_assert(*this, index_head.msb != 0);
|
||||
ivl_assert(*this, index_head.lsb == 0);
|
||||
|
||||
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
|
||||
// Evaluate all the index expressions into an
|
||||
// "unpacked_indices" array.
|
||||
list<NetExpr*>unpacked_indices;
|
||||
list<long> unpacked_indices_const;
|
||||
bool flag = indices_to_expressions(des, scope, this,
|
||||
name_tail.index, reg->unpacked_dimensions(),
|
||||
false,
|
||||
unpacked_indices,
|
||||
unpacked_indices_const);
|
||||
|
||||
// If there is a non-zero base to the memory, then build an
|
||||
// expression to calculate the canonical address.
|
||||
if (long base = reg->array_first()) {
|
||||
|
||||
word = normalize_variable_array_base(word, base,
|
||||
reg->array_count());
|
||||
eval_expr(word);
|
||||
NetExpr*canon_index = 0;
|
||||
if (flag) {
|
||||
ivl_assert(*this, unpacked_indices_const.size() == reg->unpacked_dimensions());
|
||||
canon_index = normalize_variable_unpacked(reg, unpacked_indices_const);
|
||||
if (canon_index == 0) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< "ignoring out of bounds l-value array access " << reg->name();
|
||||
for (list<long>::const_iterator cur = unpacked_indices_const.begin()
|
||||
; cur != unpacked_indices_const.end() ; ++cur) {
|
||||
cerr << "[" << *cur << "]";
|
||||
}
|
||||
cerr << "." << endl;
|
||||
}
|
||||
} else {
|
||||
ivl_assert(*this, unpacked_indices.size() == reg->unpacked_dimensions());
|
||||
canon_index = normalize_variable_unpacked(reg, unpacked_indices);
|
||||
}
|
||||
|
||||
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
lv->set_word(word);
|
||||
lv->set_word(canon_index);
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: Set array word=" << *word << endl;
|
||||
cerr << get_fileline() << ": debug: Set array word=" << *canon_index << endl;
|
||||
|
||||
// Test for the case that the index is a constant, and is out
|
||||
// of bounds. The "word" expression is the word index already
|
||||
// converted to canonical address, so this just needs to check
|
||||
// that the address is not too big.
|
||||
if (NetEConst*word_const = dynamic_cast<NetEConst*>(word)) {
|
||||
verinum word_val = word_const->value();
|
||||
long index = word_val.as_long();
|
||||
|
||||
if (index < 0 || index >= (long) reg->array_count()) {
|
||||
cerr << get_fileline() << ": warning: Constant array index "
|
||||
<< (index + reg->array_first())
|
||||
<< " is out of range for array "
|
||||
<< reg->name() << "." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* An array word may also have part selects applied to them. */
|
||||
|
||||
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||
if (name_tail.index.size() > 1)
|
||||
if (name_tail.index.size() > reg->unpacked_dimensions())
|
||||
use_sel = name_tail.index.back().sel;
|
||||
|
||||
if (reg->get_scalar() &&
|
||||
|
|
@ -335,7 +368,7 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
|||
if (reg->data_type() == IVL_VT_REAL) cerr << "real";
|
||||
else cerr << "scalar";
|
||||
cerr << " array word: " << reg->name()
|
||||
<< "[" << *word << "]" << endl;
|
||||
<< "[" << *canon_index << "]" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -404,6 +437,22 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
|||
lv->set_part(mux, lwid);
|
||||
}
|
||||
|
||||
} else if (reg->data_type() == IVL_VT_STRING) {
|
||||
// Special case: This is a select of a string
|
||||
// variable. The target of the assignment is a character
|
||||
// select of a string. Force the r-value to be an 8bit
|
||||
// vector and set the "part" to be the character select
|
||||
// expression. The code generator knows what to do with
|
||||
// this.
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Bit select of string becomes character select." << endl;
|
||||
}
|
||||
if (mux)
|
||||
lv->set_part(mux, 8);
|
||||
else
|
||||
lv->set_part(new NetEConst(verinum(lsb)), 8);
|
||||
|
||||
} else if (mux) {
|
||||
// Non-constant bit mux. Correct the mux for the range
|
||||
// of the vector, then set the l-value part select
|
||||
|
|
@ -433,6 +482,26 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PEIdent::elaborate_lval_darray_bit_(Design*des, NetScope*scope, NetAssign_*lv)const
|
||||
{
|
||||
const name_component_t&name_tail = path_.back();
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
|
||||
// For now, only support single-dimension dynamic arrays.
|
||||
ivl_assert(*this, name_tail.index.size() == 1);
|
||||
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
ivl_assert(*this, index_tail.msb != 0);
|
||||
ivl_assert(*this, index_tail.lsb == 0);
|
||||
|
||||
// Evaluate the select expression...
|
||||
NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
|
||||
lv->set_word(mux);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PEIdent::elaborate_lval_net_part_(Design*des,
|
||||
NetScope*scope,
|
||||
NetAssign_*lv) const
|
||||
|
|
@ -455,7 +524,7 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
|
|||
NetNet*reg = lv->sig();
|
||||
ivl_assert(*this, reg);
|
||||
|
||||
const list<NetNet::range_t>&packed = reg->packed_dims();
|
||||
const vector<netrange_t>&packed = reg->packed_dims();
|
||||
|
||||
// Part selects cannot select slices. So there must be enough
|
||||
// prefix_indices to get all the way to the final dimension.
|
||||
|
|
@ -544,14 +613,14 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
|||
long lsv = base_c->value().as_long();
|
||||
long offset = 0;
|
||||
// Get the signal range.
|
||||
const list<NetNet::range_t>&packed = reg->packed_dims();
|
||||
const vector<netrange_t>&packed = reg->packed_dims();
|
||||
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
|
||||
|
||||
// We want the last range, which is where we work.
|
||||
const NetNet::range_t&rng = packed.back();
|
||||
if (((rng.msb < rng.lsb) &&
|
||||
const netrange_t&rng = packed.back();
|
||||
if (((rng.get_msb() < rng.get_lsb()) &&
|
||||
use_sel == index_component_t::SEL_IDX_UP) ||
|
||||
((rng.msb > rng.lsb) &&
|
||||
((rng.get_msb() > rng.get_lsb()) &&
|
||||
use_sel == index_component_t::SEL_IDX_DO)) {
|
||||
offset = -wid + 1;
|
||||
}
|
||||
|
|
@ -563,7 +632,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
|||
if (warn_ob_select) {
|
||||
if (rel_base < 0) {
|
||||
cerr << get_fileline() << ": warning: " << reg->name();
|
||||
if (reg->array_dimensions() > 0) cerr << "[]";
|
||||
if (reg->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << "[" << lsv;
|
||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
|
|
@ -574,7 +643,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
|||
}
|
||||
if (rel_base + wid > reg->vector_width()) {
|
||||
cerr << get_fileline() << ": warning: " << reg->name();
|
||||
if (reg->array_dimensions() > 0) cerr << "[]";
|
||||
if (reg->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << "[" << lsv;
|
||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
|
|
@ -587,7 +656,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
|||
} else {
|
||||
if (warn_ob_select) {
|
||||
cerr << get_fileline() << ": warning: " << reg->name();
|
||||
if (reg->array_dimensions() > 0) cerr << "[]";
|
||||
if (reg->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << "['bx";
|
||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
|
|
@ -621,17 +690,49 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PEIdent::elaborate_lval_net_packed_member_(Design*des,
|
||||
NetScope*,
|
||||
bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*,
|
||||
NetAssign_*lv,
|
||||
const perm_string&method_name) const
|
||||
{
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": elaborate_lval_net_class_member_: "
|
||||
<< "l-value is property " << method_name
|
||||
<< " of " << lv->sig()->name() << "." << endl;
|
||||
}
|
||||
|
||||
netclass_t*class_type = lv->sig()->class_type();
|
||||
ivl_assert(*this, class_type);
|
||||
|
||||
/* Make sure the property is really present in the class. If
|
||||
not, then generate an error message and return an error. */
|
||||
const ivl_type_s*ptype = class_type->get_property(method_name);
|
||||
if (ptype == 0) {
|
||||
cerr << get_fileline() << ": error: Class " << class_type->get_name()
|
||||
<< " does not have a property " << method_name << "." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
lv->set_property(method_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
||||
NetAssign_*lv,
|
||||
const perm_string&member_name) const
|
||||
{
|
||||
NetNet*reg = lv->sig();
|
||||
ivl_assert(*this, reg);
|
||||
|
||||
netstruct_t*struct_type = reg->struct_type();
|
||||
const netstruct_t*struct_type = reg->struct_type();
|
||||
ivl_assert(*this, struct_type);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: elaborate lval packed member: "
|
||||
<< "path_=" << path_ << endl;
|
||||
}
|
||||
|
||||
if (! struct_type->packed()) {
|
||||
cerr << get_fileline() << ": sorry: Only packed structures "
|
||||
<< "are supported in l-value." << endl;
|
||||
|
|
@ -639,6 +740,27 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Shouldn't be seeing unpacked arrays of packed structs...
|
||||
ivl_assert(*this, reg->unpacked_dimensions() == 0);
|
||||
|
||||
// This is a packed member, so the name is of the form
|
||||
// "a.b[...].c[...]" which means that the path_ must have at
|
||||
// least 2 components. We are processing "c[...]" at that
|
||||
// point (otherwise known as member_name) so we'll save a
|
||||
// reference to it in name_tail. We are also processing "b[]"
|
||||
// so save that as name_base.
|
||||
|
||||
ivl_assert(*this, path_.size() >= 2);
|
||||
|
||||
pform_name_t::const_reverse_iterator name_idx = path_.rbegin();
|
||||
ivl_assert(*this, name_idx->name == member_name);
|
||||
const name_component_t&name_tail = *name_idx;
|
||||
++ name_idx;
|
||||
const name_component_t&name_base = *name_idx;
|
||||
|
||||
// Calculate the offset within the packed structure of the
|
||||
// member, and any indices. We will add in the offset of the
|
||||
// struct into the packed array later.
|
||||
unsigned long off;
|
||||
const netstruct_t::member_t* member = struct_type->packed_member(member_name, off);
|
||||
|
||||
|
|
@ -649,8 +771,90 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des,
|
|||
return false;
|
||||
}
|
||||
|
||||
lv->set_part(new NetEConst(verinum(off)), member->width());
|
||||
return true;
|
||||
unsigned long use_width = member->width();
|
||||
|
||||
if (name_tail.index.size() > member->packed_dims.size()) {
|
||||
cerr << get_fileline() << ": error: Too many index expressions for member." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the index component type. At this point, we only
|
||||
// support bit select or none.
|
||||
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||
if (!name_tail.index.empty())
|
||||
use_sel = name_tail.index.back().sel;
|
||||
|
||||
ivl_assert(*this, use_sel == index_component_t::SEL_NONE || use_sel == index_component_t::SEL_BIT);
|
||||
|
||||
if (! name_tail.index.empty()) {
|
||||
// Evaluate all but the last index expression, into prefix_indices.
|
||||
list<long>prefix_indices;
|
||||
bool rc = evaluate_index_prefix(des, scope, prefix_indices, name_tail.index);
|
||||
ivl_assert(*this, rc);
|
||||
|
||||
// Evaluate the last index expression into a constant long.
|
||||
NetExpr*texpr = elab_and_eval(des, scope, name_tail.index.back().msb, -1, true);
|
||||
long tmp;
|
||||
if (texpr == 0 || !eval_as_long(tmp, texpr)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
"Array index expressions must be constant here." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete texpr;
|
||||
|
||||
// Now use the prefix_to_slice function to calculate the
|
||||
// offset and width of the addressed slice of the member.
|
||||
long loff;
|
||||
unsigned long lwid;
|
||||
prefix_to_slice(member->packed_dims, prefix_indices, tmp, loff, lwid);
|
||||
|
||||
off += loff;
|
||||
use_width = lwid;
|
||||
}
|
||||
|
||||
// The dimenions in the expression must match the packed
|
||||
// dimensions that are declared for the variable. For example,
|
||||
// if foo is a packed array of struct, then this expression
|
||||
// must be "b[n][m]" with the right number of dimensions to
|
||||
// match the declaration of "b".
|
||||
// Note that one of the packed dimensions is the packed struct
|
||||
// itself.
|
||||
ivl_assert(*this, name_base.index.size()+1 == reg->packed_dimensions());
|
||||
|
||||
// Generate an expression that takes the input array of
|
||||
// expressions and generates a canonical offset into the
|
||||
// packed array.
|
||||
NetExpr*packed_base = 0;
|
||||
if (reg->packed_dimensions() > 1) {
|
||||
list<index_component_t>tmp_index = name_base.index;
|
||||
index_component_t member_select;
|
||||
member_select.sel = index_component_t::SEL_BIT;
|
||||
member_select.msb = new PENumber(new verinum(off));
|
||||
tmp_index.push_back(member_select);
|
||||
packed_base = collapse_array_indices(des, scope, reg, tmp_index);
|
||||
}
|
||||
|
||||
long tmp;
|
||||
if (packed_base && eval_as_long(tmp, packed_base)) {
|
||||
off = tmp;
|
||||
delete packed_base;
|
||||
packed_base = 0;
|
||||
}
|
||||
|
||||
if (packed_base == 0) {
|
||||
lv->set_part(new NetEConst(verinum(off)), use_width);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Oops, packed_base is not fully evaluated, so I don't know
|
||||
// yet what to do with it.
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "I don't know how to handle this index expression? " << *packed_base << endl;
|
||||
ivl_assert(*this, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
|
||||
|
|
|
|||
236
elab_net.cc
236
elab_net.cc
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / 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
|
||||
|
|
@ -14,7 +15,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -23,6 +24,7 @@
|
|||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
# include "compiler.h"
|
||||
|
||||
# include <cstdlib>
|
||||
|
|
@ -97,12 +99,12 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
concat operator from most significant to least significant,
|
||||
which is the order they are given in the concat list. */
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(nets[0]->data_type(),width-1,0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, tmp2_vec);
|
||||
|
||||
/* Assume that the data types of the nets are all the same, so
|
||||
we can take the data type of any, the first will do. */
|
||||
osig->data_type(nets[0]->data_type());
|
||||
osig->local_flag(true);
|
||||
osig->set_line(*this);
|
||||
|
||||
|
|
@ -153,8 +155,6 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
assert(width == 0);
|
||||
}
|
||||
|
||||
osig->data_type(nets[0]->data_type());
|
||||
osig->local_flag(true);
|
||||
return osig;
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
// Only treat as part/bit selects any index that is beyond the
|
||||
// word selects for an array. This is not an array, then
|
||||
// dimensions==0 and any index is treated as a select.
|
||||
if (name_tail.index.size() <= sig->array_dimensions()) {
|
||||
if (name_tail.index.size() <= sig->unpacked_dimensions()) {
|
||||
midx = sig->vector_width()-1;
|
||||
lidx = 0;
|
||||
return true;
|
||||
|
|
@ -247,7 +247,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
if (warn_ob_select) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< sig->name();
|
||||
if (sig->array_dimensions() > 0) cerr << "[]";
|
||||
if (sig->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << "['bx";
|
||||
if (index_tail.sel ==
|
||||
index_component_t::SEL_IDX_UP) {
|
||||
|
|
@ -279,7 +279,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
/* Warn about an indexed part select that is out of range. */
|
||||
if (warn_ob_select && (lidx < 0)) {
|
||||
cerr << get_fileline() << ": warning: " << sig->name();
|
||||
if (sig->array_dimensions() > 0) cerr << "[]";
|
||||
if (sig->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << "[" << midx_val;
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
|
|
@ -290,7 +290,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
}
|
||||
if (warn_ob_select && (midx >= (long)sig->vector_width())) {
|
||||
cerr << get_fileline() << ": warning: " << sig->name();
|
||||
if (sig->array_dimensions() > 0) {
|
||||
if (sig->unpacked_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
}
|
||||
cerr << "[" << midx_val;
|
||||
|
|
@ -337,16 +337,11 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
|
||||
cerr << get_fileline() << ": warning: Part select "
|
||||
<< sig->name();
|
||||
if (sig->array_dimensions() > 0) {
|
||||
if (sig->unpacked_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
}
|
||||
cerr << "[" << msb << ":" << lsb
|
||||
<< "] is out of range." << endl;
|
||||
#if 0
|
||||
midx_tmp = sig->vector_width() - 1;
|
||||
lidx_tmp = 0;
|
||||
des->errors += 1;
|
||||
#endif
|
||||
}
|
||||
/* This is completely out side the signal so just skip it. */
|
||||
if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
|
||||
|
|
@ -359,20 +354,31 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
}
|
||||
|
||||
case index_component_t::SEL_BIT:
|
||||
if (name_tail.index.size() > sig->array_dimensions()) {
|
||||
if (name_tail.index.size() > sig->unpacked_dimensions()) {
|
||||
long msb;
|
||||
bool bit_defined_flag;
|
||||
/* bool flag = */ calculate_bits_(des, scope, msb, bit_defined_flag);
|
||||
ivl_assert(*this, bit_defined_flag);
|
||||
midx = sig->sb_to_idx(prefix_indices, msb);
|
||||
if (midx >= (long)sig->vector_width()) {
|
||||
cerr << get_fileline() << ": error: Index " << sig->name()
|
||||
<< "[" << msb << "] is out of range."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
midx = 0;
|
||||
|
||||
if (prefix_indices.size()+2 <= sig->packed_dims().size()) {
|
||||
long tmp_loff;
|
||||
unsigned long tmp_lwid;
|
||||
bool rcl = sig->sb_to_slice(prefix_indices, msb,
|
||||
tmp_loff, tmp_lwid);
|
||||
ivl_assert(*this, rcl);
|
||||
midx = tmp_loff + tmp_lwid - 1;
|
||||
lidx = tmp_loff;
|
||||
} else {
|
||||
midx = sig->sb_to_idx(prefix_indices, msb);
|
||||
if (midx >= (long)sig->vector_width()) {
|
||||
cerr << get_fileline() << ": error: Index " << sig->name()
|
||||
<< "[" << msb << "] is out of range."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
midx = 0;
|
||||
}
|
||||
lidx = midx;
|
||||
}
|
||||
lidx = midx;
|
||||
|
||||
} else {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
|
|
@ -412,18 +418,30 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Break the path_ into the tail name and the prefix. For
|
||||
// example, a name "a.b.c" is broken into name_tail="c" and
|
||||
// path_prefix="a.b".
|
||||
const name_component_t&path_tail = path_.back();
|
||||
pform_name_t path_prefix = path_;
|
||||
path_prefix.pop_back();
|
||||
|
||||
/* If the signal is not found, check to see if this is a
|
||||
member of a struct. Take the name of the form "a.b.member",
|
||||
remove the member and store it into method_name, and retry
|
||||
the search with "a.b". */
|
||||
if (sig == 0 && path_.size() >= 2) {
|
||||
pform_name_t use_path = path_;
|
||||
method_name = peek_tail_name(use_path);
|
||||
use_path.pop_back();
|
||||
symbol_search(this, des, scope, use_path, sig, par, eve);
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||
"Symbol not found, try again with path_prefix=" << path_prefix
|
||||
<< " and method_name=" << path_tail.name << endl;
|
||||
}
|
||||
method_name = path_tail.name;
|
||||
symbol_search(this, des, scope, path_prefix, sig, par, eve);
|
||||
|
||||
// Whoops, not a struct signal, so give up on this avenue.
|
||||
if (sig && sig->struct_type() == 0) {
|
||||
cerr << get_fileline() << ": XXXXX: sig=" << sig->name()
|
||||
<< " is found, but not a struct with member " << method_name << endl;
|
||||
method_name = perm_string();
|
||||
sig = 0;
|
||||
}
|
||||
|
|
@ -460,19 +478,19 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
unsigned midx = sig->vector_width()-1, lidx = 0;
|
||||
// The default word select is the first.
|
||||
long widx = 0;
|
||||
// The widx_val is the word select as entered in the source
|
||||
// code. It's used for error messages.
|
||||
long widx_val = 0;
|
||||
|
||||
const name_component_t&name_tail = path_.back();
|
||||
list<long> unpacked_indices_const;
|
||||
|
||||
netstruct_t*struct_type = 0;
|
||||
const netstruct_t*struct_type = 0;
|
||||
if ((struct_type = sig->struct_type()) && !method_name.nil()) {
|
||||
|
||||
// Detect the variable is a structure and there was a
|
||||
// method name detected.
|
||||
// method name detected. We've already found that
|
||||
// the path_ is <>.sig.method_name and signal
|
||||
// (NetNet). We also know that sig is struct_type(), so
|
||||
// look for a method named method_name.
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||
<< "Signal " << sig->name() << " is a structure, "
|
||||
<< "try to match member " << method_name << endl;
|
||||
|
||||
|
|
@ -480,58 +498,133 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
const struct netstruct_t::member_t*member = struct_type->packed_member(method_name, member_off);
|
||||
ivl_assert(*this, member);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||
<< "Member " << method_name
|
||||
<< " has packed dimensions " << member->packed_dims << "." << endl;
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "Tail name has " << path_tail.index.size() << " indices." << endl;
|
||||
}
|
||||
|
||||
// Rewrite a member select of a packed structure as a
|
||||
// part select of the base variable.
|
||||
lidx = member_off;
|
||||
midx = lidx + member->width() - 1;
|
||||
|
||||
} else if (sig->array_dimensions() > 0) {
|
||||
// The dimensions of the tail of the prefix must match
|
||||
// the dimensions of the signal at this point. (The sig
|
||||
// has a packed dimension for the packed struct size.)
|
||||
// For example, if the path_=a[<m>][<n>].member, then
|
||||
// sig must have 3 packed dimenions: one for the struct
|
||||
// members and two actual packed dimensions.
|
||||
ivl_assert(*this, path_prefix.back().index.size()+1 == sig->packed_dimensions());
|
||||
|
||||
if (name_tail.index.empty()) {
|
||||
cerr << get_fileline() << ": error: array " << sig->name()
|
||||
<< " must be used with an index." << endl;
|
||||
// Elaborate an expression from the packed indices and
|
||||
// the member offset (into the structure) to get a
|
||||
// canonical expression into the packed signal vector.
|
||||
NetExpr*packed_base = 0;
|
||||
if (sig->packed_dimensions() > 1) {
|
||||
list<index_component_t>tmp_index = path_prefix.back().index;
|
||||
index_component_t member_select;
|
||||
member_select.sel = index_component_t::SEL_BIT;
|
||||
member_select.msb = new PENumber(new verinum(member_off));
|
||||
tmp_index.push_back(member_select);
|
||||
packed_base = collapse_array_indices(des, scope, sig, tmp_index);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "packed_base expression = " << *packed_base << endl;
|
||||
}
|
||||
}
|
||||
|
||||
long tmp;
|
||||
if (packed_base && eval_as_long(tmp, packed_base)) {
|
||||
lidx = tmp;
|
||||
midx = lidx + member->width() - 1;
|
||||
delete packed_base;
|
||||
packed_base = 0;
|
||||
}
|
||||
|
||||
// Currently, only support const dimensions here.
|
||||
ivl_assert(*this, packed_base == 0);
|
||||
|
||||
// Now the lidx/midx values get us to the member. Next
|
||||
// up, deal with bit/part selects from the member
|
||||
// itself.
|
||||
ivl_assert(*this, member->packed_dims.size() <= 1);
|
||||
ivl_assert(*this, path_tail.index.size() <= 1);
|
||||
if (! path_tail.index.empty()) {
|
||||
long tmp_off;
|
||||
unsigned long tmp_wid;
|
||||
const index_component_t&tail_sel = path_tail.index.back();
|
||||
ivl_assert(*this, tail_sel.sel == index_component_t::SEL_PART || tail_sel.sel == index_component_t::SEL_BIT);
|
||||
bool rc = calculate_part(this, des, scope, tail_sel, tmp_off, tmp_wid);
|
||||
ivl_assert(*this, rc);
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||
<< "tmp_off=" << tmp_off << ", tmp_wid=" << tmp_wid << endl;
|
||||
lidx += tmp_off;
|
||||
midx = lidx + tmp_wid - 1;
|
||||
}
|
||||
|
||||
} else if (sig->unpacked_dimensions() > 0) {
|
||||
|
||||
// Make sure there are enough indices to address an array element.
|
||||
if (path_tail.index.size() < sig->unpacked_dimensions()) {
|
||||
cerr << get_fileline() << ": error: Array " << path()
|
||||
<< " needs " << sig->unpacked_dimensions() << " indices,"
|
||||
<< " but got only " << path_tail.index.size() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const index_component_t&index_head = name_tail.index.front();
|
||||
if (index_head.sel == index_component_t::SEL_PART) {
|
||||
cerr << get_fileline() << ": error: cannot perform a part "
|
||||
<< "select on array " << sig->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
|
||||
|
||||
NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1, true);
|
||||
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||
if (!tmp) {
|
||||
// Evaluate all the index expressions into an
|
||||
// "unpacked_indices" array.
|
||||
list<NetExpr*>unpacked_indices;
|
||||
bool flag = indices_to_expressions(des, scope, this,
|
||||
path_tail.index, sig->unpacked_dimensions(),
|
||||
true,
|
||||
unpacked_indices,
|
||||
unpacked_indices_const);
|
||||
// Note that !flag includes that there were any other
|
||||
// elaboration errors generating the unpacked_indices list.
|
||||
if (!flag) {
|
||||
cerr << get_fileline() << ": error: array " << sig->name()
|
||||
<< " index must be a constant in this context." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
widx_val = tmp->value().as_long();
|
||||
if (sig->array_index_is_valid(widx_val))
|
||||
widx = sig->array_index_to_address(widx_val);
|
||||
else
|
||||
NetExpr*canon_index = 0;
|
||||
ivl_assert(*this, unpacked_indices_const.size() == sig->unpacked_dimensions());
|
||||
canon_index = normalize_variable_unpacked(sig, unpacked_indices_const);
|
||||
if (canon_index == 0) {
|
||||
// Normalize detected an out-of-bounds
|
||||
// index. Indicate that by setting the generated
|
||||
// widx to -1.
|
||||
widx = -1;
|
||||
delete tmp_ex;
|
||||
|
||||
} else {
|
||||
NetEConst*canon_const = dynamic_cast<NetEConst*>(canon_index);
|
||||
ivl_assert(*this, canon_const);
|
||||
|
||||
widx = canon_const->value().as_long();
|
||||
delete canon_index;
|
||||
}
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: Use [" << widx << "]"
|
||||
<< " to index l-value array." << endl;
|
||||
|
||||
/* The array has a part/bit select at the end. */
|
||||
if (name_tail.index.size() > sig->array_dimensions()) {
|
||||
if (path_tail.index.size() > sig->unpacked_dimensions()) {
|
||||
if (sig->get_scalar()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of ";
|
||||
if (sig->data_type() == IVL_VT_REAL) cerr << "real";
|
||||
else cerr << "scalar";
|
||||
cerr << " array word: " << sig->name()
|
||||
<< "[" << widx_val << "]" << endl;
|
||||
<< as_indices(unpacked_indices_const) << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -550,7 +643,8 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
midx = midx_tmp;
|
||||
lidx = lidx_tmp;
|
||||
}
|
||||
} else if (!name_tail.index.empty()) {
|
||||
|
||||
} else if (!path_tail.index.empty()) {
|
||||
if (sig->get_scalar()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of ";
|
||||
|
|
@ -590,15 +684,16 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
if (widx < 0 || widx >= (long) sig->pin_count()) {
|
||||
cerr << get_fileline() << ": warning: ignoring out of "
|
||||
"bounds l-value array access "
|
||||
<< sig->name() << "[" << widx_val << "]." << endl;
|
||||
<< sig->name() << as_indices(unpacked_indices_const) << "." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),
|
||||
sig->vector_width()-1,0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
sig->type(), sig->vector_width());
|
||||
sig->type(), tmp2_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->local_flag(true);
|
||||
tmp->data_type( sig->data_type() );
|
||||
connect(sig->pin(widx), tmp->pin(0));
|
||||
sig = tmp;
|
||||
}
|
||||
|
|
@ -622,10 +717,11 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
<< " wid=" << subnet_wid <<"]"
|
||||
<< endl;
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),
|
||||
subnet_wid-1,0);
|
||||
NetNet*subsig = new NetNet(sig->scope(),
|
||||
sig->scope()->local_symbol(),
|
||||
NetNet::WIRE, subnet_wid);
|
||||
subsig->data_type( sig->data_type() );
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
subsig->local_flag(true);
|
||||
subsig->set_line(*this);
|
||||
|
||||
|
|
@ -675,9 +771,9 @@ NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
|
|||
* instantiation (PGModule::elaborate_mod_) to get NetNet objects for
|
||||
* the port.
|
||||
*/
|
||||
NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
|
||||
NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope->type() == NetScope::MODULE);
|
||||
ivl_assert(*this, scope->type() == NetScope::MODULE);
|
||||
NetNet*sig = des->find_signal(scope, path_);
|
||||
if (sig == 0) {
|
||||
cerr << get_fileline() << ": error: no wire/reg " << path_
|
||||
|
|
@ -732,17 +828,17 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
|
|||
/* If this is a part select of the entire signal (or no part
|
||||
select at all) then we're done. */
|
||||
if ((lidx == 0) && (midx == (long)sig->vector_width()-1)) {
|
||||
scope->add_module_port(sig);
|
||||
scope->add_module_port_net(sig);
|
||||
return sig;
|
||||
}
|
||||
|
||||
unsigned swid = abs(midx - lidx) + 1;
|
||||
ivl_assert(*this, swid > 0 && swid < sig->vector_width());
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),swid-1,0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, swid);
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
tmp->port_type(sig->port_type());
|
||||
tmp->data_type(sig->data_type());
|
||||
tmp->set_line(*this);
|
||||
tmp->local_flag(true);
|
||||
NetNode*ps = 0;
|
||||
|
|
@ -779,7 +875,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
|
|||
ps->set_line(*this);
|
||||
des->add_node(ps);
|
||||
|
||||
scope->add_module_port(sig);
|
||||
scope->add_module_port_net(sig);
|
||||
return sig;
|
||||
}
|
||||
|
||||
|
|
|
|||
127
elab_scope.cc
127
elab_scope.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -33,8 +33,10 @@
|
|||
*/
|
||||
|
||||
# include "Module.h"
|
||||
# include "PEvent.h"
|
||||
# include "PClass.h"
|
||||
# include "PExpr.h"
|
||||
# include "PEvent.h"
|
||||
# include "PClass.h"
|
||||
# include "PGate.h"
|
||||
# include "PGenerate.h"
|
||||
# include "PTask.h"
|
||||
|
|
@ -42,6 +44,7 @@
|
|||
# include "Statement.h"
|
||||
# include "AStatement.h"
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "netenum.h"
|
||||
# include "util.h"
|
||||
# include <typeinfo>
|
||||
|
|
@ -51,7 +54,9 @@
|
|||
typedef map<perm_string,LexicalScope::param_expr_t>::const_iterator mparm_it_t;
|
||||
|
||||
static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
||||
const LexicalScope::param_expr_t&cur)
|
||||
const LexicalScope::param_expr_t&cur,
|
||||
bool is_annotatable,
|
||||
bool local_flag)
|
||||
{
|
||||
NetScope::range_t*range_list = 0;
|
||||
for (LexicalScope::range_t*range = cur.range ; range ; range = range->next) {
|
||||
|
|
@ -87,8 +92,9 @@ static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
|||
range_list = tmp;
|
||||
}
|
||||
|
||||
scope->set_parameter(name, cur.expr, cur.type, cur.msb, cur.lsb,
|
||||
cur.signed_flag, range_list, cur);
|
||||
|
||||
scope->set_parameter(name, is_annotatable, cur.expr, cur.type, cur.msb,
|
||||
cur.lsb, cur.signed_flag, local_flag, range_list, cur);
|
||||
}
|
||||
|
||||
static void collect_scope_parameters_(Design*des, NetScope*scope,
|
||||
|
|
@ -106,7 +112,7 @@ static void collect_scope_parameters_(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second);
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +131,26 @@ static void collect_scope_localparams_(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second);
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void collect_scope_specparams_(Design*des, NetScope*scope,
|
||||
const map<perm_string,LexicalScope::param_expr_t>&specparams)
|
||||
{
|
||||
for (mparm_it_t cur = specparams.begin()
|
||||
; cur != specparams.end() ; ++ cur ) {
|
||||
|
||||
// A specparam can not have the same name as a genvar.
|
||||
if (scope->find_genvar((*cur).first)) {
|
||||
cerr << cur->second.get_fileline()
|
||||
<< ": error: specparam and genvar in '"
|
||||
<< scope->fullname() << "' have the same name '"
|
||||
<< (*cur).first << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
collect_parm_item_(des, scope, (*cur).first, (*cur).second, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,12 +184,12 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
verinum max_value (0);
|
||||
if (enum_type->signed_flag) {
|
||||
min_value = v_not((pow(verinum(2),
|
||||
verinum(use_enum->base_width()-1)))) +
|
||||
verinum(use_enum->packed_width()-1)))) +
|
||||
one_value;
|
||||
max_value = pow(verinum(2), verinum(use_enum->base_width()-1)) -
|
||||
max_value = pow(verinum(2), verinum(use_enum->packed_width()-1)) -
|
||||
one_value;
|
||||
} else {
|
||||
max_value = pow(verinum(2), verinum(use_enum->base_width())) -
|
||||
max_value = pow(verinum(2), verinum(use_enum->packed_width())) -
|
||||
one_value;
|
||||
}
|
||||
min_value.has_sign(true);
|
||||
|
|
@ -227,15 +252,15 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
// The values are explicitly sized to the width of the
|
||||
// base type of the enumeration.
|
||||
verinum tmp_val (0);
|
||||
if (cur_value.len() < use_enum->base_width()) {
|
||||
if (cur_value.len() < (unsigned long)use_enum->packed_width()) {
|
||||
// Pad the current value if it is narrower than the final
|
||||
// width of the enum.
|
||||
tmp_val = pad_to_width (cur_value, use_enum->base_width());
|
||||
tmp_val = pad_to_width (cur_value, use_enum->packed_width());
|
||||
tmp_val.has_len(true);
|
||||
} else {
|
||||
// Truncate an oversized value. We report out of bound
|
||||
// values above. This may create duplicates.
|
||||
tmp_val = verinum(cur_value, use_enum->base_width());
|
||||
tmp_val = verinum(cur_value, use_enum->packed_width());
|
||||
}
|
||||
tmp_val.has_sign(enum_type->signed_flag);
|
||||
|
||||
|
|
@ -264,6 +289,30 @@ static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
|||
}
|
||||
}
|
||||
|
||||
static void elaborate_scope_class(Design*des, NetScope*scope,
|
||||
PClass*pclass)
|
||||
{
|
||||
class_type_t*use_type = pclass->type;
|
||||
netclass_t*use_class = new netclass_t(use_type->name);
|
||||
|
||||
for (map<perm_string, data_type_t*>::iterator cur = use_type->properties.begin()
|
||||
; cur != use_type->properties.end() ; ++ cur) {
|
||||
ivl_type_s*tmp = cur->second->elaborate_type(des, scope);
|
||||
use_class->set_property(cur->first, tmp);
|
||||
}
|
||||
|
||||
scope->add_class(use_class);
|
||||
}
|
||||
|
||||
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||
const map<perm_string,PClass*>&classes)
|
||||
{
|
||||
for (map<perm_string,PClass*>::const_iterator cur = classes.begin()
|
||||
; cur != classes.end() ; ++ cur) {
|
||||
elaborate_scope_class(des, scope, cur->second);
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc,
|
||||
const Module::replace_t&replacements)
|
||||
{
|
||||
|
|
@ -469,6 +518,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
|
||||
collect_scope_localparams_(des, scope, localparams);
|
||||
|
||||
collect_scope_specparams_(des, scope, specparams);
|
||||
|
||||
// Run parameter replacements that were collected from the
|
||||
// containing scope and meant for me.
|
||||
|
||||
|
|
@ -476,6 +527,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
elaborate_scope_classes(des, scope, classes);
|
||||
|
||||
// Run through the defparams for this module and save the result
|
||||
// in a table for later final override.
|
||||
|
||||
|
|
@ -519,6 +572,19 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
|||
|
||||
elaborate_scope_funcs(des, scope, funcs);
|
||||
|
||||
// Look for implicit modules and implicit gates for them.
|
||||
|
||||
for (map<perm_string,Module*>::iterator cur = nested_modules.begin()
|
||||
; cur != nested_modules.end() ; ++cur) {
|
||||
// Skip modules that must be explicitly instantiated.
|
||||
if (cur->second->port_count() > 0)
|
||||
continue;
|
||||
|
||||
PGModule*nested_gate = new PGModule(cur->second, cur->second->mod_name());
|
||||
nested_gate->set_line(*cur->second);
|
||||
gates_.push_back(nested_gate);
|
||||
}
|
||||
|
||||
// Gates include modules, which might introduce new scopes, so
|
||||
// scan all of them to create those scopes.
|
||||
|
||||
|
|
@ -708,7 +774,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
|||
genvar_verinum);
|
||||
// The file and line information should really come
|
||||
// from the genvar statement, not the for loop.
|
||||
scope->set_localparam(loop_index, gp, *this);
|
||||
scope->set_parameter(loop_index, gp, *this);
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Create implicit localparam "
|
||||
|
|
@ -1054,6 +1120,21 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
|
|||
scope->add_genvar((*cur).first, (*cur).second);
|
||||
}
|
||||
|
||||
// Scan the localparams in this scope, and store the information
|
||||
// needed to evaluate the parameter expressions. The expressions
|
||||
// will be evaluated later, once all parameter overrides for this
|
||||
// module have been done.
|
||||
collect_scope_localparams_(des, scope, localparams);
|
||||
|
||||
// Run through the defparams for this scope and save the result
|
||||
// in a table for later final override.
|
||||
|
||||
typedef list<PGenerate::named_expr_t>::const_iterator defparms_iter_t;
|
||||
for (defparms_iter_t cur = defparms.begin()
|
||||
; cur != defparms.end() ; ++ cur ) {
|
||||
scope->defparams.push_back(make_pair(cur->first, cur->second));
|
||||
}
|
||||
|
||||
// Scan the generated scope for nested generate schemes,
|
||||
// and *generate* new scopes, which is slightly different
|
||||
// from simple elaboration.
|
||||
|
|
@ -1064,12 +1145,6 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
|
|||
(*cur) -> generate_scope(des, scope);
|
||||
}
|
||||
|
||||
// Scan the localparams in this scope, and store the information
|
||||
// needed to evaluate the parameter expressions. The expressions
|
||||
// will be evaluated later, once all parameter overrides for this
|
||||
// module have been done.
|
||||
collect_scope_localparams_(des, scope, localparams);
|
||||
|
||||
// Scan through all the task and function declarations in this
|
||||
// scope.
|
||||
elaborate_scope_tasks(des, scope, tasks);
|
||||
|
|
@ -1307,8 +1382,12 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
|||
<< "." << endl;
|
||||
}
|
||||
|
||||
// Create the new scope as a MODULE with my name.
|
||||
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE);
|
||||
// Create the new scope as a MODULE with my name. Note
|
||||
// that if this is a nested module, mark it thus so that
|
||||
// scope searches will continue into the parent scope.
|
||||
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE,
|
||||
bound_type_? true : false,
|
||||
mod->program_block);
|
||||
my_scope->set_line(get_file(), mod->get_file(),
|
||||
get_lineno(), mod->get_lineno());
|
||||
my_scope->set_module_name(mod->mod_name());
|
||||
|
|
@ -1525,7 +1604,9 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
|||
<< "Elaborate block scope " << use_name
|
||||
<< " within " << scope_path(scope) << endl;
|
||||
|
||||
my_scope = new NetScope(scope, use_name, bl_type_==BL_PAR
|
||||
// The scope type is begin-end or fork-join. The
|
||||
// sub-types of fork-join are not interesting to the scope.
|
||||
my_scope = new NetScope(scope, use_name, bl_type_!=BL_SEQ
|
||||
? NetScope::FORK_JOIN
|
||||
: NetScope::BEGIN_END);
|
||||
my_scope->set_line(get_file(), get_lineno());
|
||||
|
|
|
|||
389
elab_sig.cc
389
elab_sig.cc
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / 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
|
||||
|
|
@ -14,11 +15,12 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <typeinfo>
|
||||
# include <cstdlib>
|
||||
# include <iostream>
|
||||
|
||||
|
|
@ -32,10 +34,17 @@
|
|||
# include "compiler.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "netclass.h"
|
||||
# include "netenum.h"
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
# include "netdarray.h"
|
||||
# include "netparray.h"
|
||||
# include "util.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static bool get_const_argument(NetExpr*exp, verinum&res)
|
||||
{
|
||||
switch (exp->expr_type()) {
|
||||
|
|
@ -388,7 +397,6 @@ bool PGenerate::elaborate_sig_direct_(Design*des, NetScope*container) const
|
|||
; cur != generate_schemes.end() ; ++ cur ) {
|
||||
PGenerate*item = *cur;
|
||||
if (item->scheme_type == PGenerate::GS_CASE) {
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t icur = item->generate_schemes.begin()
|
||||
; icur != item->generate_schemes.end() ; ++ icur ) {
|
||||
PGenerate*case_item = *icur;
|
||||
|
|
@ -479,6 +487,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
NetNet*ret_sig = 0;
|
||||
netvector_t*ret_vec = 0;
|
||||
|
||||
/* Create the signals/variables of the return value and write
|
||||
them into the function scope. */
|
||||
|
|
@ -514,50 +523,51 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
des->errors += 1;
|
||||
}
|
||||
|
||||
list<NetNet::range_t> packed;
|
||||
packed.push_back(NetNet::range_t(mnum, lnum));
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, packed);
|
||||
ret_sig->set_scalar(false);
|
||||
vector<netrange_t> packed;
|
||||
packed.push_back(netrange_t(mnum, lnum));
|
||||
ret_vec = new netvector_t(packed, IVL_VT_LOGIC);
|
||||
ret_vec->set_signed(return_type_.type == PTF_REG_S);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
|
||||
} else {
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG);
|
||||
ret_sig->set_scalar(true);
|
||||
ret_vec = new netvector_t(IVL_VT_LOGIC);
|
||||
ret_vec->set_signed(return_type_.type == PTF_REG_S);
|
||||
ret_vec->set_scalar(true);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
}
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(return_type_.type == PTF_REG_S);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
||||
case PTF_INTEGER:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, integer_width);
|
||||
ret_vec = new netvector_t(IVL_VT_LOGIC, integer_width-1,0);
|
||||
ret_vec->set_signed(true);
|
||||
ret_vec->set_isint(true);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(true);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
||||
case PTF_TIME:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, 64);
|
||||
ret_vec = new netvector_t(IVL_VT_LOGIC, 64-1,0);
|
||||
ret_vec->set_isint(false);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(false);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
||||
case PTF_REAL:
|
||||
case PTF_REALTIME:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, 1);
|
||||
ret_vec = new netvector_t(IVL_VT_REAL);
|
||||
ret_vec->set_signed(true);
|
||||
ret_vec->set_isint(false);
|
||||
ret_vec->set_scalar(true);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->set_scalar(true);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_REAL);
|
||||
break;
|
||||
|
||||
case PTF_ATOM2:
|
||||
|
|
@ -592,13 +602,13 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
use_wid = mnum - lnum + 1;
|
||||
}
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, use_wid);
|
||||
ret_vec = new netvector_t(IVL_VT_BOOL, use_wid-1, 0);
|
||||
ret_vec->set_isint(true);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_vec->set_signed(return_type_.type == PTF_ATOM2_S? true : false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(return_type_.type == PTF_ATOM2_S? true : false);
|
||||
ret_sig->set_isint(true);
|
||||
ret_sig->set_scalar(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_BOOL);
|
||||
break;
|
||||
|
||||
case PTF_STRING:
|
||||
|
|
@ -624,7 +634,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
}
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count() : 0);
|
||||
vector<NetNet*>ports (ports_? ports_->count() : 0);
|
||||
|
||||
if (ports_)
|
||||
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
|
||||
|
|
@ -813,64 +823,18 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
|
|||
statement_->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
|
||||
struct_type_t*struct_type)
|
||||
{
|
||||
netstruct_t*res = new netstruct_t;
|
||||
|
||||
res->packed(struct_type->packed_flag);
|
||||
|
||||
for (list<struct_member_t*>::iterator cur = struct_type->members->begin()
|
||||
; cur != struct_type->members->end() ; ++ cur) {
|
||||
|
||||
struct_member_t*curp = *cur;
|
||||
long use_msb = 0;
|
||||
long use_lsb = 0;
|
||||
if (curp->range.get() && ! curp->range->empty()) {
|
||||
ivl_assert(*curp, curp->range->size() == 1);
|
||||
pform_range_t&rangep = curp->range->front();
|
||||
PExpr*msb_pex = rangep.first;
|
||||
PExpr*lsb_pex = rangep.second;
|
||||
|
||||
NetExpr*tmp = elab_and_eval(des, scope, msb_pex, -2, true);
|
||||
ivl_assert(*curp, tmp);
|
||||
bool rc = eval_as_long(use_msb, tmp);
|
||||
ivl_assert(*curp, rc);
|
||||
|
||||
tmp = elab_and_eval(des, scope, lsb_pex, -2, true);
|
||||
ivl_assert(*curp, tmp);
|
||||
rc = eval_as_long(use_lsb, tmp);
|
||||
ivl_assert(*curp, rc);
|
||||
}
|
||||
|
||||
for (list<decl_assignment_t*>::iterator name = curp->names->begin()
|
||||
; name != curp->names->end() ; ++ name) {
|
||||
decl_assignment_t*namep = *name;
|
||||
|
||||
netstruct_t::member_t memb;
|
||||
memb.name = namep->name;
|
||||
memb.type = curp->type;
|
||||
memb.msb = use_msb;
|
||||
memb.lsb = use_lsb;
|
||||
res->append_member(memb);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool evaluate_ranges(Design*des, NetScope*scope,
|
||||
list<NetNet::range_t>&llist,
|
||||
vector<netrange_t>&llist,
|
||||
const list<pform_range_t>&rlist)
|
||||
{
|
||||
bool bad_msb = false, bad_lsb = false;
|
||||
|
||||
for (list<pform_range_t>::const_iterator cur = rlist.begin()
|
||||
; cur != rlist.end() ; ++cur) {
|
||||
NetNet::range_t lrng;
|
||||
long use_msb, use_lsb;
|
||||
|
||||
NetExpr*texpr = elab_and_eval(des, scope, cur->first, -1, true);
|
||||
if (! eval_as_long(lrng.msb, texpr)) {
|
||||
if (! eval_as_long(use_msb, texpr)) {
|
||||
cerr << cur->first->get_fileline() << ": error: "
|
||||
"Range expressions must be constant." << endl;
|
||||
cerr << cur->first->get_fileline() << " : "
|
||||
|
|
@ -883,7 +847,7 @@ static bool evaluate_ranges(Design*des, NetScope*scope,
|
|||
delete texpr;
|
||||
|
||||
texpr = elab_and_eval(des, scope, cur->second, -1, true);
|
||||
if (! eval_as_long(lrng.lsb, texpr)) {
|
||||
if (! eval_as_long(use_lsb, texpr)) {
|
||||
cerr << cur->second->get_fileline() << ": error: "
|
||||
"Range expressions must be constant." << endl;
|
||||
cerr << cur->second->get_fileline() << " : "
|
||||
|
|
@ -895,23 +859,97 @@ static bool evaluate_ranges(Design*des, NetScope*scope,
|
|||
|
||||
delete texpr;
|
||||
|
||||
llist.push_back(lrng);
|
||||
llist.push_back(netrange_t(use_msb, use_lsb));
|
||||
}
|
||||
|
||||
return bad_msb | bad_lsb;
|
||||
}
|
||||
|
||||
bool test_ranges_eeq(const list<NetNet::range_t>&lef, const list<NetNet::range_t>&rig)
|
||||
static netclass_t* locate_class_type(Design*des, NetScope*scope,
|
||||
class_type_t*class_type)
|
||||
{
|
||||
netclass_t*use_class = scope->find_class(class_type->name);
|
||||
return use_class;
|
||||
}
|
||||
|
||||
static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
|
||||
struct_type_t*struct_type)
|
||||
{
|
||||
netstruct_t*res = new netstruct_t;
|
||||
|
||||
res->packed(struct_type->packed_flag);
|
||||
|
||||
for (list<struct_member_t*>::iterator cur = struct_type->members->begin()
|
||||
; cur != struct_type->members->end() ; ++ cur) {
|
||||
|
||||
vector<netrange_t>packed_dimensions;
|
||||
|
||||
struct_member_t*curp = *cur;
|
||||
if (curp->range.get() && ! curp->range->empty()) {
|
||||
bool bad_range;
|
||||
bad_range = evaluate_ranges(des, scope, packed_dimensions, *curp->range);
|
||||
ivl_assert(*curp, !bad_range);
|
||||
} else {
|
||||
packed_dimensions.push_back(netrange_t(0,0));
|
||||
}
|
||||
|
||||
for (list<decl_assignment_t*>::iterator name = curp->names->begin()
|
||||
; name != curp->names->end() ; ++ name) {
|
||||
decl_assignment_t*namep = *name;
|
||||
|
||||
netstruct_t::member_t memb;
|
||||
memb.name = namep->name;
|
||||
memb.type = curp->type;
|
||||
memb.packed_dims = packed_dimensions;
|
||||
res->append_member(memb);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static ivl_type_s*elaborate_type(Design*des, NetScope*scope,
|
||||
data_type_t*pform_type)
|
||||
{
|
||||
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(pform_type)) {
|
||||
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type);
|
||||
return use_type;
|
||||
}
|
||||
|
||||
cerr << pform_type->get_fileline() << ": sorry: I don't know how to elaborate "
|
||||
<< typeid(*pform_type).name() << " here." << endl;
|
||||
des->errors += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static netparray_t* elaborate_parray_type(Design*des, NetScope*scope,
|
||||
parray_type_t*data_type)
|
||||
{
|
||||
|
||||
vector<netrange_t>packed_dimensions;
|
||||
bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->packed_dims);
|
||||
ivl_assert(*data_type, !bad_range);
|
||||
|
||||
ivl_type_s*element_type = elaborate_type(des, scope, data_type->base_type);
|
||||
|
||||
netparray_t*res = new netparray_t(packed_dimensions, element_type);
|
||||
//res->set_line(*data_type);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool test_ranges_eeq(const vector<netrange_t>&lef, const vector<netrange_t>&rig)
|
||||
{
|
||||
if (lef.size() != rig.size())
|
||||
return false;
|
||||
|
||||
list<NetNet::range_t>::const_iterator lcur = lef.begin();
|
||||
list<NetNet::range_t>::const_iterator rcur = rig.begin();
|
||||
vector<netrange_t>::const_iterator lcur = lef.begin();
|
||||
vector<netrange_t>::const_iterator rcur = rig.begin();
|
||||
while (lcur != lef.end()) {
|
||||
if (lcur->msb != rcur->msb)
|
||||
if (lcur->get_msb() != rcur->get_msb())
|
||||
return false;
|
||||
if (lcur->lsb != rcur->lsb)
|
||||
if (lcur->get_lsb() != rcur->get_lsb())
|
||||
return false;
|
||||
|
||||
++ lcur;
|
||||
|
|
@ -942,7 +980,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
unsigned wid = 1;
|
||||
list<NetNet::range_t>packed_dimensions;
|
||||
vector<netrange_t>packed_dimensions;
|
||||
|
||||
des->errors += error_cnt_;
|
||||
|
||||
|
|
@ -983,7 +1021,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
if (port_set_ || net_set_) {
|
||||
bool bad_range = false;
|
||||
list<NetNet::range_t> plist, nlist;
|
||||
vector<netrange_t> plist, nlist;
|
||||
/* If they exist get the port definition MSB and LSB */
|
||||
if (port_set_ && !port_.empty()) {
|
||||
bad_range |= evaluate_ranges(des, scope, plist, port_);
|
||||
|
|
@ -1049,7 +1087,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
}
|
||||
|
||||
packed_dimensions = nlist;
|
||||
wid = NetNet::vector_width(packed_dimensions);
|
||||
wid = netrange_width(packed_dimensions);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1057,19 +1095,32 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
|
||||
des, scope);
|
||||
|
||||
long array_s0 = 0;
|
||||
long array_e0 = 0;
|
||||
unsigned array_dimensions = 0;
|
||||
|
||||
/* If the ident has idx expressions, then this is a
|
||||
memory. It can only have the idx registers after the msb
|
||||
and lsb expressions are filled. And, if it has one index,
|
||||
it has both. */
|
||||
if (lidx_ || ridx_) {
|
||||
assert(lidx_ && ridx_);
|
||||
list<netrange_t>unpacked_dimensions;
|
||||
netdarray_t*netarray = 0;
|
||||
|
||||
NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1, true);
|
||||
NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1, true);
|
||||
for (list<pform_range_t>::const_iterator cur = unpacked_.begin()
|
||||
; cur != unpacked_.end() ; ++cur) {
|
||||
PExpr*use_lidx = cur->first;
|
||||
PExpr*use_ridx = cur->second;
|
||||
|
||||
// Special case: If we encounter an undefined
|
||||
// dimensions, then turn this into a dynamic array and
|
||||
// put all the packed dimensions there.
|
||||
if (use_lidx==0 && use_ridx==0) {
|
||||
netvector_t*vec = new netvector_t(packed_dimensions, data_type_);
|
||||
packed_dimensions.clear();
|
||||
ivl_assert(*this, netarray==0);
|
||||
netarray = new netdarray_t(vec);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cannot handle dynamic arrays of arrays yet.
|
||||
ivl_assert(*this, netarray==0);
|
||||
ivl_assert(*this, use_lidx && use_ridx);
|
||||
|
||||
NetExpr*lexp = elab_and_eval(des, scope, use_lidx, -1, true);
|
||||
NetExpr*rexp = elab_and_eval(des, scope, use_ridx, -1, true);
|
||||
|
||||
if ((lexp == 0) || (rexp == 0)) {
|
||||
cerr << get_fileline() << ": internal error: There is "
|
||||
|
|
@ -1086,19 +1137,21 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
delete rexp;
|
||||
delete lexp;
|
||||
|
||||
if (!const_flag) {
|
||||
long index_l, index_r;
|
||||
if (! const_flag) {
|
||||
cerr << get_fileline() << ": error: The indices "
|
||||
<< "are not constant for array ``"
|
||||
<< name_ << "''." << endl;
|
||||
des->errors += 1;
|
||||
/* Attempt to recover from error, */
|
||||
array_s0 = 0;
|
||||
array_e0 = 0;
|
||||
index_l = 0;
|
||||
index_r = 0;
|
||||
} else {
|
||||
array_s0 = lval.as_long();
|
||||
array_e0 = rval.as_long();
|
||||
}
|
||||
array_dimensions = 1;
|
||||
index_l = lval.as_long();
|
||||
index_r = rval.as_long();
|
||||
}
|
||||
|
||||
unpacked_dimensions.push_back(netrange_t(index_l, index_r));
|
||||
}
|
||||
|
||||
if (data_type_ == IVL_VT_REAL && !packed_dimensions.empty()) {
|
||||
|
|
@ -1151,10 +1204,20 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
NetNet*sig = 0;
|
||||
|
||||
// If this is a struct type, then build the net with the
|
||||
// struct type.
|
||||
if (struct_type_) {
|
||||
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type_);
|
||||
if (class_type_t*class_type = dynamic_cast<class_type_t*>(set_data_type_)) {
|
||||
// If this is a class variable, then the class type
|
||||
// should already have been elaborated. All we need to
|
||||
// do right now is locate the netclass_t object for the
|
||||
// class, and use that to build the net.
|
||||
netclass_t*use_type = locate_class_type(des, scope, class_type);
|
||||
// (No arrays of classes)
|
||||
list<netrange_t> use_unpacked;
|
||||
sig = new NetNet(scope, name_, wtype, use_unpacked, use_type);
|
||||
|
||||
} else if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(set_data_type_)) {
|
||||
// If this is a struct type, then build the net with the
|
||||
// struct type.
|
||||
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type);
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype;
|
||||
if (use_type->packed())
|
||||
|
|
@ -1167,54 +1230,90 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
sig = new NetNet(scope, name_, wtype, use_type);
|
||||
|
||||
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(set_data_type_)) {
|
||||
list<named_pexpr_t>::const_iterator sample_name = enum_type->names->begin();
|
||||
netenum_t*use_enum = scope->enumeration_for_name(sample_name->name);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||
<< " enumeration "
|
||||
<< name_ << " in scope " << scope_path(scope)
|
||||
<< " with packed_dimensions=" << packed_dimensions
|
||||
<< " and packed_width=" << use_enum->packed_width() << endl;
|
||||
}
|
||||
|
||||
ivl_assert(*this, packed_dimensions.empty());
|
||||
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_enum);
|
||||
|
||||
|
||||
} else if (netarray) {
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||
<< " dynamic array "
|
||||
<< name_ << " in scope " << scope_path(scope) << endl;
|
||||
}
|
||||
|
||||
ivl_assert(*this, packed_dimensions.empty());
|
||||
ivl_assert(*this, unpacked_dimensions.empty());
|
||||
sig = new NetNet(scope, name_, wtype, netarray);
|
||||
|
||||
} else if (parray_type_t*parray_type = dynamic_cast<parray_type_t*>(set_data_type_)) {
|
||||
// The pform gives us a parray_type_t for packed arrays
|
||||
// that show up in type definitions. This can be handled
|
||||
// a lot like packed dimensions from other means.
|
||||
|
||||
// The trick here is that the parray type has an
|
||||
// arbitrary sub-type, and not just a scalar bit...
|
||||
netparray_t*use_type = elaborate_parray_type(des, scope, parray_type);
|
||||
// Should not be getting packed dimensions other then
|
||||
// through the parray type declaration.
|
||||
ivl_assert(*this, packed_dimensions.empty());
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||
<< " parray=" << use_type->packed_dimensions()
|
||||
<< " " << name_ << unpacked_dimensions
|
||||
<< " in scope " << scope_path(scope) << endl;
|
||||
}
|
||||
|
||||
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type);
|
||||
|
||||
|
||||
} else {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype;
|
||||
if (!get_scalar()) {
|
||||
cerr << " " << packed_dimensions;
|
||||
}
|
||||
cerr << " " << name_;
|
||||
if (array_dimensions > 0) {
|
||||
cerr << " [" << array_s0 << ":" << array_e0 << "]" << endl;
|
||||
}
|
||||
cerr << " " << name_ << unpacked_dimensions;
|
||||
cerr << " in scope " << scope_path(scope) << endl;
|
||||
}
|
||||
|
||||
sig = array_dimensions > 0
|
||||
? new NetNet(scope, name_, wtype, packed_dimensions, array_s0, array_e0)
|
||||
: new NetNet(scope, name_, wtype, packed_dimensions);
|
||||
}
|
||||
ivl_variable_type_t use_data_type = data_type_;
|
||||
if (use_data_type == IVL_VT_NO_TYPE) {
|
||||
use_data_type = IVL_VT_LOGIC;
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Signal " << name_
|
||||
<< " in scope " << scope_path(scope)
|
||||
<< " defaults to data type " << use_data_type << endl;
|
||||
}
|
||||
}
|
||||
|
||||
netvector_t*vec = new netvector_t(packed_dimensions, use_data_type);
|
||||
vec->set_signed(get_signed());
|
||||
vec->set_isint(get_isint());
|
||||
if (is_implicit_scalar) vec->set_scalar(true);
|
||||
else vec->set_scalar(get_scalar());
|
||||
packed_dimensions.clear();
|
||||
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, vec);
|
||||
|
||||
// If this is an enumeration, then set the enumeration set for
|
||||
// the new signal. This turns it into an enumeration.
|
||||
if (enum_type_) {
|
||||
ivl_assert(*this, struct_type_ == 0);
|
||||
ivl_assert(*this, ! enum_type_->names->empty());
|
||||
list<named_pexpr_t>::const_iterator sample_name = enum_type_->names->begin();
|
||||
netenum_t*use_enum = scope->enumeration_for_name(sample_name->name);
|
||||
sig->set_enumeration(use_enum);
|
||||
}
|
||||
|
||||
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
|
||||
|
||||
ivl_variable_type_t use_data_type = data_type_;
|
||||
if (use_data_type == IVL_VT_NO_TYPE) {
|
||||
use_data_type = IVL_VT_LOGIC;
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Signal " << name_
|
||||
<< " in scope " << scope_path(scope)
|
||||
<< " defaults to data type " << use_data_type << endl;
|
||||
}
|
||||
}
|
||||
|
||||
sig->data_type(use_data_type);
|
||||
sig->set_line(*this);
|
||||
sig->port_type(port_type_);
|
||||
sig->set_signed(get_signed());
|
||||
sig->set_isint(get_isint());
|
||||
if (is_implicit_scalar) sig->set_scalar(true);
|
||||
else sig->set_scalar(get_scalar());
|
||||
|
||||
if (ivl_discipline_t dis = get_discipline()) {
|
||||
sig->set_discipline(dis);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "pform_types.h"
|
||||
# include "netlist.h"
|
||||
# include "netvector.h"
|
||||
# include <typeinfo>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Elaborate method not implemented for " << typeid(*this).name()
|
||||
<< "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const
|
||||
{
|
||||
switch (type_code) {
|
||||
case 32:
|
||||
if (signed_flag)
|
||||
return &netvector_t::atom2s32;
|
||||
else
|
||||
return &netvector_t::atom2u32;
|
||||
|
||||
case 16:
|
||||
if (signed_flag)
|
||||
return &netvector_t::atom2s16;
|
||||
else
|
||||
return &netvector_t::atom2u16;
|
||||
|
||||
case 8:
|
||||
if (signed_flag)
|
||||
return &netvector_t::atom2s8;
|
||||
else
|
||||
return &netvector_t::atom2u8;
|
||||
|
||||
default:
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "atom2_type_t type_code=" << type_code << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
345
elaborate.cc
345
elaborate.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2012 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
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -35,6 +35,9 @@
|
|||
# include "PGenerate.h"
|
||||
# include "PSpec.h"
|
||||
# include "netlist.h"
|
||||
# include "netvector.h"
|
||||
# include "netdarray.h"
|
||||
# include "netclass.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
# include "parse_api.h"
|
||||
|
|
@ -75,8 +78,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: PGAssign: elaborated l-value"
|
||||
<< " width=" << lval->vector_width()
|
||||
<< ", type=" << lval->data_type() << endl;
|
||||
<< " width=" << lval->vector_width() << endl;
|
||||
}
|
||||
|
||||
NetExpr*rval_expr = elaborate_rval_expr(des, scope, lval->data_type(),
|
||||
|
|
@ -115,7 +117,6 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
cerr << get_fileline() << ": debug: PGAssign: elaborated r-value"
|
||||
<< " width="<< rval->vector_width()
|
||||
<< ", type="<< rval->data_type()
|
||||
<< ", signed="<< rval->get_signed()
|
||||
<< ", expr=" << *rval_expr << endl;
|
||||
}
|
||||
|
||||
|
|
@ -164,11 +165,12 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
NetPartSelect::VP);
|
||||
des->add_node(tmp);
|
||||
tmp->set_line(*this);
|
||||
netvector_t*osig_vec = new netvector_t(rval->data_type(),
|
||||
lval->vector_width()-1,0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::TRI, lval->vector_width());
|
||||
NetNet::TRI, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(rval->data_type());
|
||||
connect(osig->pin(0), tmp->pin(0));
|
||||
rval = osig;
|
||||
need_driver_flag = false;
|
||||
|
|
@ -190,10 +192,11 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
connect(rval->pin(0), driver->pin(1));
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(rval->data_type(),
|
||||
rval->vector_width()-1,0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, rval->vector_width());
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->data_type(rval->data_type());
|
||||
tmp->local_flag(true);
|
||||
|
||||
connect(driver->pin(0), tmp->pin(0));
|
||||
|
|
@ -772,7 +775,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
NetExpr* rise_time, *fall_time, *decay_time;
|
||||
eval_delays(des, scope, rise_time, fall_time, decay_time);
|
||||
|
||||
struct attrib_list_t*attrib_list = 0;
|
||||
struct attrib_list_t*attrib_list;
|
||||
unsigned attrib_list_n = 0;
|
||||
attrib_list = evaluate_attributes(attributes, attrib_list_n,
|
||||
des, scope);
|
||||
|
|
@ -868,10 +871,11 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
des->add_node(rep);
|
||||
connect(rep->pin(1), sig->pin(0));
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC,
|
||||
instance_width-1,0);
|
||||
sig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, instance_width);
|
||||
NetNet::WIRE, osig_vec);
|
||||
sig->set_line(*this);
|
||||
sig->data_type(IVL_VT_LOGIC);
|
||||
sig->local_flag(true);
|
||||
connect(rep->pin(0), sig->pin(0));
|
||||
|
||||
|
|
@ -948,12 +952,12 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
unsigned dev = gdx*gate_count;
|
||||
connect(cur[dev+idx]->pin(0), cc->pin(gdx+1));
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(IVL_VT_LOGIC);
|
||||
NetNet*tmp2 = new NetNet(scope,
|
||||
scope->local_symbol(),
|
||||
NetNet::WIRE, 1);
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
tmp2->set_line(*this);
|
||||
tmp2->local_flag(true);
|
||||
tmp2->data_type(IVL_VT_LOGIC);
|
||||
connect(cc->pin(gdx+1), tmp2->pin(0));
|
||||
}
|
||||
|
||||
|
|
@ -965,11 +969,11 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
|||
tmp1->set_line(*this);
|
||||
des->add_node(tmp1);
|
||||
connect(tmp1->pin(1), sig->pin(0));
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type());
|
||||
NetNet*tmp2 = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, 1);
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
tmp2->set_line(*this);
|
||||
tmp2->local_flag(true);
|
||||
tmp2->data_type(sig->data_type());
|
||||
connect(tmp1->pin(0), tmp2->pin(0));
|
||||
unsigned use_idx = idx - gate_count + 1;
|
||||
unsigned dev = gdx*gate_count;
|
||||
|
|
@ -996,8 +1000,9 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
|
|||
ivl_assert(*this, dir != NetNet::NOT_A_PORT);
|
||||
ivl_assert(*this, dir != NetNet::PIMPLICIT);
|
||||
|
||||
netvector_t*tmp_type = new netvector_t(IVL_VT_LOGIC, port_wid-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, port_wid);
|
||||
NetNet::WIRE, tmp_type);
|
||||
tmp->local_flag(true);
|
||||
tmp->set_line(*this);
|
||||
|
||||
|
|
@ -1250,6 +1255,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
get_name() << "..." << endl;
|
||||
for (unsigned inst = 0 ; inst < instance.size() ; inst += 1) {
|
||||
rmod->elaborate(des, instance[inst]);
|
||||
instance[inst]->set_num_ports( rmod->port_count() );
|
||||
}
|
||||
if (debug_elaborate) cerr << get_fileline() << ": debug: ...done." << endl;
|
||||
|
||||
|
|
@ -1329,7 +1335,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
unconnected_port = true;
|
||||
}
|
||||
|
||||
// Inside the module, the port is zero or more signals
|
||||
// Inside the module, the port connects zero or more signals
|
||||
// that were already elaborated. List all those signals
|
||||
// and the NetNet equivalents, for all the instances.
|
||||
vector<PEIdent*> mport = rmod->get_port(idx);
|
||||
|
|
@ -1349,19 +1355,24 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
// will be assembled in that order as well.
|
||||
NetScope*inst_scope = instance[instance.size()-inst-1];
|
||||
|
||||
unsigned int prt_vector_width = 0;
|
||||
PortType::Enum ptype = PortType::PIMPLICIT;
|
||||
// Scan the module sub-ports for this instance...
|
||||
for (unsigned ldx = 0 ; ldx < mport.size() ; ldx += 1) {
|
||||
unsigned lbase = inst * mport.size();
|
||||
PEIdent*pport = mport[ldx];
|
||||
assert(pport);
|
||||
prts[lbase + ldx]
|
||||
= pport->elaborate_port(des, inst_scope);
|
||||
if (prts[lbase + ldx] == 0)
|
||||
NetNet *netnet = pport->elaborate_subport(des, inst_scope);
|
||||
prts[lbase + ldx] = netnet;
|
||||
if (netnet == 0)
|
||||
continue;
|
||||
|
||||
assert(prts[lbase + ldx]);
|
||||
prts_vector_width += prts[lbase + ldx]->vector_width();
|
||||
assert(netnet);
|
||||
prts_vector_width += netnet->vector_width();
|
||||
prt_vector_width += netnet->vector_width();
|
||||
ptype = PortType::merged(netnet->port_type(), ptype);
|
||||
}
|
||||
inst_scope->add_module_port_info(idx, rmod->get_port_name(idx), ptype, prt_vector_width );
|
||||
}
|
||||
|
||||
// If I find that the port is unconnected inside the
|
||||
|
|
@ -1409,6 +1420,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
<< "too complicated for elaboration." << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Elaborating INPUT port expression: " << *tmp_expr << endl;
|
||||
}
|
||||
|
||||
sig = tmp_expr->synthesize(des, scope, tmp_expr);
|
||||
if (sig == 0) {
|
||||
cerr << pins[idx]->get_fileline()
|
||||
|
|
@ -1426,11 +1443,12 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
des->add_node(tmp);
|
||||
connect(tmp->pin(1), sig->pin(0));
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),
|
||||
sig->vector_width()-1,0);
|
||||
NetNet*tmp2 = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, sig->vector_width());
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
tmp2->local_flag(true);
|
||||
tmp2->set_line(*this);
|
||||
tmp2->data_type(sig->data_type());
|
||||
connect(tmp->pin(0), tmp2->pin(0));
|
||||
sig = tmp2;
|
||||
}
|
||||
|
|
@ -1598,7 +1616,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
assert(sig);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if ((prts.size() >= 1)
|
||||
if ((! prts.empty())
|
||||
&& (prts[0]->port_type() != NetNet::PINPUT)) {
|
||||
assert(sig->type() != NetNet::REG);
|
||||
}
|
||||
|
|
@ -1922,7 +1940,7 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
|
|||
net->fall_time(fall_expr);
|
||||
net->decay_time(decay_expr);
|
||||
|
||||
struct attrib_list_t*attrib_list = 0;
|
||||
struct attrib_list_t*attrib_list;
|
||||
unsigned attrib_list_n = 0;
|
||||
attrib_list = evaluate_attributes(attributes, attrib_list_n,
|
||||
des, scope);
|
||||
|
|
@ -2068,6 +2086,10 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const
|
|||
|
||||
bool PGModule::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (bound_type_) {
|
||||
return elaborate_sig_mod_(des, scope, bound_type_);
|
||||
}
|
||||
|
||||
// Look for the module type
|
||||
map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
|
||||
if (mod != pform_modules.end())
|
||||
|
|
@ -2087,6 +2109,11 @@ bool PGModule::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
void PGModule::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (bound_type_) {
|
||||
elaborate_mod_(des, bound_type_, scope);
|
||||
return;
|
||||
}
|
||||
|
||||
// Look for the module type
|
||||
map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
|
||||
if (mod != pform_modules.end()) {
|
||||
|
|
@ -2108,10 +2135,16 @@ void PGModule::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
void PGModule::elaborate_scope(Design*des, NetScope*sc) const
|
||||
{
|
||||
// If the module type is known by design, then go right to it.
|
||||
if (bound_type_) {
|
||||
elaborate_scope_mod_(des, bound_type_, sc);
|
||||
return;
|
||||
}
|
||||
|
||||
// Look for the module type
|
||||
map<perm_string,Module*>::const_iterator mod = pform_modules.find(type_);
|
||||
if (mod != pform_modules.end()) {
|
||||
elaborate_scope_mod_(des, (*mod).second, sc);
|
||||
elaborate_scope_mod_(des, mod->second, sc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2128,7 +2161,7 @@ void PGModule::elaborate_scope(Design*des, NetScope*sc) const
|
|||
// Try again to find the module type
|
||||
mod = pform_modules.find(type_);
|
||||
if (mod != pform_modules.end()) {
|
||||
elaborate_scope_mod_(des, (*mod).second, sc);
|
||||
elaborate_scope_mod_(des, mod->second, sc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2163,6 +2196,17 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
|
|||
return lval_->elaborate_lval(des, scope, false);
|
||||
}
|
||||
|
||||
NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
|
||||
ivl_type_t net_type) const
|
||||
{
|
||||
ivl_assert(*this, rval_);
|
||||
|
||||
NetExpr*rv = rval_->elaborate_expr(des, scope, net_type, 0);
|
||||
|
||||
ivl_assert(*this, !is_constant_);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
|
||||
unsigned lv_width,
|
||||
ivl_variable_type_t lv_type) const
|
||||
|
|
@ -2297,6 +2341,18 @@ NetProc* PAssign::elaborate_compressed_(Design*des, NetScope*scope) const
|
|||
return cur;
|
||||
}
|
||||
|
||||
static bool lval_not_program_variable(const NetAssign_*lv)
|
||||
{
|
||||
while (lv) {
|
||||
NetScope*sig_scope = lv->sig()->scope();
|
||||
if (! sig_scope->program_block())
|
||||
return true;
|
||||
|
||||
lv = lv->more;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope);
|
||||
|
|
@ -2311,14 +2367,36 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
NetAssign_*lv = elaborate_lval(des, scope);
|
||||
if (lv == 0) return 0;
|
||||
|
||||
if (scope->program_block() && lval_not_program_variable(lv)) {
|
||||
cerr << get_fileline() << ": error: Blocking assignments to "
|
||||
<< "non-program variables are not allowed." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
/* If there is an internal delay expression, elaborate it. */
|
||||
NetExpr*delay = 0;
|
||||
if (delay_ != 0)
|
||||
delay = elaborate_delay_expr(delay_, des, scope);
|
||||
|
||||
NetExpr*rv;
|
||||
const ivl_type_s*lv_net_type = lv->net_type();
|
||||
|
||||
/* If the l-value is a compound type of some sort, then use
|
||||
the newer net_type form of the elaborate_rval_ method to
|
||||
handle the new types. */
|
||||
if (dynamic_cast<const netclass_t*> (lv_net_type)) {
|
||||
ivl_assert(*this, lv->more==0);
|
||||
rv = elaborate_rval_(des, scope, lv_net_type);
|
||||
|
||||
} else if (dynamic_cast<const netdarray_t*> (lv_net_type)) {
|
||||
ivl_assert(*this, lv->more==0);
|
||||
rv = elaborate_rval_(des, scope, lv_net_type);
|
||||
|
||||
} else {
|
||||
/* Elaborate the r-value expression, then try to evaluate it. */
|
||||
rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
|
||||
}
|
||||
|
||||
/* Elaborate the r-value expression, then try to evaluate it. */
|
||||
NetExpr*rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
|
||||
if (rv == 0) return 0;
|
||||
assert(rv);
|
||||
|
||||
|
|
@ -2343,11 +2421,11 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
if (delay || event_) {
|
||||
unsigned wid = count_lval_width(lv);
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(rv->expr_type(),wid-1,0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::REG, wid);
|
||||
NetNet::REG, tmp2_vec);
|
||||
tmp->local_flag(true);
|
||||
tmp->set_line(*this);
|
||||
tmp->data_type(rv->expr_type());
|
||||
|
||||
NetESignal*sig = new NetESignal(tmp);
|
||||
|
||||
|
|
@ -2438,10 +2516,17 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
if (lv->expr_type() == IVL_VT_BOOL && rv->expr_type() != IVL_VT_BOOL) {
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: Cast expression to int2" << endl;
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Cast expression to int2" << endl;
|
||||
rv = cast_to_int2(rv);
|
||||
}
|
||||
|
||||
if (lv->expr_type() == IVL_VT_REAL && rv->expr_type() != IVL_VT_REAL) {
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Cast expression to real." << endl;
|
||||
rv = cast_to_real(rv);
|
||||
}
|
||||
if (lv->enumeration() && (lv->enumeration() != rv->enumeration())) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Enumeration type mismatch in assignment." << endl;
|
||||
|
|
@ -2454,6 +2539,22 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
return cur;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if any lvalue parts are in a program block scope.
|
||||
*/
|
||||
static bool lval_is_program_variable(const NetAssign_*lv)
|
||||
{
|
||||
while (lv) {
|
||||
NetScope*sig_scope = lv->sig()->scope();
|
||||
if (sig_scope->program_block())
|
||||
return true;
|
||||
|
||||
lv = lv->more;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate non-blocking assignments. The statement is of the general
|
||||
* form:
|
||||
|
|
@ -2490,6 +2591,14 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
|
|||
NetAssign_*lv = elaborate_lval(des, scope);
|
||||
if (lv == 0) return 0;
|
||||
|
||||
if (scope->program_block() && lval_is_program_variable(lv)) {
|
||||
cerr << get_fileline() << ": error: Non-blocking assignments to "
|
||||
<< "program variables are not allowed." << endl;
|
||||
des->errors += 1;
|
||||
// This is an error, but we can let elaboration continue
|
||||
// because it would necessarily trigger other errors.
|
||||
}
|
||||
|
||||
NetExpr*rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
|
||||
if (rv == 0) return 0;
|
||||
|
||||
|
|
@ -2576,9 +2685,27 @@ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const
|
|||
{
|
||||
assert(scope);
|
||||
|
||||
NetBlock::Type type = (bl_type_==PBlock::BL_PAR)
|
||||
? NetBlock::PARA
|
||||
: NetBlock::SEQU;
|
||||
NetBlock::Type type;
|
||||
switch (bl_type_) {
|
||||
case PBlock::BL_SEQ:
|
||||
type = NetBlock::SEQU;
|
||||
break;
|
||||
case PBlock::BL_PAR:
|
||||
type = NetBlock::PARA;
|
||||
break;
|
||||
case PBlock::BL_JOIN_NONE:
|
||||
type = NetBlock::PARA_JOIN_NONE;
|
||||
break;
|
||||
case PBlock::BL_JOIN_ANY:
|
||||
type = NetBlock::PARA_JOIN_ANY;
|
||||
break;
|
||||
// Added to remove a "type" uninitialized compiler warning.
|
||||
// This should never be reached since all the PBlock enumeration
|
||||
// cases are handled above.
|
||||
default:
|
||||
type = NetBlock::SEQU;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
NetScope*nscope = 0;
|
||||
if (pscope_name() != 0) {
|
||||
|
|
@ -2695,7 +2822,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
|
|||
a separate case for each. (Yes, the statement
|
||||
will be elaborated again for each.) */
|
||||
PExpr*cur_expr = *idx_expr;
|
||||
NetExpr*gu = 0;
|
||||
NetExpr*gu;
|
||||
NetProc*st = 0;
|
||||
assert(cur_expr);
|
||||
gu = elab_and_eval(des, scope, cur_expr, -1);
|
||||
|
|
@ -2833,7 +2960,7 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const
|
|||
if ((parm_count== 1) && (parms_[0] == 0))
|
||||
parm_count = 0;
|
||||
|
||||
svector<NetExpr*>eparms (parm_count);
|
||||
vector<NetExpr*>eparms (parm_count);
|
||||
|
||||
perm_string name = peek_tail_name(path_);
|
||||
|
||||
|
|
@ -2912,6 +3039,12 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
|||
|
||||
NetScope*task = des->find_task(scope, path_);
|
||||
if (task == 0) {
|
||||
// Maybe this is a method attached to a signal?
|
||||
if (gn_system_verilog()) {
|
||||
NetProc*tmp = elaborate_method_(des, scope);
|
||||
if (tmp) return tmp;
|
||||
}
|
||||
|
||||
cerr << get_fileline() << ": error: Enable of unknown task "
|
||||
<< "``" << path_ << "''." << endl;
|
||||
des->errors += 1;
|
||||
|
|
@ -3094,6 +3227,39 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
|||
return block;
|
||||
}
|
||||
|
||||
NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope) const
|
||||
{
|
||||
pform_name_t use_path = path_;
|
||||
perm_string method_name = peek_tail_name(use_path);
|
||||
use_path.pop_back();
|
||||
|
||||
NetNet *net;
|
||||
const NetExpr *par;
|
||||
NetEvent *eve;
|
||||
const NetExpr *ex1, *ex2;
|
||||
|
||||
symbol_search(this, des, scope, use_path,
|
||||
net, par, eve, ex1, ex2);
|
||||
|
||||
if (net == 0)
|
||||
return 0;
|
||||
|
||||
// Is this a delete method for dynamic arrays?
|
||||
if (net->darray_type() && method_name=="delete") {
|
||||
NetESignal*sig = new NetESignal(net);
|
||||
|
||||
vector<NetExpr*> argv (1);
|
||||
argv[0] = sig;
|
||||
|
||||
NetSTask*sys = new NetSTask("$ivl_darray_method$delete",
|
||||
IVL_SFUNC_AS_TASK_IGNORE, argv);
|
||||
sys->set_line(*this);
|
||||
return sys;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate a procedural continuous assign. This really looks very
|
||||
* much like other procedural assignments, at this point, but there
|
||||
|
|
@ -4123,7 +4289,7 @@ bool PProcess::elaborate(Design*des, NetScope*scope) const
|
|||
// Evaluate the attributes for this process, if there
|
||||
// are any. These attributes are to be attached to the
|
||||
// NetProcTop object.
|
||||
struct attrib_list_t*attrib_list = 0;
|
||||
struct attrib_list_t*attrib_list;
|
||||
unsigned attrib_list_n = 0;
|
||||
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope);
|
||||
|
||||
|
|
@ -4443,53 +4609,11 @@ static void elaborate_tasks(Design*des, NetScope*scope,
|
|||
* When a module is instantiated, it creates the scope then uses this
|
||||
* method to elaborate the contents of the module.
|
||||
*/
|
||||
|
||||
bool Module::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool result_flag = true;
|
||||
|
||||
// Elaborate specparams
|
||||
typedef map<perm_string,PExpr*>::const_iterator specparam_it_t;
|
||||
for (specparam_it_t cur = specparams.begin() ;
|
||||
cur != specparams.end() ; ++ cur ) {
|
||||
|
||||
NetExpr*val = elab_and_eval(des, scope, (*cur).second, -1, true);
|
||||
NetScope::spec_val_t value;
|
||||
|
||||
if (NetECReal*val_cr = dynamic_cast<NetECReal*> (val)) {
|
||||
|
||||
value.type = IVL_VT_REAL;
|
||||
value.real_val = val_cr->value().as_double();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Elaborate "
|
||||
<< "specparam " << (*cur).first
|
||||
<< " value=" << value.real_val << endl;
|
||||
}
|
||||
|
||||
} else if (NetEConst*val_c = dynamic_cast<NetEConst*> (val)) {
|
||||
|
||||
value.type = IVL_VT_BOOL;
|
||||
value.integer = val_c->value().as_long();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Elaborate "
|
||||
<< "specparam " << (*cur).first
|
||||
<< " value=" << value.integer << endl;
|
||||
}
|
||||
|
||||
} else {
|
||||
value.type = IVL_VT_NO_TYPE;
|
||||
cerr << (*cur).second->get_fileline() << ": error: "
|
||||
<< "specparam " << (*cur).first
|
||||
<< " value is not constant: " << *val << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
assert(val);
|
||||
delete val;
|
||||
scope->specparams[(*cur).first] = value;
|
||||
}
|
||||
|
||||
// Elaborate within the generate blocks.
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
|
|
@ -4627,7 +4751,6 @@ bool PGenerate::elaborate_direct_(Design*des, NetScope*container) const
|
|||
// contain anything. Instead scan the case items, which
|
||||
// are listed as sub-schemes of the item.
|
||||
if (item->scheme_type == PGenerate::GS_CASE) {
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t icur = item->generate_schemes.begin()
|
||||
; icur != item->generate_schemes.end() ; ++ icur ) {
|
||||
PGenerate*case_item = *icur;
|
||||
|
|
@ -4738,6 +4861,9 @@ class top_defparams : public elaborator_work_item_t {
|
|||
|
||||
virtual void elaborate_runrun()
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << "debug: top_defparams::elaborate_runrun()" << endl;
|
||||
}
|
||||
// This method recurses through the scopes, looking for
|
||||
// defparam assignments to apply to the parameters in the
|
||||
// various scopes. This needs to be done after all the scopes
|
||||
|
|
@ -4749,6 +4875,10 @@ class top_defparams : public elaborator_work_item_t {
|
|||
// scopes and evaluate the parameters all the way down to
|
||||
// constants.
|
||||
des->evaluate_parameters();
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << "debug: top_defparams::elaborate_runrun() done" << endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -4762,6 +4892,10 @@ class later_defparams : public elaborator_work_item_t {
|
|||
|
||||
virtual void elaborate_runrun()
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << "debug: later_defparams::elaborate_runrun()" << endl;
|
||||
}
|
||||
|
||||
list<NetScope*>tmp_list;
|
||||
for (set<NetScope*>::iterator cur = des->defparams_later.begin()
|
||||
; cur != des->defparams_later.end() ; ++ cur )
|
||||
|
|
@ -4774,7 +4908,13 @@ class later_defparams : public elaborator_work_item_t {
|
|||
tmp_list.pop_front();
|
||||
cur->run_defparams_later(des);
|
||||
}
|
||||
des->evaluate_parameters();
|
||||
|
||||
// The overridden parameters will be evaluated later in
|
||||
// a top_defparams work item.
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << "debuf: later_defparams::elaborate_runrun() done" << endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -4859,7 +4999,7 @@ Design* elaborate(list<perm_string>roots)
|
|||
|
||||
// Make the root scope. This makes a NetScope object and
|
||||
// pushes it into the list of root scopes in the Design.
|
||||
NetScope*scope = des->make_root_scope(*root);
|
||||
NetScope*scope = des->make_root_scope(*root, rmod->program_block);
|
||||
|
||||
// Collect some basic properties of this scope from the
|
||||
// Module definition.
|
||||
|
|
@ -4933,10 +5073,22 @@ Design* elaborate(list<perm_string>roots)
|
|||
// creates all the NetNet and NetMemory objects for declared
|
||||
// objects.
|
||||
for (i = 0; i < root_elems.count(); i++) {
|
||||
|
||||
Module *rmod = root_elems[i]->mod;
|
||||
NetScope *scope = root_elems[i]->scope;
|
||||
scope->set_num_ports( rmod->port_count() );
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
|
||||
<< ": port elaboration root "
|
||||
<< rmod->port_count() << " ports" << endl;
|
||||
}
|
||||
|
||||
if (! rmod->elaborate_sig(des, scope)) {
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
|
||||
<< ": elaborate_sig failed!!!" << endl;
|
||||
}
|
||||
delete des;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4945,11 +5097,24 @@ Design* elaborate(list<perm_string>roots)
|
|||
// defined for the root modules. This code does that.
|
||||
for (unsigned idx = 0; idx < rmod->port_count(); idx += 1) {
|
||||
vector<PEIdent*> mport = rmod->get_port(idx);
|
||||
unsigned int prt_vector_width = 0;
|
||||
PortType::Enum ptype = PortType::PIMPLICIT;
|
||||
for (unsigned pin = 0; pin < mport.size(); pin += 1) {
|
||||
// This really does more than we need and adds extra
|
||||
// stuff to the design that should be cleaned later.
|
||||
(void) mport[pin]->elaborate_port(des, scope);
|
||||
NetNet *netnet = mport[pin]->elaborate_subport(des, scope);
|
||||
if (netnet != 0) {
|
||||
// Elaboration may actually fail with erroneous input source
|
||||
prt_vector_width += netnet->vector_width();
|
||||
ptype = PortType::merged(netnet->port_type(), ptype);
|
||||
}
|
||||
}
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>" << ": debug: " << rmod->mod_name()
|
||||
<< ": adding module port "
|
||||
<< rmod->get_port_name(idx) << endl;
|
||||
}
|
||||
scope->add_module_port_info(idx, rmod->get_port_name(idx), ptype, prt_vector_width );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4976,5 +5141,11 @@ Design* elaborate(list<perm_string>roots)
|
|||
des = 0;
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>" << ": debug: "
|
||||
<< " finishing with "
|
||||
<< des->find_root_scopes().size() << " root scopes " << endl;
|
||||
}
|
||||
|
||||
return des;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008,2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-2012 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
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -55,7 +55,7 @@ bool AProcess::elaborate(Design*des, NetScope*scope) const
|
|||
// Evaluate the attributes for this process, if there
|
||||
// are any. These attributes are to be attached to the
|
||||
// NetProcTop object.
|
||||
struct attrib_list_t*attrib_list = 0;
|
||||
struct attrib_list_t*attrib_list;
|
||||
unsigned attrib_list_n = 0;
|
||||
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope);
|
||||
|
||||
|
|
|
|||
21
emit.cc
21
emit.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -385,6 +385,10 @@ void NetScope::emit_scope(struct target_t*tgt) const
|
|||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
|
||||
tgt->event(cur);
|
||||
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur)
|
||||
tgt->class_type(this, cur->second);
|
||||
|
||||
for (list<netenum_t*>::const_iterator cur = enum_sets_.begin()
|
||||
; cur != enum_sets_.end() ; ++cur)
|
||||
tgt->enumeration(this, *cur);
|
||||
|
|
@ -551,6 +555,21 @@ void NetENetenum::expr_scan(struct expr_scan_t*tgt) const
|
|||
tgt->expr_netenum(this);
|
||||
}
|
||||
|
||||
void NetENew::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_new(this);
|
||||
}
|
||||
|
||||
void NetENull::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_null(this);
|
||||
}
|
||||
|
||||
void NetEProperty::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_property(this);
|
||||
}
|
||||
|
||||
void NetEScope::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_scope(this);
|
||||
|
|
|
|||
2
eval.cc
2
eval.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
|
|||
356
eval_tree.cc
356
eval_tree.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -34,11 +34,11 @@ NetExpr* NetExpr::eval_tree()
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool get_real_arg_(NetExpr*expr, verireal&val)
|
||||
static bool get_real_arg_(const NetExpr*expr, verireal&val)
|
||||
{
|
||||
switch (expr->expr_type()) {
|
||||
case IVL_VT_REAL: {
|
||||
NetECReal*c = dynamic_cast<NetECReal*> (expr);
|
||||
const NetECReal*c = dynamic_cast<const NetECReal*> (expr);
|
||||
if (c == 0) return false;
|
||||
val = c->value();
|
||||
break;
|
||||
|
|
@ -46,13 +46,16 @@ static bool get_real_arg_(NetExpr*expr, verireal&val)
|
|||
|
||||
case IVL_VT_BOOL:
|
||||
case IVL_VT_LOGIC: {
|
||||
NetEConst*c = dynamic_cast<NetEConst*>(expr);
|
||||
const NetEConst*c = dynamic_cast<const NetEConst*>(expr);
|
||||
if (c == 0) return false;
|
||||
verinum tmp = c->value();
|
||||
val = verireal(tmp.as_double());
|
||||
break;
|
||||
}
|
||||
|
||||
case IVL_VT_DARRAY:
|
||||
return false;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
@ -60,7 +63,7 @@ static bool get_real_arg_(NetExpr*expr, verireal&val)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool get_real_arguments(NetExpr*le, NetExpr*re,
|
||||
static bool get_real_arguments(const NetExpr*le, const NetExpr*re,
|
||||
double&lval, double&rval)
|
||||
{
|
||||
verireal val;
|
||||
|
|
@ -82,15 +85,15 @@ bool NetEBinary::get_real_arguments_(verireal&lval, verireal&rval)
|
|||
return true;
|
||||
}
|
||||
|
||||
NetECReal* NetEBAdd::eval_tree_real_()
|
||||
NetECReal* NetEBAdd::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
|
||||
{
|
||||
verireal lval;
|
||||
verireal rval;
|
||||
double lval;
|
||||
double rval;
|
||||
|
||||
bool flag = get_real_arguments_(lval, rval);
|
||||
bool flag = get_real_arguments(l, r, lval, rval);
|
||||
if (!flag) return 0;
|
||||
|
||||
verireal res_val;
|
||||
double res_val;
|
||||
|
||||
switch (op()) {
|
||||
case '+':
|
||||
|
|
@ -103,7 +106,7 @@ NetECReal* NetEBAdd::eval_tree_real_()
|
|||
ivl_assert(*this, 0);
|
||||
}
|
||||
|
||||
NetECReal*res = new NetECReal( res_val );
|
||||
NetECReal*res = new NetECReal( verireal(res_val) );
|
||||
ivl_assert(*this, res);
|
||||
res->set_line(*this);
|
||||
|
||||
|
|
@ -119,52 +122,24 @@ NetExpr* NetEBAdd::eval_tree()
|
|||
eval_expr(left_);
|
||||
eval_expr(right_);
|
||||
|
||||
if (expr_type() == IVL_VT_REAL)
|
||||
return eval_tree_real_();
|
||||
|
||||
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
|
||||
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
|
||||
|
||||
/* If both operands are constant, then replace the entire
|
||||
expression with a constant value. */
|
||||
if (lc != 0 && rc != 0) {
|
||||
verinum lval = lc->value();
|
||||
verinum rval = rc->value();
|
||||
|
||||
unsigned wid = expr_width();
|
||||
ivl_assert(*this, wid > 0);
|
||||
ivl_assert(*this, lval.len() == wid);
|
||||
ivl_assert(*this, rval.len() == wid);
|
||||
|
||||
verinum val;
|
||||
switch (op_) {
|
||||
case '+':
|
||||
val = verinum(lval + rval, wid);
|
||||
break;
|
||||
case '-':
|
||||
val = verinum(lval - rval, wid);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEConst *res = new NetEConst(val);
|
||||
ivl_assert(*this, res);
|
||||
res->set_line(*this);
|
||||
|
||||
if (debug_eval_tree)
|
||||
cerr << get_fileline() << ": debug: Evaluated: " << *this
|
||||
<< " --> " << *res << endl;
|
||||
|
||||
// First try to elaborate the expression completely.
|
||||
NetExpr*res = eval_arguments_(left_,right_);
|
||||
if (res != 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Try to combine a right constant value with the right
|
||||
constant value of a sub-expression add. For example, the
|
||||
expression (a + 2) - 1 can be rewritten as a + 1. */
|
||||
// If the expression type is real, then do not attempt the
|
||||
// following alternative processing.
|
||||
if (expr_type() == IVL_VT_REAL)
|
||||
return 0;
|
||||
|
||||
// The expression has not evaluated to a constant. Let's still
|
||||
// try to optimize by trying to combine a right constant value
|
||||
// with the right constant value of a sub-expression add. For
|
||||
// example, the expression (a + 2) - 1 can be rewritten as a + 1.
|
||||
|
||||
NetEBAdd*se = dynamic_cast<NetEBAdd*>(left_);
|
||||
lc = se? dynamic_cast<NetEConst*>(se->right_) : 0;
|
||||
NetEConst*lc = se? dynamic_cast<NetEConst*>(se->right_) : 0;
|
||||
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
|
||||
|
||||
if (lc != 0 && rc != 0) {
|
||||
ivl_assert(*this, se != 0);
|
||||
|
|
@ -200,11 +175,56 @@ NetExpr* NetEBAdd::eval_tree()
|
|||
tmp->set_line(*right_);
|
||||
delete right_;
|
||||
right_ = tmp;
|
||||
/* We've changed the subexpression, but the result is
|
||||
still not constant, so return nil here anyhow. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We may have changed the subexpression, but the result is
|
||||
// still not constant, so return nil here anyhow.
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr* NetEBAdd::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
{
|
||||
if (expr_type() == IVL_VT_REAL)
|
||||
return eval_tree_real_(l,r);
|
||||
|
||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
|
||||
|
||||
/* If both operands are constant, then replace the entire
|
||||
expression with a constant value. */
|
||||
if (lc != 0 && rc != 0) {
|
||||
verinum lval = lc->value();
|
||||
verinum rval = rc->value();
|
||||
|
||||
unsigned wid = expr_width();
|
||||
ivl_assert(*this, wid > 0);
|
||||
ivl_assert(*this, lval.len() == wid);
|
||||
ivl_assert(*this, rval.len() == wid);
|
||||
|
||||
verinum val;
|
||||
switch (op_) {
|
||||
case '+':
|
||||
val = verinum(lval + rval, wid);
|
||||
break;
|
||||
case '-':
|
||||
val = verinum(lval - rval, wid);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEConst *res = new NetEConst(val);
|
||||
ivl_assert(*this, res);
|
||||
res->set_line(*this);
|
||||
|
||||
if (debug_eval_tree)
|
||||
cerr << get_fileline() << ": debug: Evaluated: " << *this
|
||||
<< " --> " << *res << endl;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* Nothing more to be done, the value is not constant. */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -276,13 +296,12 @@ NetEConst* NetEBBits::eval_tree()
|
|||
return new NetEConst(res);
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_less_()
|
||||
NetEConst* NetEBComp::eval_less_(const NetExpr*le, const NetExpr*re) const
|
||||
{
|
||||
if (right_->expr_type() == IVL_VT_REAL ||
|
||||
left_->expr_type() == IVL_VT_REAL)
|
||||
return eval_leeq_real_(left_, right_, false);
|
||||
if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL)
|
||||
return eval_leeq_real_(le, re, false);
|
||||
|
||||
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
|
||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(re);
|
||||
if (rc == 0) return 0;
|
||||
|
||||
verinum rv = rc->value();
|
||||
|
|
@ -292,12 +311,12 @@ NetEConst* NetEBComp::eval_less_()
|
|||
return res;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = must_be_leeq_(left_, rv, false)) {
|
||||
if (NetEConst*tmp = must_be_leeq_(le, rv, false)) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Now go on to the normal test of the values. */
|
||||
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
|
||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(le);
|
||||
if (lc == 0) return 0;
|
||||
|
||||
verinum lv = lc->value();
|
||||
|
|
@ -318,7 +337,7 @@ NetEConst* NetEBComp::eval_less_()
|
|||
}
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::must_be_leeq_(NetExpr*le, const verinum&rv, bool eq_flag)
|
||||
NetEConst* NetEBComp::must_be_leeq_(const NetExpr*le, const verinum&rv, bool eq_flag) const
|
||||
{
|
||||
assert(le->expr_width() > 0);
|
||||
verinum lv (verinum::V1, le->expr_width());
|
||||
|
|
@ -339,7 +358,7 @@ NetEConst* NetEBComp::must_be_leeq_(NetExpr*le, const verinum&rv, bool eq_flag)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*re, bool eq_flag)
|
||||
NetEConst* NetEBComp::eval_leeq_real_(const NetExpr*le, const NetExpr*re, bool eq_flag) const
|
||||
{
|
||||
double lval;
|
||||
double rval;
|
||||
|
|
@ -358,14 +377,13 @@ NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*re, bool eq_flag)
|
|||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_leeq_()
|
||||
NetEConst* NetEBComp::eval_leeq_(const NetExpr*le, const NetExpr*re) const
|
||||
{
|
||||
if (right_->expr_type() == IVL_VT_REAL ||
|
||||
left_->expr_type() == IVL_VT_REAL)
|
||||
return eval_leeq_real_(left_, right_, true);
|
||||
if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL)
|
||||
return eval_leeq_real_(le, re, true);
|
||||
// assert(expr_type() == IVL_VT_LOGIC);
|
||||
|
||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||
const NetEConst*r = dynamic_cast<const NetEConst*>(re);
|
||||
if (r == 0) return 0;
|
||||
|
||||
verinum rv = r->value();
|
||||
|
|
@ -375,18 +393,18 @@ NetEConst* NetEBComp::eval_leeq_()
|
|||
return res;
|
||||
}
|
||||
|
||||
if (left_->expr_width() == 0) {
|
||||
if (le->expr_width() == 0) {
|
||||
cerr << get_fileline() << ": internal error: Something wrong "
|
||||
<< "with the left side width of <= ?" << endl;
|
||||
cerr << get_fileline() << ": : " << *this << endl;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = must_be_leeq_(left_, rv, true)) {
|
||||
if (NetEConst*tmp = must_be_leeq_(le, rv, true)) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Now go on to the normal test of the values. */
|
||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||
const NetEConst*l = dynamic_cast<const NetEConst*>(le);
|
||||
if (l == 0) return 0;
|
||||
|
||||
verinum lv = l->value();
|
||||
|
|
@ -407,13 +425,12 @@ NetEConst* NetEBComp::eval_leeq_()
|
|||
}
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_gt_()
|
||||
NetEConst* NetEBComp::eval_gt_(const NetExpr*le, const NetExpr*re) const
|
||||
{
|
||||
if (right_->expr_type() == IVL_VT_REAL ||
|
||||
left_->expr_type() == IVL_VT_REAL)
|
||||
return eval_leeq_real_(right_, left_, false);
|
||||
if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL)
|
||||
return eval_leeq_real_(re, le, false);
|
||||
|
||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||
const NetEConst*l = dynamic_cast<const NetEConst*>(le);
|
||||
if (l == 0) return 0;
|
||||
|
||||
verinum lv = l->value();
|
||||
|
|
@ -423,12 +440,12 @@ NetEConst* NetEBComp::eval_gt_()
|
|||
return res;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = must_be_leeq_(right_, lv, false)) {
|
||||
if (NetEConst*tmp = must_be_leeq_(re, lv, false)) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Now go on to the normal test of the values. */
|
||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||
const NetEConst*r = dynamic_cast<const NetEConst*>(re);
|
||||
if (r == 0) return 0;
|
||||
|
||||
verinum rv = r->value();
|
||||
|
|
@ -449,13 +466,12 @@ NetEConst* NetEBComp::eval_gt_()
|
|||
}
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_gteq_()
|
||||
NetEConst* NetEBComp::eval_gteq_(const NetExpr*le, const NetExpr*re) const
|
||||
{
|
||||
if (right_->expr_type() == IVL_VT_REAL ||
|
||||
left_->expr_type() == IVL_VT_REAL)
|
||||
return eval_leeq_real_(right_, left_, true);
|
||||
if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL)
|
||||
return eval_leeq_real_(re, le, true);
|
||||
|
||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||
const NetEConst*l = dynamic_cast<const NetEConst*>(left_);
|
||||
if (l == 0) return 0;
|
||||
|
||||
verinum lv = l->value();
|
||||
|
|
@ -465,12 +481,12 @@ NetEConst* NetEBComp::eval_gteq_()
|
|||
return res;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = must_be_leeq_(right_, lv, true)) {
|
||||
if (NetEConst*tmp = must_be_leeq_(re, lv, true)) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Now go on to the normal test of the values. */
|
||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||
const NetEConst*r = dynamic_cast<const NetEConst*>(re);
|
||||
if (r == 0) return 0;
|
||||
|
||||
verinum rv = r->value();
|
||||
|
|
@ -498,15 +514,15 @@ NetEConst* NetEBComp::eval_gteq_()
|
|||
* are equal, but there are are x/z bits, then the situation is
|
||||
* ambiguous so the result is x.
|
||||
*/
|
||||
NetEConst* NetEBComp::eval_eqeq_real_(bool ne_flag)
|
||||
NetEConst* NetEBComp::eval_eqeq_real_(bool ne_flag, const NetExpr*le, const NetExpr*re) const
|
||||
{
|
||||
verireal lval;
|
||||
verireal rval;
|
||||
double lval;
|
||||
double rval;
|
||||
|
||||
bool flag = get_real_arguments_(lval, rval);
|
||||
bool flag = get_real_arguments(le, re, lval, rval);
|
||||
if (! flag) return 0;
|
||||
|
||||
verinum result(((lval.as_double() == rval.as_double()) ^ ne_flag) ?
|
||||
verinum result(((lval == rval) ^ ne_flag) ?
|
||||
verinum::V1 : verinum::V0, 1);
|
||||
NetEConst*res = new NetEConst(result);
|
||||
ivl_assert(*this, res);
|
||||
|
|
@ -514,14 +530,14 @@ NetEConst* NetEBComp::eval_eqeq_real_(bool ne_flag)
|
|||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_eqeq_(bool ne_flag)
|
||||
NetEConst* NetEBComp::eval_eqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const
|
||||
{
|
||||
if (left_->expr_type() == IVL_VT_REAL ||
|
||||
right_->expr_type() == IVL_VT_REAL)
|
||||
return eval_eqeq_real_(ne_flag);
|
||||
if (le->expr_type() == IVL_VT_REAL ||
|
||||
re->expr_type() == IVL_VT_REAL)
|
||||
return eval_eqeq_real_(ne_flag, le, re);
|
||||
|
||||
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
|
||||
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
|
||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(le);
|
||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(re);
|
||||
if (lc == 0 || rc == 0) return 0;
|
||||
|
||||
const verinum&lv = lc->value();
|
||||
|
|
@ -631,10 +647,10 @@ NetEConst* NetEBComp::eval_eqeq_(bool ne_flag)
|
|||
return result;
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag)
|
||||
NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const
|
||||
{
|
||||
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
|
||||
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
|
||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(le);
|
||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(re);
|
||||
if (lc == 0 || rc == 0) return 0;
|
||||
|
||||
const verinum&lv = lc->value();
|
||||
|
|
@ -687,47 +703,54 @@ NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag)
|
|||
return result;
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
{
|
||||
NetEConst*res = 0;
|
||||
|
||||
switch (op_) {
|
||||
case 'E': // Case equality (===)
|
||||
res = eval_eqeqeq_(false, l, r);
|
||||
break;
|
||||
|
||||
case 'e': // Equality (==)
|
||||
res = eval_eqeq_(false, l, r);
|
||||
break;
|
||||
|
||||
case 'G': // >=
|
||||
res = eval_gteq_(l, r);
|
||||
break;
|
||||
|
||||
case 'L': // <=
|
||||
res = eval_leeq_(l, r);
|
||||
break;
|
||||
|
||||
case 'N': // Case inequality (!==)
|
||||
res = eval_eqeqeq_(true, l, r);
|
||||
break;
|
||||
|
||||
case 'n': // not-equal (!=)
|
||||
res = eval_eqeq_(true, l, r);
|
||||
break;
|
||||
|
||||
case '<': // Less than
|
||||
res = eval_less_(l, r);
|
||||
break;
|
||||
|
||||
case '>': // Greater than
|
||||
res = eval_gt_(l, r);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_tree()
|
||||
{
|
||||
eval_expr(left_);
|
||||
eval_expr(right_);
|
||||
|
||||
NetEConst*res = 0;
|
||||
|
||||
switch (op_) {
|
||||
case 'E': // Case equality (===)
|
||||
res = eval_eqeqeq_(false);
|
||||
break;
|
||||
|
||||
case 'e': // Equality (==)
|
||||
res = eval_eqeq_(false);
|
||||
break;
|
||||
|
||||
case 'G': // >=
|
||||
res = eval_gteq_();
|
||||
break;
|
||||
|
||||
case 'L': // <=
|
||||
res = eval_leeq_();
|
||||
break;
|
||||
|
||||
case 'N': // Case inequality (!==)
|
||||
res = eval_eqeqeq_(true);
|
||||
break;
|
||||
|
||||
case 'n': // not-equal (!=)
|
||||
res = eval_eqeq_(true);
|
||||
break;
|
||||
|
||||
case '<': // Less than
|
||||
res = eval_less_();
|
||||
break;
|
||||
|
||||
case '>': // Greater than
|
||||
res = eval_gt_();
|
||||
break;
|
||||
|
||||
}
|
||||
NetEConst*res = eval_arguments_(left_, right_);
|
||||
if (res == 0) return 0;
|
||||
res->set_line(*this);
|
||||
|
||||
|
|
@ -934,15 +957,15 @@ NetEConst* NetEBLogic::eval_tree()
|
|||
}
|
||||
|
||||
|
||||
NetExpr* NetEBMult::eval_tree_real_()
|
||||
NetExpr* NetEBMult::eval_tree_real_(const NetExpr*l, const NetExpr*r) const
|
||||
{
|
||||
verireal lval;
|
||||
verireal rval;
|
||||
double lval;
|
||||
double rval;
|
||||
|
||||
bool flag = get_real_arguments_(lval, rval);
|
||||
bool flag = get_real_arguments(l, r, lval, rval);
|
||||
if (! flag) return 0;
|
||||
|
||||
NetECReal*res = new NetECReal(lval * rval);
|
||||
NetECReal*res = new NetECReal( verireal(lval * rval) );
|
||||
ivl_assert(*this, res);
|
||||
res->set_line(*this);
|
||||
|
||||
|
|
@ -958,11 +981,16 @@ NetExpr* NetEBMult::eval_tree()
|
|||
eval_expr(left_);
|
||||
eval_expr(right_);
|
||||
|
||||
if (expr_type() == IVL_VT_REAL) return eval_tree_real_();
|
||||
return eval_arguments_(left_, right_);
|
||||
}
|
||||
|
||||
NetExpr* NetEBMult::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
{
|
||||
if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r);
|
||||
assert(expr_type() == IVL_VT_LOGIC);
|
||||
|
||||
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
|
||||
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
|
||||
const NetEConst*lc = dynamic_cast<const NetEConst*>(l);
|
||||
const NetEConst*rc = dynamic_cast<const NetEConst*>(r);
|
||||
if (lc == 0 || rc == 0) return 0;
|
||||
|
||||
verinum lval = lc->value();
|
||||
|
|
@ -1043,9 +1071,13 @@ NetEConst* NetEBShift::eval_tree()
|
|||
{
|
||||
eval_expr(left_);
|
||||
eval_expr(right_);
|
||||
return eval_arguments_(left_,right_);
|
||||
}
|
||||
|
||||
NetEConst*le = dynamic_cast<NetEConst*>(left_);
|
||||
NetEConst*re = dynamic_cast<NetEConst*>(right_);
|
||||
NetEConst* NetEBShift::eval_arguments_(const NetExpr*l, const NetExpr*r) const
|
||||
{
|
||||
const NetEConst*le = dynamic_cast<const NetEConst*>(l);
|
||||
const NetEConst*re = dynamic_cast<const NetEConst*>(r);
|
||||
if (le == 0 || re == 0) return 0;
|
||||
|
||||
NetEConst*res;
|
||||
|
|
@ -1098,7 +1130,7 @@ NetEConst* NetEConcat::eval_tree()
|
|||
}
|
||||
|
||||
unsigned gap = 0;
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
|
||||
// Parameter not here? This is an error, but presumably
|
||||
// already caught and we are here just to catch more.
|
||||
|
|
@ -1149,7 +1181,7 @@ NetEConst* NetEConcat::eval_tree()
|
|||
|
||||
unsigned cur = 0;
|
||||
bool is_string_flag = true;
|
||||
for (unsigned idx = parms_.count() ; idx > 0 ; idx -= 1) {
|
||||
for (unsigned idx = parms_.size() ; idx > 0 ; idx -= 1) {
|
||||
NetEConst*expr = dynamic_cast<NetEConst*>(parms_[idx-1]);
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
|
@ -1314,12 +1346,18 @@ NetExpr* NetETernary::eval_tree()
|
|||
eval_expr(true_val_);
|
||||
eval_expr(false_val_);
|
||||
|
||||
NetEConst*t = dynamic_cast<NetEConst*>(true_val_);
|
||||
NetEConst*f = dynamic_cast<NetEConst*>(false_val_);
|
||||
return blended_arguments_(true_val_, false_val_);
|
||||
}
|
||||
|
||||
NetExpr*NetETernary::blended_arguments_(const NetExpr*te, const NetExpr*fe) const
|
||||
{
|
||||
|
||||
const NetEConst*t = dynamic_cast<const NetEConst*>(te);
|
||||
const NetEConst*f = dynamic_cast<const NetEConst*>(fe);
|
||||
if (t == 0 || f == 0) {
|
||||
verireal tv, fv;
|
||||
if (!get_real_arg_(true_val_, tv)) return 0;
|
||||
if (!get_real_arg_(false_val_, fv)) return 0;
|
||||
if (!get_real_arg_(te, tv)) return 0;
|
||||
if (!get_real_arg_(te, fv)) return 0;
|
||||
|
||||
verireal val = verireal(0.0);
|
||||
if (tv.as_double() == fv.as_double()) val = tv;
|
||||
|
|
@ -1963,8 +2001,16 @@ NetExpr* NetEUFunc::eval_tree()
|
|||
}
|
||||
|
||||
if (need_const_) {
|
||||
cerr << get_fileline() << ": sorry: Constant user functions are "
|
||||
"not yet supported." << endl;
|
||||
NetFuncDef*def = func_->func_def();
|
||||
ivl_assert(*this, def);
|
||||
|
||||
vector<NetExpr*>args(parms_.size());
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1)
|
||||
args[idx] = parms_[idx]->dup_expr();
|
||||
|
||||
NetExpr*res = def->evaluate_function(*this, args);
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -14,11 +14,8 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: hello_vpi.c,v 1.5 2007/01/17 05:35:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file contains an example VPI module to demonstrate the tools
|
||||
|
|
@ -60,22 +57,3 @@ void (*vlog_startup_routines[])() = {
|
|||
my_hello_register,
|
||||
0
|
||||
};
|
||||
/*
|
||||
* $Log: hello_vpi.c,v $
|
||||
* Revision 1.5 2007/01/17 05:35:48 steve
|
||||
* Fix typo is hello_vpi.c example.
|
||||
*
|
||||
* Revision 1.4 2006/10/30 22:46:25 steve
|
||||
* Updates for Cygwin portability (pr1585922)
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/08/11 23:47:04 steve
|
||||
* Add missing Log and Ident strings.
|
||||
*
|
||||
* Revision 1.1 2002/04/18 03:25:16 steve
|
||||
* More examples.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $Id: sqrt-virtex.v,v 1.5 2007/03/22 16:08:18 steve Exp $"
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $Id: sqrt.vl,v 1.5 2007/03/22 16:08:18 steve Exp $"
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
// This example describes a 16x1 RAM that can be synthesized into
|
||||
|
|
|
|||
152
expr_synth.cc
152
expr_synth.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2012 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
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
# include <iostream>
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netvector.h"
|
||||
# include "netmisc.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
|
|
@ -118,11 +119,11 @@ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
}
|
||||
|
||||
perm_string path = lsig->scope()->local_symbol();
|
||||
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
|
||||
perm_string oname = osig->scope()->local_symbol();
|
||||
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
|
||||
|
|
@ -173,11 +174,11 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
rsig = pad_to_width(des, rsig, width, *this);
|
||||
|
||||
assert(lsig->vector_width() == rsig->vector_width());
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(expr_type());
|
||||
|
||||
perm_string oname = scope->local_symbol();
|
||||
NetLogic*gate;
|
||||
|
|
@ -243,11 +244,11 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
rsig = pad_to_width(des, rsig, width, *this);
|
||||
}
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(IVL_VT_LOGIC);
|
||||
|
||||
// Test if the comparison is signed.
|
||||
//
|
||||
|
|
@ -390,11 +391,11 @@ NetNet* NetEBPow::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
connect(powr->pin_DataA(), lsig->pin(0));
|
||||
connect(powr->pin_DataB(), rsig->pin(0));
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
osig->local_flag(true);
|
||||
|
||||
connect(powr->pin_Result(), osig->pin(0));
|
||||
|
|
@ -427,11 +428,11 @@ NetNet* NetEBMult::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
connect(mult->pin_DataA(), lsig->pin(0));
|
||||
connect(mult->pin_DataB(), rsig->pin(0));
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
osig->local_flag(true);
|
||||
|
||||
connect(mult->pin_Result(), osig->pin(0));
|
||||
|
|
@ -452,11 +453,11 @@ NetNet* NetEBDiv::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
if (real_args) width = 1;
|
||||
else width = expr_width();
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(lsig->data_type(), width-1, 0);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(lsig->data_type());
|
||||
osig->set_signed(has_sign());
|
||||
osig->local_flag(true);
|
||||
|
||||
switch (op()) {
|
||||
|
|
@ -530,10 +531,10 @@ NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
return 0;
|
||||
}
|
||||
|
||||
netvector_t*osig_tmp = new netvector_t(expr_type());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
NetNet::IMPLICIT, osig_tmp);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
NetLogic*olog;
|
||||
|
|
@ -597,10 +598,10 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
if (shift == 0)
|
||||
return lsig;
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1,0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
// ushift is the amount of pad created by the shift.
|
||||
|
|
@ -618,10 +619,10 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
psel->set_line(*this);
|
||||
des->add_node(psel);
|
||||
|
||||
netvector_t*psig_vec = new netvector_t(expr_type(), part_width-1, 0);
|
||||
NetNet*psig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, part_width);
|
||||
NetNet::IMPLICIT, psig_vec);
|
||||
psig->set_line(*this);
|
||||
psig->data_type(expr_type());
|
||||
psig->local_flag(true);
|
||||
connect(psig->pin(0), psel->pin(0));
|
||||
|
||||
|
|
@ -646,10 +647,11 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
znum);
|
||||
des->add_node(zcon);
|
||||
|
||||
netvector_t*zsig_vec = new netvector_t(osig->data_type(),
|
||||
znum.len()-1, 0);
|
||||
NetNet*zsig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, znum.len());
|
||||
NetNet::WIRE, zsig_vec);
|
||||
zsig->set_line(*this);
|
||||
zsig->data_type(osig->data_type());
|
||||
zsig->local_flag(true);
|
||||
connect(zcon->pin(0), zsig->pin(0));
|
||||
|
||||
|
|
@ -676,10 +678,10 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
|
||||
if (rsig == 0) return 0;
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1, 0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(),
|
||||
|
|
@ -702,11 +704,11 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
{
|
||||
/* First, synthesize the operands. */
|
||||
unsigned num_parms = parms_.count();
|
||||
NetNet**tmp = new NetNet*[parms_.count()];
|
||||
unsigned num_parms = parms_.size();
|
||||
NetNet**tmp = new NetNet*[parms_.size()];
|
||||
bool flag = true;
|
||||
ivl_variable_type_t data_type = IVL_VT_NO_TYPE;
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
if (parms_[idx]->expr_width() == 0) {
|
||||
/* We need to synthesize a replication of zero. */
|
||||
tmp[idx] = parms_[idx]->synthesize(des, scope, root);
|
||||
|
|
@ -739,10 +741,10 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
|
||||
/* Make a NetNet object to carry the output vector. */
|
||||
perm_string path = scope->local_symbol();
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
|
||||
netvector_t*osig_vec = new netvector_t(data_type, expr_width()-1, 0);
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(data_type);
|
||||
|
||||
NetConcat*concat = new NetConcat(scope, scope->local_symbol(),
|
||||
osig->vector_width(),
|
||||
|
|
@ -754,8 +756,8 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
unsigned count_input_width = 0;
|
||||
unsigned cur_pin = 1;
|
||||
for (unsigned rpt = 0; rpt < repeat(); rpt += 1) {
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
unsigned concat_item = parms_.count()-idx-1;
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
unsigned concat_item = parms_.size()-idx-1;
|
||||
if (tmp[concat_item] == 0) continue;
|
||||
connect(concat->pin(cur_pin), tmp[concat_item]->pin(0));
|
||||
cur_pin += 1;
|
||||
|
|
@ -785,11 +787,11 @@ NetNet* NetEConst::synthesize(Design*des, NetScope*scope, NetExpr*)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(expr_type());
|
||||
osig->set_signed(has_sign());
|
||||
|
||||
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
|
||||
con->set_line(*this);
|
||||
|
|
@ -806,11 +808,11 @@ NetNet* NetECReal::synthesize(Design*des, NetScope*scope, NetExpr*)
|
|||
{
|
||||
perm_string path = scope->local_symbol();
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::WIRE, 1);
|
||||
netvector_t*osig_vec = new netvector_t(IVL_VT_REAL);
|
||||
osig_vec->set_signed(has_sign());
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::WIRE, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(IVL_VT_REAL);
|
||||
osig->set_signed(has_sign());
|
||||
|
||||
NetLiteral*con = new NetLiteral(scope, scope->local_symbol(), value_);
|
||||
con->set_line(*this);
|
||||
|
|
@ -839,10 +841,10 @@ NetNet* NetEUBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
}
|
||||
|
||||
unsigned width = isig->vector_width();
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, width);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
perm_string oname = scope->local_symbol();
|
||||
|
|
@ -882,11 +884,12 @@ NetNet* NetEUnary::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
if (expr_->has_sign() == false)
|
||||
return sub;
|
||||
|
||||
netvector_t*sig_vec = new netvector_t(sub->data_type(),
|
||||
sub->vector_width()-1, 0);
|
||||
NetNet*sig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, sub->vector_width());
|
||||
NetNet::WIRE, sig_vec);
|
||||
sig->set_line(*this);
|
||||
sig->local_flag(true);
|
||||
sig->data_type(sub->data_type());
|
||||
|
||||
NetAbs*tmp = new NetAbs(scope, scope->local_symbol(), sub->vector_width());
|
||||
tmp->set_line(*this);
|
||||
|
|
@ -956,10 +959,10 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
gate->set_line(*this);
|
||||
des->add_node(gate);
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
|
|
@ -1006,8 +1009,6 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
|
||||
if (sub == 0) return 0;
|
||||
|
||||
NetNet*off = 0;
|
||||
|
||||
// Detect the special case that there is a base expression and
|
||||
// it is constant. In this case we can generate fixed part selects.
|
||||
if (NetEConst*base_const = dynamic_cast<NetEConst*>(base_)) {
|
||||
|
|
@ -1064,10 +1065,12 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
NetPartSelect::VP);
|
||||
des->add_node(sel);
|
||||
|
||||
ivl_assert(*this, select_width > 0);
|
||||
netvector_t*tmp_vec = new netvector_t(sub->data_type(),
|
||||
select_width-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, select_width);
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->data_type(sub->data_type());
|
||||
tmp->local_flag(true);
|
||||
connect(sel->pin(0), tmp->pin(0));
|
||||
|
||||
|
|
@ -1091,10 +1094,10 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
connect(cat->pin(concat_count), above->pin(0));
|
||||
}
|
||||
|
||||
tmp_vec = new netvector_t(sub->data_type(), expr_width()-1, 0);
|
||||
tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, expr_width());
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->data_type(sub->data_type());
|
||||
tmp->local_flag(true);
|
||||
connect(cat->pin(0), tmp->pin(0));
|
||||
}
|
||||
|
|
@ -1105,16 +1108,17 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
// actual part/bit select. Generate a NetPartSelect object to
|
||||
// do the work, and replace "sub" with the selected output.
|
||||
if (base_ != 0) {
|
||||
off = base_->synthesize(des, scope, root);
|
||||
NetNet*off = base_->synthesize(des, scope, root);
|
||||
|
||||
NetPartSelect*sel = new NetPartSelect(sub, off, expr_width(),
|
||||
base_->has_sign());
|
||||
sel->set_line(*this);
|
||||
des->add_node(sel);
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(sub->data_type(),
|
||||
expr_width()-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
tmp->data_type(sub->data_type());
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->local_flag(true);
|
||||
tmp->set_line(*this);
|
||||
sub = tmp;
|
||||
|
|
@ -1135,10 +1139,11 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
// extension or 0 extension, depending on the has_sign() mode
|
||||
// of the expression.
|
||||
|
||||
netvector_t*net_vec = new netvector_t(expr_type(), expr_width()-1, 0);
|
||||
net_vec->set_signed(has_sign());
|
||||
NetNet*net = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
NetNet::IMPLICIT, net_vec);
|
||||
net->set_line(*this);
|
||||
net->data_type(expr_type());
|
||||
net->local_flag(true);
|
||||
if (has_sign()) {
|
||||
NetSignExtend*pad = new NetSignExtend(scope,
|
||||
|
|
@ -1149,7 +1154,6 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
|
||||
connect(pad->pin(1), sub->pin(0));
|
||||
connect(pad->pin(0), net->pin(0));
|
||||
net->set_signed(true);
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -1166,10 +1170,10 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
con->set_line(*this);
|
||||
des->add_node(con);
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(expr_type(), pad_width-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, pad_width);
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->data_type(expr_type());
|
||||
tmp->local_flag(true);
|
||||
connect(tmp->pin(0), con->pin(0));
|
||||
|
||||
|
|
@ -1221,9 +1225,9 @@ NetNet* NetETernary::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
ivl_assert(*this, csig->vector_width() == 1);
|
||||
|
||||
unsigned width=expr_width();
|
||||
NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, width);
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->data_type(expr_type());
|
||||
osig->local_flag(true);
|
||||
|
||||
/* Make sure the types match. */
|
||||
|
|
@ -1266,11 +1270,12 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
if (word_ == 0)
|
||||
return net_;
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(net_->data_type(),
|
||||
net_->vector_width()-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, net_->vector_width());
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->local_flag(true);
|
||||
tmp->data_type(net_->data_type());
|
||||
|
||||
// For NetExpr objects, the word index is already converted to
|
||||
// a canonical (lsb==0) address. Just use the index directly.
|
||||
|
|
@ -1355,12 +1360,12 @@ NetNet* NetESFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
net->set_line(*this);
|
||||
des->add_node(net);
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(def->type, def->wid-1, 0);
|
||||
osig_vec->set_signed(def->type==IVL_VT_REAL? true : false);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, def->wid);
|
||||
NetNet::WIRE, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->set_signed(def->type==IVL_VT_REAL? true : false);
|
||||
osig->data_type(def->type);
|
||||
|
||||
connect(net->pin(0), osig->pin(0));
|
||||
|
||||
|
|
@ -1386,11 +1391,11 @@ NetNet* NetESFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
|
||||
NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
{
|
||||
svector<NetNet*> eparms (parms_.count());
|
||||
vector<NetNet*> eparms (parms_.size());
|
||||
|
||||
/* Synthesize the arguments. */
|
||||
bool errors = false;
|
||||
for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
|
||||
for (unsigned idx = 0; idx < eparms.size(); idx += 1) {
|
||||
if (dynamic_cast<NetEEvent*> (parms_[idx])) {
|
||||
errors = true;
|
||||
continue;
|
||||
|
|
@ -1423,16 +1428,17 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
|||
des->add_node(net);
|
||||
|
||||
/* Create an output signal and connect it to the function. */
|
||||
netvector_t*osig_vec = new netvector_t(result_sig_->expr_type(),
|
||||
result_sig_->vector_width()-1, 0);
|
||||
NetNet*osig = new NetNet(scope_, scope_->local_symbol(), NetNet::WIRE,
|
||||
result_sig_->vector_width());
|
||||
osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(result_sig_->expr_type());
|
||||
connect(net->pin(0), osig->pin(0));
|
||||
|
||||
/* Connect the pins to the arguments. */
|
||||
NetFuncDef*def = func_->func_def();
|
||||
for (unsigned idx = 0; idx < eparms.count(); idx += 1) {
|
||||
for (unsigned idx = 0; idx < eparms.size(); idx += 1) {
|
||||
unsigned width = def->port(idx)->vector_width();
|
||||
NetNet*tmp;
|
||||
if (eparms[idx]->get_signed()) {
|
||||
|
|
|
|||
22
functor.cc
22
functor.cc
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -24,6 +24,8 @@
|
|||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
functor_t::~functor_t()
|
||||
{
|
||||
}
|
||||
|
|
@ -52,6 +54,10 @@ void functor_t::lpm_compare(Design*, NetCompare*)
|
|||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_concat(Design*, NetConcat*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_const(Design*, NetConst*)
|
||||
{
|
||||
}
|
||||
|
|
@ -84,6 +90,10 @@ void functor_t::lpm_mux(Design*, NetMux*)
|
|||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_part_select(Design*, NetPartSelect*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_pow(Design*, NetPow*)
|
||||
{
|
||||
}
|
||||
|
|
@ -185,6 +195,11 @@ void NetCompare::functor_node(Design*des, functor_t*fun)
|
|||
fun->lpm_compare(des, this);
|
||||
}
|
||||
|
||||
void NetConcat::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_concat(des, this);
|
||||
}
|
||||
|
||||
void NetConst::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_const(des, this);
|
||||
|
|
@ -225,6 +240,11 @@ void NetMux::functor_node(Design*des, functor_t*fun)
|
|||
fun->lpm_mux(des, this);
|
||||
}
|
||||
|
||||
void NetPartSelect::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_part_select(des, this);
|
||||
}
|
||||
|
||||
void NetPow::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_pow(des, this);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __functor_H
|
||||
#define __functor_H
|
||||
/*
|
||||
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2008,2012 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
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
@ -57,6 +57,9 @@ struct functor_t {
|
|||
/* This method is called for each structural comparator. */
|
||||
virtual void lpm_compare(class Design*des, class NetCompare*);
|
||||
|
||||
/* This method is called for each structural concatenation. */
|
||||
virtual void lpm_concat(class Design*des, class NetConcat*);
|
||||
|
||||
/* This method is called for each structural constant. */
|
||||
virtual void lpm_const(class Design*des, class NetConst*);
|
||||
|
||||
|
|
@ -81,6 +84,8 @@ struct functor_t {
|
|||
/* This method is called for each MUX. */
|
||||
virtual void lpm_mux(class Design*des, class NetMux*);
|
||||
|
||||
virtual void lpm_part_select(class Design*des, class NetPartSelect*);
|
||||
|
||||
/* This method is called for each power. */
|
||||
virtual void lpm_pow(class Design*des, class NetPow*);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ SUFFIX=@SUFFIX@
|
|||
|
||||
# These are used for linking...
|
||||
LD=$CC
|
||||
LDFLAGS="@SHARED@ -L@LIBDIR@"
|
||||
LDFLAGS="@IVCTARGETFLAGS@ @SHARED@ -L@LIBDIR@"
|
||||
LDLIBS="-lveriuser$SUFFIX -lvpi$SUFFIX"
|
||||
|
||||
CCSRC=
|
||||
|
|
|
|||
42
ivl.def
42
ivl.def
|
|
@ -63,6 +63,7 @@ ivl_expr_file
|
|||
ivl_expr_lineno
|
||||
ivl_expr_name
|
||||
ivl_expr_nature
|
||||
ivl_expr_net_type
|
||||
ivl_expr_opcode
|
||||
ivl_expr_oper1
|
||||
ivl_expr_oper2
|
||||
|
|
@ -70,6 +71,7 @@ ivl_expr_oper3
|
|||
ivl_expr_parameter
|
||||
ivl_expr_parm
|
||||
ivl_expr_parms
|
||||
ivl_expr_property_idx
|
||||
ivl_expr_repeat
|
||||
ivl_expr_scope
|
||||
ivl_expr_sel_type
|
||||
|
|
@ -140,6 +142,7 @@ ivl_lpm_width
|
|||
ivl_lval_idx
|
||||
ivl_lval_mux
|
||||
ivl_lval_part_off
|
||||
ivl_lval_property_idx
|
||||
ivl_lval_sel_type
|
||||
ivl_lval_sig
|
||||
ivl_lval_width
|
||||
|
|
@ -166,6 +169,7 @@ ivl_parameter_basename
|
|||
ivl_parameter_expr
|
||||
ivl_parameter_file
|
||||
ivl_parameter_lineno
|
||||
ivl_parameter_local
|
||||
|
||||
ivl_path_condit
|
||||
ivl_path_delay
|
||||
|
|
@ -175,10 +179,21 @@ ivl_path_source
|
|||
ivl_path_source_negedge
|
||||
ivl_path_source_posedge
|
||||
|
||||
ivl_process_analog
|
||||
ivl_process_attr_cnt
|
||||
ivl_process_attr_val
|
||||
ivl_process_file
|
||||
ivl_process_lineno
|
||||
ivl_process_scope
|
||||
ivl_process_stmt
|
||||
ivl_process_type
|
||||
|
||||
ivl_scope_attr_cnt
|
||||
ivl_scope_attr_val
|
||||
ivl_scope_basename
|
||||
ivl_scope_children
|
||||
ivl_scope_class
|
||||
ivl_scope_classes
|
||||
ivl_scope_def
|
||||
ivl_scope_def_file
|
||||
ivl_scope_def_lineno
|
||||
|
|
@ -194,6 +209,10 @@ ivl_scope_logs
|
|||
ivl_scope_log
|
||||
ivl_scope_lpms
|
||||
ivl_scope_lpm
|
||||
ivl_scope_mod_module_ports
|
||||
ivl_scope_mod_module_port_name
|
||||
ivl_scope_mod_module_port_type
|
||||
ivl_scope_mod_module_port_width
|
||||
ivl_scope_mod_port
|
||||
ivl_scope_name
|
||||
ivl_scope_param
|
||||
|
|
@ -228,6 +247,7 @@ ivl_signal_local
|
|||
ivl_signal_lsb
|
||||
ivl_signal_msb
|
||||
ivl_signal_name
|
||||
ivl_signal_net_type
|
||||
ivl_signal_nex
|
||||
ivl_signal_npath
|
||||
ivl_signal_packed_dimensions
|
||||
|
|
@ -240,18 +260,6 @@ ivl_signal_signed
|
|||
ivl_signal_type
|
||||
ivl_signal_width
|
||||
|
||||
ivl_path_delay
|
||||
ivl_path_source
|
||||
|
||||
ivl_process_analog
|
||||
ivl_process_attr_cnt
|
||||
ivl_process_attr_val
|
||||
ivl_process_file
|
||||
ivl_process_lineno
|
||||
ivl_process_scope
|
||||
ivl_process_stmt
|
||||
ivl_process_type
|
||||
|
||||
ivl_statement_type
|
||||
|
||||
ivl_stmt_block_count
|
||||
|
|
@ -296,6 +304,16 @@ ivl_switch_scope
|
|||
ivl_switch_type
|
||||
ivl_switch_width
|
||||
|
||||
ivl_type_base
|
||||
ivl_type_element
|
||||
ivl_type_name
|
||||
ivl_type_packed_dimensions
|
||||
ivl_type_packed_lsb
|
||||
ivl_type_packed_msb
|
||||
ivl_type_prop_name
|
||||
ivl_type_prop_type
|
||||
ivl_type_properties
|
||||
|
||||
ivl_udp_init
|
||||
ivl_udp_file
|
||||
ivl_udp_lineno
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ivl_assert_h
|
||||
|
|
|
|||
137
ivl_target.h
137
ivl_target.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __ivl_target_H
|
||||
#define __ivl_target_H
|
||||
/*
|
||||
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2012 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
|
||||
|
|
@ -16,17 +16,24 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <inttypes.h>
|
||||
|
||||
/* Re the _CLASS define: clang++ wants this to be class to match the
|
||||
* definition, but clang (the C) compiler needs it to be a struct
|
||||
* since class is not defined in C. They are effecively both pointers
|
||||
* to an object so everything works out. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define _BEGIN_DECL extern "C" {
|
||||
#define _END_DECL }
|
||||
#define _CLASS class
|
||||
#else
|
||||
#define _BEGIN_DECL
|
||||
#define _END_DECL
|
||||
#define _CLASS struct
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
|
@ -157,21 +164,8 @@ typedef struct ivl_array_s *ivl_array_t;
|
|||
typedef struct ivl_branch_s *ivl_branch_t;
|
||||
typedef struct ivl_delaypath_s*ivl_delaypath_t;
|
||||
typedef struct ivl_design_s *ivl_design_t;
|
||||
/* clang++ wants this to be class to match the definition, but clang
|
||||
* (the C) compiler needs it to be a struct since class is not defined
|
||||
* in C. They are effecively both pointers to an object so everything
|
||||
* works out. */
|
||||
#ifdef __cplusplus
|
||||
typedef class ivl_discipline_s*ivl_discipline_t;
|
||||
#else
|
||||
typedef struct ivl_discipline_s*ivl_discipline_t;
|
||||
#endif
|
||||
/* See the comments above. */
|
||||
#ifdef __cplusplus
|
||||
typedef class netenum_t *ivl_enumtype_t;
|
||||
#else
|
||||
typedef struct netenum_t *ivl_enumtype_t;
|
||||
#endif
|
||||
typedef _CLASS ivl_discipline_s*ivl_discipline_t;
|
||||
typedef _CLASS netenum_t *ivl_enumtype_t;
|
||||
typedef struct ivl_event_s *ivl_event_t;
|
||||
typedef struct ivl_expr_s *ivl_expr_t;
|
||||
typedef struct ivl_island_s *ivl_island_t;
|
||||
|
|
@ -180,12 +174,7 @@ typedef struct ivl_lval_s *ivl_lval_t;
|
|||
typedef struct ivl_net_const_s*ivl_net_const_t;
|
||||
typedef struct ivl_net_logic_s*ivl_net_logic_t;
|
||||
typedef struct ivl_udp_s *ivl_udp_t;
|
||||
/* See the comments above. */
|
||||
#ifdef __cplusplus
|
||||
typedef class ivl_nature_s *ivl_nature_t;
|
||||
#else
|
||||
typedef struct ivl_nature_s *ivl_nature_t;
|
||||
#endif
|
||||
typedef _CLASS ivl_nature_s *ivl_nature_t;
|
||||
typedef struct ivl_net_probe_s*ivl_net_probe_t;
|
||||
typedef struct ivl_nexus_s *ivl_nexus_t;
|
||||
typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t;
|
||||
|
|
@ -193,9 +182,11 @@ typedef struct ivl_parameter_s*ivl_parameter_t;
|
|||
typedef struct ivl_process_s *ivl_process_t;
|
||||
typedef struct ivl_scope_s *ivl_scope_t;
|
||||
typedef struct ivl_signal_s *ivl_signal_t;
|
||||
typedef struct ivl_port_info_s*ivl_port_info_t;
|
||||
typedef struct ivl_switch_s *ivl_switch_t;
|
||||
typedef struct ivl_memory_s *ivl_memory_t; //XXXX __attribute__((deprecated));
|
||||
typedef struct ivl_statement_s*ivl_statement_t;
|
||||
typedef const _CLASS ivl_type_s*ivl_type_t;
|
||||
|
||||
/*
|
||||
* These are types that are defined as enumerations. These have
|
||||
|
|
@ -233,7 +224,10 @@ typedef enum ivl_expr_type_e {
|
|||
IVL_EX_ENUMTYPE = 21,
|
||||
IVL_EX_EVENT = 17,
|
||||
IVL_EX_MEMORY = 4,
|
||||
IVL_EX_NEW = 23,
|
||||
IVL_EX_NULL = 22,
|
||||
IVL_EX_NUMBER = 5,
|
||||
IVL_EX_PROPERTY = 24,
|
||||
IVL_EX_REALNUM = 16,
|
||||
IVL_EX_SCOPE = 6,
|
||||
IVL_EX_SELECT = 7,
|
||||
|
|
@ -363,7 +357,7 @@ typedef enum ivl_scope_type_e {
|
|||
|
||||
/* Signals (ivl_signal_t) that are ports into the scope that contains
|
||||
them have a port type. Otherwise, they are port IVL_SIP_NONE. */
|
||||
typedef enum ivl_signal_port_e {
|
||||
typedef enum OUT {
|
||||
IVL_SIP_NONE = 0,
|
||||
IVL_SIP_INPUT = 1,
|
||||
IVL_SIP_OUTPUT= 2,
|
||||
|
|
@ -406,6 +400,8 @@ typedef enum ivl_statement_type_e {
|
|||
IVL_ST_FORCE = 14,
|
||||
IVL_ST_FOREVER = 15,
|
||||
IVL_ST_FORK = 16,
|
||||
IVL_ST_FORK_JOIN_ANY = 28,
|
||||
IVL_ST_FORK_JOIN_NONE = 29,
|
||||
IVL_ST_FREE = 26,
|
||||
IVL_ST_RELEASE = 17,
|
||||
IVL_ST_REPEAT = 18,
|
||||
|
|
@ -432,6 +428,8 @@ typedef enum ivl_variable_type_e {
|
|||
IVL_VT_BOOL = 3,
|
||||
IVL_VT_LOGIC = 4,
|
||||
IVL_VT_STRING = 5,
|
||||
IVL_VT_DARRAY = 6, /* Array (esp. dynamic array) */
|
||||
IVL_VT_CLASS = 7, /* SystemVerilog class instances */
|
||||
IVL_VT_VECTOR = IVL_VT_LOGIC /* For compatibility */
|
||||
} ivl_variable_type_t;
|
||||
|
||||
|
|
@ -770,6 +768,11 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
|
|||
* Get the data type of the expression node. This uses the variable
|
||||
* type enum to express the type of the expression node.
|
||||
*
|
||||
* ivl_expr_net_type
|
||||
* This is used in some cases to carry more advanced type
|
||||
* descriptions. Over the long run, all type informatino will be
|
||||
* moved into the ivl_type_t type description method.
|
||||
*
|
||||
* ivl_expr_width
|
||||
* This method returns the bit width of the expression at this
|
||||
* node. It can be applied to any expression node, and returns the
|
||||
|
|
@ -802,6 +805,22 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
|
|||
*
|
||||
* - IVL_EX_BINARY
|
||||
*
|
||||
* - IVL_EX_PROPERTY
|
||||
* This expression represents the property select from a class
|
||||
* type, for example "foo.property" where "foo" is a class handle and
|
||||
* "property" is the name of one of the properties of the class. The
|
||||
* ivl_expr_signal function returns the ivl_signal_t for "foo" and the
|
||||
* data_type for the signal will be IVL_VT_CLASS.
|
||||
*
|
||||
* The ivl_signal_net_type(sig) for the "foo" signal will be a class
|
||||
* type and from there you can get access to the type information.
|
||||
*
|
||||
* Elaboration reduces the properties of a class to a vector numbered
|
||||
* from 0 to the number of properties. The ivl_expr_property_idx()
|
||||
* function gets the index of the selected property into the property
|
||||
* table. That number can be passed to ivl_type_prop_*() functions to
|
||||
* get details about the property.
|
||||
*
|
||||
* - IVL_EX_SELECT
|
||||
* This expression takes two operands, oper1 is the expression to
|
||||
* select from, and oper2 is the selection base. The ivl_expr_width
|
||||
|
|
@ -810,6 +829,14 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
|
|||
* conversion from signal units to vector units, so the result of
|
||||
* ivl_expr_oper1 should range from 0 to ivl_expr_width().
|
||||
*
|
||||
* This exprsesion is also used to implement string substrings. If the
|
||||
* sub-expression (oper1) is IVL_VT_STRING, then the base expression
|
||||
* (oper2) is a charaster address, with 0 the first address of the
|
||||
* string, 1 the second, and so on. This is OPPOSITE how a part select
|
||||
* of a string cast to a vector works, to be aware. The size of the
|
||||
* expression is an even multiple of 8, and is 8 times the number of
|
||||
* characters to pick.
|
||||
*
|
||||
* - IVL_EX_SIGNAL
|
||||
* This expression references a signal vector. The ivl_expr_signal
|
||||
* function gets a handle for the signal that is referenced. The
|
||||
|
|
@ -839,6 +866,7 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
|
|||
*/
|
||||
|
||||
extern ivl_expr_type_t ivl_expr_type(ivl_expr_t net);
|
||||
extern ivl_type_t ivl_expr_net_type(ivl_expr_t net);
|
||||
extern ivl_variable_type_t ivl_expr_value(ivl_expr_t net);
|
||||
extern const char*ivl_expr_file(ivl_expr_t net);
|
||||
extern unsigned ivl_expr_lineno(ivl_expr_t net);
|
||||
|
|
@ -855,7 +883,7 @@ extern uint64_t ivl_expr_delay_val(ivl_expr_t net);
|
|||
extern double ivl_expr_dvalue(ivl_expr_t net);
|
||||
/* IVL_EX_ENUMTYPE */
|
||||
extern ivl_enumtype_t ivl_expr_enumtype(ivl_expr_t net);
|
||||
/* IVL_EX_SIGNAL, IVL_EX_SFUNC, IVL_EX_VARIABLE */
|
||||
/* IVL_EX_PROPERTY IVL_EX_SIGNAL IVL_EX_SFUNC IVL_EX_VARIABLE */
|
||||
extern const char* ivl_expr_name(ivl_expr_t net);
|
||||
/* IVL_EX_BACCESS */
|
||||
extern ivl_nature_t ivl_expr_nature(ivl_expr_t net);
|
||||
|
|
@ -879,9 +907,11 @@ extern unsigned ivl_expr_repeat(ivl_expr_t net);
|
|||
extern ivl_select_type_t ivl_expr_sel_type(ivl_expr_t net);
|
||||
/* IVL_EX_EVENT */
|
||||
extern ivl_event_t ivl_expr_event(ivl_expr_t net);
|
||||
/* IVL_EX_PROPERTY */
|
||||
extern int ivl_expr_property_idx(ivl_expr_t net);
|
||||
/* IVL_EX_SCOPE */
|
||||
extern ivl_scope_t ivl_expr_scope(ivl_expr_t net);
|
||||
/* IVL_EX_SIGNAL */
|
||||
/* IVL_EX_PROPERTY IVL_EX_SIGNAL */
|
||||
extern ivl_signal_t ivl_expr_signal(ivl_expr_t net);
|
||||
/* any expression */
|
||||
extern int ivl_expr_signed(ivl_expr_t net);
|
||||
|
|
@ -1419,6 +1449,11 @@ extern const char*ivl_lpm_string(ivl_lpm_t net);
|
|||
* ivl_expr_t that represents the index expression. Otherwise, it
|
||||
* returns 0.
|
||||
*
|
||||
* ivl_lval_property_idx
|
||||
* If the l-value is a class object, this is the name of a property
|
||||
* to select from the object. If this property is not present (<0)
|
||||
* then the l-value represents the class object itself.
|
||||
*
|
||||
* SEMANTIC NOTES
|
||||
* The ivl_lval_width is not necessarily the same as the width of the
|
||||
* signal or memory word it represents. It is the width of the vector
|
||||
|
|
@ -1444,6 +1479,7 @@ extern ivl_expr_t ivl_lval_mux(ivl_lval_t net); /* XXXX Obsolete? */
|
|||
extern ivl_expr_t ivl_lval_idx(ivl_lval_t net);
|
||||
extern ivl_expr_t ivl_lval_part_off(ivl_lval_t net);
|
||||
extern ivl_select_type_t ivl_lval_sel_type(ivl_lval_t net);
|
||||
extern int ivl_lval_property_idx(ivl_lval_t net);
|
||||
extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
|
||||
|
||||
|
||||
|
|
@ -1566,6 +1602,10 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
|||
* Return the value of the parameter. This should be a simple
|
||||
* constant expression, an IVL_EX_STRING or IVL_EX_NUMBER.
|
||||
*
|
||||
* ivl_parameter_local
|
||||
* Return whether parameter was local (localparam, implicit genvar etc)
|
||||
* or not.
|
||||
*
|
||||
* ivl_parameter_file
|
||||
* ivl_parameter_lineno
|
||||
* Returns the file and line where this parameter is defined
|
||||
|
|
@ -1573,7 +1613,7 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
|||
extern const char* ivl_parameter_basename(ivl_parameter_t net);
|
||||
extern ivl_scope_t ivl_parameter_scope(ivl_parameter_t net);
|
||||
extern ivl_expr_t ivl_parameter_expr(ivl_parameter_t net);
|
||||
|
||||
extern int ivl_parameter_local(ivl_parameter_t net);
|
||||
extern const char* ivl_parameter_file(ivl_parameter_t net);
|
||||
extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
|
||||
|
||||
|
|
@ -1719,6 +1759,8 @@ extern ivl_statement_t ivl_scope_def(ivl_scope_t net);
|
|||
extern const char* ivl_scope_def_file(ivl_scope_t net);
|
||||
extern unsigned ivl_scope_def_lineno(ivl_scope_t net);
|
||||
|
||||
extern unsigned ivl_scope_classes(ivl_scope_t net);
|
||||
extern ivl_type_t ivl_scope_class(ivl_scope_t net, unsigned idx);
|
||||
extern unsigned ivl_scope_enumerates(ivl_scope_t net);
|
||||
extern ivl_enumtype_t ivl_scope_enumerate(ivl_scope_t net, unsigned idx);
|
||||
extern unsigned ivl_scope_events(ivl_scope_t net);
|
||||
|
|
@ -1736,6 +1778,12 @@ extern const char* ivl_scope_basename(ivl_scope_t net);
|
|||
extern unsigned ivl_scope_params(ivl_scope_t net);
|
||||
extern ivl_parameter_t ivl_scope_param(ivl_scope_t net, unsigned idx);
|
||||
extern ivl_scope_t ivl_scope_parent(ivl_scope_t net);
|
||||
|
||||
extern unsigned ivl_scope_mod_module_ports(ivl_scope_t net);
|
||||
extern const char *ivl_scope_mod_module_port_name(ivl_scope_t net, unsigned idx );
|
||||
extern ivl_signal_port_t ivl_scope_mod_module_port_type(ivl_scope_t net, unsigned idx );
|
||||
extern unsigned ivl_scope_mod_module_port_width(ivl_scope_t net, unsigned idx );
|
||||
|
||||
extern unsigned ivl_scope_ports(ivl_scope_t net);
|
||||
extern ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx);
|
||||
extern ivl_nexus_t ivl_scope_mod_port(ivl_scope_t net, unsigned idx);
|
||||
|
|
@ -1876,6 +1924,7 @@ extern int ivl_signal_msb(ivl_signal_t net) __attribute__((deprecated));
|
|||
extern int ivl_signal_lsb(ivl_signal_t net) __attribute__((deprecated));
|
||||
extern unsigned ivl_signal_width(ivl_signal_t net);
|
||||
extern ivl_signal_port_t ivl_signal_port(ivl_signal_t net);
|
||||
extern int ivl_signal_module_port_index(ivl_signal_t net);
|
||||
extern int ivl_signal_signed(ivl_signal_t net);
|
||||
extern int ivl_signal_integer(ivl_signal_t net);
|
||||
extern int ivl_signal_local(ivl_signal_t net);
|
||||
|
|
@ -1884,6 +1933,7 @@ extern unsigned ivl_signal_npath(ivl_signal_t net);
|
|||
extern ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx);
|
||||
extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net);
|
||||
extern ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net);
|
||||
extern ivl_type_t ivl_signal_net_type(ivl_signal_t net);
|
||||
extern const char* ivl_signal_name(ivl_signal_t net);
|
||||
extern const char* ivl_signal_basename(ivl_signal_t net);
|
||||
extern const char* ivl_signal_attr(ivl_signal_t net, const char*key);
|
||||
|
|
@ -1971,7 +2021,7 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
|
|||
* Statements that have event arguments (TRIGGER and WAIT) make
|
||||
* those event objects available through these methods.
|
||||
*
|
||||
* ivl_stmt_lval
|
||||
* ivl_stmt_lval
|
||||
* ivl_stmt_lvals
|
||||
* Return the number of l-values for an assignment statement, or
|
||||
* the specific l-value. If there is more than 1 l-value, then the
|
||||
|
|
@ -2069,11 +2119,11 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
|
|||
* triggers. The statement waits even if the sub-statement is nul.
|
||||
*/
|
||||
|
||||
/* IVL_ST_BLOCK, IVL_ST_FORK */
|
||||
/* IVL_ST_BLOCK, IVL_ST_FORK, IVL_ST_FORK_JOIN_ANY, IVL_ST_FORK_JOIN_NONE */
|
||||
extern unsigned ivl_stmt_block_count(ivl_statement_t net);
|
||||
/* IVL_ST_BLOCK, IVL_ST_FORK */
|
||||
/* IVL_ST_BLOCK, IVL_ST_FORK, IVL_ST_FORK_JOIN_ANY, IVL_ST_FORK_JOIN_NONE */
|
||||
extern ivl_scope_t ivl_stmt_block_scope(ivl_statement_t net);
|
||||
/* IVL_ST_BLOCK, IVL_ST_FORK */
|
||||
/* IVL_ST_BLOCK, IVL_ST_FORK, IVL_ST_FORK_JOIN_ANY, IVL_ST_FORK_JOIN_NONE */
|
||||
extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i);
|
||||
/* IVL_ST_UTASK IVL_ST_DISABLE */
|
||||
extern ivl_scope_t ivl_stmt_call(ivl_statement_t net);
|
||||
|
|
@ -2172,6 +2222,31 @@ extern ivl_attribute_t ivl_switch_attr_val(ivl_switch_t net, unsigned idx);
|
|||
extern const char* ivl_switch_file(ivl_switch_t net);
|
||||
extern unsigned ivl_switch_lineno(ivl_switch_t net);
|
||||
|
||||
/* TYPES
|
||||
*
|
||||
* ivl_type_base
|
||||
* This returns the base type for the type. See the
|
||||
* ivl_variable_type_t definition for the various base types.
|
||||
*
|
||||
* ivl_type_element
|
||||
* Return the type of the element of an array. This is only valid
|
||||
* for array types.
|
||||
*
|
||||
* SEMANTIC NOTES
|
||||
*
|
||||
* Class types have names and properties.
|
||||
*/
|
||||
extern ivl_variable_type_t ivl_type_base(ivl_type_t net);
|
||||
extern ivl_type_t ivl_type_element(ivl_type_t net);
|
||||
extern unsigned ivl_type_packed_dimensions(ivl_type_t net);
|
||||
extern int ivl_type_packed_lsb(ivl_type_t net, unsigned dim);
|
||||
extern int ivl_type_packed_msb(ivl_type_t net, unsigned dim);
|
||||
extern const char* ivl_type_name(ivl_type_t net);
|
||||
extern int ivl_type_properties(ivl_type_t net);
|
||||
extern const char* ivl_type_prop_name(ivl_type_t net, int idx);
|
||||
extern ivl_type_t ivl_type_prop_type(ivl_type_t net, int idx);
|
||||
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
# define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "ivl_target.h"
|
||||
|
|
|
|||
|
|
@ -14,9 +14,8 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Library 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
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <stdio.h>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue