Compare commits

..
1 Commits
725 changed files with 47588 additions and 132487 deletions
+27
View File
@@ -0,0 +1,27 @@
lexor_keyword.cc
parse.h
parse.cc
parse.cc.output
parse.output
syn-rules.cc
syn-rules.cc.output
syn-rules.output
lexor.cc
iverilog-vpi
iverilog-vpi.pdf
iverilog-vpi.ps
ivl
ivl.exp
dep
configure
Makefile
check
check.cc
check.vvp
config.status
config.log
config.cache
autom4te.cache
config.h
_pli_types.h
dosify
-2
View File
@@ -1,2 +0,0 @@
# gperf in MSYS chokes on DOS line endings
*.gperf text eol=lf
-116
View File
@@ -1,116 +0,0 @@
# Lines that start with '#' are comments.
#
# This file is for the development branch of Icarus Verilog.
#
# The following files will be ignored by git.
# Normal editor rules
*.swp
*~
# Top level generic files
tags
TAGS
cscope.*
*.patch
*.orig
# Object files and libraries
*.[oa]
gmon*.out
gmon*.txt
# From autoconf
configure
config.log
config.status
Makefile
/_pli_types.h
config.h
/tgt-pcb/pcb_config.h
/tgt-pcb/fp.cc
/tgt-pcb/fp.h
/tgt-pcb/fp.output
/tgt-pcb/fp_lex.cc
/tgt-vvp/vvp_config.h
/tgt-vhdl/vhdl_config.h
/vpi/vpi_config.h
stamp-*-h
/version.h
/version_tag.h
# Directories
autom4te.cache
dep
# Compiler back end and library files
/tgt-vvp/*.conf
*.tgt
*.vpi
/cadpli/cadpli.vpl
/tgt-blif/Makefile
# lex, yacc and gperf output
/driver/cflexor.c
/driver/cfparse.c
/driver/cfparse.h
/driver/cfparse.output
/ivlpp/lexor.c
/vhdlpp/lexor.cc
/vhdlpp/lexor_keyword.cc
/vhdlpp/parse.cc
/vhdlpp/parse.h
/vhdlpp/parse.output
/vhdlpp/vhdlpp_config.h
/vhdlpp/vhdlpp
/lexor.cc
/lexor_keyword.cc
/parse.cc
/parse.h
/parse.output
/syn-rules.cc
/syn-rules.output
/vpi/sdf_lexor.c
/vpi/sdf_parse.c
/vpi/sdf_parse.h
/vpi/sdf_parse.output
/vpi/sys_readmem_lex.c
/vpi/table_mod_lexor.c
/vpi/table_mod_parse.c
/vpi/table_mod_parse.h
/vpi/table_mod_parse.output
/vvp/dump.*
/vvp/lexor.cc
/vvp/parse.cc
/vvp/parse.h
/vvp/parse.output
# Program created files
/vvp/tables.cc
/iverilog-vpi.man
/driver-vpi/res.rc
/driver/iverilog.man
/vvp/vvp.man
# The executables.
*.exe
/driver/iverilog
/iverilog-vpi
/ivl
/ivlpp/ivlpp
/vvp/vvp
/ivl.exp
/vvp/vvp.exp
# Check output
/check.vvp
+1 -1
View File
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
+5 -5
View File
@@ -1,7 +1,7 @@
#ifndef IVL_AStatement_H
#define IVL_AStatement_H
#ifndef __AStatement_H
#define __AStatement_H
/*
* Copyright (c) 2008-2014 Stephen Williams ([email protected])
* Copyright (c) 2008 Stephen Williams ([email protected])
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include <map>
@@ -82,4 +82,4 @@ class AProcess : public LineInfo {
AProcess& operator= (const AProcess&);
};
#endif /* IVL_AStatement_H */
#endif
+40 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2010 Stephen Williams ([email protected])
* Copyright (c) 2000 Stephen Williams ([email protected])
*
* 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,13 +14,16 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.cc,v 1.6 2004/02/20 18:53:33 steve Exp $"
#endif
# include "config.h"
# include "Attrib.h"
# include <cassert>
# include <assert.h>
Attrib::Attrib()
{
@@ -99,3 +102,37 @@ const verinum& Attrib::attr_value(unsigned idx) const
assert(idx < nlist_);
return list_[idx].val;
}
/*
* $Log: Attrib.cc,v $
* Revision 1.6 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.3 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
*/
+36 -6
View File
@@ -1,7 +1,7 @@
#ifndef IVL_Attrib_H
#define IVL_Attrib_H
#ifndef __Attrib_H
#define __Attrib_H
/*
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
* Copyright (c) 2000 Stephen Williams ([email protected])
*
* 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,8 +16,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.h,v 1.5 2004/02/20 18:53:33 steve Exp $"
#endif
# include "StringHeap.h"
# include "verinum.h"
@@ -30,7 +33,7 @@ class Attrib {
public:
Attrib();
virtual ~Attrib();
~Attrib();
const verinum&attribute(perm_string key) const;
void attribute(perm_string key, const verinum&value);
@@ -57,4 +60,31 @@ class Attrib {
Attrib& operator= (const Attrib&);
};
#endif /* IVL_Attrib_H */
/*
* $Log: Attrib.h,v $
* Revision 1.5 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.2 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
*/
#endif
+3 -3
View File
@@ -54,7 +54,7 @@ So, if your program doesn't compile, tell me so, tell me where the
error occurs, and include a complete Perfectly Valid Test Program(tm).
You tell me that it fails to compile for you, and I find that it
compiles for me, then hooray I fixed it. It can happen, you
know. What's on my disk is more recent than the latest snapshot.
know. What's on my disk is more recent then the latest snapshot.
If your program does compile, but generates incorrect output, I need
to know what it says and what you think it should say. From this I can
@@ -82,9 +82,9 @@ clarification.
If the output is strictly correct, but just not good enough for
practical use, I would like to know. These sorts of problems are
likely to be more subjective than a core dump, but are worthy of
likely to be more subjective then a core dump, but are worthy of
consideration. However, realize that outright errors will get more
attention than missed optimizations.
attention then missed optimizations.
THE MAKING OF A GOOD TEST PROGRAM
+21 -21
View File
@@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
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.
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
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@@ -335,5 +335,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
-502
View File
@@ -1,502 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
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.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
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.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
+83 -52
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* 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,40 +14,44 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.cc,v 1.8 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
# include "HName.h"
# include <iostream>
# include <cstring>
# include <cstdlib>
# include <climits>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
using namespace std;
hname_t::hname_t()
{
number_ = INT_MIN;
}
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_(1)
{
number_[0] = num;
}
hname_t::hname_t(perm_string text, vector<int>&nums)
: name_(text), number_(nums)
{
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)
@@ -57,55 +61,51 @@ hname_t& hname_t::operator = (const hname_t&that)
return *this;
}
bool hname_t::operator < (const hname_t&r) const
hname_t::~hname_t()
{
int cmp = strcmp(name_, r.name_);
}
perm_string hname_t::peek_name(void) const
{
return name_;
}
bool hname_t::has_number() const
{
return number_ != INT_MIN;
}
int hname_t::peek_number() const
{
return number_;
}
bool operator < (const hname_t&l, const hname_t&r)
{
int cmp = strcmp(l.peek_name(), r.peek_name());
if (cmp < 0) return true;
if (cmp > 0) return false;
// The text parts are equal, so compare then number
// parts. Finish as soon as we find one to be less or more
// than the other.
size_t idx = 0;
while (number_.size() > idx || r.number_.size() > idx) {
// Ran out of l numbers, so less.
if (number_.size() <= idx)
return true;
// Ran out of r numbers, so greater.
if (r.number_.size() <= idx)
return false;
if (number_[idx] < r.number_[idx])
return true;
if (number_[idx] > r.number_[idx])
return false;
idx += 1;
}
// Fall-through means that we are equal, including all the
// number parts, so not less.
return false;
if (l.has_number() && r.has_number())
return l.peek_number() < r.peek_number();
else
return false;
}
bool hname_t::operator == (const hname_t&r) const
bool operator == (const hname_t&l, const hname_t&r)
{
if (name_ == r.name_) {
if (number_.size() != r.number_.size())
return false;
for (size_t idx = 0 ; idx < number_.size() ; idx += 1)
if (number_[idx] != r.number_[idx]) return false;
return true;
if (l.peek_name() == r.peek_name()) {
if (l.has_number() && r.has_number())
return l.peek_number() == r.peek_number();
else
return true;
}
return false;
}
bool operator != (const hname_t&l, const hname_t&r)
{ return ! (l==r); }
ostream& operator<< (ostream&out, const hname_t&that)
{
if (that.peek_name() == 0) {
@@ -114,8 +114,39 @@ ostream& operator<< (ostream&out, const hname_t&that)
}
out << that.peek_name();
for (size_t idx = 0 ; idx < that.number_.size() ; idx += 1)
out << "[" << that.number_[idx] << "]";
if (that.has_number())
out << "[" << that.peek_number() << "]";
return out;
}
/*
* $Log: HName.cc,v $
* Revision 1.8 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.7 2007/05/16 19:12:33 steve
* Fix hname_t use of space for 1 perm_string.
*
* Revision 1.6 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.5 2002/11/02 03:27:52 steve
* Allow named events to be referenced by
* hierarchical names.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/01/05 04:36:06 steve
* include malloc.h only when available.
*
* Revision 1.2 2001/12/18 04:52:45 steve
* Include config.h for namespace declaration.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/
+18 -42
View File
@@ -1,7 +1,7 @@
#ifndef IVL_HName_H
#define IVL_HName_H
#ifndef __HName_H
#define __HName_H
/*
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
* Copyright (c) 2001-2008 Stephen Williams ([email protected])
*
* 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,15 +16,17 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include <iostream>
# include <list>
# include <vector>
# include "StringHeap.h"
# include <cassert>
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
#endif
#endif
/*
* This class represents a component of a Verilog hierarchical name. A
@@ -36,72 +38,46 @@
class hname_t {
friend ostream& operator<< (ostream&out, const hname_t&that);
public:
hname_t ();
explicit hname_t (perm_string text);
explicit hname_t (perm_string text, int num);
explicit hname_t (perm_string text, std::vector<int>&nums);
hname_t (const hname_t&that);
~hname_t();
hname_t& operator= (const hname_t&);
bool operator == (const hname_t&that) const;
bool operator < (const hname_t&that) const;
// Return the string part of the hname_t.
perm_string peek_name(void) const;
size_t has_numbers() const;
int peek_number(size_t idx) const;
bool has_number() const;
int peek_number() const;
private:
perm_string name_;
// If the number is anything other than INT_MIN, then this is
// the numeric part of the name. Otherwise, it is not part of
// the name at all.
std::vector<int> number_;
int number_;
private: // not implemented
};
inline hname_t::~hname_t()
{
}
inline perm_string hname_t::peek_name(void) const
{
return name_;
}
inline int hname_t::peek_number(size_t idx) const
{
assert(number_.size() > idx);
return number_[idx];
}
inline size_t hname_t::has_numbers() const
{
return number_.size();
}
extern bool operator < (const hname_t&, const hname_t&);
extern bool operator == (const hname_t&, const hname_t&);
extern bool operator != (const hname_t&, const hname_t&);
extern ostream& operator<< (ostream&, const hname_t&);
inline bool operator != (const hname_t&l, const hname_t&r)
{ return ! (l == r); }
inline ostream& operator<< (ostream&out, const list<hname_t>&ll)
{
list<hname_t>::const_iterator cur = ll.begin();
out << *cur;
++ cur;
cur ++;
while (cur != ll.end()) {
out << "." << *cur;
++ cur;
cur ++;
}
return out;
}
#endif /* IVL_HName_H */
#endif
+3 -8
View File
@@ -14,24 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "LineInfo.h"
# include <sstream>
using namespace std;
LineInfo::LineInfo()
: lineno_(0)
{
}
LineInfo::LineInfo(const LineInfo&that) :
file_(that.file_), lineno_(that.lineno_)
{
}
LineInfo::~LineInfo()
{
}
+7 -8
View File
@@ -1,7 +1,7 @@
#ifndef IVL_LineInfo_H
#define IVL_LineInfo_H
#ifndef __LineInfo_H
#define __LineInfo_H
/*
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "StringHeap.h"
@@ -36,12 +36,11 @@ using namespace std;
class LineInfo {
public:
LineInfo();
LineInfo(const LineInfo&that);
virtual ~LineInfo();
~LineInfo();
// Get a fully formatted file/lineno
string get_fileline() const;
// Set the file/line from another LineInfo object.
// Set the file/line fro another LineInfo object.
void set_line(const LineInfo&that);
// Access parts of LineInfo data
@@ -55,4 +54,4 @@ class LineInfo {
unsigned lineno_;
};
#endif /* IVL_LineInfo_H */
#endif
+163 -223
View File
@@ -12,67 +12,53 @@
#
# 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., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
SHELL = /bin/sh
# The interesting make targets are:
# Normally, the "make" will build all the files only by dependencies.
# The MODE, however, can control your rebuild intentions. The proper way
# to use the MODE is on the make command like, this this:
#
# make version
# Force the version_tag.h file to be rebuilt. Otherwise, it will only
# be built if it is missing.
# make MODE=XXXX all
#
# make all
# make install
# The possible MODE= values are:
#
# The "suffix" is used as an installation suffix. It modifies certain
# key install paths/files such that a build and install of Icarus Verilog
# with the same $(prefix) but a different $(suffix) will not interfere.
# The normal configuration leaves suffix empty
suffix = @install_suffix@
# regular
# Build as normal
#
# full
# Do some extra builds. in particular:
# Build version.h again, even if it already exists.
#
MODE=regular
# This version string is only used in the version message printed
# by the compiler. It reflects the assigned version number for the
# product as a whole. Most components also print the CVS Name: token
# in order to get a more automatic version stamp as well.
VERSION = 0.9.devel
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
datarootdir = @datarootdir@
SUBDIRS = ivlpp vhdlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver
# Only run distclean for these directories.
NOTUSED = tgt-fpga tgt-pal tgt-verilog
SUBDIRS = @subdirs@
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
else
NOTUSED += driver-vpi
endif
# To get the version headers to build correctly we only want to look
# for C++ files in the source directory. All other files will require
# an explicit $(srcdir). The one exception to this is if we need to
# rebuild the lexor_keyword.cc file. If we do, then we want to use the
# local version instead of the one is $(srcdir).
vpath lexor_keyword.cc .
vpath %.cc $(srcdir)/libmisc
vpath %.cc $(srcdir)
VPATH = $(srcdir)
bindir = @bindir@
libdir = @libdir@
# This is actually the directory where we install our own header files.
# It is a little different from the generic includedir.
includedir = @includedir@/iverilog$(suffix)
includedir = @includedir@
mandir = @mandir@
dllib=@DLLIB@
# For a cross compile these defines will need to be set accordingly.
HOSTCC = @CC@
HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
CC = @CC@
CXX = @CXX@
DLLTOOL = @DLLTOOL@
INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -83,130 +69,75 @@ MAN = @MAN@
PS2PDF = @PS2PDF@
GIT = @GIT@
ifeq (@srcdir@,.)
INCLUDE_PATH = -I. -Ilibmisc
else
INCLUDE_PATH = -I. -I$(srcdir) -I$(srcdir)/libmisc
endif
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@
CXXFLAGS = -Wall @CXXFLAGS@
PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@
CTARGETFLAGS = @CTARGETFLAGS@
# Source files in the libmisc directory
M = LineInfo.o StringHeap.o
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
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 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 nettypes.o net_analog.o net_assign.o \
net_design.o netclass.o netdarray.o \
netenum.o netparray.o netqueue.o netscalar.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_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 PModport.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
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
all: dep version.h ivl@EXEEXT@
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) VERSION=$(VERSION) $@); done
for dir in ivlpp ; \
do (cd $$dir ; $(MAKE) VERSION=$(VERSION) $@); done
cd driver ; $(MAKE) VERSION=$(VERSION) $@
# In the windows world, the installer will need a dosify program to
# dosify text files.
ifeq (@MINGW32@,yes)
all: dosify.exe
dosify.exe: $(srcdir)/dosify.c
$(HOSTCC) $(HOSTCFLAGS) -o dosify.exe $(srcdir)/dosify.c
all: dep dosify.exe
dosify.exe: dosify.c
$(CC) -o dosify.exe dosify.c
endif
# This rule rules the compiler in the trivial hello.vl program to make
# sure the basics were compiled properly.
check: all
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
test -r check.conf || cp $(srcdir)/check.conf .
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
ifeq (@WIN32@,yes)
ifeq (@install_suffix@,)
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
else
# On Windows if we have a suffix we must run the vvp part of
# the test with a suffix since it was built/linked that way.
ln vvp/vvp.exe vvp/vvp$(suffix).exe
vvp/vvp$(suffix) -M- -M./vpi ./check.vvp | grep 'Hello, World'
rm vvp/vvp$(suffix).exe
endif
else
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
endif
clean:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
rm -f *.o parse.cc parse.h lexor.cc
rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps
rm -f parse.output syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
do (cd $$dir ; $(MAKE) $@); done
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
rm -f ivl.exp iverilog-vpi.pdf iverilog-vpi.ps parse.output
rm -f syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc*
rm -rf dep
rm -f version.exe
distclean: clean
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) $@ && ) true
rm -f Makefile config.status config.log config.cache
rm -f stamp-config-h config.h
rm -f stamp-_pli_types-h _pli_types.h
ifneq (@srcdir@,.)
rm -f version_tag.h check.conf
rmdir $(SUBDIRS) $(NOTUSED)
endif
rm -rf autom4te.cache
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
do (cd $$dir ; $(MAKE) $@); done
rm -f Makefile config.status config.log config.cache config.h
rm -f _pli_types.h
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
cppcheck-all:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) cppcheck && ) true
$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) cppcheck && ) true
$(MAKE) cppcheck
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_pexpr.o elab_scope.o \
elab_sig.o elab_sig_analog.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 net_event.o net_expr.o net_func.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_types.o \
set_width.o symbol_search.o sync.o sys_funcs.o \
verinum.o verireal.o target.o \
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
PExpr.o PGate.o PGenerate.o PScope.o PSpec.o \
PTask.o PUdp.o PFunction.o PWire.o Statement.o AStatement.o StringHeap.o \
$(FF) $(TT)
Makefile: $(srcdir)/Makefile.in config.status
./config.status --file=$@
dep:
mkdir dep
stamp-config-h: $(srcdir)/config.h.in config.status
@rm -f $@
./config.status config.h
config.h: stamp-config-h
stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
@rm -f $@
./config.status _pli_types.h
_pli_types.h: stamp-_pli_types-h
$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
cd $(srcdir) && autoconf
config.status: $(srcdir)/configure
./config.status --recheck
Makefile: Makefile.in config.h.in config.status
./config.status
ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps.
# The first step makes an ivl.exe that dlltool can use to make an
@@ -214,7 +145,7 @@ ifeq (@WIN32@,yes)
# that really exports the things that the import library imports.
ivl@EXEEXT@: $O $(srcdir)/ivl.def
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
$(DLLTOOL) --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
dlltool --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
--output-lib libivl.a --output-exp ivl.exp
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
else
@@ -222,170 +153,179 @@ ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
ifeq (@MINGW32@,no)
all: iverilog-vpi
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
else
all: dep iverilog-vpi
iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
iverilog-vpi: iverilog-vpi.sh
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@SUFFIX@;$(suffix);' \
-e 's;@IVCC@;$(CC);' \
-e 's;@IVCXX@;$(CXX);' \
-e 's;@IVCFLAGS@;$(CFLAGS);' \
-e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \
-e 's;@IVCTARGETFLAGS@;$(CTARGETFLAGS);' \
-e 's;@INCLUDEDIR@;$(includedir);' \
-e 's;@IVCFLAGS@;$(CXXFLAGS);' \
-e 's;@INCLUDEDIR@;@includedir@;' \
-e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
$(HOSTCC) $(HOSTCFLAGS) -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
dep:
mkdir dep
%.o: %.cc config.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
%.o: %.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
mv $*.d dep/$*.d
# Here are some explicit dependencies needed to get things going.
main.o: main.cc version_tag.h
lexor.o: lexor.cc parse.h
parse.o: parse.cc
# Build this in two steps to avoid parallel build issues (see pr3462585)
parse.cc: $(srcdir)/parse.y
$(YACC) --verbose -t -p VL -d -o $@ $<
parse.h: parse.cc
mv parse.cc.h $@ 2>/dev/null || mv parse.hh $@
parse.cc parse.h: $(srcdir)/parse.y
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
syn-rules.cc: $(srcdir)/syn-rules.y
$(YACC) --verbose -t -p syn_ -o $@ $<
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
lexor.cc: $(srcdir)/lexor.lex
$(LEX) -s -t $< > $@
$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
gperf -o -i 7 -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
lexor_keyword.cc: lexor_keyword.gperf
gperf -o -i 7 -C -k 1-4,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@
tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@
iverilog-vpi.ps: iverilog-vpi.man
$(MAN) -t ./iverilog-vpi.man > iverilog-vpi.ps
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
$(MAN) -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
iverilog-vpi.pdf: iverilog-vpi.ps
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
# version_tag.h file in the source tree (included in snapshots and releases),
# and finally use nothing.
# version.h file in the source tree (included in snapshots and releases), and
# finally use nothing.
ifeq ($(MODE),full)
.PHONY: version.h
endif
# "true" and "false" in the next few lines are Unix shell command names
ifeq ($(GIT),none)
GIT_PRESENT = false
else
GIT_PRESENT = true
endif
version_tag.h version:
version.h:
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
echo "Using git-describe for VERSION_TAG"; \
tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \
tmp=`$(GIT) --git-dir $(srcdir)/.git describe \
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
elif test -r $(srcdir)/version_tag.h; then \
echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \
diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \
echo "$$tmp" | diff - $@ > /dev/null 2>&1 || echo "$$tmp" > $@ || exit 1; \
elif test -r $(srcdir)/$@; then \
echo "Using $(srcdir)/$@ for VERSION_TAG"; \
diff $(srcdir)/$@ $@ > /dev/null 2>&1 || cp $(srcdir)/$@ $@; \
else \
echo "Using empty VERSION_TAG"; \
echo '#define VERSION_TAG ""' > version_tag.h; \
echo '#define VERSION_TAG ""' > $@; \
fi
ifeq (@MINGW32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
else
INSTALL_DOC = $(prefix)/iverilog-vpi$(suffix).pdf $(mandir)/man1/iverilog-vpi$(suffix).1
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf $(mandir)/man1/iverilog-vpi.1
all: dep iverilog-vpi.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOCDIR = $(mandir)/man1
endif
ifeq (@MINGW32@,yes)
WIN32_INSTALL =
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
else
WIN32_INSTALL = $(bindir)/iverilog-vpi$(suffix)
WIN32_INSTALL = $(bindir)/iverilog-vpi
endif
install: all installdirs $(libdir)/ivl$(suffix)/ivl@EXEEXT@ $(libdir)/ivl$(suffix)/include/constants.vams $(libdir)/ivl$(suffix)/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/sv_vpi_user.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/include/constants.vams $(libdir)/ivl/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
$(bindir)/iverilog-vpi: ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi $(DESTDIR)$(bindir)/iverilog-vpi
$(libdir)/ivl$(suffix)/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@"
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(DESTDIR)$(libdir)/ivl/ivl@EXEEXT@
$(libdir)/ivl$(suffix)/include/constants.vams: $(srcdir)/constants.vams
$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
$(libdir)/ivl/include/constants.vams: $(srcdir)/constants.vams
$(INSTALL_DATA) $(srcdir)/constants.vams $(DESTDIR)$(libdir)/ivl/include/constants.vams
$(libdir)/ivl$(suffix)/include/disciplines.vams: $(srcdir)/disciplines.vams
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"
$(libdir)/ivl/include/disciplines.vams: $(srcdir)/disciplines.vams
$(INSTALL_DATA) $(srcdir)/disciplines.vams $(DESTDIR)$(libdir)/ivl/include/disciplines.vams
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h"
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(DESTDIR)$(includedir)/ivl_target.h
$(includedir)/_pli_types.h: _pli_types.h
$(INSTALL_DATA) $< "$(DESTDIR)$(includedir)/_pli_types.h"
$(includedir)/sv_vpi_user.h: $(srcdir)/sv_vpi_user.h
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(includedir)/sv_vpi_user.h"
$(INSTALL_DATA) $< $(DESTDIR)$(includedir)/_pli_types.h
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h"
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(DESTDIR)$(includedir)/vpi_user.h
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h"
$(INSTALL_DATA) $(srcdir)/acc_user.h $(DESTDIR)$(includedir)/acc_user.h
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
$(INSTALL_DATA) $(srcdir)/veriuser.h $(DESTDIR)$(includedir)/veriuser.h
$(mandir)/man1/iverilog-vpi$(suffix).1: iverilog-vpi.man
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
$(mandir)/man1/iverilog-vpi.1: $(srcdir)/iverilog-vpi.man
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(DESTDIR)$(mandir)/man1/iverilog-vpi.1
$(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
$(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf $(DESTDIR)$(prefix)/iverilog-vpi.pdf
# In windows installations, put a few examples and the quick_start
# into the destination directory.
ifeq (@MINGW32@,yes)
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
mv tmp.vl $(prefix)/hello.vl
installdirs: $(srcdir)/mkinstalldirs
$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(includedir)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)/include" \
"$(DESTDIR)$(mandir)" \
"$(DESTDIR)$(mandir)/man1"
$(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
mv tmp.vl $(prefix)/sqrt.vl
$(prefix)/sqrt-virtex.v: $(srcdir)/examples/sqrt-virtex.v
./dosify.exe $(srcdir)/examples/sqrt-virtex.v tmp.vl
mv tmp.vl $(prefix)/sqrt-virtex.v
$(prefix)/QUICK_START.txt: $(srcdir)/QUICK_START.txt
./dosify.exe $(srcdir)/QUICK_START.txt tmp.txt
mv tmp.txt $(prefix)/QUICK_START.txt
endif
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(includedir) $(DESTDIR)$(libdir)/ivl \
$(DESTDIR)$(libdir)/ivl/include $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1
uninstall:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)"
for f in verilog$(suffix) iverilog-vpi$(suffix) gverilog$(suffix)@EXEEXT@; \
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)"
rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
do rm -f $(DESTDIR)$(libdir)/ivl/$$f; done
-rmdir $(DESTDIR)$(libdir)/ivl/include
-rmdir $(DESTDIR)$(libdir)/ivl
for f in verilog iverilog-vpi gverilog@EXEEXT@; \
do rm -f $(DESTDIR)$(bindir)/$$f; done
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
do rm -f $(DESTDIR)$(includedir)/$$f; done
rm -f $(DESTDIR)$(mandir)/man1/iverilog-vpi.1 $(DESTDIR)$(prefix)/iverilog-vpi.pdf
-include $(patsubst %.o, dep/%.d, $O)
-include $(patsubst %.o, dep/%.d, vpithunk.o)
+9 -33
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
@@ -22,22 +22,14 @@
# include "Module.h"
# include "PGate.h"
# include "PWire.h"
# include <cassert>
list<Module::named_expr_t> Module::user_defparms;
# include <assert.h>
/* n is a permallocated string. */
Module::Module(LexicalScope*parent, perm_string n)
: PScopeExtra(n, parent)
Module::Module(perm_string n)
: PScope(n)
{
library_flag = false;
is_cell = false;
program_block = false;
uc_drive = UCD_NONE;
timescale_warn_done = false;
time_unit = 0;
time_precision = 0;
time_from_timescale = false;
default_nettype = NetNet::NONE;
}
Module::~Module()
@@ -90,29 +82,12 @@ 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 || ports[idx]->name.str() == 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. Port references
that aren't simple or escaped identifiers are
also inaccessible to binding by name. */
return perm_string::literal("unnamed");
}
return ports[idx]->name;
}
PGate* Module::get_gate(perm_string name)
{
for (list<PGate*>::iterator cur = gates_.begin()
; cur != gates_.end() ; ++ cur ) {
; cur != gates_.end()
; cur ++ ) {
if ((*cur)->get_name() == name)
return *cur;
@@ -125,3 +100,4 @@ const list<PGate*>& Module::get_gates() const
{
return gates_;
}
+26 -49
View File
@@ -1,7 +1,7 @@
#ifndef IVL_Module_H
#define IVL_Module_H
#ifndef __Module_H
#define __Module_H
/*
* Copyright (c) 1998-2015 Stephen Williams ([email protected])
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
@@ -35,7 +35,6 @@ class PExpr;
class PEIdent;
class PGate;
class PGenerate;
class PModport;
class PSpecPath;
class PTask;
class PFunction;
@@ -48,13 +47,9 @@ class NetScope;
* A module is a named container and scope. A module holds a bunch of
* semantic quantities such as wires and gates. The module is
* therefore the handle for grasping the described circuit.
*
* SystemVerilog introduces program blocks and interfaces. These have
* much in common with modules, so the Module class is used to represent
* these containers as well.
*/
class Module : public PScopeExtra, public LineInfo {
class Module : public PScope, public LineInfo {
/* The module ports are in general a vector of port_t
objects. Each port has a name and an ordered list of
@@ -69,8 +64,8 @@ class Module : public PScopeExtra, public LineInfo {
public:
/* The name passed here is the module name, not the instance
name. This name must be a permallocated string. */
explicit Module(LexicalScope*parent, perm_string name);
name. This make must be a permallocated string. */
explicit Module(perm_string name);
~Module();
/* Initially false. This is set to true if the module has been
@@ -79,25 +74,12 @@ class Module : public PScopeExtra, public LineInfo {
other effect. */
bool library_flag;
bool is_cell;
NetNet::Type default_nettype;
/* 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;
/* This is true if the module represents a interface
instead of a module/cell. Interfaces have different
content restrictions and some extra allowed items. */
bool is_interface;
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
UCDriveType uc_drive;
/* 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;
/* specparams are simpler then other params, in that they have
no type information. They are merely constant
expressions. */
map<perm_string,PExpr*>specparams;
/* The module also has defparam assignments which don't create
new parameters within the module, but may be used to set
@@ -105,7 +87,6 @@ class Module : public PScopeExtra, public LineInfo {
instantiated modules. */
typedef pair<pform_name_t,PExpr*> named_expr_t;
list<named_expr_t>defparms;
static list<named_expr_t>user_defparms;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -124,22 +105,19 @@ class Module : public PScopeExtra, public LineInfo {
/* These are the timescale for this module. The default is
set by the `timescale directive. */
int time_unit, time_precision;
bool time_from_timescale;
bool timescale_warn_done;
/* The module has a list of generate schemes that appear in
/* Task definitions within this module */
map<perm_string,PTask*> tasks;
map<perm_string,PFunction*> funcs;
/* The module has a list of genvars that may be used in
various generate schemes. */
map<perm_string,LineInfo*> genvars;
/* the module has a list of generate schemes that appear in
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;
/* An interface can contain one or more named modport lists.
The parser will ensure these don't appear in modules or
program blocks. */
map<perm_string,PModport*> modports;
list<PSpecPath*> specify_paths;
// The mod_name() is the name of the module type.
@@ -151,9 +129,6 @@ 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;
@@ -161,18 +136,20 @@ class Module : public PScopeExtra, public LineInfo {
void dump(ostream&out) const;
bool elaborate(Design*, NetScope*scope) const;
typedef map<perm_string,PExpr*> replace_t;
typedef map<perm_string,NetExpr*> replace_t;
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep);
bool elaborate_sig(Design*, NetScope*scope) const;
private:
void dump_specparams_(ostream&out, unsigned indent) const;
list<PGate*> gates_;
static void elaborate_parm_item_(perm_string name, const param_expr_t&cur,
Design*des, NetScope*scope);
private: // Not implemented
Module(const Module&);
Module& operator= (const Module&);
};
#endif /* IVL_Module_H */
#endif
-30
View File
@@ -1,30 +0,0 @@
/*
* Copyright (c) 2012 Stephen Williams ([email protected])
*
* 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 "PClass.h"
PClass::PClass(perm_string name, LexicalScope*parent)
: PScopeExtra(name, parent), type(0)
{
}
PClass::~PClass()
{
}
-47
View File
@@ -1,47 +0,0 @@
#ifndef IVL_PClass_H
#define IVL_PClass_H
/*
* Copyright (c) 2012-2014 Stephen Williams ([email protected])
*
* 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"
# include <iostream>
class PChainConstructor;
/*
* SystemVerilog supports class declarations with their own lexical
* scope, etc. The parser arranges for these to be created and
* collected.
*/
class PClass : public PScopeExtra, public LineInfo {
public:
explicit PClass (perm_string name, LexicalScope*parent);
~PClass();
void dump(std::ostream&out, unsigned indent) const;
public:
class_type_t*type;
};
#endif /* IVL_PClass_H */
+28 -65
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2011 Stephen Williams ([email protected])
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
@@ -26,11 +26,6 @@
# include "verinum.h"
# include "netmisc.h"
bool dly_used_no_timescale = false;
bool dly_used_timescale = false;
bool display_ts_dly_warning = true;
PDelays::PDelays()
{
delete_flag_ = true;
@@ -55,54 +50,36 @@ void PDelays::set_delay(PExpr*del)
}
void PDelays::set_delays(const list<PExpr*>*del, bool df)
void PDelays::set_delays(const svector<PExpr*>*del, bool df)
{
assert(del);
assert(del->size() <= 3);
list<PExpr*>::const_iterator cur = del->begin();
for (unsigned idx = 0 ; cur != del->end() ; idx += 1, ++cur)
delay_[idx] = *cur;
assert(del->count() <= 3);
for (unsigned idx = 0 ; idx < del->count() ; idx += 1)
delay_[idx] = (*del)[idx];
delete_flag_ = df;
}
unsigned PDelays::delay_count() const
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
{
unsigned dly_cnt = 0;
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
if (delay_[idx]) dly_cnt += 1;
return dly_cnt;
}
static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
{
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
/* Print a warning if we find default and `timescale based
* delays in the design, since this is likely an error. */
if (scope->time_from_timescale()) dly_used_timescale = true;
else dly_used_no_timescale = true;
if (display_ts_dly_warning &&
dly_used_no_timescale && dly_used_timescale) {
cerr << "warning: Found both default and "
"`timescale based delays. Use" << endl;
cerr << " -Wtimescale to find the "
"module(s) with no `timescale." << endl;
display_ts_dly_warning = false;
}
NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
eval_expr(dex);
/* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time
units, and return an adjusted value. */
if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
uint64_t delay = get_scaled_time_from_real(des, scope, tmp);
verireal fn = tmp->value();
int shift = scope->time_unit() - des->get_precision();
long delay = fn.as_long(shift);
if (delay < 0)
delay = 0;
delete tmp;
NetEConst*tmp2 = new NetEConst(verinum(delay, 64));
NetEConst*tmp2 = new NetEConst(verinum(delay));
tmp2->set_line(*expr);
return tmp2;
}
@@ -110,10 +87,12 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
verinum fn = tmp->value();
uint64_t delay = des->scale_to_precision(fn.as_ulong64(), scope);
unsigned long delay =
des->scale_to_precision(fn.as_ulong(), scope);
delete tmp;
NetEConst*tmp2 = new NetEConst(verinum(delay, 64));
NetEConst*tmp2 = new NetEConst(verinum(delay));
tmp2->set_line(*expr);
return tmp2;
}
@@ -124,20 +103,16 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
{
if (expr == 0)
return 0;
if (dynamic_cast<NetESignal*> (expr))
return expr;
if (dynamic_cast<NetEConst*> (expr))
return expr;
NetNet*sig = expr->synthesize(des, scope, expr);
NetNet*sig = expr->synthesize(des, scope);
if (sig == 0) {
cerr << expr->get_fileline() << ": error: Expression " << *expr
<< " is not suitable as a delay expression." << endl;
des->errors += 1;
<< " is not suitable for delay expression." << endl;
return 0;
}
@@ -145,18 +120,6 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
return expr;
}
static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
{
NetEConst *c_rise = dynamic_cast<NetEConst*>(rise);
NetEConst *c_fall = dynamic_cast<NetEConst*>(fall);
if (c_rise && c_fall) {
if (c_rise->value() < c_fall->value()) return rise;
else return fall;
}
return 0;
}
void PDelays::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
@@ -178,14 +141,14 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
if (delay_[2]) {
decay_time = calculate_val(des, scope, delay_[2]);
if (as_nets_flag)
decay_time = make_delay_nets(des, scope,
decay_time);
if (as_nets_flag)
decay_time = make_delay_nets(des, scope, decay_time);
} else {
// If this is zero then we need to do the min()
// at run time.
decay_time = calc_decay_time(rise_time, fall_time);
if (rise_time < fall_time)
decay_time = rise_time;
else
decay_time = fall_time;
}
} else {
assert(delay_[2] == 0);
+39 -9
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PDelays_H
#define IVL_PDelays_H
#ifndef __PDelays_H
#define __PDelays_H
/*
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
* Copyright (c) 1999-2002 Stephen Williams ([email protected])
*
* 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,12 +16,14 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PDelays.h,v 1.9 2006/01/03 05:22:14 steve Exp $"
#endif
# include "svector.h"
# include <string>
# include <list>
# include <iostream>
#ifdef __GNUC__
@@ -49,9 +51,7 @@ class PDelays {
this object takes ownership of the expressions, and will
delete it in the destructor. */
void set_delay(PExpr*);
void set_delays(const list<PExpr*>*del, bool delete_flag=true);
unsigned delay_count() const;
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
void eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
@@ -72,4 +72,34 @@ class PDelays {
ostream& operator << (ostream&o, const PDelays&);
#endif /* IVL_PDelays_H */
/*
* $Log: PDelays.h,v $
* Revision 1.9 2006/01/03 05:22:14 steve
* Handle complex net node delays.
*
* Revision 1.8 2006/01/02 05:33:19 steve
* Node delays can be more general expressions in structural contexts.
*
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.5 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
* Revision 1.4 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.3 2001/01/16 02:44:17 steve
* Use the iosfwd header if available.
*
* Revision 1.2 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
*/
#endif
+27 -1
View File
@@ -14,8 +14,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.cc,v 1.5 2004/02/19 06:57:10 steve Exp $"
#endif
# include "config.h"
@@ -35,3 +38,26 @@ perm_string PEvent::name() const
return name_;
}
/*
* $Log: PEvent.cc,v $
* Revision 1.5 2004/02/19 06:57:10 steve
* Memory and Event names use perm_string.
*
* Revision 1.4 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
*/
+42 -5
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PEvent_H
#define IVL_PEvent_H
#ifndef __PEvent_H
#define __PEvent_H
/*
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
* Copyright (c) 2000-2004 Stephen Williams ([email protected])
*
* 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,8 +16,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.h,v 1.9 2004/02/19 06:57:10 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
@@ -51,4 +54,38 @@ class PEvent : public LineInfo {
PEvent& operator= (const PEvent&);
};
#endif /* IVL_PEvent_H */
/*
* $Log: PEvent.h,v $
* Revision 1.9 2004/02/19 06:57:10 steve
* Memory and Event names use perm_string.
*
* Revision 1.8 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.7 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.4 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
* Revision 1.3 2000/04/09 17:44:30 steve
* Catch event declarations during scope elaborate.
*
* Revision 1.2 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*
* Revision 1.1 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
*/
#endif
+23 -295
View File
@@ -1,6 +1,5 @@
/*
* Copyright (c) 1998-2012 Stephen Williams <[email protected]>
* Copyright CERN 2013 / Stephen Williams ([email protected])
* Copyright (c) 1998-2008 Stephen Williams <[email protected]>
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -15,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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
@@ -24,28 +23,19 @@
# include "compiler.h"
# include "PExpr.h"
# include "PWire.h"
# include "Module.h"
# include "netmisc.h"
# include "util.h"
# include <typeinfo>
PExpr::PExpr()
{
expr_type_ = IVL_VT_NO_TYPE;
expr_width_ = 0;
min_width_ = 0;
signed_flag_ = false;
expr_type_ = IVL_VT_NO_TYPE;
}
PExpr::~PExpr()
{
}
void PExpr::declare_implicit_nets(LexicalScope*, NetNet::Type)
{
}
bool PExpr::has_aa_term(Design*, NetScope*) const
{
return false;
@@ -56,65 +46,21 @@ bool PExpr::is_the_same(const PExpr*that) const
return typeid(this) == typeid(that);
}
NetNet* PExpr::elaborate_lnet(Design*, NetScope*) const
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
{
cerr << get_fileline() << ": error: "
<< "expression not valid in assign l-value: "
<< *this << endl;
cerr << get_fileline() << ": error: expression not valid in assign l-value: "
<< *this << endl;
return 0;
}
NetNet* PExpr::elaborate_bi_net(Design*, NetScope*) const
NetNet* PExpr::elaborate_bi_net(Design*des, NetScope*) const
{
cerr << get_fileline() << ": error: "
<< "expression not valid as argument to inout port: "
<< *this << endl;
<< "expression not valid as argument to inout port: "
<< *this << endl;
return 0;
}
bool PExpr::is_collapsible_net(Design*, NetScope*) const
{
return false;
}
const char* PExpr::width_mode_name(width_mode_t mode)
{
switch (mode) {
case PExpr::SIZED:
return "sized";
case PExpr::UNSIZED:
return "unsized";
case PExpr::EXPAND:
return "expand";
case PExpr::LOSSLESS:
return "lossless";
case PExpr::UPSIZE:
return "upsize";
default:
return "??";
}
}
PEAssignPattern::PEAssignPattern()
{
}
PEAssignPattern::PEAssignPattern(const list<PExpr*>&p)
: parms_(p.size())
{
size_t idx = 0;
for (list<PExpr*>::const_iterator cur = p.begin()
; cur != p.end() ; ++cur) {
parms_[idx] = *cur;
idx += 1;
}
}
PEAssignPattern::~PEAssignPattern()
{
}
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r)
{
@@ -124,42 +70,15 @@ PEBinary::~PEBinary()
{
}
void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
assert(left_ && right_);
left_->declare_implicit_nets(scope, type);
right_->declare_implicit_nets(scope, type);
}
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
{
assert(left_ && right_);
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
}
PECastSize::PECastSize(unsigned si, PExpr*b)
: size_(si), base_(b)
{
}
PECastSize::~PECastSize()
{
}
PECastType::PECastType(data_type_t*t, PExpr*b)
: target_(t), base_(b)
{
}
PECastType::~PECastType()
{
}
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
l_width_ = 0;
r_width_ = 0;
}
PEBComp::~PEBComp()
@@ -176,26 +95,8 @@ PEBLogic::~PEBLogic()
{
}
PEBLeftWidth::PEBLeftWidth(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
}
PEBLeftWidth::~PEBLeftWidth()
{
}
PEBPower::PEBPower(char op, PExpr*l, PExpr*r)
: PEBLeftWidth(op, l, r)
{
}
PEBPower::~PEBPower()
{
}
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
: PEBLeftWidth(op, l, r)
: PEBinary(op, l, r)
{
}
@@ -204,12 +105,7 @@ PEBShift::~PEBShift()
}
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
: package_(0), path_(n), parms_(parms)
{
}
PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector<PExpr *> &parms)
: package_(pkg), path_(n), parms_(parms)
: path_(n), parms_(parms)
{
}
@@ -221,58 +117,31 @@ static pform_name_t pn_from_ps(perm_string n)
return tmp;
}
PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *> &parms)
: package_(pkg), path_(pn_from_ps(n)), parms_(parms.size())
{
int tmp_idx = 0;
assert(parms_.size() == parms.size());
for (list<PExpr*>::const_iterator idx = parms.begin()
; idx != parms.end() ; ++idx)
parms_[tmp_idx++] = *idx;
}
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
: package_(0), path_(pn_from_ps(n)), parms_(parms)
: path_(pn_from_ps(n)), parms_(parms)
{
}
PECallFunction::PECallFunction(perm_string n)
: package_(0), path_(pn_from_ps(n))
: path_(pn_from_ps(n))
{
}
// NOTE: Anachronism. Try to work all use of svector out.
PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
: package_(0), path_(n), parms_(parms.size())
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(vector_from_svector(parms))
{
int tmp_idx = 0;
assert(parms_.size() == parms.size());
for (list<PExpr*>::const_iterator idx = parms.begin()
; idx != parms.end() ; ++idx)
parms_[tmp_idx++] = *idx;
}
PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms)
: package_(0), path_(pn_from_ps(n)), parms_(parms.size())
PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(vector_from_svector(parms))
{
int tmp_idx = 0;
assert(parms_.size() == parms.size());
for (list<PExpr*>::const_iterator idx = parms.begin()
; idx != parms.end() ; ++idx)
parms_[tmp_idx++] = *idx;
}
PECallFunction::~PECallFunction()
{
}
void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx]->declare_implicit_nets(scope, type);
}
}
bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
{
bool flag = false;
@@ -282,17 +151,9 @@ bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
return flag;
}
PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r)
: parms_(p.size()), width_modes_(SIZED, p.size()), repeat_(r)
PEConcat::PEConcat(const svector<PExpr*>&p, PExpr*r)
: parms_(p), repeat_(r)
{
int tmp_idx = 0;
assert(parms_.size() == p.size());
for (list<PExpr*>::const_iterator idx = p.begin()
; idx != p.end() ; ++idx)
parms_[tmp_idx++] = *idx;
tested_scope_ = 0;
repeat_count_ = 1;
}
PEConcat::~PEConcat()
@@ -300,17 +161,10 @@ PEConcat::~PEConcat()
delete repeat_;
}
void PEConcat::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx]->declare_implicit_nets(scope, type);
}
}
bool PEConcat::has_aa_term(Design*des, NetScope*scope) const
{
bool flag = false;
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
flag = parms_[idx]->has_aa_term(des, scope) || flag;
}
if (repeat_)
@@ -344,14 +198,6 @@ PExpr* PEEvent::expr() const
return expr_;
}
PENull::PENull(void)
{
}
PENull::~PENull()
{
}
PEFNumber::PEFNumber(verireal*v)
: value_(v)
{
@@ -368,69 +214,19 @@ const verireal& PEFNumber::value() const
}
PEIdent::PEIdent(const pform_name_t&that)
: package_(0), path_(that), no_implicit_sig_(false)
: path_(that)
{
}
PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
: package_(0), no_implicit_sig_(no_implicit_sig)
PEIdent::PEIdent(perm_string s)
{
path_.push_back(name_component_t(s));
}
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
: package_(pkg), path_(that), no_implicit_sig_(true)
{
}
PEIdent::~PEIdent()
{
}
void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
/* We create an implicit wire if:
- this is a simple identifier
- an identifier of that name has not already been declared in
any enclosing scope.
- this is not an implicit named port connection */
if (no_implicit_sig_)
return;
if ((path_.size() == 1) && (path_.front().index.size() == 0)) {
perm_string name = path_.front().name;
LexicalScope*ss = scope;
while (ss) {
if (ss->wires.find(name) != ss->wires.end())
return;
if (ss->localparams.find(name) != ss->localparams.end())
return;
if (ss->parameters.find(name) != ss->parameters.end())
return;
if (ss->genvars.find(name) != ss->genvars.end())
return;
if (ss->events.find(name) != ss->events.end())
return;
/* Strictly speaking, we should also check for name clashes
with tasks, functions, named blocks, module instances,
and generate blocks. However, this information is not
readily available. As these names would not be legal in
this context, we can declare implicit nets here and rely
on later checks for name clashes to report the error. */
ss = ss->parent_scope();
}
PWire*net = new PWire(name, type, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
net->set_file(get_file());
net->set_lineno(get_lineno());
net->set_range_scalar(SR_NET);
scope->wires[name] = net;
if (warn_implicit) {
cerr << get_fileline() << ": warning: implicit "
"definition of wire '" << name << "'." << endl;
}
}
}
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
{
NetNet* net = 0;
@@ -439,7 +235,7 @@ bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
const NetExpr*ex1, *ex2;
scope = symbol_search(this, des, scope, path_, net, par, eve, ex1, ex2);
scope = symbol_search(0, des, scope, path_, net, par, eve, ex1, ex2);
if (scope)
return scope->is_auto();
@@ -447,43 +243,6 @@ bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
return false;
}
PENewArray::PENewArray(PExpr*size_expr, PExpr*init_expr)
: size_(size_expr), init_(init_expr)
{
}
PENewArray::~PENewArray()
{
delete size_;
}
PENewClass::PENewClass(void)
{
}
PENewClass::PENewClass(const list<PExpr*>&p)
: parms_(p.size())
{
size_t tmp_idx = 0;
for (list<PExpr*>::const_iterator cur = p.begin()
; cur != p.end() ; ++ cur) {
parms_[tmp_idx++] = *cur;
}
}
PENewClass::~PENewClass()
{
}
PENewCopy::PENewCopy(PExpr*src)
: src_(src)
{
}
PENewCopy::~PENewCopy()
{
}
PENumber::PENumber(verinum*vp)
: value_(vp)
{
@@ -533,14 +292,6 @@ PETernary::~PETernary()
{
}
void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
assert(expr_ && tru_ && fal_);
expr_->declare_implicit_nets(scope, type);
tru_->declare_implicit_nets(scope, type);
fal_->declare_implicit_nets(scope, type);
}
bool PETernary::has_aa_term(Design*des, NetScope*scope) const
{
assert(expr_ && tru_ && fal_);
@@ -549,15 +300,6 @@ bool PETernary::has_aa_term(Design*des, NetScope*scope) const
|| fal_->has_aa_term(des, scope);
}
PETypename::PETypename(data_type_t*dt)
: data_type_(dt)
{
}
PETypename::~PETypename()
{
}
PEUnary::PEUnary(char op, PExpr*ex)
: op_(op), expr_(ex)
{
@@ -567,22 +309,8 @@ PEUnary::~PEUnary()
{
}
void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
assert(expr_);
expr_->declare_implicit_nets(scope, type);
}
bool PEUnary::has_aa_term(Design*des, NetScope*scope) const
{
assert(expr_);
return expr_->has_aa_term(des, scope);
}
PEVoid::PEVoid()
{
}
PEVoid::~PEVoid()
{
}
+172 -578
View File
File diff suppressed because it is too large Load Diff
+14 -48
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2013 Stephen Williams ([email protected])
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
*
* 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,26 +14,30 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "PTask.h"
# include "Statement.h"
# include <cassert>
# include "ivl_assert.h"
PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
: PTaskFunc(name, parent), statement_(0)
#include "PTask.h"
PFunction::PFunction(perm_string name, PScope*parent, bool is_auto__)
: PScope(name, parent), ports_(0), statement_(0)
{
is_auto_ = is_auto__;
return_type_ = 0;
return_type_.type = PTF_NONE;
}
PFunction::~PFunction()
{
}
void PFunction::set_ports(svector<PWire *>*p)
{
assert(ports_ == 0);
ports_ = p;
}
void PFunction::set_statement(Statement*s)
{
assert(s != 0);
@@ -41,45 +45,7 @@ void PFunction::set_statement(Statement*s)
statement_ = s;
}
void PFunction::push_statement_front(Statement*stmt)
{
// This can only happen after the statement is initially set.
ivl_assert(*this, statement_);
// Get the PBlock of the statement. If it is not a PBlock,
// then create one to wrap the existing statement and the new
// statement that we're pushing.
PBlock*blk = dynamic_cast<PBlock*> (statement_);
if (blk == 0) {
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
tmp->set_line(*this);
vector<Statement*>tmp_list(1);
tmp_list[0] = statement_;
tmp->set_statement(tmp_list);
statement_ = tmp;
blk = tmp;
}
// Now do the push.
blk->push_statement_front(stmt);
}
void PFunction::set_return(data_type_t*t)
void PFunction::set_return(PTaskFuncArg t)
{
return_type_ = t;
}
PChainConstructor* PFunction::extract_chain_constructor()
{
PChainConstructor*res = 0;
if ((res = dynamic_cast<PChainConstructor*> (statement_))) {
statement_ = 0;
} else if (PBlock*blk = dynamic_cast<PBlock*>(statement_)) {
res = blk->extract_chain_constructor();
}
return res;
}
+88 -154
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2013 Stephen Williams ([email protected])
* Copyright (c) 1999-2007 Stephen Williams ([email protected])
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
@@ -22,68 +22,55 @@
# include "PGate.h"
# include "PExpr.h"
# include "verinum.h"
# include <cassert>
# include <assert.h>
void PGate::set_pins_(list<PExpr*>*pins)
PGate::PGate(perm_string name,
svector<PExpr*>*pins,
const svector<PExpr*>*del)
: name_(name), pins_(pins)
{
assert(pins);
assert(pins->size() == pins_.size());
for (size_t idx = 0 ; idx < pins_.size() ; idx += 1) {
pins_[idx] = pins->front();
pins->pop_front();
}
assert(pins->empty());
delete pins;
}
PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
: name_(name), pins_(pins? pins->size() : 0)
{
if (pins) set_pins_(pins);
if (del) delay_.set_delays(del);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
str0_ = STRONG;
str1_ = STRONG;
}
PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del)
: name_(name), pins_(pins? pins->size() : 0)
PGate::PGate(perm_string name,
svector<PExpr*>*pins,
PExpr*del)
: name_(name), pins_(pins)
{
if (pins) set_pins_(pins);
if (del) delay_.set_delay(del);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
str0_ = STRONG;
str1_ = STRONG;
}
PGate::PGate(perm_string name, list<PExpr*>*pins)
: name_(name), pins_(pins? pins->size() : 0)
PGate::PGate(perm_string name, svector<PExpr*>*pins)
: name_(name), pins_(pins)
{
if (pins) set_pins_(pins);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
str0_ = STRONG;
str1_ = STRONG;
}
PGate::~PGate()
{
}
ivl_drive_t PGate::strength0() const
PGate::strength_t PGate::strength0() const
{
return str0_;
}
void PGate::strength0(ivl_drive_t s)
void PGate::strength0(PGate::strength_t s)
{
str0_ = s;
}
ivl_drive_t PGate::strength1() const
PGate::strength_t PGate::strength1() const
{
return str1_;
}
void PGate::strength1(ivl_drive_t s)
void PGate::strength1(PGate::strength_t s)
{
str1_ = s;
}
@@ -112,21 +99,69 @@ void PGate::eval_delays(Design*des, NetScope*scope,
as_net_flag);
}
unsigned PGate::delay_count() const
void PGate::eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
return delay_.delay_count();
NetExpr*rise_expr, *fall_expr, *decay_expr;
delay_.eval_delays(des, scope, rise_expr, fall_expr, decay_expr);
if (rise_expr == 0) {
rise_time = 0;
fall_time = 0;
decay_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (rise_expr)) {
rise_time = tmp->value().as_ulong();
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
rise_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (fall_expr)) {
fall_time = tmp->value().as_ulong();
} else {
if (fall_expr != rise_expr) {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
}
des->errors += 1;
fall_time = 0;
}
if (NetEConst*tmp = dynamic_cast<NetEConst*> (decay_expr)) {
decay_time = tmp->value().as_ulong();
} else {
cerr << get_fileline() << ": error: Delay expressions must be "
<< "constant here." << endl;
cerr << get_fileline() << ": : Cannot calculate "
<< *rise_expr << endl;
des->errors += 1;
decay_time = 0;
}
}
PGAssign::PGAssign(list<PExpr*>*pins)
PGAssign::PGAssign(svector<PExpr*>*pins)
: PGate(perm_string(), pins)
{
assert(pin_count() == 2);
assert(pins->count() == 2);
}
PGAssign::PGAssign(list<PExpr*>*pins, list<PExpr*>*dels)
PGAssign::PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels)
: PGate(perm_string(), pins, dels)
{
assert(pin_count() == 2);
assert(pins->count() == 2);
}
PGAssign::~PGAssign()
@@ -134,14 +169,14 @@ PGAssign::~PGAssign()
}
PGBuiltin::PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins,
list<PExpr*>*del)
svector<PExpr*>*pins,
svector<PExpr*>*del)
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
{
}
PGBuiltin::PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins,
svector<PExpr*>*pins,
PExpr*del)
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
{
@@ -161,128 +196,26 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
lsb_ = lsb;
}
const char* PGBuiltin::gate_name() const
{
switch(type_) {
case AND:
return "AND";
break;
case NAND:
return "NAND";
break;
case OR:
return "OR";
break;
case NOR:
return "NOR";
break;
case XOR:
return "XOR";
break;
case XNOR:
return "XNOR";
break;
case BUF:
return "BUF";
break;
case NOT:
return "NOT";
break;
case BUFIF0:
return "BUFIF0";
break;
case NOTIF0:
return "NOTIF0";
break;
case BUFIF1:
return "BUFIF1";
break;
case NOTIF1:
return "NOTIF1";
break;
case NMOS:
return "NMOS";
break;
case RNMOS:
return "RNMOS";
break;
case PMOS:
return "PMOS";
break;
case RPMOS:
return "RPMOS";
break;
case TRAN:
return "TRAN";
break;
case RTRAN:
return "RTRAN";
break;
case TRANIF0:
return "TRANIF0";
break;
case RTRANIF0:
return "RTRANIF0";
break;
case TRANIF1:
return "TRANIF1";
break;
case RTRANIF1:
return "RTRANIF1";
break;
case CMOS:
return "CMOS";
break;
case RCMOS:
return "RCMOS";
break;
case PULLUP:
return "PULLUP";
break;
case PULLDOWN:
return "PULLDOWN";
break;
}
return "<unknown>";
}
PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
: PGate(name, pins), bound_type_(0), type_(type), overrides_(0), pins_(0),
PGModule::PGModule(perm_string type, perm_string name, svector<PExpr*>*pins)
: PGate(name, pins), overrides_(0), pins_(0),
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
type_ = type;
}
PGModule::PGModule(perm_string type, perm_string name,
named<PExpr*>*pins, unsigned npins)
: PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins),
: PGate(name, 0), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
}
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)
{
type_ = type;
}
PGModule::~PGModule()
{
}
void PGModule::set_parameters(list<PExpr*>*o)
void PGModule::set_parameters(svector<PExpr*>*o)
{
assert(overrides_ == 0);
overrides_ = o;
@@ -305,7 +238,8 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
lsb_ = lsb;
}
perm_string PGModule::get_type() const
perm_string PGModule::get_type()
{
return type_;
}
+39 -49
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PGate_H
#define IVL_PGate_H
#ifndef __PGate_H
#define __PGate_H
/*
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "svector.h"
@@ -26,8 +26,6 @@
# include "PDelays.h"
# include "netlist.h"
# include <map>
# include <list>
# include <vector>
# include <string>
class PExpr;
class PUdp;
@@ -50,18 +48,29 @@ class Module;
class PGate : public LineInfo {
public:
explicit PGate(perm_string name, list<PExpr*>*pins,
const list<PExpr*>*del);
enum strength_t { HIGHZ, WEAK, PULL, STRONG, SUPPLY };
explicit PGate(perm_string name, list<PExpr*>*pins,
explicit PGate(perm_string name, svector<PExpr*>*pins,
const svector<PExpr*>*del);
explicit PGate(perm_string name, svector<PExpr*>*pins,
PExpr*del);
explicit PGate(perm_string name, list<PExpr*>*pins);
explicit PGate(perm_string name, svector<PExpr*>*pins);
virtual ~PGate();
perm_string get_name() const { return name_; }
// This method evaluates the delays all the way to an
// integer. If the delay is non-constant, then set the times
// to 0, print an error message and mark an error to the
// design.
void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
// This evaluates the delays as far as possible, but returns
// an expression, and do not signal errors.
void eval_delays(Design*des, NetScope*scope,
@@ -70,16 +79,14 @@ class PGate : public LineInfo {
NetExpr*&decay_time,
bool as_net_flag =false) const;
unsigned delay_count() const;
unsigned pin_count() const { return pins_? pins_->count() : 0; }
PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
unsigned pin_count() const { return pins_.size(); }
PExpr*pin(unsigned idx) const { return pins_[idx]; }
strength_t strength0() const;
strength_t strength1() const;
ivl_drive_t strength0() const;
ivl_drive_t strength1() const;
void strength0(ivl_drive_t);
void strength1(ivl_drive_t);
void strength0(strength_t);
void strength1(strength_t);
map<perm_string,PExpr*> attributes;
@@ -89,7 +96,7 @@ class PGate : public LineInfo {
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
protected:
const vector<PExpr*>& get_pins() const { return pins_; }
const svector<PExpr*>& get_pins() const { return *pins_; }
void dump_pins(ostream&out) const;
void dump_delays(ostream&out) const;
@@ -97,11 +104,9 @@ class PGate : public LineInfo {
private:
perm_string name_;
PDelays delay_;
vector<PExpr*>pins_;
svector<PExpr*>*pins_;
ivl_drive_t str0_, str1_;
void set_pins_(list<PExpr*>*pins);
strength_t str0_, str1_;
private: // not implemented
PGate(const PGate&);
@@ -115,8 +120,8 @@ class PGate : public LineInfo {
class PGAssign : public PGate {
public:
explicit PGAssign(list<PExpr*>*pins);
explicit PGAssign(list<PExpr*>*pins, list<PExpr*>*dels);
explicit PGAssign(svector<PExpr*>*pins);
explicit PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels);
~PGAssign();
void dump(ostream&out, unsigned ind =4) const;
@@ -124,7 +129,6 @@ class PGAssign : public PGate {
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private:
void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const;
};
@@ -148,15 +152,14 @@ class PGBuiltin : public PGate {
public:
explicit PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins,
list<PExpr*>*del);
svector<PExpr*>*pins,
svector<PExpr*>*del);
explicit PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins,
svector<PExpr*>*pins,
PExpr*del);
~PGBuiltin();
Type type() const { return type_; }
const char * gate_name() const;
void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(ostream&out, unsigned ind =4) const;
@@ -167,15 +170,12 @@ class PGBuiltin : public PGate {
unsigned calculate_array_count_(Design*, NetScope*,
long&high, long&low) const;
void calculate_gate_and_lval_count_(unsigned&gate_count,
unsigned&lval_count) const;
unsigned calculate_output_count_(void) const;
NetNode* create_gate_for_output_(Design*, NetScope*,
perm_string gate_name,
unsigned instance_width) const;
bool check_delay_count(Design*des) const;
Type type_;
PExpr*msb_;
PExpr*lsb_;
@@ -195,22 +195,19 @@ class PGModule : public PGate {
// If the binding of ports is by position, this constructor
// builds everything all at once.
explicit PGModule(perm_string type, perm_string name,
list<PExpr*>*pins);
svector<PExpr*>*pins);
// If the binding of ports is by name, this constructor takes
// the bindings and stores them for later elaboration.
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();
// Parameter overrides can come as an ordered list, or a set
// of named expressions.
void set_parameters(list<PExpr*>*o);
void set_parameters(svector<PExpr*>*o);
void set_parameters(named<PExpr*>*pa, unsigned npa);
// Modules can be instantiated in ranges. The parser uses this
@@ -224,12 +221,11 @@ class PGModule : public PGate {
// This returns the module name of this module. It is a
// permallocated string.
perm_string get_type() const;
perm_string get_type();
private:
Module*bound_type_;
perm_string type_;
list<PExpr*>*overrides_;
svector<PExpr*>*overrides_;
named<PExpr*>*pins_;
unsigned npins_;
@@ -244,20 +240,14 @@ class PGModule : public PGate {
friend class delayed_elaborate_scope_mod_instances;
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
unsigned calculate_instance_count_(Design*, NetScope*,
long&high, long&low,
perm_string name) const;
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
void elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const;
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
// Not currently used.
#if 0
bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const;
#endif
NetNet*resize_net_to_port_(Design*des, NetScope*scope,
NetNet*sig, unsigned port_wid,
NetNet::PortType dir, bool as_signed) const;
};
#endif /* IVL_PGate_H */
#endif
+9 -83
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2011 Stephen Williams ([email protected])
* Copyright (c) 2006 Stephen Williams ([email protected])
*
* 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,21 +14,20 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGenerate.cc,v 1.4 2007/06/02 03:42:12 steve Exp $"
#endif
# include "PGenerate.h"
# include "PWire.h"
# include "ivl_assert.h"
PGenerate::PGenerate(LexicalScope*parent, unsigned id)
: LexicalScope(parent), id_number(id)
PGenerate::PGenerate(unsigned id)
: id_number(id)
{
direct_nested_ = false;
scheme_type = GS_NONE;
loop_init = 0;
loop_test = 0;
loop_step = 0;
parent = 0;
lexical_scope = 0;
}
PGenerate::~PGenerate()
@@ -39,76 +38,3 @@ void PGenerate::add_gate(PGate*gate)
{
gates.push_back(gate);
}
void PGenerate::probe_for_direct_nesting_(void)
{
direct_nested_ = false;
ivl_assert(*this, scheme_type==GS_CASE_ITEM || scheme_type==GS_CONDIT || scheme_type==GS_ELSE);
// If this scheme has received an explicit name, then it
// cannot be direct nested.
if (scope_name[0] != '$') return;
if (! tasks.empty()) return;
if (! funcs.empty()) return;
if (! gates.empty()) return;
if (! parameters.empty()) return;
if (! localparams.empty()) return;
if (! events.empty()) return;
if (! wires.empty()) return;
if (! genvars.empty()) return;
if (! behaviors.empty()) return;
if (! analog_behaviors.empty()) return;
if (generate_schemes.empty()) return;
switch (generate_schemes.size()) {
case 1: {
PGenerate*child = generate_schemes.front();
if (child->scheme_type == GS_CONDIT)
direct_nested_ = true;
if (child->scheme_type == GS_CASE)
direct_nested_ = true;
break;
}
case 2: {
PGenerate*child1 = generate_schemes.front();
PGenerate*child2 = generate_schemes.back();
if (child1->scheme_type==GS_CONDIT && child2->scheme_type==GS_ELSE)
direct_nested_ = true;
if (child2->scheme_type==GS_CONDIT && child1->scheme_type==GS_ELSE)
direct_nested_ = true;
break;
}
}
}
ostream& operator << (ostream&out, PGenerate::scheme_t type)
{
switch (type) {
case PGenerate::GS_NONE:
out << "GS_NONE";
break;
case PGenerate::GS_LOOP:
out << "GS_LOOP";
break;
case PGenerate::GS_CONDIT:
out << "GS_CONDIT";
break;
case PGenerate::GS_ELSE:
out << "GS_ELSE";
break;
case PGenerate::GS_CASE:
out << "GS_CASE";
break;
case PGenerate::GS_CASE_ITEM:
out << "GS_CASE_ITEM";
break;
case PGenerate::GS_NBLOCK:
out << "GS_NBLOCK";
break;
}
return out;
}
+8 -29
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PGenerate_H
#define IVL_PGenerate_H
#ifndef __PGenerate_H
#define __PGenerate_H
/*
* Copyright (c) 2006-2014 Stephen Williams ([email protected])
* Copyright (c) 2006-2008 Stephen Williams ([email protected])
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "LineInfo.h"
@@ -25,7 +25,6 @@
# include "PScope.h"
# include <list>
# include <map>
# include <valarray>
# include "pform_types.h"
class Design;
@@ -53,7 +52,7 @@ class PWire;
class PGenerate : public LineInfo, public LexicalScope {
public:
explicit PGenerate(LexicalScope*parent, unsigned id_number);
explicit PGenerate(unsigned id_number);
~PGenerate();
// Generate schemes have an ID number, for when the scope is
@@ -63,7 +62,7 @@ class PGenerate : public LineInfo, public LexicalScope {
// This is used during parsing to stack lexical scopes within
// this generate scheme.
// LexicalScope*lexical_scope;
PScope*lexical_scope;
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE,
GS_CASE, GS_CASE_ITEM, GS_NBLOCK};
@@ -75,14 +74,6 @@ class PGenerate : public LineInfo, public LexicalScope {
PExpr*loop_init;
PExpr*loop_test;
PExpr*loop_step;
// Case items may have multiple guard expression values. It is
// enough for any on of the guards to match the case statement
// 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*);
@@ -93,7 +84,7 @@ class PGenerate : public LineInfo, public LexicalScope {
// Generate schemes can contain further generate schemes.
list<PGenerate*> generate_schemes;
// PGenerate*parent;
PGenerate*parent;
// This method is called by the elaboration of a module to
// generate scopes. the container is the scope that is to
@@ -113,30 +104,18 @@ class PGenerate : public LineInfo, public LexicalScope {
bool generate_scope_case_(Design*des, NetScope*container);
bool generate_scope_nblock_(Design*des, NetScope*container);
// Call probe during elaborate_scope to calculate the
// direct_nested_ flag. It is OK to store the direct_nested_
// information here because "direct nested" is a property of
// the lexical generate code.
void probe_for_direct_nesting_(void);
bool direct_nested_;
// Elaborate_scope within a generated scope.
void elaborate_subscope_(Design*des, NetScope*scope);
void elaborate_subscope_direct_(Design*des, NetScope*scope);
// These are the scopes created by generate_scope.
list<NetScope*>scope_list_;
// internal function called on each scope generated by this scheme.
bool elaborate_sig_(Design*des, NetScope*scope) const;
bool elaborate_sig_direct_(Design*des, NetScope*scope) const;
bool elaborate_(Design*des, NetScope*scope) const;
bool elaborate_direct_(Design*des, NetScope*scope) const;
private: // not implemented
PGenerate(const PGenerate&);
PGenerate& operator= (const PGenerate&);
};
extern std::ostream& operator << (std::ostream&, PGenerate::scheme_t);
#endif /* IVL_PGenerate_H */
#endif
-52
View File
@@ -1,52 +0,0 @@
#ifndef IVL_PModport_H
#define IVL_PModport_H
/*
* Copyright (c) 2015 Stephen Williams ([email protected])
*
* 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 "LineInfo.h"
# include "PScope.h"
# include "StringHeap.h"
# include "netlist.h"
# include <vector>
/*
* The PModport class represents a parsed SystemVerilog modport list.
*/
class PModport : public LineInfo {
public:
// The name is a perm-allocated string. It is the simple name
// of the modport, without any scope.
explicit PModport(perm_string name);
~PModport();
perm_string name() const { return name_; }
typedef pair <NetNet::PortType,PExpr*> simple_port_t;
map<perm_string,simple_port_t> simple_ports;
private:
perm_string name_;
private: // not implemented
PModport(const PModport&);
PModport& operator= (const PModport&);
};
#endif /* IVL_PModport_H */
-30
View File
@@ -1,30 +0,0 @@
/*
* Copyright (c) 2012 Stephen Williams ([email protected])
* Copyright CERN 2013 / Stephen Williams ([email protected])
*
* 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()
{
}
-47
View File
@@ -1,47 +0,0 @@
#ifndef IVL_PPackage_H
#define IVL_PPackage_H
/*
* Copyright (c) 2012-2014 Stephen Williams ([email protected])
* Copyright CERN 2013 / Stephen Williams ([email protected])
*
* 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"
# include <iostream>
/*
* 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();
bool elaborate_scope(Design*des, NetScope*scope);
bool elaborate_sig(Design*des, NetScope*scope) const;
bool elaborate(Design*des, NetScope*scope) const;
void pform_dump(std::ostream&out) const;
};
#endif /* IVL_PPackage_H */
+5 -23
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008,2010 Stephen Williams ([email protected])
* Copyright (c) 2008 Stephen Williams ([email protected])
*
* 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,26 +14,23 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "PScope.h"
PScope::PScope(perm_string n, LexicalScope*parent)
: LexicalScope(parent), name_(n)
PScope::PScope(perm_string n, PScope*parent)
: name_(n), parent_(parent)
{
}
PScope::PScope(perm_string n)
: LexicalScope(0), name_(n)
: name_(n), parent_(0)
{
}
PScope::~PScope()
{
for(map<perm_string, data_type_t*>::iterator it = typedefs.begin();
it != typedefs.end(); ++it)
delete it->second;
}
PWire* LexicalScope::wires_find(perm_string name)
@@ -44,18 +41,3 @@ PWire* LexicalScope::wires_find(perm_string name)
else
return (*cur).second;
}
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
: PScope(n, parent)
{
}
PScopeExtra::PScopeExtra(perm_string n)
: PScope(n)
{
}
PScopeExtra::~PScopeExtra()
{
}
+9 -62
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PScope_H
#define IVL_PScope_H
#ifndef __PScope_H
#define __PScope_H
/*
* Copyright (c) 2008-2014 Stephen Williams ([email protected])
* Copyright (c) 2008 Stephen Williams ([email protected])
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "LineInfo.h"
@@ -24,17 +24,11 @@
# include "pform_types.h"
# include "ivl_target.h"
# include <map>
# include <set>
# include <vector>
class PEvent;
class PExpr;
class PFunction;
class PPackage;
class AProcess;
class PProcess;
class PClass;
class PTask;
class PWire;
class Design;
@@ -52,7 +46,7 @@ class NetScope;
class LexicalScope {
public:
explicit LexicalScope(LexicalScope*parent) : parent_(parent) { }
explicit LexicalScope() { }
// A virtual destructor is so that dynamic_cast can work.
virtual ~LexicalScope() { }
@@ -89,49 +83,27 @@ class LexicalScope {
map<perm_string,param_expr_t>parameters;
map<perm_string,param_expr_t>localparams;
// Defined types in the scope.
map<perm_string,data_type_t*>typedefs;
// Named events in the scope.
map<perm_string,PEvent*>events;
// Symbols that are imported. Bind the imported name to the
// package from which the name is imported.
std::map<perm_string,PPackage*>imports;
// Nets and variables (wires) in the scope
map<perm_string,PWire*>wires;
PWire* wires_find(perm_string name);
// Genvars in the scope. These will only be present in module
// scopes, but are listed here to allow them to be found when
// creating implicit nets.
map<perm_string,LineInfo*> genvars;
// Behaviors (processes) in this scope
list<PProcess*> behaviors;
list<AProcess*> analog_behaviors;
// Enumeration sets.
std::set<enum_type_t*> enum_sets;
LexicalScope* parent_scope() const { return parent_; }
protected:
void dump_typedefs_(ostream&out, unsigned indent) const;
void dump_parameters_(ostream&out, unsigned indent) const;
void dump_localparams_(ostream&out, unsigned indent) const;
void dump_enumerations_(ostream&out, unsigned indent) const;
void dump_events_(ostream&out, unsigned indent) const;
void dump_wires_(ostream&out, unsigned indent) const;
private:
LexicalScope*parent_;
};
class PScope : public LexicalScope {
@@ -145,11 +117,12 @@ class PScope : public LexicalScope {
// modules do not nest in Verilog, the parent must be nil for
// modules. Scopes for tasks and functions point to their
// containing module.
PScope(perm_string name, LexicalScope*parent);
PScope(perm_string name, PScope*parent);
PScope(perm_string name);
virtual ~PScope();
perm_string pscope_name() const { return name_; }
PScope* pscope_parent() { return parent_; }
protected:
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
@@ -158,33 +131,7 @@ class PScope : public LexicalScope {
private:
perm_string name_;
PScope*parent_;
};
/*
* Some scopes can carry definitions. These include Modules and PClass
* scopes. These derive from PScopeExtra so that they hold the maps of
* extra definitions.
*/
class PScopeExtra : public PScope {
public:
PScopeExtra(perm_string, LexicalScope*parent);
PScopeExtra(perm_string);
~PScopeExtra();
/* Task definitions within this module */
std::map<perm_string,PTask*> tasks;
std::map<perm_string,PFunction*> funcs;
/* class definitions within this module. */
std::map<perm_string,PClass*> classes;
/* This is the lexical order of the classes, and is used by
elaboration to choose an elaboration order. */
std::vector<PClass*> classes_lexical;
protected:
void dump_classes_(ostream&out, unsigned indent) const;
void dump_tasks_(ostream&out, unsigned indent) const;
void dump_funcs_(ostream&out, unsigned indent) const;
};
#endif /* IVL_PScope_H */
#endif
+6 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2011 Stephen Williams <[email protected]>
* Copyright (c) 2006 Stephen Williams <[email protected]>
*
* 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,19 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PSpec.cc,v 1.2 2007/02/12 01:52:21 steve Exp $"
#endif
# include "PSpec.h"
PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity,
bool full_flag)
PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt)
: conditional(false), condition(0), edge(0),
src(src_cnt), dst(dst_cnt),
data_source_expression(0)
{
full_flag_ = full_flag;
polarity_ = polarity;
}
PSpecPath::~PSpecPath()
+9 -17
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PSpec_H
#define IVL_PSpec_H
#ifndef __PSpec_H
#define __PSpec_H
/*
* Copyright (c) 2006-2014 Stephen Williams <[email protected]>
* Copyright (c) 2006 Stephen Williams <[email protected]>
*
* 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,8 +16,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PSpec.h,v 1.3 2007/04/13 02:34:35 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
@@ -46,18 +49,11 @@ class PExpr;
*
* If data_source_expression != nil, then the path is edge sensitive
* and the edge might not be 0.
*
* The full flag is used to verify that only vectors of the same size
* are used in a parallel connection. Icarus always creates a full
* connection between the source and destination. The polarity is for
* informational (display) purposes only. The polarity is either '+',
* '-' or 0.
*/
class PSpecPath : public LineInfo {
public:
PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity,
bool full_flag);
PSpecPath(unsigned src_cnt, unsigned dst_cnt);
~PSpecPath();
void elaborate(class Design*des, class NetScope*scope) const;
@@ -70,10 +66,6 @@ class PSpecPath : public LineInfo {
class PExpr* condition;
// Edge specification (-1==negedge, 0 = no edge, 1==posedge)
int edge;
// Is this a full connection.
bool full_flag_;
// What is the polarity of the connection.
char polarity_;
// Ordered set of source nodes of a path
std::vector<perm_string> src;
// Ordered set of destination nodes of a path
@@ -84,4 +76,4 @@ class PSpecPath : public LineInfo {
std::vector<class PExpr*>delays;
};
#endif /* IVL_PSpec_H */
#endif
+11 -37
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2008,2010 Stephen Williams ([email protected])
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
*
* 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,47 +14,15 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "PTask.h"
# include <cassert>
PTaskFunc::PTaskFunc(perm_string n, LexicalScope*p)
: PScope(n,p), this_type_(0), ports_(0)
{
}
PTaskFunc::~PTaskFunc()
{
}
void PTaskFunc::set_ports(vector<pform_tf_port_t>*p)
{
assert(ports_ == 0);
ports_ = p;
}
void PTaskFunc::set_this(class_type_t*type, PWire*this_wire)
{
assert(this_type_ == 0);
this_type_ = type;
// Push a synthesis argument that is the "this" value.
if (ports_==0)
ports_ = new vector<pform_tf_port_t>;
size_t use_size = ports_->size();
ports_->resize(use_size + 1);
for (size_t idx = use_size ; idx > 0 ; idx -= 1)
ports_->at(idx) = ports_->at(idx-1);
ports_->at(0) = pform_tf_port_t(this_wire);
}
PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__)
: PTaskFunc(name, parent), statement_(0)
PTask::PTask(perm_string name, PScope*parent, bool is_auto__)
: PScope(name, parent), ports_(0), statement_(0)
{
is_auto_ = is_auto__;
}
@@ -63,6 +31,12 @@ PTask::~PTask()
{
}
void PTask::set_ports(svector<PWire*>*p)
{
assert(ports_ == 0);
ports_ = p;
}
void PTask::set_statement(Statement*s)
{
assert(statement_ == 0);
+28 -61
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PTask_H
#define IVL_PTask_H
#ifndef __PTask_H
#define __PTask_H
/*
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
*
* 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,69 +16,45 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "LineInfo.h"
# include "PScope.h"
# include "svector.h"
# include "StringHeap.h"
# include <string>
# include <vector>
# include <list>
class Design;
class NetExpr;
class NetNet;
class NetScope;
class PChainConstructor;
class PWire;
class Statement;
class PExpr;
enum PTaskFuncEnum {
PTF_NONE,
PTF_REG,
PTF_REG_S,
PTF_INTEGER,
PTF_REAL,
PTF_REALTIME,
PTF_TIME
};
class PTaskFunc : public PScope, public LineInfo {
public:
PTaskFunc(perm_string name, LexicalScope*parent);
~PTaskFunc();
void set_ports(std::vector<pform_tf_port_t>*p);
void set_this(class_type_t*use_type, PWire*this_wire);
// If this task is a method of a class, this returns a pointer
// to the class type.
inline class_type_t* method_of() const { return this_type_; }
virtual void elaborate_sig(Design*des, NetScope*scope) const =0;
virtual void elaborate(Design*des, NetScope*scope) const =0;
virtual void dump(std::ostream&, unsigned) const =0;
protected:
// Elaborate the ports list. Write into the ports vector the
// NetNet pointers for the ports, and write into the pdefs the
// default value expressions, if any.
void elaborate_sig_ports_(Design*des, NetScope*scope,
std::vector<NetNet*>&ports,
std::vector<NetExpr*>&pdefs) const;
void dump_ports_(std::ostream&out, unsigned ind) const;
private:
class_type_t*this_type_;
std::vector<pform_tf_port_t>*ports_;
struct PTaskFuncArg {
PTaskFuncEnum type;
svector<PExpr*>*range;
};
/*
* The PTask holds the parsed definitions of a task.
*/
class PTask : public PTaskFunc {
class PTask : public PScope, public LineInfo {
public:
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
explicit PTask(perm_string name, PScope*parent, bool is_auto);
~PTask();
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s);
// Tasks introduce scope, to need to be handled during the
@@ -98,6 +74,7 @@ class PTask : public PTaskFunc {
void dump(ostream&, unsigned) const;
private:
svector<PWire*>*ports_;
Statement*statement_;
bool is_auto_;
@@ -113,26 +90,15 @@ class PTask : public PTaskFunc {
*
* The output value is not elaborated until elaborate_sig.
*/
class PFunction : public PTaskFunc {
class PFunction : public PScope, public LineInfo {
public:
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
explicit PFunction(perm_string name, PScope*parent, bool is_auto);
~PFunction();
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s);
void set_return(data_type_t*t);
inline Statement* get_statement() { return statement_; }
// Push this statement to the front of the existing
// definition. If the statement is a simple statement, make a
// block to contain the statements.
void push_statement_front(Statement*stmt);
// This is only used if this function is a constructor. In
// that case, this method looks for a PChainConstructor in the
// statement and extracts it if found.
PChainConstructor*extract_chain_constructor();
void set_return(PTaskFuncArg t);
void elaborate_scope(Design*des, NetScope*scope) const;
@@ -147,9 +113,10 @@ class PFunction : public PTaskFunc {
void dump(ostream&, unsigned) const;
private:
data_type_t* return_type_;
PTaskFuncArg return_type_;
svector<PWire *> *ports_;
Statement *statement_;
bool is_auto_;
};
#endif /* IVL_PTask_H */
#endif
+17 -1
View File
@@ -14,8 +14,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.cc,v 1.3 2004/03/08 00:47:44 steve Exp $"
#endif
# include "PUdp.h"
@@ -35,3 +38,16 @@ unsigned PUdp::find_port(const char*name)
return ports.count();
}
/*
* $Log: PUdp.cc,v $
* Revision 1.3 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.2 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.1 2003/07/15 05:07:13 steve
* Move PUdp constructor into compiled file.
*
*/
+59 -8
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PUdp_H
#define IVL_PUdp_H
#ifndef __PUdp_H
#define __PUdp_H
/*
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
*
* 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,11 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
#endif
# include <map>
# include "LineInfo.h"
# include "StringHeap.h"
# include "svector.h"
# include "verinum.h"
@@ -29,7 +31,7 @@ class PExpr;
/*
* This class represents a parsed UDP. This is a much simpler object
* than a module or macromodule.
* then a module or macromodule.
*
* - all ports are scalar,
* - pin 0 (the first port) is always output,
@@ -48,7 +50,7 @@ class PExpr;
* If the UDP is sequential, the "initial" member is taken to be the
* initial value assigned in the source, or 'x' if none is given.
*/
class PUdp : public LineInfo {
class PUdp {
public:
explicit PUdp(perm_string n, unsigned nports);
@@ -76,4 +78,53 @@ class PUdp : public LineInfo {
PUdp& operator= (const PUdp&);
};
#endif /* IVL_PUdp_H */
/*
* $Log: PUdp.h,v $
* Revision 1.12 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.11 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.10 2003/07/15 05:07:13 steve
* Move PUdp constructor into compiled file.
*
* Revision 1.9 2003/07/15 03:49:22 steve
* Spelling fixes.
*
* Revision 1.8 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.5 2001/04/22 23:09:45 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.4 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.3 1999/06/15 03:44:53 steve
* Get rid of the STL vector template.
*
* Revision 1.2 1998/12/01 00:42:13 steve
* Elaborate UDP devices,
* Support UDP type attributes, and
* pass those attributes to nodes that
* are instantiated by elaboration,
* Put modules into a map instead of
* a simple list.
*
* Revision 1.1 1998/11/25 02:35:53 steve
* Parse UDP primitives all the way to pform.
*
*/
#endif
+21 -95
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2012 Stephen Williams ([email protected])
* Copyright (c) 1999-2007 Stephen Williams ([email protected])
*
* 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,13 +14,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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "PWire.h"
# include "PExpr.h"
# include <cassert>
# include <assert.h>
PWire::PWire(perm_string n,
NetNet::Type t,
@@ -28,9 +28,9 @@ PWire::PWire(perm_string n,
ivl_variable_type_t dt)
: 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), set_data_type_(0),
discipline_(0)
port_msb_(0), port_lsb_(0), port_set_(false),
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0),
lidx_(0), ridx_(0), discipline_(0)
{
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
@@ -58,15 +58,7 @@ bool PWire::set_wire_type(NetNet::Type t)
type_ = t;
return true;
case NetNet::IMPLICIT_REG:
if (t == NetNet::REG) {
type_ = t;
return true;
}
if (t == NetNet::INTEGER) {
type_ = NetNet::REG;
isint_ = true;
return true;
}
if (t == NetNet::REG) { type_ = t; return true; }
return false;
case NetNet::REG:
if (t == NetNet::INTEGER) {
@@ -120,7 +112,6 @@ bool PWire::set_data_type(ivl_variable_type_t dt)
assert(data_type_ == IVL_VT_NO_TYPE);
data_type_ = dt;
return true;
}
@@ -141,24 +132,11 @@ bool PWire::get_signed() const
bool PWire::get_isint() const
{
if (isint_)
return true;
if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(set_data_type_)) {
return tmp->integer_flag;
}
return false;
return isint_;
}
bool PWire::get_scalar() const
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
{
return is_scalar_;
}
void PWire::set_range_scalar(PWSRType type)
{
is_scalar_ = true;
switch (type) {
case SR_PORT:
if (port_set_) {
@@ -166,6 +144,8 @@ void PWire::set_range_scalar(PWSRType type)
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
} else {
port_msb_ = m;
port_lsb_ = l;
port_set_ = true;
}
return;
@@ -176,6 +156,8 @@ void PWire::set_range_scalar(PWSRType type)
<< "'' has already been declared." << endl;
error_cnt_ += 1;
} else {
net_msb_ = m;
net_lsb_ = l;
net_set_ = true;
}
return;
@@ -193,82 +175,26 @@ void PWire::set_range_scalar(PWSRType type)
error_cnt_ += 1;
}
} else {
port_msb_ = m;
port_lsb_ = l;
port_set_ = true;
net_msb_ = m;
net_lsb_ = l;
net_set_ = true;
}
return;
}
}
void PWire::set_range(const list<pform_range_t>&rlist, PWSRType type)
void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
{
switch (type) {
case SR_PORT:
if (port_set_) {
cerr << get_fileline() << ": error: Port ``" << name_
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
} else {
port_ = rlist;
port_set_ = true;
is_scalar_ = false;
}
return;
case SR_NET:
if (net_set_) {
cerr << get_fileline() << ": error: Net ``" << name_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
} else {
net_ = rlist;
net_set_ = true;
is_scalar_ = false;
}
return;
case SR_BOTH:
if (port_set_ || net_set_) {
if (port_set_) {
cerr << get_fileline() << ": error: Port ``" << name_
<< "'' has already been declared a port." << endl;
error_cnt_ += 1;
}
if (net_set_) {
cerr << get_fileline() << ": error: Net ``" << name_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
}
} else {
port_ = rlist;
port_set_ = true;
net_ = rlist;
net_set_ = true;
is_scalar_ = false;
}
return;
}
}
void PWire::set_unpacked_idx(const list<pform_range_t>&ranges)
{
if (! unpacked_.empty()) {
if (lidx_ != 0 || ridx_ != 0) {
cerr << get_fileline() << ": error: Array ``" << name_
<< "'' has already been declared." << endl;
error_cnt_ += 1;
} else {
unpacked_ = ranges;
}
}
void PWire::set_data_type(data_type_t*type)
{
assert(set_data_type_ == 0);
set_data_type_ = type;
if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(type)) {
if (tmp->integer_flag)
isint_ = true;
lidx_ = ldx;
ridx_ = rdx;
}
}
+16 -27
View File
@@ -1,7 +1,7 @@
#ifndef IVL_PWire_H
#define IVL_PWire_H
#ifndef __PWire_H
#define __PWire_H
/*
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
* Copyright (c) 1998-2007 Stephen Williams ([email protected])
*
* 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,13 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "netlist.h"
# include "LineInfo.h"
# include <list>
# include <map>
# include "svector.h"
# include "StringHeap.h"
#ifdef HAVE_IOSFWD
@@ -33,7 +33,6 @@ class ostream;
class PExpr;
class Design;
class netdarray_t;
/*
* The different type of PWire::set_range() calls.
@@ -71,17 +70,13 @@ class PWire : public LineInfo {
void set_signed(bool flag);
bool get_signed() const;
bool get_isint() const;
bool get_scalar() const;
bool set_data_type(ivl_variable_type_t dt);
ivl_variable_type_t get_data_type() const;
void set_range_scalar(PWSRType type);
void set_range(const std::list<pform_range_t>&ranges, PWSRType type);
void set_range(PExpr*msb, PExpr*lsb, PWSRType type);
void set_unpacked_idx(const std::list<pform_range_t>&ranges);
void set_data_type(data_type_t*type);
void set_memory_idx(PExpr*ldx, PExpr*rdx);
void set_discipline(ivl_discipline_t);
ivl_discipline_t get_discipline(void) const;
@@ -102,25 +97,19 @@ class PWire : public LineInfo {
bool isint_; // original type of integer
// These members hold expressions for the bit width of the
// wire. If they do not exist, the wire is 1 bit wide. If they
// do exist, they represent the packed dimensions of the
// bit. The first item in the list is the first range, and so
// on. For example "reg [3:0][7:0] ..." will contains the
// range_t object for [3:0] first and [7:0] last.
std::list<pform_range_t>port_;
// wire. If they do not exist, the wire is 1 bit wide.
PExpr*port_msb_;
PExpr*port_lsb_;
bool port_set_;
std::list<pform_range_t>net_;
PExpr*net_msb_;
PExpr*net_lsb_;
bool net_set_;
bool is_scalar_;
unsigned error_cnt_;
// If this wire is actually a memory, these indices will give
// me the size and address ranges of the memory.
std::list<pform_range_t>unpacked_;
// This is the complex type of the wire. the data_type_ may
// modify how this is interpreted.
data_type_t*set_data_type_;
// me the size and address range of the memory.
PExpr*lidx_;
PExpr*ridx_;
ivl_discipline_t discipline_;
@@ -129,4 +118,4 @@ class PWire : public LineInfo {
PWire& operator= (const PWire&);
};
#endif /* IVL_PWire_H */
#endif
+33 -17
View File
@@ -8,7 +8,7 @@ Icarus Verilog is intended to compile ALL of the Verilog HDL as
described in the IEEE-1364 standard. Of course, it's not quite there
yet. It does currently handle a mix of structural and behavioral
constructs. For a view of the current state of Icarus Verilog, see its
home page at <http://iverilog.icarus.com/>.
home page at <http://www.icarus.com/eda/verilog>.
Icarus Verilog is not aimed at being a simulator in the traditional
sense, but a compiler that generates code employed by back-end
@@ -64,7 +64,7 @@ on a UNIX-like system:
- termcap
The readline library in turn uses termcap.
If you are building from git, you will also need software to generate
If you are building from CVS, you will also need software to generate
the configure scripts.
- autoconf 2.53
@@ -85,6 +85,10 @@ Normally, this command automatically figures out everything it needs
to know. It generally works pretty well. There are a few flags to the
configure script that modify its behavior:
--without-ipal
This turns off support for Icarus PAL, whether ipal
libraries are installed or not.
--prefix=<root>
The default is /usr/local, which causes the tool suite to
be compiled for install in /usr/local/bin,
@@ -95,16 +99,27 @@ configure script that modify its behavior:
common to use --prefix=/opt. You can configure for a non-root
install with --prefix=$HOME.
--enable-suffix
--enable-suffix=<your-suffix>
--disable-suffix
Enable/disable changing the names of install files to use
a suffix string so that this version or install can co-
exist with other versions. This renames the installed
commands (iverilog, iverilog-vpi, vvp) and the installed
library files and include directory so that installations
with the same prefix but different suffix are guaranteed
to not interfere with each other.
--enable-vvp32 (experimental)
If compiling on AMD64 systems, this enables the
compilation of 32bit compatible vvp (vvp32) and the vpi
modules that match.
2.2.1 Special AMD64 Instructions
(The Icarus Verilog RPM for x86_64 is build using these instructions.)
If you are building for Linux/AMD64 (a.k.a x86_64) then to get the
most out of your install, first make sure you have both 64bit and
32bit development libraries installed. Then configure with this
somewhat more complicated command:
./configure libdir64='$(prefix)/lib64' vpidir1=vpi64 vpidir2=. --enable-vvp32
This reflects the convention on AMD64 systems that 64bit libraries go
into lib64 directories. The "--enable-vvp32" also turns on 32bit
compatibility files. A 32bit version of vvp (vvp32) will be created,
as well as 32bit versions of the development libraries and bundled VPI
libraries.
2.3 (Optional) Testing
@@ -156,9 +171,8 @@ step. There may be dangling references, and it is not yet clear which
module is the root.
One can see a human readable version of the final pform by using the
``-P <path>'' flag to the ``ivl'' subcommand. This will cause ivl
to dump the pform into the file named <path>. (Note that this is not
normally done, unless debugging the ``ivl'' subcommand.)
``-P <path>'' flag to the compiler. This will cause iverilog to dump
the pform into the file named <path>.
3.3 Elaboration
@@ -184,7 +198,8 @@ first, followed by the structural and behavioral elaboration.
This pass scans through the pform looking for scopes and parameters. A
tree of NetScope objects is built up and placed in the Design object,
with the root module represented by the root NetScope object. The
elab_scope.cc file contains most of the code for handling this phase.
elab_scope.cc and elab_pexpr.cc files contain most of the code for
handling this phase.
The tail of the elaborate_scope behavior (after the pform is
traversed) includes a scan of the NetScope tree to locate defparam
@@ -237,7 +252,7 @@ item. The syntax of the $attribute item is:
$attribute (<identifier>, <key>, <value>);
The $attribute keyword looks like a system task invocation. The
difference here is that the parameters are more restricted than those
difference here is that the parameters are more restricted then those
of a system task. The <identifier> must be an identifier. This will be
the item to get an attribute. The <key> and <value> are strings, not
expressions, that give the key and the value of the attribute to be
@@ -475,3 +490,4 @@ file. However, I have early on received aid in the form of fixes,
Verilog guidance, and especially testing from many people. Testers in
particular include a larger community of people interested in a GPL
Verilog for Linux.
+18 -129
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2013 Stephen Williams ([email protected])
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
*
* 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,14 +14,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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "Statement.h"
# include "PExpr.h"
# include "ivl_assert.h"
Statement::~Statement()
{
@@ -52,27 +51,22 @@ PAssign_::~PAssign_()
}
PAssign::PAssign(PExpr*lval__, PExpr*ex)
: PAssign_(lval__, ex, false), op_(0)
{
}
PAssign::PAssign(PExpr*lval__, char op, PExpr*ex)
: PAssign_(lval__, ex, false), op_(op)
: PAssign_(lval__, ex, false)
{
}
PAssign::PAssign(PExpr*lval__, PExpr*d, PExpr*ex)
: PAssign_(lval__, d, ex), op_(0)
: PAssign_(lval__, d, ex)
{
}
PAssign::PAssign(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
: PAssign_(lval__, cnt, d, ex), op_(0)
: PAssign_(lval__, cnt, d, ex)
{
}
PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant)
: PAssign_(lval__, ex, is_constant), op_(0)
: PAssign_(lval__, ex, is_constant)
{
}
@@ -99,7 +93,7 @@ PAssignNB::~PAssignNB()
{
}
PBlock::PBlock(perm_string n, LexicalScope*parent, BL_TYPE t)
PBlock::PBlock(perm_string n, PScope*parent, BL_TYPE t)
: PScope(n, parent), bl_type_(t)
{
}
@@ -111,79 +105,23 @@ PBlock::PBlock(BL_TYPE t)
PBlock::~PBlock()
{
for (unsigned idx = 0 ; idx < list_.size() ; idx += 1)
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1)
delete list_[idx];
}
PChainConstructor* PBlock::extract_chain_constructor()
{
if (list_.empty())
return 0;
if (PChainConstructor*res = dynamic_cast<PChainConstructor*> (list_[0])) {
for (size_t idx = 0 ; idx < list_.size()-1 ; idx += 1)
list_[idx] = list_[idx+1];
list_.resize(list_.size()-1);
return res;
}
return 0;
}
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)
void PBlock::set_statement(const svector<Statement*>&st)
{
list_ = st;
}
void PBlock::push_statement_front(Statement*that)
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
: path_(n), parms_(p)
{
ivl_assert(*this, bl_type_==BL_SEQ);
list_.resize(list_.size()+1);
for (size_t idx = list_.size()-1 ; idx > 0 ; idx -= 1)
list_[idx] = list_[idx-1];
list_[0] = that;
}
PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
: package_(0), path_(n), parms_(p.size())
PCallTask::PCallTask(perm_string n, const svector<PExpr*>&p)
: parms_(p)
{
list<PExpr*>::const_iterator cur = p.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx] = *cur;
++cur;
}
assert(cur == p.end());
}
PCallTask::PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&p)
: package_(pkg), path_(n), parms_(p.size())
{
list<PExpr*>::const_iterator cur = p.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx] = *cur;
++cur;
}
assert(cur == p.end());
}
PCallTask::PCallTask(perm_string n, const list<PExpr*>&p)
: package_(0), parms_(p.size())
{
list<PExpr*>::const_iterator cur = p.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx] = *cur;
++cur;
}
assert(cur == p.end());
path_.push_back(name_component_t(n));
}
@@ -221,21 +159,6 @@ PCAssign::~PCAssign()
delete expr_;
}
PChainConstructor::PChainConstructor(const list<PExpr*>&parms)
: parms_(parms.size())
{
list<PExpr*>::const_iterator cur = parms.begin();
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx] = *cur;
++cur;
}
assert(cur == parms.end());
}
PChainConstructor::~PChainConstructor()
{
}
PCondit::PCondit(PExpr*ex, Statement*i, Statement*e)
: expr_(ex), if_(i), else_(e)
{
@@ -277,17 +200,6 @@ PDisable::~PDisable()
{
}
PDoWhile::PDoWhile(PExpr*ex, Statement*st)
: cond_(ex), statement_(st)
{
}
PDoWhile::~PDoWhile()
{
delete cond_;
delete statement_;
}
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
: expr_(ee), statement_(0)
{
@@ -336,20 +248,6 @@ PForce::~PForce()
delete expr_;
}
PForeach::PForeach(perm_string av, const list<perm_string>&ix, Statement*s)
: array_var_(av), index_vars_(ix.size()), statement_(s)
{
size_t idx = 0;
for (list<perm_string>::const_iterator cur = ix.begin()
; cur != ix.end() ; ++cur)
index_vars_[idx++] = *cur;
}
PForeach::~PForeach()
{
delete statement_;
}
PForever::PForever(Statement*s)
: statement_(s)
{
@@ -361,8 +259,9 @@ PForever::~PForever()
}
PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
Statement*step, Statement*st)
: name1_(n1), expr1_(e1), cond_(cond), step_(step), statement_(st)
PExpr*n2, PExpr*e2, Statement*st)
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
statement_(st)
{
}
@@ -396,16 +295,6 @@ PRepeat::~PRepeat()
delete statement_;
}
PReturn::PReturn(PExpr*e)
: expr_(e)
{
}
PReturn::~PReturn()
{
delete expr_;
}
PTrigger::PTrigger(const pform_name_t&e)
: event_(e)
{
@@ -415,8 +304,8 @@ PTrigger::~PTrigger()
{
}
PWhile::PWhile(PExpr*ex, Statement*st)
: cond_(ex), statement_(st)
PWhile::PWhile(PExpr*e1, Statement*st)
: cond_(e1), statement_(st)
{
}
+35 -135
View File
@@ -1,7 +1,7 @@
#ifndef IVL_Statement_H
#define IVL_Statement_H
#ifndef __Statement_H
#define __Statement_H
/*
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
*
* 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,12 +16,10 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include <string>
# include <vector>
# include <list>
# include "ivl_target.h"
# include "svector.h"
# include "StringHeap.h"
@@ -31,8 +29,6 @@
# include "HName.h"
# include "LineInfo.h"
class PExpr;
class PChainConstructor;
class PPackage;
class Statement;
class PEventStatement;
class Design;
@@ -44,9 +40,9 @@ class NetScope;
/*
* The PProcess is the root of a behavioral process. Each process gets
* one of these, which contains its type (initial, always, or final)
* and a pointer to the single statement that is the process. A module
* may have several concurrent processes.
* one of these, which contains its type (initial or always) and a
* pointer to the single statement that is the process. A module may
* have several concurrent processes.
*/
class PProcess : public LineInfo {
@@ -106,13 +102,8 @@ class PAssign_ : public Statement {
protected:
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t lv_net_type,
ivl_variable_type_t lv_type,
unsigned lv_width) const;
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const;
NetExpr* elaborate_rval_obj_(Design*, NetScope*,
ivl_variable_type_t type) const;
NetExpr* elaborate_rval_(Design*, NetScope*, unsigned lv_width,
ivl_variable_type_t type) const;
PExpr* delay_;
PEventStatement*event_;
@@ -127,12 +118,7 @@ class PAssign_ : public Statement {
class PAssign : public PAssign_ {
public:
// lval - assignment l-value
// ex - assignment r-value
// op - compressed assignment operator (i.e. '+', '-', ...)
// de - delayed assignment delay expression
explicit PAssign(PExpr*lval, PExpr*ex);
explicit PAssign(PExpr*lval, char op, PExpr*ex);
explicit PAssign(PExpr*lval, PExpr*de, PExpr*ex);
explicit PAssign(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex);
explicit PAssign(PExpr*lval, PExpr*ex, bool is_constant);
@@ -142,8 +128,6 @@ class PAssign : public PAssign_ {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
NetProc* elaborate_compressed_(Design*des, NetScope*scope) const;
char op_;
};
class PAssignNB : public PAssign_ {
@@ -172,30 +156,17 @@ class PAssignNB : public PAssign_ {
class PBlock : public PScope, public Statement {
public:
enum BL_TYPE { BL_SEQ, BL_PAR, BL_JOIN_NONE, BL_JOIN_ANY };
enum BL_TYPE { BL_SEQ, BL_PAR };
// 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);
explicit PBlock(perm_string n, PScope*parent, BL_TYPE t);
// If it doesn't have a name, it's not a scope
explicit PBlock(BL_TYPE t);
~PBlock();
BL_TYPE bl_type() const { return bl_type_; }
// This is only used if this block is the statement list for a
// constructor. We look for a PChainConstructor as the first
// statement, and if it is there, extract it.
PChainConstructor*extract_chain_constructor();
// 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);
// Copy the statement from that block to the front of this
// block.
void push_statement_front(Statement*that);
void set_statement(const svector<Statement*>&st);
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
@@ -203,20 +174,31 @@ class PBlock : public PScope, public Statement {
virtual void elaborate_sig(Design*des, NetScope*scope) const;
private:
BL_TYPE bl_type_;
std::vector<Statement*>list_;
const BL_TYPE bl_type_;
svector<Statement*>list_;
};
class PCallTask : public Statement {
public:
explicit PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&parms);
explicit PCallTask(const pform_name_t&n, const list<PExpr*>&parms);
explicit PCallTask(perm_string n, const list<PExpr*>&parms);
explicit PCallTask(const pform_name_t&n, const svector<PExpr*>&parms);
explicit PCallTask(perm_string n, const svector<PExpr*>&parms);
~PCallTask();
const pform_name_t& path() const;
unsigned nparms() const { return parms_.count(); }
PExpr*&parm(unsigned idx)
{ assert(idx < parms_.count());
return parms_[idx];
}
PExpr* parm(unsigned idx) const
{ assert(idx < parms_.count());
return parms_[idx];
}
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
@@ -224,28 +206,15 @@ 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,
bool add_this_flag = false) const;
NetProc*elaborate_function_(Design*des, NetScope*scope) const;
NetProc*elaborate_build_call_(Design*des, NetScope*scope,
NetScope*task, NetExpr*use_this) const;
NetProc*elaborate_sys_task_method_(Design*des, NetScope*scope,
NetNet*net,
perm_string method_name,
const char*sys_task_name) const;
bool test_task_calls_ok_(Design*des, NetScope*scope) const;
PPackage*package_;
pform_name_t path_;
vector<PExpr*> parms_;
svector<PExpr*> parms_;
};
class PCase : public Statement {
public:
struct Item {
list<PExpr*>expr;
svector<PExpr*>expr;
Statement*stat;
};
@@ -282,26 +251,6 @@ class PCAssign : public Statement {
PExpr*expr_;
};
/*
* This represents the syntax "super.new(...)". This is not really an
* executable statement, but the elaborator will handle these
* specially and will remove them from the statement stream. If any
*/
class PChainConstructor : public Statement {
public:
PChainConstructor(const list<PExpr*>&parms);
~PChainConstructor();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
inline const std::vector<PExpr*>& chain_args(void) const
{ return parms_; }
private:
std::vector<PExpr*> parms_;
};
class PCondit : public Statement {
public:
@@ -369,22 +318,6 @@ class PDisable : public Statement {
pform_name_t scope_;
};
class PDoWhile : public Statement {
public:
PDoWhile(PExpr*ex, Statement*st);
~PDoWhile();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
PExpr*cond_;
Statement*statement_;
};
/*
* The event statement represents the event delay in behavioral
* code. It comes from such things as:
@@ -421,7 +354,6 @@ class PEventStatement : public Statement {
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
NetProc* elaborate_wait(Design*des, NetScope*scope, NetProc*st) const;
NetProc* elaborate_wait_fork(Design*des, NetScope*scope) const;
private:
svector<PEEvent*>expr_;
@@ -444,26 +376,6 @@ class PForce : public Statement {
PExpr*expr_;
};
class PForeach : public Statement {
public:
explicit PForeach(perm_string var, const std::list<perm_string>&ix, Statement*stmt);
~PForeach();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(ostream&out, unsigned ind) const;
private:
NetProc* elaborate_static_array_(Design*des, NetScope*scope,
const std::vector<netrange_t>&dims) const;
private:
perm_string array_var_;
std::vector<perm_string> index_vars_;
Statement*statement_;
};
class PForever : public Statement {
public:
explicit PForever(Statement*s);
@@ -482,7 +394,7 @@ class PForStatement : public Statement {
public:
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
Statement*step, Statement*body);
PExpr*n2, PExpr*e2, Statement*st);
~PForStatement();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
@@ -496,7 +408,8 @@ class PForStatement : public Statement {
PExpr*cond_;
Statement*step_;
PExpr* name2_;
PExpr* expr2_;
Statement*statement_;
};
@@ -536,19 +449,6 @@ class PRelease : public Statement {
PExpr*lval_;
};
class PReturn : public Statement {
public:
explicit PReturn(PExpr*e);
~PReturn();
NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(std::ostream&out, unsigned ind) const;
private:
PExpr*expr_;
};
/*
* The PTrigger statement sends a trigger to a named event. Take the
* name here.
@@ -569,7 +469,7 @@ class PTrigger : public Statement {
class PWhile : public Statement {
public:
PWhile(PExpr*ex, Statement*st);
PWhile(PExpr*e1, Statement*st);
~PWhile();
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
@@ -582,4 +482,4 @@ class PWhile : public Statement {
Statement*statement_;
};
#endif /* IVL_Statement_H */
#endif
+34 -42
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2004 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,20 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.cc,v 1.6 2004/02/18 17:11:54 steve Exp $"
#endif
# include "StringHeap.h"
# include <iostream>
# include <cstdlib>
# include <cstring>
# include <cassert>
#ifdef CHECK_WITH_VALGRIND
# include "ivl_alloc.h"
static char **string_pool = NULL;
static unsigned string_pool_count = 0;
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include <string.h>
# include <assert.h>
StringHeap::StringHeap()
{
@@ -50,12 +49,6 @@ const char* StringHeap::add(const char*text)
unsigned rem = HEAPCELL - cell_ptr_;
if (rem < (len+1)) {
cell_base_ = (char*)malloc(HEAPCELL);
#ifdef CHECK_WITH_VALGRIND
string_pool_count += 1;
string_pool = (char **) realloc(string_pool,
string_pool_count*sizeof(char **));
string_pool[string_pool_count-1] = cell_base_;
#endif
cell_ptr_ = 0;
cell_count_ += 1;
assert(cell_base_ != 0);
@@ -90,22 +83,6 @@ StringHeapLex::~StringHeapLex()
{
}
void StringHeapLex::cleanup()
{
#ifdef CHECK_WITH_VALGRIND
for (unsigned idx = 0 ; idx < string_pool_count ; idx += 1) {
free(string_pool[idx]);
}
free(string_pool);
string_pool = NULL;
string_pool_count = 0;
for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1) {
hash_table_[idx] = 0;
}
#endif
}
unsigned StringHeapLex::add_hit_count() const
{
return hit_count_;
@@ -202,13 +179,28 @@ bool operator < (perm_string a, perm_string b)
return false;
}
ostream& operator << (ostream&out, perm_string that)
{
if (that.nil())
out << "<nil>";
else
out << that.str();
return out;
}
/*
* $Log: StringHeap.cc,v $
* Revision 1.6 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.5 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.4 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.3 2003/01/16 21:44:46 steve
* Keep some debugging status.
*
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/08/04 19:13:16 steve
* dll uses StringHeap for named items.
*
*/
const perm_string empty_perm_string = perm_string::literal("");
+34 -11
View File
@@ -1,7 +1,7 @@
#ifndef IVL_StringHeap_H
#define IVL_StringHeap_H
#ifndef __StringHeap_H
#define __StringHeap_H
/*
* Copyright (c) 2002-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2004 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,9 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: StringHeap.h,v 1.6 2005/06/14 19:13:43 steve Exp $"
#endif
# include "config.h"
# include <string>
using namespace std;
@@ -30,8 +34,6 @@ class perm_string {
perm_string(const perm_string&that) : text_(that.text_) { }
~perm_string() { }
inline bool nil() const { return text_ == 0; }
perm_string& operator = (const perm_string&that)
{ text_ = that.text_; return *this; }
@@ -39,7 +41,7 @@ class perm_string {
operator const char* () const { return str(); }
// This is an escape for making perm_string objects out of
// literals. For example, perm_string::literal("Label"); Please
// literals. For example, per_string::literal("Label"); Please
// do *not* cheat and pass arbitrary const char* items here.
static perm_string literal(const char*t) { return perm_string(t); }
@@ -52,7 +54,6 @@ class perm_string {
const char*text_;
};
extern const perm_string empty_perm_string;
extern bool operator == (perm_string a, perm_string b);
extern bool operator == (perm_string a, const char* b);
extern bool operator != (perm_string a, perm_string b);
@@ -61,7 +62,6 @@ extern bool operator > (perm_string a, perm_string b);
extern bool operator < (perm_string a, perm_string b);
extern bool operator >= (perm_string a, perm_string b);
extern bool operator <= (perm_string a, perm_string b);
extern ostream& operator << (ostream&out, perm_string that);
/*
* The string heap is a way to permanently allocate strings
@@ -107,7 +107,6 @@ class StringHeapLex : private StringHeap {
unsigned add_count() const;
unsigned add_hit_count() const;
void cleanup();
private:
enum { HASH_SIZE = 4096 };
@@ -121,4 +120,28 @@ class StringHeapLex : private StringHeap {
StringHeapLex& operator= (const StringHeapLex&);
};
#endif /* IVL_StringHeap_H */
/*
* $Log: StringHeap.h,v $
* Revision 1.6 2005/06/14 19:13:43 steve
* gcc3/4 compile errors.
*
* Revision 1.5 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.4 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.3 2003/01/16 21:44:46 steve
* Keep some debugging status.
*
* Revision 1.2 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.1 2002/08/04 19:13:16 steve
* dll uses StringHeap for named items.
*
*/
#endif
+46 -5
View File
@@ -1,7 +1,7 @@
#ifndef PLI_TYPES_H
#define PLI_TYPES_H
#ifndef PLI_TYPES
#define PLI_TYPES
/*
* Copyright (c) 2003-2014 Stephen Williams ([email protected])
* Copyright (c) 2003 Stephen Williams ([email protected])
*
* 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,8 +16,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: _pli_types.h.in,v 1.8 2007/06/05 21:32:30 steve Exp $"
#endif
# undef HAVE_INTTYPES_H
@@ -85,4 +88,42 @@ typedef char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
#endif
#endif /* PLI_TYPES_H */
/*
* $Log: _pli_types.h.in,v $
* Revision 1.8 2007/06/05 21:32:30 steve
* More standard PLI_BYTE8.
*
* Revision 1.7 2003/11/12 02:38:44 steve
* Clean up manual definitions of PLI_UINT64_FMT.
*
* Revision 1.6 2003/11/08 20:06:21 steve
* Spelling fixes in comments.
*
* Revision 1.5 2003/10/29 03:28:27 steve
* Add the PLU_UINT64_FMT string for formatting output.
*
* Revision 1.4 2003/10/29 03:23:12 steve
* Portably handle time format of VCD prints.
*
* Revision 1.3 2003/10/02 21:30:06 steve
* Use configured TIME_FMT in vcd dump printf.
*
* Revision 1.2 2003/10/02 19:33:44 steve
* Put libraries in libdir64.
*
* Revision 1.1 2003/09/30 01:33:13 steve
* Add PLI_UINT64 to _pli_types.h.
*
* Revision 1.2 2003/05/26 04:39:16 steve
* Typo type name.
*
* Revision 1.1 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
*/
#endif
+87 -7
View File
@@ -1,7 +1,7 @@
#ifndef ACC_USER_H
#define ACC_USER_H
#ifndef __acc_user_H
#define __acc_user_H
/*
* Copyright (c) 2002-2014 Stephen Williams ([email protected])
* Copyright (c) 2002 Stephen Williams ([email protected])
*
* 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,8 +16,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: acc_user.h,v 1.20 2003/12/17 15:45:07 steve Exp $"
#endif
/*
* This header file contains the definitions and declarations needed
@@ -228,9 +231,8 @@ extern PLI_INT32 acc_fetch_size(handle obj);
extern PLI_INT32 acc_fetch_type(handle obj);
extern PLI_INT32 acc_fetch_fulltype(handle obj);
extern PLI_INT32 acc_fetch_paramtype(handle obj);
extern PLI_INT32 acc_fetch_range(handle object, int *msb, int *lsb);
extern const char* acc_fetch_type_str(PLI_INT32 type);
extern char* acc_fetch_type_str(PLI_INT32 type);
extern char* acc_fetch_value(handle obj, const char*fmt, s_acc_value*value);
@@ -271,4 +273,82 @@ extern char* acc_version(void);
EXTERN_C_END
#endif /* ACC_USER_H */
/*
* $Log: acc_user.h,v $
* Revision 1.20 2003/12/17 15:45:07 steve
* Add acc_set_scope function.
*
* Revision 1.19 2003/10/10 02:57:45 steve
* Some PLI1 stubs.
*
* Revision 1.18 2003/06/13 19:23:41 steve
* Add a bunch more PLI1 routines.
*
* Revision 1.17 2003/06/04 01:56:20 steve
* 1) Adds configure logic to clean up compiler warnings
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
* tf_isetrealdelay, acc_handle_scope
* 3) makes acc_next reentrant
* 4) adds basic vpiWire type support
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
* 6) add vpiLeftRange/RigthRange to signals
*
* Revision 1.16 2003/05/30 04:18:31 steve
* Add acc_next function.
*
* Revision 1.15 2003/05/29 02:35:41 steve
* acc_fetch_type supports module.
*
* Revision 1.14 2003/05/29 02:21:45 steve
* Implement acc_fetch_defname and its infrastructure in vvp.
*
* Revision 1.13 2003/05/24 03:02:04 steve
* Add implementation of acc_handle_by_name.
*
* Revision 1.12 2003/05/18 00:16:35 steve
* Add PLI_TRACE tracing of PLI1 modules.
*
* Add tf_isetdelay and friends, and add
* callback return values for acc_vcl support.
*
* Revision 1.11 2003/04/24 18:57:05 steve
* Add acc_fetch_fulltype function.
*
* Revision 1.10 2003/04/20 02:48:39 steve
* Support value change callbacks.
*
* Revision 1.9 2003/04/12 18:57:13 steve
* More acc_ function stubs.
*
* Revision 1.8 2003/03/13 04:35:09 steve
* Add a bunch of new acc_ and tf_ functions.
*
* Revision 1.7 2003/02/17 06:39:47 steve
* Add at least minimal implementations for several
* acc_ functions. Add support for standard ACC
* string handling.
*
* Add the _pli_types.h header file to carry the
* IEEE1364-2001 standard PLI type declarations.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2002/06/11 15:19:12 steve
* Add acc_fetch_argc/argv/version (mruff)
*
* Revision 1.4 2002/06/07 02:58:58 steve
* Add a bunch of acc/tf functions. (mruff)
*
* Revision 1.3 2002/06/02 19:03:29 steve
* Add acc_handle_tfarg and acc_next_topmode
*
* Revision 1.2 2002/05/30 02:06:05 steve
* Implement acc_product_version.
*
* Revision 1.1 2002/05/23 03:46:42 steve
* Add the acc_user.h header file.
*
*/
#endif
Vendored
+43 -82
View File
@@ -1,23 +1,29 @@
# AX_ENABLE_SUFFIX
# ----------------
# Create the configure option --enable-suffix[=suffix] to generate suffix
# strings for the installed commands. This allows for shared installs of
# different builds. Remember to change the default suffix string to some
# value appropriate for the current version.
AC_DEFUN([AX_ENABLE_SUFFIX],
[AC_ARG_ENABLE([suffix],[AC_HELP_STRING([--enable-suffix],
[Use/set the installation command suffix])],
[true],[enable_suffix=no])
if test X$enable_suffix = Xyes; then
install_suffix='-0.10'
elif test X$enable_suffix = Xno; then
install_suffix=''
else
install_suffix="$enable_suffix"
# AX_CPP_IDENT
# ------------
# Check if the C compiler supports #ident
# Define and substitute ident_support if so.
#
# It would be simpler and more consistent with the rest of the autoconf
# structure to AC_DEFINE(HAVE_CPP_IDENT) instead of
# ident_support='-DHAVE_CVS_IDENT=1' and AC_SUBST(ident_support), but that
# change would require all C files in the icarus top level directory to
# put #include <config.h> before the #ifdef HAVE_CVS_IDENT (and change
# HAVE_CVS_IDENT to HAVE_CPP_IDENT). That would also remove all special
# ident_support handling from the Makefile. Manyana.
#
AC_DEFUN([AX_CPP_IDENT],
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
[AC_TRY_COMPILE([
#ident "$Id: aclocal.m4,v 1.7 2007/05/16 23:59:12 steve Exp $"
],[while (0) {}],
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
if test $ax_cv_cpp_ident = yes; then
ident_support='-DHAVE_CVS_IDENT=1'
fi
AC_SUBST(install_suffix)
])# AX_ENABLE_SUFFIX
AC_SUBST(ident_support)
])# AC_CPP_IDENT
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
# ------------------------------
@@ -26,7 +32,7 @@ AC_SUBST(install_suffix)
# - the object file produced by AC_COMPILE_IFELSE is called "conftest.$ac_objext"
# - the nm(1) utility is available, and its name is "nm".
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF],
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([void underscore(void){}])],
[AC_COMPILE_IFELSE([void underscore(void){}],
[AS_IF([nm conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
[AC_MSG_ERROR([underscore test crashed])]
)])
@@ -64,24 +70,19 @@ fi
# AX_WIN32
# --------
# Combined check for several flavors of Microsoft Windows so
# their "issues" can be dealt with
# their "issues" can be dealt with
AC_DEFUN([AX_WIN32],
[AC_MSG_CHECKING([for Microsoft Windows])
AC_REQUIRE([AC_CANONICAL_HOST]) []dnl
case $host_os in
*cygwin*) MINGW32=no; WIN32=yes;;
*mingw*) MINGW32=yes; WIN32=yes;;
*) MINGW32=no; WIN32=no;;
esac
[AC_CYGWIN
AC_MINGW32
WIN32=no
AC_MSG_CHECKING([for Microsoft Windows])
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
then
WIN32=yes
fi
AC_SUBST(MINGW32)
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
if test $WIN32 = yes; then
AC_MSG_CHECKING([for MinGW])
AC_MSG_RESULT($MINGW32)
fi
])# AX_WIN32
# AX_LD_EXTRALIBS
@@ -112,10 +113,6 @@ case "${host}" in
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-mingw*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
@@ -127,13 +124,6 @@ case "${host}" in
*-*-darwin*)
shared="-bundle -undefined suppress -flat_namespace"
;;
*-*-solaris*)
if test ${using_sunpro_c} = 1
then
shared="-G"
fi
;;
esac
AC_SUBST(shared)
AC_MSG_RESULT($shared)
@@ -152,20 +142,10 @@ case "${host}" in
PICFLAG=
;;
*-*-mingw*)
PICFLAG=
;;
*-*-hpux*)
PICFLAG=+z
;;
*-*-solaris*)
if test ${using_sunpro_c} = 1
then
PICFLAG=-G
fi
;;
esac
AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
@@ -197,10 +177,6 @@ case "${host}" in
rdynamic=""
;;
*-*-mingw*)
rdynamic=""
;;
*-*-hpux*)
rdynamic="-E"
;;
@@ -218,29 +194,14 @@ AC_SUBST(strip_dynamic)
# AC_MSG_RESULT($strip_dynamic)
])# AX_LD_RDYNAMIC
# AX_C99_STRTOD
# -------------
AC_DEFUN([AX_C99_STRTOD],
[# On MinGW we need to jump through hoops to get a C99 compliant strtod().
# mingw-w64 doesn't need this, and the 64-bit version doesn't support it.
# AX_CPP_PRECOMP
# --------------
AC_DEFUN([AX_CPP_PRECOMP],
[# Darwin requires -no-cpp-precomp
case "${host}" in
*-*-mingw32)
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
*-*-darwin*)
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
CFLAGS="-no-cpp-precomp $CFLAGS"
;;
esac
])# AX_C99_STRTOD
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp file name are based on the header name.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[
_config_header=$1
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
]) #_AC_AM_CONFIG_HEADER_HOOK
])# AX_CPP_PRECOMP
+6 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2010 Stephen Williams ([email protected])
* Copyright (c) 2002-2008 Stephen Williams ([email protected])
*
* 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,14 +14,14 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "functor.h"
# include "netlist.h"
# include <cassert>
# include <assert.h>
bool NetAssign::is_asynchronous()
{
@@ -50,8 +50,8 @@ bool NetEvWait::is_asynchronous()
level sensitive, but the nex_async_ method takes care of
that test. */
NexusSet*sense = new NexusSet;
for (unsigned idx = 0 ; idx < events_.size() ; idx += 1) {
NexusSet*tmp = events_[idx]->nex_async_();
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
NexusSet*tmp = event(idx)->nex_async_();
if (tmp == 0) {
delete sense;
return false;
@@ -82,7 +82,7 @@ bool NetProc::is_asynchronous()
return false;
}
bool NetProcTop::is_asynchronous() const
bool NetProcTop::is_asynchronous()
{
if (type_ == IVL_PR_INITIAL)
return false;
+10 -7
View File
@@ -2,15 +2,18 @@
#
# This shell script exists to run autoconf on source distributions
# 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.
# 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.
#
echo "Autoconf in root..."
autoconf -f
echo "Precompiling lexor_keyword.gperf"
gperf -o -i 7 -C -k 1-4,6,9,\$ -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
for dir in vpi vvp tgt-vvp tgt-fpga tgt-stub tgt-vhdl libveriuser cadpli
do
echo "Autoconf in $dir..."
( cd ./$dir ; autoconf -f --include=.. )
done
echo "Precompiling vhdlpp/lexor_keyword.gperf"
(cd vhdlpp ; gperf -o -i 7 --ignore-case -C -k 1-4,6,9,\$ -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc )
echo "Precompiling lexor_keyword.gperf"
gperf -o -i 7 -C -k 1-4,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
+7
View File
@@ -0,0 +1,7 @@
Makefile
cadpli.vpl
dep
configure
config.log
config.status
autom4te.cache
+26 -32
View File
@@ -12,12 +12,13 @@
#
# 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., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
SHELL = /bin/sh
suffix = @install_suffix@
VERSION = 0.9.devel
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -29,66 +30,59 @@ bindir = @bindir@
libdir = @libdir@
includedir = $(prefix)/include
vpidir = @libdir@/ivl$(suffix)
vpidir = @libdir@/ivl
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
ifeq (@srcdir@,.)
INCLUDE_PATH = -I. -I..
else
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
endif
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
O = cadpli.o
SHARED = @shared@
all:
all: dep cadpli.vpl $(ALL32)
# No specific check operations.
check: all
clean:
rm -rf *.o dep cadpli.vpl
distclean: clean
rm -f Makefile config.log
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=cadpli/$@
dep:
mkdir dep
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $<
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $<
mv $*.d dep
O = cadpli.o
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
ifeq (@MINGW32@,yes)
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
endif
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
$(CC) @shared@ $(LDFLAGS) -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
$(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
install: all installdirs $(vpidir)/cadpli.vpl
clean:
rm -rf *.o dep cadpli.vpl bin32
distclean: clean
rm -f Makefile config.status config.log config.cache
install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32)
$(vpidir)/cadpli.vpl: ./cadpli.vpl
$(INSTALL_PROGRAM) ./cadpli.vpl "$(DESTDIR)$(vpidir)/cadpli.vpl"
$(INSTALL_PROGRAM) ./cadpli.vpl $(DESTDIR)$(vpidir)/cadpli.vpl
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(vpidir)"
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(DESTDIR)$(vpidir)
uninstall: $(UNINSTALL32)
rm -f "$(DESTDIR)$(vpidir)/cadpli.vpl"
rm -f $(DESTDIR)$(vpidir)/cadpli.vpl
uninstall32:
+40 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2010 Stephen Williams ([email protected])
* Copyright (c) 2003 Stephen Williams ([email protected])
*
* 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,17 +14,21 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cadpli.c,v 1.7 2004/09/10 00:15:45 steve Exp $"
#endif
# include <vpi_user.h>
# include <veriuser.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <string.h>
# include <assert.h>
# include "config.h"
# include "ivl_dlfcn.h"
# include "ivl_alloc.h"
typedef void* (*funcvp)(void);
@@ -79,7 +83,38 @@ static void thunker_register(void)
}
}
void (*vlog_startup_routines[])(void) = {
void (*vlog_startup_routines[])() = {
thunker_register,
0
};
/*
* $Log: cadpli.c,v $
* Revision 1.7 2004/09/10 00:15:45 steve
* Remove bad casts.
*
* Revision 1.6 2004/09/05 21:19:51 steve
* Better type safety.
*
* Revision 1.5 2003/08/26 16:26:02 steve
* ifdef idents correctly.
*
* Revision 1.4 2003/04/30 01:28:06 steve
* Remove veriusertfs stuf.
*
* Revision 1.3 2003/02/22 04:04:38 steve
* Only include malloc.h if it is present.
*
* Revision 1.2 2003/02/17 00:01:25 steve
* Use a variant of ivl_dlfcn to do dynamic loading
* from within the cadpli module.
*
* Change the +cadpli flag to -cadpli, to keep the
* plusargs namespace clear.
*
* Revision 1.1 2003/02/16 02:23:54 steve
* Add the cadpli interface module.
*
*/
+13
View File
@@ -2,6 +2,7 @@
CADENCE PLI1 MODULES
Copyright 2003 Stephen Williams
$Id: cadpli.txt,v 1.2 2003/02/17 00:01:25 steve Exp $
With the cadpli module, Icarus Verilog is able to load PLI1
applications that were compiled and linked to be dynamic loaded by
@@ -33,3 +34,15 @@ the +loadpli1= argument to Verilog-XL.
The integration from this point is seamless. The PLI application
hardly knows that it is being invoked by Icarus Verilog instead of
Verilog-XL, so operates as it would otherwise.
$Log: cadpli.txt,v $
Revision 1.2 2003/02/17 00:01:25 steve
Use a variant of ivl_dlfcn to do dynamic loading
from within the cadpli module.
Change the +cadpli flag to -cadpli, to keep the
plusargs namespace clear.
Revision 1.1 2003/02/16 02:44:47 steve
Add the cadpli HOWTO.
+61
View File
@@ -0,0 +1,61 @@
AC_INIT(Makefile.in)
AC_PROG_CC
AC_PROG_CXX
AC_CHECK_TOOL(STRIP, strip, true)
AC_EXEEXT
AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
AC_PROG_INSTALL
AC_CHECK_HEADERS(malloc.h)
AC_CHECK_SIZEOF(unsigned long long)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned)
# --
# Look for a dl library to use. First look for the standard dlopen
# functions, and failing that look for the HP specific shl_load function.
AC_CHECK_HEADERS(dlfcn.h dl.h, break)
DLLIB=''
AC_CHECK_LIB(dl,dlopen,[DLLIB=-ldl])
if test -z "$DLLIB" ; then
AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
fi
AC_SUBST(DLLIB)
AX_CPP_PRECOMP
# Compiler option for position independent code, needed when making shared objects.
AX_C_PICFLAG
# Linker option used when compiling the target
AX_LD_RDYNAMIC
# linker options when building a shared library
AX_LD_SHAREDLIB_OPTS
AX_LD_EXTRALIBS
#######################
## test for underscores. The vpi module loader in vvm needs to know this
## in order to know the name of the start symbol for the .vpi module.
#######################
AX_C_UNDERSCORES_LEADING
AX_C_UNDERSCORES_TRAILING
#######################
## end of test for underscores
#######################
AX_CPP_IDENT
AC_OUTPUT(Makefile)
+24 -5
View File
@@ -1,7 +1,7 @@
#ifndef IVL_ivl_dlfcn_H
#define IVL_ivl_dlfcn_H
#ifndef __ivl_dlfcn_H
#define __ivl_dlfcn_H
/*
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* 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,8 +16,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_dlfcn.h,v 1.3 2004/10/04 01:10:56 steve Exp $"
#endif
#if defined(__MINGW32__)
# include <windows.h>
@@ -91,4 +94,20 @@ static __inline__ const char*dlerror(void)
{ return strerror( errno ); }
#endif
#endif /* IVL_ivl_dlfcn_H */
/*
* $Log: ivl_dlfcn.h,v $
* Revision 1.3 2004/10/04 01:10:56 steve
* Clean up spurious trailing white space.
*
* Revision 1.2 2003/12/12 05:43:08 steve
* Some systems dlsym requires leading _ or not on whim.
*
* Revision 1.1 2003/02/17 00:01:25 steve
* Use a variant of ivl_dlfcn to do dynamic loading
* from within the cadpli module.
*
* Change the +cadpli flag to -cadpli, to keep the
* plusargs namespace clear.
*
*/
#endif
+11 -110
View File
@@ -1,7 +1,7 @@
#ifndef IVL_compiler_H
#define IVL_compiler_H
#ifndef __compiler_H
#define __compiler_H
/*
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include <list>
@@ -36,17 +36,6 @@
*/
extern unsigned integer_width;
/*
* The width_cap is the width limit for unsized expressions.
*/
extern unsigned width_cap;
/*
* This is the maximum number of recursive module loops allowed within
* a generate block.
*/
extern unsigned recursive_mod_limit;
/* The TIME_WIDTH is the width of time variables. */
#ifndef TIME_WIDTH
# define TIME_WIDTH 64
@@ -79,6 +68,7 @@ extern unsigned recursive_mod_limit;
/* Implicit definitions of wires. */
extern bool warn_implicit;
extern bool error_implicit;
/* inherit timescales across files. */
extern bool warn_timescale;
@@ -86,48 +76,18 @@ extern bool warn_timescale;
/* Warn about legal but questionable module port bindings. */
extern bool warn_portbinding;
/* Warn about constant out of bound selects. */
extern bool warn_ob_select;
/* Warn about structures that may have infinite loops. */
extern bool warn_inf_loop;
/* Warn about always @* statements where a part or word select causes
sensitivity to an entire vector or array. */
extern bool warn_sens_entire_vec;
extern bool warn_sens_entire_arr;
/* Warn about level-appropriate anachronisms. */
extern bool warn_anachronisms;
/* This is true if verbose output is requested. */
extern bool verbose_flag;
extern bool debug_scopes;
extern bool debug_eval_tree;
extern bool debug_elaborate;
extern bool debug_emit;
extern bool debug_synth2;
extern bool debug_optimizer;
/* Control evaluation of functions at compile time:
* 0 = only for functions in constant expressions
* 1 = only for automatic functions
* 2 = for all functions
* Level 2 should only be used if the user can guarantee that a
* function's local variables are never accessed from outside the
* function. */
extern unsigned opt_const_func;
/* Possibly temporary flag to control virtualization of pin arrays */
extern bool disable_virtual_pins;
/* The vlog95 code generator does not want the compiler to generate concat-Z
* LPM objects so this flag is used to block them from being generated. */
extern bool disable_concatz_generation;
/* Limit to size of devirtualized arrays */
extern unsigned long array_size_limit;
extern bool debug_automatic;
/* Path to a directory useful for finding subcomponents. */
extern const char*basedir;
@@ -141,13 +101,9 @@ extern int build_library_index(const char*path, bool key_case_sensitive);
specific language features. */
enum generation_t {
GN_VER1995 = 1,
GN_VER2001_NOCONFIG = 2,
GN_VER2001 = 3,
GN_VER2005 = 4,
GN_VER2005_SV = 5,
GN_VER2009 = 6,
GN_VER2012 = 7,
GN_DEFAULT = 4
GN_VER2001 = 2,
GN_VER2005 = 3,
GN_DEFAULT = 3
};
extern generation_t generation_flag;
@@ -162,10 +118,6 @@ extern bool gn_icarus_misc_flag;
is false, then skip elaboration of specify behavior. */
extern bool gn_specify_blocks_flag;
/* If this flag is true, then elaborate assertions. If this flag is
false, then stub out assertion statements. */
extern bool gn_assertions_flag;
/* If this flag is true, then support/elaborate Verilog-AMS. */
extern bool gn_verilog_ams_flag;
@@ -173,41 +125,6 @@ extern bool gn_verilog_ams_flag;
is scalar and the net/register definition is vectored. */
extern bool gn_io_range_error_flag;
/* If this flag is true, then force re-evaluation of user functions
in a continuous assignment when any part of the expression is
re-evaluated. */
extern bool gn_strict_ca_eval_flag;
/* If this flag is true, then force strict conformance to the IEEE
standard expression width rules. */
extern bool gn_strict_expr_width_flag;
/* If variables can be converted to uwires by a continuous assignment
(assuming no procedural assign, then return true. This will be true
for SystemVerilog */
static inline bool gn_var_can_be_uwire(void)
{
if (generation_flag == GN_VER2005_SV ||
generation_flag == GN_VER2009 ||
generation_flag == GN_VER2012)
return true;
return false;
}
static inline bool gn_system_verilog(void)
{
if (generation_flag == GN_VER2005_SV ||
generation_flag == GN_VER2009 ||
generation_flag == GN_VER2012)
return true;
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
@@ -217,9 +134,6 @@ enum { GN_KEYWORDS_1364_1995 = 0x0001,
GN_KEYWORDS_1364_2001_CONFIG = 0x0004,
GN_KEYWORDS_1364_2005 = 0x0008,
GN_KEYWORDS_VAMS_2_3 = 0x0010,
GN_KEYWORDS_1800_2005 = 0x0020,
GN_KEYWORDS_1800_2009 = 0x0040,
GN_KEYWORDS_1800_2012 = 0x0080,
GN_KEYWORDS_ICARUS = 0x8000
};
extern int lexor_keyword_mask;
@@ -242,12 +156,7 @@ extern map<perm_string,bool> library_file_map;
* much sense to use a StringHeapLex to hold them.
*/
extern StringHeapLex lex_strings;
/*
* The ivl_target.h API in a variety of places keeps strings of
* bits. Manage these as perm_string in a StringHeap.
*/
extern StringHeapLex bits_strings;
extern StringHeap misc_strings;
/*
* The filename_strings are perm_strings for file names. They are put
@@ -274,13 +183,5 @@ struct sfunc_return_type {
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
extern int load_sys_func_table(const char*path);
extern void cleanup_sys_func_table();
/*
* In system Verilog it is allowed with a warning to call a function
* as a task. You can even cast the return value away and have no
* warning message.
*/
extern ivl_sfunc_as_task_t def_sfunc_as_task;
#endif /* IVL_compiler_H */
#endif
+675 -749
View File
File diff suppressed because it is too large Load Diff
+47 -16
View File
@@ -1,7 +1,7 @@
#ifndef IVL_config_H /* -*- c++ -*- */
#define IVL_config_H
#ifndef __config_H /* -*- c++ -*- */
#define __config_H
/*
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* 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,8 +16,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: config.h.in,v 1.12 2007/02/02 04:33:00 steve Exp $"
#endif
#if defined(__cplusplus)
# if !defined(__GNUC__)
@@ -36,13 +39,13 @@
# undef HAVE_GETOPT_H
# undef HAVE_INTTYPES_H
# undef HAVE_LIBIBERTY_H
# undef HAVE_MALLOC_H
# undef HAVE_DLFCN_H
# undef HAVE_DL_H
# undef HAVE_FCHMOD
# undef HAVE_LIBREADLINE
# undef HAVE_LIBZ
# undef HAVE_LIBBZ2
# undef HAVE_LROUND
# undef HAVE_SYS_WAIT_H
# undef WORDS_BIGENDIAN
@@ -50,16 +53,44 @@
# include <inttypes.h>
#endif
/* 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
* special valgrind hooks for the memory pools.
* $Log: config.h.in,v $
* Revision 1.12 2007/02/02 04:33:00 steve
* Use inttypes.h instead of stdint.h for portability.
*
* Revision 1.11 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.10 2003/08/26 16:26:01 steve
* ifdef idents correctly.
*
* Revision 1.9 2003/07/03 16:29:55 steve
* spemm WORDS_BIGENDIAN correctly.
*
* Revision 1.8 2003/03/07 02:44:33 steve
* Implement $realtobits.
*
* Revision 1.7 2003/02/20 00:49:24 steve
* detect -lz and -lbz2 libraries.
*
* Revision 1.6 2003/01/10 19:01:04 steve
* Only use libiberty.h if available.
*
* Revision 1.5 2002/08/11 23:39:33 steve
* Remove VVM option.
*
* Revision 1.4 2002/02/16 03:18:53 steve
* Make vvm optional, normally off.
*
* Revision 1.3 2001/10/18 16:16:23 steve
* Include HAVE_SYS_WAIT in config.h (PR#306)
*
* Revision 1.2 2001/09/15 18:27:04 steve
* Make configure detect malloc.h
*
* Revision 1.1 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
*/
# undef CHECK_WITH_VALGRIND
#endif /* IVL_config_H */
#endif /* __config_H */
Vendored
+138 -491
View File
File diff suppressed because it is too large Load Diff
+10 -209
View File
@@ -2,27 +2,12 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(netlist.h)
AC_CONFIG_HEADER(config.h)
AC_CONFIG_HEADER(_pli_types.h)
AC_CONFIG_HEADER(vhdlpp/vhdlpp_config.h)
AC_CONFIG_HEADER(vvp/config.h)
AC_CONFIG_HEADER(vpi/vpi_config.h)
AC_CONFIG_HEADER(libveriuser/config.h)
AC_CONFIG_HEADER(tgt-vvp/vvp_config.h)
AC_CONFIG_HEADER(tgt-vhdl/vhdl_config.h)
AC_CONFIG_HEADER(tgt-pcb/pcb_config.h)
AC_CANONICAL_HOST
dnl Checks for programs.
AC_PROG_CC
# AC_PROG_CC_C99 is only available in autoconf version 2.60 and later.
AC_PREREQ([2.60])
AC_PROG_CC_C99
AC_PROG_CXX
AC_PROG_RANLIB
AC_CHECK_TOOL(LD, ld, false)
AC_CHECK_TOOL(AR, ar, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(STRIP, strip, true)
AC_CHECK_TOOL(WINDRES,windres,false)
AC_CHECK_PROGS(XGPERF,gperf,none)
AC_CHECK_PROGS(MAN,man,none)
AC_CHECK_PROGS(PS2PDF,ps2pdf,none)
@@ -32,7 +17,7 @@ then
echo ""
echo "*** Warning: No suitable gperf found. ***"
echo " The gperf package is essential for building ivl from"
echo " git sources, or modifying the parse engine of ivl itself."
echo " CVS 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 ""
@@ -60,87 +45,10 @@ AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32
# Check to see if we are using the Sun compiler. If so then configure
# some of the flags to match the Sun compiler syntax. This is also used
# in the aclocal.m4 file to configure the flags used to build and link
# dynamic libraries
AC_CHECK_DECL(__SUNPRO_C, using_sunpro_c=1, using_sunpro_c=0)
if test ${using_sunpro_c} = 1
then
AC_SUBST(DEPENDENCY_FLAG, [-xMMD])
AC_SUBST(WARNING_FLAGS, [""])
AC_SUBST(WARNING_FLAGS_CXX, [""])
else
# Check to see if -Wextra is supported.
iverilog_temp_cflags="$CFLAGS"
CFLAGS="-Wextra $CFLAGS"
AC_MSG_CHECKING(if gcc supports -Wextra)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[[iverilog_wextra_flag="-Wextra";] AC_MSG_RESULT(yes)],
[[iverilog_wextra_flag="-W";] AC_MSG_RESULT(no)])
CFLAGS="$iverilog_temp_cflags"
AC_LANG_CPLUSPLUS
AC_SUBST(DEPENDENCY_FLAG, [-MD])
AC_SUBST(WARNING_FLAGS, ["-Wall $iverilog_wextra_flag -Wshadow"])
AC_SUBST(WARNING_FLAGS_CC, ["-Wstrict-prototypes"])
AC_SUBST(WARNING_FLAGS_CXX, [""])
fi
AC_CHECK_HEADERS(getopt.h malloc.h inttypes.h libiberty.h iosfwd sys/wait.h)
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)
if test ${using_sunpro_c} = 1
then
if test ${using_sunpro_cc} = 0
then
echo "*** Error: No support for mixing GNU and Sun compilers. ***"
echo " Using Sun C compiler and GNU C++ compiler.."
exit 1
fi
else
if test ${using_sunpro_cc} = 1
then
echo "*** Error: No support for mixing GNU and Sun compilers. ***"
echo " Using GNU C compiler and Sun C++ compiler.."
exit 1
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)
AC_CHECK_SIZEOF(unsigned)
# vvp uses these...
AC_CHECK_LIB(termcap, tputs)
AC_CHECK_LIB(readline, readline)
AC_CHECK_LIB(history, add_history)
AC_CHECK_HEADERS(readline/readline.h readline/history.h sys/resource.h)
case "${host}" in *linux*) AC_DEFINE([LINUX], [1], [Host operating system is Linux.]) ;; esac
# vpi uses these
AC_CHECK_LIB(pthread, pthread_create)
AC_CHECK_LIB(z, gzwrite)
AC_CHECK_LIB(z, gzwrite, HAVE_LIBZ=yes, HAVE_LIBZ=no)
AC_SUBST(HAVE_LIBZ)
@@ -153,23 +61,6 @@ AC_CHECK_LIB(bz2, BZ2_bzdopen, HAVE_LIBBZ2=yes, HAVE_LIBBZ2=no)
fi
AC_SUBST(HAVE_LIBBZ2)
# The lxt/lxt2 files from GTKWave use these...
AC_FUNC_ALLOCA
AC_FUNC_FSEEKO
# valgrind checks
AC_ARG_WITH([valgrind], [AC_HELP_STRING([--with-valgrind],
[Add valgrind hooks])],
[], [check_valgrind=yes])
AS_IF([test "x$check_valgrind" = xyes],
[AC_MSG_NOTICE([Not using valgrind hooks])],
[AC_CHECK_HEADER([valgrind/memcheck.h],
[AC_DEFINE([CHECK_WITH_VALGRIND], [1],
[Define to one to use the valgrind hooks])],
[AC_MSG_ERROR([Could not find <valgrind/memcheck.h>])])])
AC_MSG_CHECKING(for sys/times)
AC_TRY_LINK(
#include <unistd.h>
@@ -193,92 +84,22 @@ 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
AC_LANG(C)
AC_LANG_C
AC_C_BIGENDIAN
# $host
AX_ENABLE_SUFFIX
AX_LD_EXTRALIBS
# Compiler option for position independent code, needed when making shared objects.
# CFLAGS inherited by cadpli/Makefile?
AX_C_PICFLAG
# may modify LDFLAGS
AX_C99_STRTOD
# Processor specific compile flags
case "${host}" in
alpha*-*-linux*)
CPPFLAGS="-mieee $CPPFLAGS"
CFLAGS="-mieee $CFLAGS"
;;
*-*-mingw*)
CXXFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CXXFLAGS"
CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CFLAGS"
;;
esac
# Do some more operating system specific setup. We put the file64_support
# define in a substitution instead of simply a define because there
# are source files (namely lxt support files) that don't include any
# config.h header file.
file64_support=''
case "${host}" in
*-*-linux*)
AC_DEFINE([_LARGEFILE_SOURCE], [1], [Indicates LFS (i.e. the ability to create files larger than 2 GiB on 32-bit operating systems).])
file64_support='-D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64'
;;
esac
AC_SUBST(file64_support)
# Check that these functions exist. They are mostly C99
# functions that older compilers may not yet support.
AC_CHECK_FUNCS(fopen64)
# The following math functions may be defined in the math library so look
# in the default libraries first and then look in -lm for them. On some
# systems we may need to use the compiler in C99 mode to get a definition.
# We requested C99 mode earlier with AC_PROG_CC_C99.
AC_SEARCH_LIBS([lround], [m], [AC_DEFINE([HAVE_LROUND], [1])])
AC_SEARCH_LIBS([llround], [m], [AC_DEFINE([HAVE_LLROUND], [1])])
AC_SEARCH_LIBS([nan], [m], [AC_DEFINE([HAVE_NAN], [1])])
AC_SEARCH_LIBS([fmin], [m], [AC_DEFINE([HAVE_FMIN], [1])])
AC_SEARCH_LIBS([fmax], [m], [AC_DEFINE([HAVE_FMAX], [1])])
# Check to see if an unsigned long and uint64_t are the same from
# a compiler perspective. We can not just check that they are the
# same size since unsigned long and unsigned long long are not the
# same from an overloading perspective even though they could be
# the same size on some 64 bit machines. The result from this test
# is only used if inttypes.h is available, so if the test fails for
# that reason we don't care.
AC_LANG(C++)
AC_MSG_CHECKING(if uint64_t and unsigned long are identical)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "inttypes.h"
static bool check(unsigned long val)
{
return val != 0;
}
static bool check(uint64_t val)
{
return val != 0;
}]], [[unsigned long ulval = 1;
bool result = check(ulval);
uint64_t uival = 1;
result &= check(uival);
return !result;]])],
[AC_MSG_RESULT(no)],
[AC_DEFINE([UINT64_T_AND_ULONG_SAME], [1]) AC_MSG_RESULT(yes)])
# may modify CPPFLAGS and CFLAGS
AX_CPP_PRECOMP
# Linker option used when compiling the target
AX_LD_RDYNAMIC
@@ -298,29 +119,9 @@ AX_C_UNDERSCORES_TRAILING
## end of test for underscores
#######################
#######################
# Sanity check the configured results
#######################
AX_CPP_IDENT
AC_MSG_CHECKING(for sanity of prefix)
if test `echo "$prefix" | wc -w` != 1
then
AC_MSG_ERROR(cannot configure white space in prefix: $prefix)
fi
AC_MSG_RESULT(ok)
# XXX disable tgt-fpga for the moment
AC_CONFIG_SUBDIRS(vvp vpi tgt-stub tgt-null tgt-vvp tgt-vhdl libveriuser cadpli)
AC_MSG_CHECKING(for sanity of exec_prefix)
if test `echo "$exec_prefix" | wc -w` != 1
then
AC_MSG_ERROR(cannot configure white space in exec_prefix: $exec_prefix)
fi
AC_MSG_RESULT(ok)
AC_MSG_CHECKING(for sanity of libdir)
if test `echo "$libdir" | wc -w` != 1
then
AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
fi
AC_MSG_RESULT(ok)
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 tgt-blif/Makefile tgt-sizer/Makefile)
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
-3
View File
@@ -1,3 +0,0 @@
// These are correct and are used to find the base (zero) pin.
thisSubtraction:netlist.h:4976
thisSubtraction:netlist.h:4985
+764 -249
View File
File diff suppressed because it is too large Load Diff
+154 -574
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -14,22 +14,22 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "discipline.h"
ivl_nature_s::ivl_nature_s(perm_string name__, perm_string access__)
nature_t::nature_t(perm_string name__, perm_string access__)
: name_(name__), access_(access__)
{
}
ivl_nature_s::~ivl_nature_s()
nature_t::~nature_t()
{
}
ivl_discipline_s::ivl_discipline_s(perm_string name__, ivl_dis_domain_t domain__,
ivl_nature_t pot, ivl_nature_t flow__)
nature_t*pot, nature_t*flow__)
: name_(name__), domain_(domain__), potential_(pot), flow_(flow__)
{
}
+15 -15
View File
@@ -1,7 +1,7 @@
#ifndef IVL_discipline_H
#define IVL_discipline_H
#ifndef __discipline_H
#define __discipline_H
/*
* Copyright (c) 2008-2014 Stephen Williams ([email protected])
* Copyright (c) 2008 Stephen Williams ([email protected])
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/*
@@ -33,10 +33,10 @@
extern std::ostream& operator << (std::ostream&, ivl_dis_domain_t);
class ivl_nature_s : public LineInfo {
class nature_t : public LineInfo {
public:
explicit ivl_nature_s(perm_string name, perm_string access);
~ivl_nature_s();
explicit nature_t(perm_string name, perm_string access);
~nature_t();
perm_string name() const { return name_; }
// Identifier for the access function for this nature
@@ -50,28 +50,28 @@ class ivl_nature_s : public LineInfo {
class ivl_discipline_s : public LineInfo {
public:
explicit ivl_discipline_s (perm_string name, ivl_dis_domain_t dom,
ivl_nature_t pot, ivl_nature_t flow);
nature_t*pot, nature_t*flow);
~ivl_discipline_s();
perm_string name() const { return name_; }
ivl_dis_domain_t domain() const { return domain_; }
ivl_nature_t potential() const { return potential_; }
ivl_nature_t flow() const { return flow_; }
const nature_t*potential() const { return potential_; }
const nature_t*flow() const { return flow_; }
private:
perm_string name_;
ivl_dis_domain_t domain_;
ivl_nature_t potential_;
ivl_nature_t flow_;
nature_t*potential_;
nature_t*flow_;
private: // not implemented
ivl_discipline_s(const ivl_discipline_s&);
ivl_discipline_s& operator = (const ivl_discipline_s&);
};
extern map<perm_string,ivl_nature_t> natures;
extern map<perm_string,nature_t*> natures;
extern map<perm_string,ivl_discipline_t> disciplines;
// Map access function name to the nature that it accesses.
extern map<perm_string,ivl_nature_t> access_function_nature;
extern map<perm_string,nature_t*> access_function_nature;
#endif /* IVL_discipline_H */
#endif
+25 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2009 Stephen Williams ([email protected])
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* 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,8 +14,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: dosify.c,v 1.5 2003/07/15 16:17:47 steve Exp $"
#endif
/*
* This is a simple program to make a dosified copy of the
@@ -48,7 +51,6 @@ int main(int argc, char*argv[])
ofile = fopen(argv[2], "wb");
if (ofile == 0) {
fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
fclose(ifile);
return 2;
}
@@ -62,7 +64,25 @@ int main(int argc, char*argv[])
pr = ch;
}
fclose(ifile);
fclose(ofile);
return 0;
}
/*
* $Log: dosify.c,v $
* Revision 1.5 2003/07/15 16:17:47 steve
* Fix spelling of ifdef.
*
* Revision 1.4 2003/07/15 03:49:22 steve
* Spelling fixes.
*
* Revision 1.3 2002/08/12 01:34:58 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 2001/08/03 17:06:47 steve
* Add install of examples for Windows.
*
*/
+2
View File
@@ -0,0 +1,2 @@
Makefile
iverilog-vpi.exe
+21 -41
View File
@@ -12,12 +12,13 @@
#
# 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., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
SHELL = /bin/sh
suffix = @install_suffix@
VERSION = 0.9.devel
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -26,8 +27,6 @@ datarootdir = @datarootdir@
VPATH = $(srcdir)
suffix = @install_suffix@
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
includedir = $(prefix)/include
@@ -36,70 +35,51 @@ mandir = @mandir@
dllib=@DLLIB@
CC = @CC@
WINDRES = @WINDRES@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
ifeq (@srcdir@,.)
INCLUDE_PATH = -I. -I..
else
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
endif
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
O = main.o res.o
all: iverilog-vpi@EXEEXT@
check: all
clean:
rm -f *.o config.h iverilog-vpi@EXEEXT@ res.rc
rm -f *.o config.h
rm -f iverilog-vpi@EXEEXT@
distclean: clean
rm -f Makefile config.log
rm -f Makefile
cppcheck: main.c
cppcheck --enable=all -f $(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=driver-vpi/$@
O = main.o res.o
iverilog-vpi@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
main.o: $(srcdir)/main.c config.h
main.o: main.c config.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
config.h: $(srcdir)/config.h.in Makefile
config.h: config.h.in
sed -e 's;@IVLCC@;@CC@;' -e 's;@IVLCXX@;@CXX@;' \
-e 's;@SUFFIX@;$(suffix);g' \
-e 's;@IVLCFLAGS@;$(CFLAGS);' \
-e 's;@IVLCXXFLAGS@;$(CXXFLAGS);' \
-e 's;@IVLCFLAGS@;@CXXFLAGS@;' \
-e 's;@SHARED@;@shared@;' $< > $@
# Windows specific...
res.rc: $(srcdir)/res.rc.in ../version.exe
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%n,0,0'`';' \
$(srcdir)/res.rc.in > $@
res.o: res.rc
$(WINDRES) -i res.rc -o res.o
windres -i res.rc -o res.o
#
install: all installdirs $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
install: all installdirs $(bindir)/iverilog-vpi@EXEEXT@
$(bindir)/iverilog-vpi$(suffix)@EXEEXT@: ./iverilog-vpi@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(bindir)/iverilog-vpi$(suffix)@EXEEXT@"
$(bindir)/iverilog-vpi@EXEEXT@: ./iverilog-vpi@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ $(bindir)/iverilog-vpi@EXEEXT@
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(bindir)"
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(bindir)
uninstall:
rm -f $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
rm -f $(bindir)/iverilog-vpi@EXEEXT@
+1 -3
View File
@@ -4,7 +4,5 @@
#define IVERILOG_VPI_CC "@IVLCC@"
#define IVERILOG_VPI_CXX "@IVLCXX@"
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@"
#define IVERILOG_VPI_CXXFLAGS " @IVLCXXFLAGS@"
#define IVERILOG_VPI_LDFLAGS "@SHARED@"
#define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@"
#define IVERILOG_SUFFIX "@SUFFIX@"
#define IVERILOG_VPI_LDLIBS "-lveriuser -lvpi"
+165 -182
View File
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2002 Gus Baldauf ([email protected])
* Copyright (c) 2015 Martin Whitaker
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -15,13 +14,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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/*
* iverilog-vpi.c
*
* this program provides the functionality of iverilog-vpi.sh under Windows
* this program provides the functionality of iverilog-vpi.sh under Win32
*/
#include <stdio.h>
@@ -33,7 +32,7 @@
#include <windows.h>
static void setup_ivl_environment(void);
static void setup_ivl_environment();
static void assign(char **ptr, char *str);
/* The compile options: compiler, flags, etc. are in here */
@@ -44,17 +43,16 @@ static void assign(char **ptr, char *str);
static struct global_strings {
char *pCCSRC; /* list of C source files (*.c) */
char *pCXSRC; /* list of C++ source files (*.cc, *.cpp) */
char *pOBJ; /* list of object files */
char *pLIB; /* list of library files */
char *pINCS; /* list of include directories */
char *pDEFS; /* list of definitions */
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
char *pOBJ; /* list of object files */
char *pLIB; /* list of library files */
char *pINCS; /* list of include directories */
char *pDEFS; /* list of definitions */
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
char *pMINGW; /* path to MinGW directory */
char *pIVL; /* path to IVL directory */
char *pCCFLAGS; /* compiler flags for compiling C source files */
char *pCXFLAGS; /* compiler flags for compiling C++ source files */
char *pLDLIBS; /* linker flags for final linking stage */
char *pCCNAME; /* base name of compiler */
char *pIVL; /* path to IVL directory */
char *pCFLAGS; /* CFLAGS option */
char *pLDLIBS; /* LDLIBS option */
char *pNewPath; /* new PATH environment variable setting */
char *pLD; /* what to use for a linker */
} gstr;
@@ -77,21 +75,21 @@ static void myExit(int exitVal)
deInitDynString(gstr.pOUT);
deInitDynString(gstr.pMINGW);
deInitDynString(gstr.pIVL);
deInitDynString(gstr.pCCFLAGS);
deInitDynString(gstr.pCXFLAGS);
deInitDynString(gstr.pCFLAGS);
deInitDynString(gstr.pLDLIBS);
deInitDynString(gstr.pCCNAME);
deInitDynString(gstr.pLD);
deInitDynString(gstr.pNewPath);
free(gstr.pLD);
exit(exitVal);
}
/* display usage summary and exit */
static void usage(void)
static void usage()
{
fprintf(stderr, "usage: iverilog-vpi" IVERILOG_SUFFIX " [options] [src and obj files]...\n");
fprintf(stderr, " or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
fprintf(stderr,"usage: iverilog-vpi [src and obj files]...\n");
fprintf(stderr," or iverilog-vpi -mingw=dir\n");
fprintf(stderr," or iverilog-vpi -ivl=dir\n");
myExit(1);
}
@@ -100,7 +98,7 @@ static void initDynString(char **str)
*str = (char *) malloc(1);
if (!*str) {
fprintf(stderr, "error: out of memory\n");
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
@@ -109,10 +107,8 @@ static void initDynString(char **str)
/* initialize dynamic memory buffers */
static void init(void)
static void init()
{
char *ptr;
initDynString(&gstr.pCCSRC);
initDynString(&gstr.pCXSRC);
initDynString(&gstr.pOBJ);
@@ -122,17 +118,9 @@ static void init(void)
initDynString(&gstr.pOUT);
initDynString(&gstr.pMINGW);
initDynString(&gstr.pIVL);
initDynString(&gstr.pCCFLAGS);
initDynString(&gstr.pCXFLAGS);
initDynString(&gstr.pCFLAGS);
initDynString(&gstr.pLDLIBS);
initDynString(&gstr.pCCNAME);
initDynString(&gstr.pLD);
/* Get the base name of the C compiler. */
assign(&gstr.pCCNAME, IVERILOG_VPI_CC);
ptr = strchr(gstr.pCCNAME, ' ');
if (ptr != NULL) *ptr = '\0';
initDynString(&gstr.pNewPath);
/* By default use the C compiler to link the programs. */
assign(&gstr.pLD, IVERILOG_VPI_CC);
}
@@ -148,7 +136,7 @@ static int endsIn (char *end, char *str)
ext = str + (strlen(str) - strlen(end));
return stricmp(end, ext) ? 0 : 1;
return stricmp(end,ext) ? 0 : 1;
}
/* return true if "str" begins with "prefix", case insensitive */
@@ -158,35 +146,32 @@ static int startsWith (char *prefix, char *str)
if (strlen(prefix) >= strlen(str))
return 0;
return strnicmp(prefix, str, strlen(prefix)) ? 0 : 1;
return strnicmp(prefix,str,strlen(prefix)) ? 0 : 1;
}
/* append "app" to "ptr", allocating memory as needed */
/* if count is zero, then copy all characters of "app" */
static void appendn (char **ptr, char *app, size_t count)
static void appendn (char **ptr, char *app, int count)
{
char *nptr = (char *) realloc(*ptr, strlen(*ptr) +
(count ? count : strlen(app)) + 1);
*ptr = (char *) realloc(*ptr,strlen(*ptr)+(count?count:strlen(app))+1);
if (nptr == NULL) {
fprintf(stderr, "error: out of memory\n");
free(*ptr);
if (*ptr == NULL) {
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
*ptr = nptr;
if (count)
strncat(*ptr, app, count);
strncat(*ptr,app,count);
else
strcat(*ptr, app);
strcat(*ptr,app);
}
/* append "app" to "ptr", allocating memory as needed */
static void append (char **ptr, char *app)
{
appendn(ptr, app, 0);
appendn(ptr,app,0);
}
/* if the string does not end with a backslash, add one */
@@ -194,36 +179,34 @@ static void append (char **ptr, char *app)
static void appendBackSlash(char **str)
{
if ((*str)[strlen(*str)-1] != '\\')
append(str, "\\");
append(str,"\\");
}
/* copy count characters of "str" to "ptr", allocating memory as needed */
/* if count is zero, then copy all characters of "str" */
static void assignn (char **ptr, char *str, size_t count)
static void assignn (char **ptr, char *str, int count)
{
char *nptr = (char *) realloc(*ptr, (count ? count : strlen(str)) + 1);
*ptr = (char *) realloc(*ptr,(count?count:strlen(str))+1);
if (nptr == NULL) {
fprintf(stderr, "error: out of memory\n");
free(*ptr);
if (*ptr == NULL) {
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
*ptr = nptr;
if (count) {
strncpy(*ptr, str, count);
strncpy(*ptr,str,count);
(*ptr)[count] = 0;
}
else
strcpy(*ptr, str);
strcpy(*ptr,str);
}
/* copy count characters of "str" to "ptr", allocating memory as needed */
static void assign (char **ptr, char *str)
{
assignn(ptr, str, 0);
assignn(ptr,str,0);
}
/* get a copy of a Icarus Verilog registry string key */
@@ -235,11 +218,11 @@ static int GetRegistryKey(char *key, char **value)
char *regKeyBuffer;
DWORD regKeyType, regKeySize;
lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Icarus Verilog", 0, KEY_QUERY_VALUE, &hkKey);
lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\Icarus Verilog",0,KEY_QUERY_VALUE,&hkKey);
if (lrv != ERROR_SUCCESS)
return 0;
lrv = RegQueryValueEx(hkKey, key, NULL, &regKeyType, NULL, &regKeySize);
lrv = RegQueryValueEx(hkKey,key,NULL,&regKeyType,NULL,&regKeySize);
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
lrv = RegCloseKey(hkKey);
return 0;
@@ -248,14 +231,12 @@ static int GetRegistryKey(char *key, char **value)
regKeyBuffer = (char *) malloc(regKeySize+1);
if (!regKeyBuffer) {
lrv = RegCloseKey(hkKey);
fprintf(stderr, "error: out of memory\n");
fprintf(stderr,"error: out of memory\n");
myExit(4);
}
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
/* This needs an unsigned char *, but for MinGW the char is signed. */
lrv = RegQueryValueEx(hkKey, key, NULL, &regKeyType,
(unsigned char *) regKeyBuffer, &regKeySize);
lrv = RegQueryValueEx(hkKey,key,NULL,&regKeyType,regKeyBuffer,&regKeySize);
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
lrv = RegCloseKey(hkKey);
free(regKeyBuffer);
@@ -264,7 +245,7 @@ static int GetRegistryKey(char *key, char **value)
RegCloseKey(hkKey);
assign(value, regKeyBuffer);
assign(value,regKeyBuffer);
free(regKeyBuffer);
return 1;
@@ -274,30 +255,25 @@ static int GetRegistryKey(char *key, char **value)
static void SetRegistryKey(char *key, char *value)
{
long lrv;
HKEY hkKey;
DWORD res;
lrv = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Icarus Verilog", 0, "",
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkKey, &res);
if (lrv != ERROR_SUCCESS) {
char message[1024];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lrv, LANG_USER_DEFAULT,
message, sizeof(message), NULL);
fprintf(stderr, "error: couldn't write to registry - %s\n", message);
if (lrv == ERROR_ACCESS_DENIED) {
fprintf(stderr, " try running as administrator\n");
}
return;
}
if (RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
"Software\\Icarus Verilog",
0,
"",
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,NULL,
&hkKey,
&res) != ERROR_SUCCESS)
return;
/* This needs an unsigned char *, but for MinGW the char is signed. */
RegSetValueEx(hkKey, key, 0, REG_SZ, (unsigned char *) value,
strlen(value)+1);
RegSetValueEx(hkKey,key,0,REG_SZ,value,strlen(value)+1);
RegCloseKey(hkKey);
printf("info: storing %s in Windows' registry entry\n", value);
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n", key);
printf("info: storing %s in Windows' registry entry\n",value);
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n",key);
}
/* parse the command line, assign results to global variable strings */
@@ -314,6 +290,7 @@ static int parse(int argc, char *argv[])
char lib_option[] = "-l";
char inc_option[] = "-I";
char mingw_option[] = "-mingw=";
char ivl_option[] = "-ivl=";
char def_option[] = "-D";
if (argc == 1) return 0;
@@ -353,7 +330,7 @@ static int parse(int argc, char *argv[])
/* Check for compiled object files */
else if (endsIn(dot_o_ext, argv[idx])) {
++srcFileCnt;
append(&gstr.pOBJ, " ");
append(&gstr.pOBJ," ");
append(&gstr.pOBJ, argv[idx]);
if (!*gstr.pOUT)
assignn(&gstr.pOUT, argv[idx],
@@ -363,6 +340,10 @@ static int parse(int argc, char *argv[])
else if (startsWith(mingw_option, argv[idx]))
assignn(&gstr.pMINGW, argv[idx]+sizeof(mingw_option)-1,
strlen(argv[idx])-(sizeof(mingw_option)-1));
/* Check for the -ivl option */
else if (startsWith(ivl_option, argv[idx]))
assignn(&gstr.pIVL, argv[idx]+sizeof(ivl_option)-1,
strlen(argv[idx])-(sizeof(ivl_option)-1));
/* Check for the --name option */
else if (startsWith(name_option, argv[idx])) {
assignn(&gstr.pOUT, argv[idx]+sizeof(name_option)-1,
@@ -386,7 +367,7 @@ static int parse(int argc, char *argv[])
/* Check for the --cflags option */
else if (stricmp("--cflags", argv[idx]) == 0) {
setup_ivl_environment();
printf("%s\n", gstr.pCCFLAGS);
printf("%s\n", gstr.pCFLAGS);
myExit(0);
}
/* Check for the --ldflags option */
@@ -403,7 +384,7 @@ static int parse(int argc, char *argv[])
/* Check for the --install-dir option */
else if (stricmp("--install-dir", argv[idx]) == 0) {
setup_ivl_environment();
printf("%s\\lib\\ivl" IVERILOG_SUFFIX "\\.\n", gstr.pIVL);
printf("%s\\\\lib\\\\ivl\\\\.\n", gstr.pIVL);
myExit(0);
}
/* This is different than iverilog-vpi.sh, we don't
@@ -412,16 +393,15 @@ static int parse(int argc, char *argv[])
}
/* In case there is a --name without source/object files */
if (0 == srcFileCnt) assign(&gstr.pOUT, "");
if (0 == srcFileCnt) assign(&gstr.pOUT,"");
if (*gstr.pOUT) {
/* Normally it's an error if there are no source or object files */
/* Unless we are setting the IVL or MinGW registry entries */
if (!*gstr.pOUT) {
if (!*gstr.pMINGW && !*gstr.pIVL) return 0;
} else
/* We have a valid result file so add the .vpi extension */
append(&gstr.pOUT, ".vpi");
} else {
/* Unless we are setting the MinGW registry entry, it's
an error if there are no source or object files */
if (!*gstr.pMINGW) return 0;
}
return 1;
}
@@ -432,126 +412,124 @@ static void checkMingwDir(char *root)
{
int irv;
struct _stat stat_buf;
char *path;
char *path;
initDynString(&path);
assign(&path, gstr.pMINGW);
assign(&path,gstr.pMINGW);
appendBackSlash(&path);
append(&path, "bin\\");
append(&path, gstr.pCCNAME);
append(&path, ".exe");
append(&path,"bin\\" IVERILOG_VPI_CC ".exe");
irv = _stat(path,&stat_buf);
deInitDynString(path);
if (irv) {
fprintf(stderr, "error: %s\n", root);
fprintf(stderr, " does not appear to be the valid root directory of\n");
fprintf(stderr, " MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
fprintf(stderr, " point to the MinGW root directory. For a Windows command\n");
fprintf(stderr, " shell the option would be something like -mingw=c:\\mingw\n");
fprintf(stderr, " For a Cygwin shell the option would be something like\n");
fprintf(stderr, " -mingw=c:\\\\mingw\n");
fprintf(stderr,"error: %s does not appear to be the valid root directory\n",root);
fprintf(stderr," of MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
fprintf(stderr," point to the MinGW root directory. For a Windows command\n");
fprintf(stderr," shell the option would be something like -mingw=c:\\mingw\n");
fprintf(stderr," For a Cygwin shell the option would be something like\n");
fprintf(stderr," -mingw=c:\\\\mingw\n");
myExit(5);
}
}
/* do minimal check that the Icarus Verilog root directory looks valid */
static void checkIvlDir(char *root)
{
int irv;
struct _stat stat_buf;
char *path;
initDynString(&path);
assign(&path,gstr.pIVL);
appendBackSlash(&path);
append(&path,"bin\\vvp.exe");
irv = _stat(path,&stat_buf);
deInitDynString(path);
if (irv) {
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi.exe to\n");
fprintf(stderr," point to the Icarus Verilog root directory. For a Windows\n");
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
fprintf(stderr," For a Cygwin shell the option would be something like\n");
fprintf(stderr," -ivl=c:\\\\iverilog\n");
myExit(6);
}
}
/* see if we can find mingw root */
#define IVL_REGKEY_MINGW "MingwDir"
static void setup_mingw_environment(void)
static void setup_mingw_environment()
{
char buffer[1]; /* doesn't matter how big this is, as we don't use the result */
char *path;
char *pOldPATH = getenv("PATH"); /* get current path */
if (*gstr.pMINGW) {
checkMingwDir(gstr.pMINGW);
if (!*gstr.pOUT) SetRegistryKey(IVL_REGKEY_MINGW, gstr.pMINGW);
} else if (GetRegistryKey(IVL_REGKEY_MINGW, &gstr.pMINGW)) {
checkMingwDir(gstr.pMINGW);
} else if (SearchPath(NULL, gstr.pCCNAME, ".exe", sizeof(buffer), buffer, NULL)) {
return;
} else {
fprintf(stderr, "error: cannot locate the MinGW C compiler - either add its location\n");
fprintf(stderr, " to the PATH environment variable or use the -mingw option of\n");
fprintf(stderr, " iverilog-vpi.exe to point to the MinGW root directory. For\n");
fprintf(stderr, " a Windows command shell the option would be something like\n");
fprintf(stderr, " -mingw=c:\\mingw For a Cygwin shell the option would be\n");
fprintf(stderr, " something like -mingw=c:\\\\mingw\n");
myExit(5);
}
SetRegistryKey(IVL_REGKEY_MINGW,gstr.pMINGW);
} else if (!GetRegistryKey(IVL_REGKEY_MINGW,&gstr.pMINGW)) {
fprintf(stderr,"error: can not locate the MinGW root directory, use the -mingw option of\n");
fprintf(stderr," iverilog-vpi.exe to point to the MinGW root directory. For\n");
fprintf(stderr," a Windows command shell the option would be something like\n");
fprintf(stderr," -mingw=c:\\mingw For a Cygwin shell the option would be\n");
fprintf(stderr," something like -mingw=c:\\\\mingw\n");
myExit(5);
}
/* Create new path with MinGW in it */
initDynString(&path);
assign(&path, "PATH=");
append(&path, gstr.pMINGW);
appendBackSlash(&path);
append(&path, "bin;");
append(&path, getenv("PATH"));
assign(&gstr.pNewPath,"PATH=");
append(&gstr.pNewPath,gstr.pMINGW);
appendBackSlash(&gstr.pNewPath);
append(&gstr.pNewPath, "\\");
append(&gstr.pNewPath,"bin;");
append(&gstr.pNewPath,pOldPATH);
/* Place new path in environment */
_putenv(path);
deInitDynString(path);
_putenv(gstr.pNewPath);
}
/* find the iverilog root and initialise the compiler options */
/* see if we can find iverilog root */
static void setup_ivl_environment(void)
#define IVL_REGKEY_IVL "InstallDir"
static void setup_ivl_environment()
{
char path[4096];
char *ptr;
if (*gstr.pIVL) {
checkIvlDir(gstr.pIVL);
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
} else if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
fprintf(stderr," of iverilog-vpi.exe to point to the Icarus Verilog root directory.\n");
fprintf(stderr," For a Windows command shell the option would be something like\n");
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
myExit(6);
}
/* Extract the Icarus Verilog root directory from the path to the
command. The command path will look something like this:
C:\iverilog\bin\iverilog-vpi.exe
The corresponding root directory is
C:\iverilog
so we chop off the file name and the last directory. */
GetModuleFileName(NULL, path, sizeof(path));
ptr = strrchr(path, '\\');
if (!ptr) {
fprintf(stderr, "error: couldn't find start of program name in command path '%s'\n", path);
myExit(6);
}
*ptr = 0;
ptr = strrchr(path, '\\');
if (!ptr) {
fprintf(stderr, "error: couldn't find start of bin directory in command path '%s'\n", path);
myExit(6);
}
*ptr = 0;
assign(&gstr.pIVL, path);
/* Build up the CCFLAGS option string */
assign(&gstr.pCCFLAGS, IVERILOG_VPI_CFLAGS " -I\"");
append(&gstr.pCCFLAGS, gstr.pIVL);
appendBackSlash(&gstr.pCCFLAGS);
append(&gstr.pCCFLAGS, "include\\iverilog\"" IVERILOG_SUFFIX);
/* Build up the CXFLAGS option string */
assign(&gstr.pCXFLAGS, IVERILOG_VPI_CXXFLAGS " -I\"");
append(&gstr.pCXFLAGS, gstr.pIVL);
appendBackSlash(&gstr.pCXFLAGS);
append(&gstr.pCXFLAGS, "include\\iverilog\"" IVERILOG_SUFFIX);
/* Build up the CFLAGS option string */
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS);
append(&gstr.pCFLAGS," -I");
append(&gstr.pCFLAGS,gstr.pIVL);
appendBackSlash(&gstr.pCFLAGS);
append(&gstr.pCFLAGS, "\\");
append(&gstr.pCFLAGS,"include");
/* Build up the LDFLAGS option string */
assign(&gstr.pLDLIBS, "-L\"");
append(&gstr.pLDLIBS, gstr.pIVL);
assign(&gstr.pLDLIBS,"-L");
append(&gstr.pLDLIBS,gstr.pIVL);
appendBackSlash(&gstr.pLDLIBS);
append(&gstr.pLDLIBS, "lib\" " IVERILOG_VPI_LDLIBS);
append(&gstr.pLDLIBS, "\\");
append(&gstr.pLDLIBS,"lib ");
append(&gstr.pLDLIBS,IVERILOG_VPI_LDLIBS);
}
/* compile source modules */
static void compile(char *pSource, char *pFlags, char **pObject, int *compile_errors, char *compiler)
static void compile(char *pSource, char **pObject, int *compile_errors, char *compiler)
{
char *ptr1 = pSource;
char *ptr2 = strchr(ptr1, ' ');
@@ -578,7 +556,7 @@ static void compile(char *pSource, char *pFlags, char **pObject, int *compile_er
append(&buf, " ");
append(&buf, gstr.pDEFS);
append(&buf, " ");
append(&buf, pFlags);
append(&buf, gstr.pCFLAGS);
append(&buf, " ");
append(&buf, gstr.pINCS);
append(&buf, " ");
@@ -603,22 +581,27 @@ static void compile(char *pSource, char *pFlags, char **pObject, int *compile_er
/* using the global strings, compile and link */
static void compile_and_link(void)
static void compile_and_link()
{
char *buf=0;
int iRet, compile_errors = 0;
/* To make the output match iverilog-vpi.sh do not print out the
* root directories */
// printf("MinGW root directory: %s.\n", gstr.pMINGW);
checkMingwDir(gstr.pMINGW);
// printf("Icarus Verilog root directory: %s.\n", gstr.pIVL);
checkIvlDir(gstr.pIVL);
/* compile the C source files (*.c) */
compile(gstr.pCCSRC, gstr.pCCFLAGS, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CC );
compile(gstr.pCCSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CC );
/* compile the C++ source files (*.cc, *.cpp) */
compile(gstr.pCXSRC, gstr.pCXFLAGS, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CXX);
compile(gstr.pCXSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CXX);
if (compile_errors) {
fprintf(stderr, "iverilog-vpi: %d file(s) failed to compile.\n",
fprintf(stderr,"iverilog-vpi: %d file(s) failed to compile.\n",
compile_errors);
myExit(2);
}
@@ -649,7 +632,7 @@ int main(int argc, char *argv[])
{
init();
if (!parse(argc, argv)) usage();
if (!parse(argc,argv)) usage();
setup_mingw_environment();
setup_ivl_environment();
+2 -2
View File
@@ -10,7 +10,7 @@ LANGUAGE 9, 4
1 VERSIONINFO
FILEVERSION 2002,11,13,0
PRODUCTVERSION @PRODUCTVERSION@
PRODUCTVERSION 0,7,0,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x2L
FILEOS 0x40004L
@@ -28,7 +28,7 @@ BEGIN
VALUE "LegalCopyright", "Copyright 2002 Gus Baldauf\0"
VALUE "OriginalFilename", "iverilog-vpi.exe\0"
VALUE "ProductName", "Icarus Verilog\0"
VALUE "ProductVersion", "@PRODUCTVERSION@\0"
VALUE "ProductVersion", "0, 7, 0, 0\0"
END
END
BLOCK "VarFileInfo"
+15
View File
@@ -0,0 +1,15 @@
a.out
Makefile
parse.c
parse.h
parse.output
lexor.c
cfparse.c
cfparse.h
cfparse.output
cflexor.c
foo.*
iverilog
iverilog.ps
iverilog.pdf
tmp.pdf
+38 -70
View File
@@ -12,12 +12,13 @@
#
# 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., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
# Software Foundation, Inc.,
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
SHELL = /bin/sh
suffix = @install_suffix@
VERSION = 0.9.devel
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -37,112 +38,79 @@ CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
LEX = @LEX@
YACC = @YACC@
MAN = @MAN@
PS2PDF = @PS2PDF@
ifeq (@srcdir@,.)
INCLUDE_PATH = -I. -I..
else
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
endif
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
O = main.o substit.o cflexor.o cfparse.o
all: dep iverilog@EXEEXT@ iverilog.man
check: all
all: iverilog@EXEEXT@
clean:
rm -f *.o cflexor.c cfparse.c cfparse.h cfparse.output
rm -f iverilog@EXEEXT@ iverilog.man iverilog.pdf iverilog.ps
rm -rf dep
rm -f *.o lexor.c parse.c parse.h parse.output
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
rm -f iverilog@EXEEXT@ iverilog.pdf iverilog.ps
distclean: clean
rm -f Makefile config.log
rm -f Makefile
cppcheck: $(O:.o=.c)
cppcheck --enable=all -f \
-UYY_USER_INIT \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
$(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=driver/$@
dep:
mkdir dep
O = main.o substit.o cflexor.o cfparse.o
iverilog@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
cflexor.c: $(srcdir)/cflexor.lex
$(LEX) -s -t $< > $@
cflexor.c: cflexor.lex
flex -s -Pcf -ocflexor.c $(srcdir)/cflexor.lex
# Build this in two steps to avoid parallel build issues (see pr3462585)
cfparse.c: $(srcdir)/cfparse.y
$(YACC) --verbose -t -p cf -d -o $@ $<
cfparse.h: cfparse.c
cfparse.h cfparse.c: cfparse.y
bison --verbose -t -d -o cfparse.c --name-prefix=cf $(srcdir)/cfparse.y
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep
main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h Makefile
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_SUFFIX='"$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
mv $*.d dep
main.o: main.c globals.h ../version.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
cflexor.o: cflexor.c cfparse.h
build_string.o: build_string.c globals.h
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
cfparse.o: cfparse.c globals.h cfparse_misc.h
iverilog.man: $(srcdir)/iverilog.man.in ../version.exe
../version.exe `head -1 $(srcdir)/iverilog.man.in`'\n' > $@
tail -n +2 $(srcdir)/iverilog.man.in >> $@
iverilog.ps: iverilog.man
$(MAN) -t ./iverilog.man > iverilog.ps
iverilog.ps: $(srcdir)/iverilog.man
$(MAN) -t $(srcdir)/iverilog.man > iverilog.ps
iverilog.pdf: iverilog.ps
$(PS2PDF) iverilog.ps iverilog.pdf
ifeq (@MINGW32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
INSTALL_DOC = $(mandir)/man1/iverilog.1
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
INSTALL_DOC = $(mandir)/man1/iverilog.1
else
INSTALL_DOC = $(prefix)/iverilog$(suffix).pdf $(mandir)/man1/iverilog$(suffix).1
INSTALL_DOC = $(prefix)/iverilog.pdf $(mandir)/man1/iverilog.1
all: iverilog.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
INSTALL_DOC = $(mandir)/man1/iverilog.1
INSTALL_DOCDIR = $(mandir)/man1
endif
install: all installdirs $(bindir)/iverilog$(suffix)@EXEEXT@ $(INSTALL_DOC)
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(INSTALL_DOC)
$(bindir)/iverilog$(suffix)@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
$(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(DESTDIR)$(bindir)/iverilog@EXEEXT@
$(mandir)/man1/iverilog$(suffix).1: iverilog.man
$(INSTALL_DATA) iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1"
$(mandir)/man1/iverilog.1: $(srcdir)/iverilog.man
$(INSTALL_DATA) $(srcdir)/iverilog.man $(DESTDIR)$(mandir)/man1/iverilog.1
$(prefix)/iverilog$(suffix).pdf: iverilog.pdf
$(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf"
$(prefix)/iverilog.pdf: iverilog.pdf
$(INSTALL_DATA) iverilog.pdf $(prefix)/iverilog.pdf
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(INSTALL_DOCDIR)"
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(INSTALL_DOCDIR)
uninstall:
rm -f "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
rm -f "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1" "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf"
-include $(patsubst %.o, dep/%.d, $O)
rm -f $(DESTDIR)$(bindir)/iverilog@EXEEXT@
rm -f $(DESTDIR)$(mandir)/man1/iverilog.1 $(DESTDIR)$(prefix)/iverilog.pdf
+8 -29
View File
@@ -1,10 +1,10 @@
%option prefix="cf"
%option nounput
%option noinput
%{
/*
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -19,8 +19,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cflexor.lex,v 1.11 2007/03/22 16:08:18 steve Exp $"
#endif
# include "cfparse.h"
# include "cfparse_misc.h"
@@ -76,23 +79,13 @@ int cmdfile_stack_ptr = 0;
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
"+parameter+" { BEGIN(PLUS_ARGS); return TOK_PARAMETER; }
"+timescale+" { BEGIN(PLUS_ARGS); return TOK_TIMESCALE; }
"+vhdl-work+" { BEGIN(PLUS_ARGS); return TOK_VHDL_WORK; }
"+vhdl-libdir+" { BEGIN(PLUS_ARGS); return TOK_VHDL_LIBDIR; }
"+width-cap+" { BEGIN(PLUS_ARGS); return TOK_WIDTH_CAP; }
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
/* If it is not any known plus-flag, return the generic form. */
"+"[^\n \t\b\f\r+]* {
@@ -197,6 +190,7 @@ 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) "
@@ -214,7 +208,6 @@ 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. */
@@ -243,17 +236,3 @@ void cfreset(FILE*fd, const char*path)
current_file = strdup(path);
cflloc.first_line = 1;
}
/*
* Modern version of flex (>=2.5.9) can clean up the scanner data.
*/
void destroy_lexor(void)
{
# ifdef FLEX_SCANNER
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
yylex_destroy();
# endif
# endif
# endif
}
+11 -48
View File
@@ -1,6 +1,6 @@
%{
/*
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
* Copyright (c) 20001 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -15,16 +15,18 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: cfparse.y,v 1.12 2007/04/19 02:52:53 steve Exp $"
#endif
# include "globals.h"
# include "cfparse_misc.h"
# include <ctype.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include "ivl_alloc.h"
/*
@@ -39,13 +41,13 @@ static void translate_file_name(char*text)
break;
case 1:
while (*text) {
*text = toupper((int)*text);
*text = toupper(*text);
text += 1;
}
break;
case 2:
while (*text) {
*text = tolower((int)*text);
*text = tolower(*text);
text += 1;
}
break;
@@ -59,9 +61,8 @@ static void translate_file_name(char*text)
};
%token TOK_Da TOK_Dc TOK_Dv TOK_Dy
%token TOK_DEFINE TOK_INCDIR TOK_INTEGER_WIDTH TOK_LIBDIR TOK_LIBDIR_NOCASE
%token TOK_LIBEXT TOK_PARAMETER TOK_TIMESCALE TOK_VHDL_WORK TOK_VHDL_LIBDIR
%token TOK_WIDTH_CAP
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
%token TOK_INTEGER_WIDTH
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%%
@@ -138,41 +139,11 @@ item
free(tmp);
}
| TOK_PARAMETER TOK_PLUSARG
{ char*tmp = substitutions($2);
process_parameter(tmp);
free($2);
free(tmp);
}
/* The +timescale token is used to set the default timescale for
the simulator. */
| TOK_TIMESCALE TOK_PLUSARG
{ char*tmp = substitutions($2);
process_timescale(tmp);
free($2);
free(tmp);
}
| TOK_DEFINE TOK_PLUSARG
{ process_define($2);
free($2);
}
| TOK_VHDL_WORK TOK_PLUSARG
{ char*tmp = substitutions($2);
vhdlpp_work = tmp;
free($2);
}
| TOK_VHDL_LIBDIR TOK_PLUSARG
{ char*tmp = substitutions($2);
vhdlpp_libdir = realloc(vhdlpp_libdir, (vhdlpp_libdir_cnt+1)*sizeof(char*));
vhdlpp_libdir[vhdlpp_libdir_cnt] = tmp;
vhdlpp_libdir_cnt += 1;
free($2);
}
/* The +incdir token introduces a list of +<path> arguments that are
the include directories to search. */
@@ -192,13 +163,6 @@ item
free(tmp);
}
| TOK_WIDTH_CAP TOK_PLUSARG
{ char*tmp = substitutions($2);
free($2);
width_cap = strtoul(tmp,0,10);
free(tmp);
}
/* The +<word> tokens that are not otherwise matched, are
ignored. The skip_args rule arranges for all the argument words
to be consumed. */
@@ -221,7 +185,7 @@ item
}
| error
{ fprintf(stderr, "Error: unable to parse line %u in "
{ fprintf(stderr, "Error: unable to parse line %d in "
"%s.\n", cflloc.first_line, current_file);
return 1;
}
@@ -270,6 +234,5 @@ skip_arg : TOK_PLUSARG
int yyerror(const char*msg)
{
(void)msg; /* Parameter is not used. */
return 0;
}
+5 -6
View File
@@ -1,7 +1,7 @@
#ifndef IVL_cfparse_misc_H
#define IVL_cfparse_misc_H
#ifndef __cfparse_misc_H
#define __cfparse_misc_H
/*
* Copyright (c) 2001-2014 Picture Elements, Inc.
* Copyright (c) 2001 Picture Elements, Inc.
* Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/*
@@ -38,7 +38,6 @@ int cflex(void);
int cferror(const char *);
int cfparse(void);
void switch_to_command_file(const char *);
void destroy_lexor(void);
char *current_file;
#endif /* IVL_cfparse_misc_H */
#endif
+72 -16
View File
@@ -1,7 +1,7 @@
#ifndef IVL_globals_H
#define IVL_globals_H
#ifndef __globals_H
#define __globals_H
/*
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
* Copyright (c) 2000 Stephen Williams ([email protected])
*
* 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,21 +16,42 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: globals.h,v 1.21 2007/04/19 02:52:53 steve Exp $"
#endif
# include <stddef.h>
/* This is the base (i.e. -B<value>) of the Icarus Verilog files. */
extern const char*base;
/* This is the path to the iconfig file sent to ivl. */
extern char* iconfig_path;
extern char* iconfig_common_path;
/* This is the optional -M<dependfile> value, if one was supplied. */
extern const char*depfile;
/* This is the optional -N<path> value, if one was supplied. */
extern const char*npath;
/* This is the name of the output file that the user selected. */
extern const char*opath;
/* This pointer is set if there were -s<value> parameters. */
extern char*start;
/* This flag is true if the -S flag was used on the command line. */
extern int synth_flag;
/* This is the name of the selected target. */
extern const char*targ;
/* This is the integer-width argument that will be passed to ivl. */
extern unsigned integer_width;
/* This is the width-cap argument that will be passed to ivl. */
extern unsigned width_cap;
extern const char*vhdlpp_work;
extern const char**vhdlpp_libdir;
extern unsigned vhdlpp_libdir_cnt;
/* Perform variable substitutions on the string. */
extern char* substitutions(const char*str);
@@ -48,10 +69,45 @@ extern void process_include_dir(const char*name);
/* Add a new -D define. */
extern void process_define(const char*name);
/* Add a new parameter definition */
extern void process_parameter(const char*name);
/* -v */
extern int verbose_flag;
/* Set the default timescale for the simulator. */
extern void process_timescale(const char*ts_string);
extern char warning_flags[];
#endif /* IVL_globals_H */
/* -y and -Y flags from the command line. */
extern char* library_flags;
extern char* library_flags2;
/*
* $Log: globals.h,v $
* Revision 1.21 2007/04/19 02:52:53 steve
* Add support for -v flag in command file.
*
* Revision 1.20 2007/03/07 04:24:59 steve
* Make integer width controllable.
*
* Revision 1.19 2003/11/18 06:31:46 steve
* Remove the iverilog.conf file.
*
* Revision 1.18 2003/11/13 04:09:49 steve
* Pass flags through the temporary config file.
*
* Revision 1.17 2003/11/01 04:21:57 steve
* Add support for a target static config file.
*
* Revision 1.16 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.15 2002/06/23 20:10:51 steve
* Variable substitution in command files.
*
* Revision 1.14 2002/05/28 20:40:37 steve
* ivl indexes the search path for libraries, and
* supports case insensitive module-to-file lookup.
*
* Revision 1.13 2002/05/28 00:50:40 steve
* Add the ivl -C flag for bulk configuration
* from the driver, and use that to run library
* modules through the preprocessor.
*/
#endif
+59 -165
View File
@@ -1,14 +1,13 @@
.TH iverilog 1 "Aug 7th, 2015" "" "Version %M.%n%E"
.TH iverilog 1 "April 22nd, 2008" Version "0.9.devel"
.SH NAME
iverilog - Icarus Verilog compiler
.SH SYNOPSIS
.B iverilog
[\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
[\-Pparameter=value] [\-pflag=value]
[\-dname] [\-g1995|\-g2001|\-g2005|\-g2005-sv|\-g2009|\-g2012|\-g<feature>]
[\-Iincludedir] [\-mmodule] [\-M[mode=]file] [\-Nfile] [\-ooutputfilename]
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] sourcefile
[-ESVv] [-Bpath] [-ccmdfile|-fcmdfile] [-Dmacro[=defn]] [-pflag=value]
[-dname] [-g1995|-g2001|-g2005|-g<feature>]
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
.SH DESCRIPTION
.PP
@@ -19,18 +18,19 @@ simulation, and \fIfpga\fP for synthesis. Other target
types are added as code generators are implemented.
.SH OPTIONS
.l
\fIiverilog\fP accepts the following options:
.TP 8
.B -B\fIbase\fP
The \fIiverilog\fP program uses external programs and configuration
files to preprocess and compile the Verilog source. Normally, the path
used to locate these tools is built into the \fIiverilog\fP
program. However, the \fB\-B\fP switch allows the user to select a
program. However, the \fB-B\fP switch allows the user to select a
different set of programs. The path given is used to locate
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
.TP 8
.B -c\fIfile\fP -f\fIfile\fP
These flags specify an input file that contains a list of Verilog
These flags specifies an input file that contains a list of Verilog
source files. This is similar to the \fIcommand file\fP of other
Verilog simulators, in that it is a file that contains the file names
instead of taking them on the command line. See \fBCommand Files\fP below.
@@ -43,14 +43,8 @@ Verilog source.
.B -D\fImacro=defn\fP
Defines macro \fImacro\fP as \fIdefn\fP.
.TP 8
.B -P\fIparameter=value\fP
Override (i.e. defparam) a parameter in a root module. This allows the
user to override at compile time (defparam) a parameter in a root
module instance. For example, \fB\-Pmain.foo=2\fP overrides the
parameter foo in the root instance main with the value 2.
.TP 8
.B -d\fIname\fP
Activate a class of compiler debugging messages. The \fB\-d\fP switch may
Activate a class of compiler debugging messages. The \fB-d\fP switch may
be used as often as necessary to activate all the desired messages.
Supported names are scopes, eval_tree, elaborate, and synth2;
any other names are ignored.
@@ -61,26 +55,20 @@ is the Verilog input, but with file inclusions and macro references
expanded and removed. This is useful, for example, to preprocess
Verilog source for use by other compilers.
.TP 8
.B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005\fI|\fP-g2005-sv\fI|\fP-g2009\fI|\fP-g2012
Select the Verilog language \fIgeneration\fP to support in the compiler.
This selects between \fIIEEE1364\-1995\fP, \fIIEEE1364\-2001\fP,
\fIIEEE1364\-2005\fP, \fIIEEE1800\-2005\fP, \fIIEEE1800\-2009\fP, or
\fIIEEE1800\-2012\fP.
Icarus Verilog currently defaults to the \fIIEEE1364\-2005\fP generation
of the language. This flag is used to restrict the language to a set of
keywords/features, this allows simulation of older Verilog code that may
use newer keywords and for compatibility with other tools. Much of the
\fIIEEE1800\fP generations functionality is not currently supported.
The \fIIEEE1800\fP generations do parse all the keywords, so they can
be used to verify that \fIIEEE1364\fP compliant Verilog code does not
use any of the new \fIIEEE1800\fP keywords.
.B -g1995\fI|\fP-g2001\fI|\fP-g2005
Select the Verilog language \fIgeneration\fP to support in the
compiler. This selects between \fIIEEE1364-1995\fP,
\fIIEEE1364-2001\fP(2), or \fIIEEE1364-2005\fP. Normally,
Icarus Verilog defaults to the latest known generation of the
language. This flag is most useful to restrict the language to a set
supported by tools of specific generations, for compatibility with
other tools.
.TP 8
.B -gverilog-ams\fI|\fP-gno-verilog-ams
Enable or disable (default) support for Verilog\-AMS.
Very little Verilog\-AMS specific functionality is currently supported.
.B -gverilog-ams\fI|-fP-gno-verilog-ams
Enable or disable (default) support for Verilog-AMS.
.TP 8
.B -gspecify\fI|\fP-gno-specify
Enable or disable (default) specify block support. When enabled,
Enable (default) or disable specify block support. When enabled,
specify block code is elaborated. When disabled, specify blocks are
parsed but ignored. Specify blocks are commonly not needed for RTL
simulation, and in fact can hurt performance of the
@@ -93,13 +81,6 @@ include directory after all other explicit include directories. This
standard include directory is a convenient place to install standard
header files that a Verilog program may include.
.TP 8
.B -grelative-include\fI|\fP-gno-relative-include
Enable or disable (default) adding the local files directory to
the beginning of the include file search path. This allows files
to be included relative to the current file not the more common
files are only found in the working directory or in the specified
include file search path.
.TP 8
.B -gxtypes\fI|\fP-gno-xtypes
Enable (default) or disable support for extended types. Enabling
extended types allows for new types that are supported by Icarus
@@ -112,49 +93,22 @@ The standards requires that a vectored port have matching ranges for its
port declaration as well as any net/register declaration. It was common
practice in the past to only specify the range for the net/register
declaration and some tools still allow this. By default any mismatch is
reported as a error. Using \fB\-gno\-io\-range\-error\fP will produce a
reported as a error. Using \fI-gno-io-range-error\fP will produce a
warning instead of a fatal error for the case of a vectored net/register
and a scalar port declaration.
.TP 8
.B -gstrict-ca-eval\fI|\fP-gno-strict-ca-eval
The standard requires that if any input to a continuous assignment
expression changes value, the entire expression is re-evaluated. By
default, parts of the expression that do not depend on the changed
input value(s) are not re-evaluated. If an expression contains a call
to a function that doesn't depend solely on its input values or that
has side effects, the resulting behavior will differ from that
required by the standard. Using \fI\-gstrict\-ca\-eval\fP will force
standard compliant behavior (with some loss in performance).
.TP 8
.B -gstrict-expr-width\fI|\fP-gno-strict-expr-width
Enable or disable (default) strict compliance with the standard rules
for determining expression bit lengths. When disabled, the RHS of a
parameter assignment is evaluated as a lossless expression, as is any
expression containing an unsized constant number, and unsized constant
numbers are not truncated to integer width.
.TP 8
.B -I\fIincludedir\fP
Append directory \fIincludedir\fP to list of directories searched
for Verilog include files. The \fB\-I\fP switch may be used many times
for Verilog include files. The \fB-I\fP switch may be used many times
to specify several directories to search, the directories are searched
in the order they appear on the command line.
.TP 8
.B -M\fIpath\fP
This is equivalent to \fB\-Mall=path\fP. Preserved for backwards
compatibility.
.TP 8
.B -M\fImode=path\fP
Write into the file specified by path a list of files that contribute to
the compilation of the design. If \fBmode\fP is \fBall\fP or \fBprefix\fP,
this includes files that are included by include directives and files
that are automatically loaded by library support as well as the files
explicitly specified by the user. If \fBmode\fP is \fBinclude\fP, only
files that are included by include directives are listed. If \fBmode\fP
is \fBmodule\fP, only files that are specified by the user or that are
automatically loaded by library support are listed. The output is one
file name per line, with no leading or trailing space. If \fBmode\fP
is \fBprefix\fP, files that are included by include directives are
prefixed by "I " and other files are prefixed by "M ".
Write into the file specified by path a list of files that contribute
to the compilation of the design. This includes files that are
included by include directives and files that are automatically loaded
by library support. The output is one file name per line, with no
leading or trailing space.
.TP 8
.B -m\fImodule\fP
Add this module to the list of VPI modules to be loaded by the
@@ -174,7 +128,7 @@ Place output in the file \fIfilename\fP. If no output file name is
specified, \fIiverilog\fP uses the default name \fBa.out\fP.
.TP 8
.B -p\fIflag=value\fP
Assign a value to a target specific flag. The \fB\-p\fP switch may be
Assign a value to a target specific flag. The \fB-p\fP switch may be
used as often as necessary to specify all the desired flags. The flags
that are used depend on the target that is selected, and are described
in target specific documentation. Flags that are not used are ignored.
@@ -182,15 +136,15 @@ in target specific documentation. Flags that are not used are ignored.
.B -S
Synthesize. Normally, if the target can accept behavioral
descriptions the compiler will leave processes in behavioral
form. The \fB\-S\fP switch causes the compiler to perform synthesis
form. The \fB-S\fP switch causes the compiler to perform synthesis
even if it is not necessary for the target. If the target type is a
netlist format, the \fB\-S\fP switch is unnecessary and has no effect.
netlist format, the \fB-S\fP switch is unnecessary and has no effect.
.TP 8
.B -s \fItopmodule\fP
Specify the top level module to elaborate. Icarus Verilog will by default
choose modules that are not instantiated in any other modules, but
sometimes that is not sufficient, or instantiates too many modules. If
the user specifies one or more root modules with \fB\-s\fP flags, then
the user specifies one or more root modules with \fB-s\fP flags, then
they will be used as root modules instead.
.TP 8
.B -T\fImin|typ|max\fP
@@ -213,12 +167,6 @@ a reference to a key temporary file that passes information to the
compiler proper. To keep that file from being deleted at the end
of the process, provide a file name of your own in the environment
variable \fBIVERILOG_ICONFIG\fP.
If the selected target is \fIvvp\fP, the \fB\-v\fP switch is appended
to the shebang line in the compiler output file, so directly executing
the compiler output file will turn on verbose messages in \fIvvp\fP.
This extra verbosity can be avoided by using the \fIvvp\fP command to
indirectly execute the compiler output file.
.TP 8
.B -V
Print the version of the compiler, and exit.
@@ -226,18 +174,13 @@ Print the version of the compiler, and exit.
.B -W\fIclass\fP
Turn on different classes of warnings. See the \fBWARNING TYPES\fP
section below for descriptions of the different warning groups. If
multiple \fB\-W\fP switches are used, the warning set is the union of
multiple \fB-W\fP switches are used, the warning set is the union of
all the requested classes.
.TP 8
.B -y\fIlibdir\fP
Append the directory to the library module search path. When the
compiler finds an undefined module, it looks in these directories for
files with the right name.
.TP 8
.B -Y\fIsuffix\fP
Add suffix to the list of accepted file name suffixes used when
searching a library for cells. The list defaults to the single
entry \fI.v\fP.
.SH MODULE LIBRARIES
@@ -256,7 +199,7 @@ library or in the main design.
.SH TARGETS
The Icarus Verilog compiler supports a variety of targets, for
different purposes, and the \fB\-t\fP switch is used to select the
different purposes, and the \fB-t\fP switch is used to select the
desired target.
.TP 8
@@ -267,16 +210,14 @@ checking the syntax of the Verilog source.
.B vvp
This is the default. The vvp target generates code for the vvp
runtime. The output is a complete program that simulates the design
but must be run by the \fBvvp\fP command. The -pfileline=1 option
can be used to add procedural statement debugging opcodes to the
generated code.
but must be run by the \fBvvp\fP command.
.TP 8
.B fpga
This is a synthesis target that supports a variety of fpga devices,
mostly by EDIF format output. The Icarus Verilog fpga code generator
can generate complete designs or EDIF macros that can in turn be
imported into larger designs by other tools. The \fBfpga\fP target
implies the synthesis \fB\-S\fP flag.
implies the synthesis \fB-S\fP flag.
.TP 8
.B vhdl
This target produces a VHDL translation of the Verilog netlist. The
@@ -285,20 +226,14 @@ the modules in the Verilog source code. Note that only a subset of
the Verilog language is supported. See the wiki for more information.
.SH "WARNING TYPES"
These are the types of warnings that can be selected by the \fB\-W\fP
These are the types of warnings that can be selected by the \fB-W\fP
switch. All the warning types (other than \fBall\fP) can also be
prefixed with \fBno\-\fP to turn off that warning. This is most useful
after a \fB\-Wall\fP argument to suppress isolated warning types.
prefixed with \fBno-\fP to turn off that warning. This is most useful
after a \fB-Wall\fP argument to suppress isolated warning types.
.TP 8
.B all
This enables the anachronisms, implicit, portbind, select\-range,
timescale, and sensitivity\-entire\-array warning categories.
.TP 8
.B anachronisms
This enables warnings for use of features that have been deprecated
or removed in the selected generation of the Verilog language.
This enables all supported warning categories.
.TP 8
.B implicit
@@ -312,12 +247,6 @@ This enables warnings for ports of module instantiations that are not
connected but probably should be. Dangling input ports, for example,
will generate a warning.
.TP 8
.B select-range
This enables warnings for constant out of bound selects. This includes
partial or fully out of bound selects as well as a select containing
a 'bx or 'bz in the index.
.TP 8
.B timescale
This enables warnings for inconsistent use of the timescale
@@ -330,7 +259,7 @@ and dependent on compilation order.
.B infloop
This enables warnings for \fRalways\fP statements that may have runtime
infinite loops (has paths with no or zero delay). This class of warnings
is not included in \fB\-Wall\fP and hence does not have a \fBno\-\fP variant.
is not included in \fB-Wall\fP and hence does not have a \fBno-\fP variant.
A fatal error message will always be printed when the compiler can
determine that there will definitely be an infinite loop (all paths have
no or zero delay).
@@ -341,22 +270,6 @@ verified. It is expected that many of the warnings will be false
positives, since the code treats the value of all variables and signals
as indeterminate.
.TP 8
.B sensitivity-entire-vector
This enables warnings for when a part select within an "always @*"
statement results in the entire vector being added to the implicit
sensitivity list. Although this behaviour is prescribed by the IEEE
standard, it is not what might be expected and can have performance
implications if the vector is large.
.TP 8
.B sensitivity-entire-array
This enables warnings for when a word select within an "always @*"
statement results in the entire array being added to the implicit
sensitivity list. Although this behaviour is prescribed by the IEEE
standard, it is not what might be expected and can have performance
implications if the array is large.
.SH "SYSTEM FUNCTION TABLE FILES"
If the source file name as a \fB.sft\fP suffix, then it is taken to be
a system function table file. A System function table file is used to
@@ -398,14 +311,14 @@ character. Variables are substituted in file names.
.TP 8
.B -c\ \fIcmdfile\fP -f\ \fIcmdfile\fP
A \fB\-c\fP or \fB\-f\fP token prefixes a command file, exactly like it
A \fB-c\fP or \fB-f\fP token prefixes a command file, exactly like it
does on the command line. The cmdfile may be on the same line or the
next non-comment line.
.TP 8
.B -y\ \fIlibdir\fP
A \fB\-y\fP token prefixes a library directory in the command file,
exactly like it does on the command line. The parameter to the \fB\-y\fP
A \fB-y\fP token prefixes a library directory in the command file,
exactly like it does on the command line. The parameter to the \fB-y\fP
flag may be on the same line or the next non-comment line.
Variables in the \fIlibdir\fP are substituted.
@@ -413,7 +326,7 @@ Variables in the \fIlibdir\fP are substituted.
.TP 8
.B +incdir+\fIincludedir\fP
The \fB+incdir+\fP token in command files gives directories to search
for include files in much the same way that \fB\-I\fP flags work on the
for include files in much the same way that \fB-I\fP flags work on the
command line. The difference is that multiple \fI+includedir\fP
directories are valid parameters to a single \fB+incdir+\fP token,
although you may also have multiple \fB+incdir+\fP lines.
@@ -424,12 +337,12 @@ Variables in the \fIincludedir\fP are substituted.
.B +libext+\fIext\fP
The \fB+libext\fP token in command files fives file extensions to try
when looking for a library file. This is useful in conjunction with
\fB\-y\fP flags to list suffixes to try in each directory before moving
\fB-y\fP flags to list suffixes to try in each directory before moving
on to the next library directory.
.TP 8
.B +libdir+\fIdir\fP
This is another way to specify library directories. See the \-y flag.
This is another way to specify library directories. See the -y flag.
.TP 8
.B +libdir-nocase+\fIdir\fP
@@ -441,31 +354,19 @@ letters are correct. For example, "foo" matches "Foo.v" but not
.TP 8
.B +define+\fINAME\fP=\fIvalue\fP
The \fB+define+\fP token is the same as the \fB\-D\fP option on the
The \fB+define+\fP token is the same as the \fB-D\fP option on the
command line. The value part of the token is optional.
.TP 8
.B +parameter+\fINAME\fP=\fIvalue\fP
The \fB+parameter+\fP token is the same as the \fB\-P\fP option on the
command line.
.TP 8
.B +timescale+\fIvalue\fP
The \fB+timescale+\fP token is used to set the default timescale for
the simulation. This is the time units and precision before any
`timescale directive or after a `resetall directive. The default is
1s/1s.
.TP 8
.B +toupper-filename
.B +toupper-filename\fP
This token causes file names after this in the command file to be
translated to uppercase. This helps with situations where a directory
has passed through a DOS machine, and in the process the file names
become munged.
.TP 8
.B +tolower-filename
This is similar to the \fB+toupper\-filename\fP hack described above.
.B +tolower-filename\fP
This is similar to the \fB+toupper-filename\fP hack described above.
.TP 8
.B +integer-width+\fIvalue\fP
@@ -473,17 +374,10 @@ This allows the programmer to select the width for integer variables
in the Verilog source. The default is 32, the value can be any desired
integer value.
.TP 8
.B +width-cap+\fIvalue\fP
This allows the programmer to select the width cap for unsized expressions.
If the calculated width for an unsized expression exceeds this value, the
compiler will issue a warning and limit the expression width to this value.
.SH "VARIABLES IN COMMAND FILES"
In certain cases, iverilog supports variables in command files. These
are strings of the form "$(\fIvarname\fP)" or "${\fIvarname\fP}", where
\fIvarname\fP is the
are strings of the form "$(\fIvarname\fP)", where \fIvarname\fP is the
name of the environment variable to read. The entire string is
replaced with the contents of that variable. Variables are only
substituted in contexts that explicitly support them, including file
@@ -496,12 +390,12 @@ from preprocessor defines elsewhere in the file or the command line.
The following macros are predefined by the compiler:
.TP 8
.B __ICARUS__ = 1
This is always defined when compiling with Icarus Verilog.
.B __ICARUS__ = 1\fP
This is defined always when compiling with Icarus Verilog.
.TP 8
.B __VAMS_ENABLE__ = 1
This is defined if Verilog\-AMS is enabled.
.B __VAMS_ENABLE__ = 1\fp
This is defined if Verilog-AMS is enabled.
.SH EXAMPLES
These examples assume that you have a Verilog source file called hello.v in
@@ -513,11 +407,11 @@ To compile hello.v to an executable file called a.out:
To compile hello.v to an executable file called hello:
iverilog \-o hello hello.v
iverilog -o hello hello.v
To compile and run explicitly using the vvp runtime:
iverilog \-ohello.vvp \-tvvp hello.v
iverilog -ohello.vvp -tvvp hello.v
.SH "AUTHOR"
.nf
@@ -525,14 +419,14 @@ Steve Williams ([email protected])
.SH SEE ALSO
vvp(1),
.BR "<http://iverilog.icarus.com/>"
.BR "<http://www.icarus.com/eda/verilog/>"
Tips on using, debugging, and developing the compiler can be found at
.BR "<http://iverilog.wikia.com/>"
.SH COPYRIGHT
.nf
Copyright \(co 2002\-2015 Stephen Williams
Copyright \(co 2002-2008 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+100 -355
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2015 Stephen Williams ([email protected])
* Copyright (c) 2000-2008 Stephen Williams ([email protected])
*
* 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,12 +14,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "version_base.h"
# include "version_tag.h"
# include "version.h"
const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n"
@@ -32,16 +31,14 @@ const char NOTICE[] =
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
" GNU General Public License for more details.\n"
"\n"
" You should have received a copy of the GNU General Public License along\n"
" with this program; if not, write to the Free Software Foundation, Inc.,\n"
" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n"
" You should have received a copy of the GNU General Public License\n"
" along with this program; if not, write to the Free Software\n"
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
;
const char HELP[] =
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile]\n"
" [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012] [-g<feature>]\n"
" [-D macro[=defn]] [-I includedir]\n"
" [-M [mode=]depfile] [-m module]\n"
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile] [-g1|-g2|-g2x]\n"
" [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
" [-N file] [-o filename] [-p flag=value]\n"
" [-s topmodule] [-t target] [-T min|typ|max]\n"
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
@@ -63,15 +60,13 @@ const char HELP[] =
#endif
#ifdef __MINGW32__
# include <windows.h>
# include <io.h>
#include <windows.h>
#ifdef HAVE_LIBIBERTY_H
# include <libiberty.h>
#include <libiberty.h>
#endif
#endif
#include <fcntl.h>
#ifdef HAVE_GETOPT_H
#if HAVE_GETOPT_H
#include <getopt.h>
#endif
@@ -95,7 +90,6 @@ extern const char*optarg;
# include "globals.h"
#include "cfparse_misc.h" /* cfparse() */
#include "ivl_alloc.h"
#ifdef __MINGW32__
const char sep = '\\';
@@ -106,43 +100,27 @@ const char sep = '/';
extern void cfreset(FILE*fd, const char*path);
const char*base = 0;
const char*ivlpp_dir = 0;
const char*vhdlpp_dir= 0;
const char*vhdlpp_work = 0;
const char*pbase = 0;
const char*mtm = 0;
const char*opath = "a.out";
const char*npath = 0;
const char*targ = "vvp";
const char*depfile = 0;
const char**vhdlpp_libdir = 0;
unsigned vhdlpp_libdir_cnt = 0;
char depmode = 'a';
const char*generation = "2005";
const char*gen_specify = "no-specify";
const char*gen_assertions = "assertions";
const char*gen_specify = "specify";
const char*gen_xtypes = "xtypes";
const char*gen_icarus = "icarus-misc";
const char*gen_io_range_error = "io-range-error";
const char*gen_strict_ca_eval = "no-strict-ca-eval";
const char*gen_strict_expr_width = "no-strict-expr-width";
const char*gen_verilog_ams = "no-verilog-ams";
/* Boolean: true means use a default include dir, false means don't */
int gen_std_include = 1;
/* Boolean: true means add the local file directory to the start
of the include list. */
int gen_relative_include = 0;
char warning_flags[16] = "n";
char warning_flags[16] = "";
unsigned integer_width = 32;
unsigned width_cap = 65536;
char*mod_list = 0;
char*command_filename = 0;
@@ -161,7 +139,8 @@ FILE*iconfig_file = 0;
char*compiled_defines_path = 0;
static char iconfig_common_path[4096] = "";
static char iconfig_common_path_buf[4096] = "";
char*iconfig_common_path = iconfig_common_path_buf;
int synth_flag = 0;
int verbose_flag = 0;
@@ -181,14 +160,8 @@ typedef struct t_command_file {
p_command_file cmd_file_head = NULL; /* The FIFO head */
p_command_file cmd_file_tail = NULL; /* The FIFO tail */
/* Temporarily store parameter definition from command line and
* parse it after we have dealt with command file
*/
static const char** defparm_base = 0;
static int defparm_size = 0;
/* Function to add a command file name to the FIFO. */
static void add_cmd_file(const char* filename)
void add_cmd_file(const char* filename)
{
p_command_file new;
@@ -205,7 +178,7 @@ static void add_cmd_file(const char* filename)
}
/* Function to return the top command file name from the FIFO. */
static char *get_cmd_file(void)
char *get_cmd_file()
{
char *filename;
@@ -222,6 +195,8 @@ static char *get_cmd_file(void)
}
#ifdef __MINGW32__
# include <io.h>
# include <fcntl.h>
static FILE*fopen_safe(const char*path)
{
FILE*file = 0;
@@ -234,6 +209,7 @@ static FILE*fopen_safe(const char*path)
return file;
}
#else
# include <fcntl.h>
static FILE*fopen_safe(const char*path)
{
FILE*file = 0;
@@ -247,23 +223,6 @@ static FILE*fopen_safe(const char*path)
}
#endif
#ifdef __MINGW32__
/*
* The MinGW version of getenv() returns the path with a forward
* slash. This should be converted to a back slash to keep every
* thing in the code using a back slash. This function wraps the
* code for this in one place. The conversion can not be done
* directly on the getenv() result since it is const char*.
*/
static void convert_to_MS_path(char *path)
{
char *t;
for (t = path; *t; t++) {
if (*t == '/') *t = '\\';
}
}
#endif
static const char*my_tempfile(const char*str, FILE**fout)
{
FILE*file;
@@ -292,11 +251,7 @@ static const char*my_tempfile(const char*str, FILE**fout)
file = NULL;
while ((retry > 0) && (file == NULL)) {
unsigned code = rand();
snprintf(pathbuf, sizeof pathbuf, "%s%c%s%04x",
tmpdir, sep, str, code);
#ifdef __MINGW32__
convert_to_MS_path(pathbuf);
#endif
sprintf(pathbuf, "%s%c%s%04x", tmpdir, sep, str, code);
file = fopen_safe(pathbuf);
retry -= 1;
}
@@ -307,24 +262,17 @@ static const char*my_tempfile(const char*str, FILE**fout)
static int t_version_only(void)
{
int rc;
remove(source_path);
free(source_path);
fflush(0);
snprintf(tmp, sizeof tmp, "%s%civlpp -V", ivlpp_dir, sep);
rc = system(tmp);
if (rc != 0) {
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
}
snprintf(tmp, sizeof tmp, "%s%civlpp -V", pbase, sep);
system(tmp);
fflush(0);
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep,
snprintf(tmp, sizeof tmp, "%s%civl -V -C%s -C%s", pbase, sep,
iconfig_path, iconfig_common_path);
rc = system(tmp);
if (rc != 0) {
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
}
system(tmp);
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(iconfig_path);
@@ -340,8 +288,8 @@ static int t_version_only(void)
static void build_preprocess_command(int e_flag)
{
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F\"%s\" -f\"%s\" -p\"%s\" ",
ivlpp_dir, sep, verbose_flag?" -v":"",
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F%s -f%s -p%s ",
pbase,sep, verbose_flag?" -v":"",
e_flag?"":" -L", defines_path, source_path,
compiled_defines_path);
}
@@ -359,7 +307,7 @@ static int t_preprocess_only(void)
strcpy(cmd, tmp);
if (strcmp(opath,"-") != 0) {
snprintf(tmp, sizeof tmp, " > \"%s\"", opath);
snprintf(tmp, sizeof tmp, " > %s", opath);
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
@@ -384,7 +332,6 @@ static int t_preprocess_only(void)
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors preprocessing Verilog program.\n");
free(cmd);
return WEXITSTATUS(rc);
}
@@ -402,7 +349,7 @@ static int t_preprocess_only(void)
* needed to run the command from the configuration file (which is
* already parsed for us) so we can handle must of the generic cases.
*/
static int t_compile(void)
static int t_compile()
{
unsigned rc;
@@ -413,12 +360,14 @@ static int t_compile(void)
char*cmd = malloc(ncmd + 1);
strcpy(cmd, tmp);
#ifndef __MINGW32__
#ifdef __MINGW32__
unsigned ncmd_start = ncmd;
#else
int rtn;
#endif
/* Build the ivl command and pipe it to the preprocessor. */
snprintf(tmp, sizeof tmp, " | %s%civl", base, sep);
snprintf(tmp, sizeof tmp, " | %s/ivl", base);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
@@ -433,25 +382,35 @@ static int t_compile(void)
}
if (npath != 0) {
snprintf(tmp, sizeof tmp, " -N\"%s\"", npath);
snprintf(tmp, sizeof tmp, " -N%s", npath);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
ncmd += rc;
}
snprintf(tmp, sizeof tmp, " -C\"%s\"", iconfig_path);
snprintf(tmp, sizeof tmp, " -C%s", iconfig_path);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
ncmd += rc;
snprintf(tmp, sizeof tmp, " -C\"%s\" -- -", iconfig_common_path);
snprintf(tmp, sizeof tmp, " -C%s -- -", iconfig_common_path);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
strcpy(cmd+ncmd, tmp);
ncmd += rc;
#ifdef __MINGW32__
{
char *t;
for (t = cmd+ncmd_start; *t; t++)
{
if (*t == '/') *t = '\\';
}
}
#endif
if (verbose_flag)
printf("translate: %s\n", cmd);
@@ -494,24 +453,15 @@ static int t_compile(void)
static void process_warning_switch(const char*name)
{
if (strcmp(name,"all") == 0) {
process_warning_switch("anachronisms");
process_warning_switch("implicit");
process_warning_switch("portbind");
process_warning_switch("select-range");
process_warning_switch("timescale");
process_warning_switch("sensitivity-entire-array");
} else if (strcmp(name,"anachronisms") == 0) {
if (! strchr(warning_flags, 'n'))
strcat(warning_flags, "n");
} else if (strcmp(name,"implicit") == 0) {
if (! strchr(warning_flags, 'i'))
strcat(warning_flags, "i");
} else if (strcmp(name,"portbind") == 0) {
if (! strchr(warning_flags, 'p'))
strcat(warning_flags, "p");
} else if (strcmp(name,"select-range") == 0) {
if (! strchr(warning_flags, 's'))
strcat(warning_flags, "s");
} else if (strcmp(name,"timescale") == 0) {
if (! strchr(warning_flags, 't'))
strcat(warning_flags, "t");
@@ -520,18 +470,6 @@ static void process_warning_switch(const char*name)
} else if (strcmp(name,"infloop") == 0) {
if (! strchr(warning_flags, 'l'))
strcat(warning_flags, "l");
} else if (strcmp(name,"sensitivity-entire-vector") == 0) {
if (! strchr(warning_flags, 'v'))
strcat(warning_flags, "v");
} else if (strcmp(name,"sensitivity-entire-array") == 0) {
if (! strchr(warning_flags, 'a'))
strcat(warning_flags, "a");
} else if (strcmp(name,"no-anachronisms") == 0) {
char*cp = strchr(warning_flags, 'n');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-implicit") == 0) {
char*cp = strchr(warning_flags, 'i');
if (cp) while (*cp) {
@@ -544,33 +482,12 @@ static void process_warning_switch(const char*name)
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-select-range") == 0) {
char*cp = strchr(warning_flags, 's');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-timescale") == 0) {
char*cp = strchr(warning_flags, 't');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-sensitivity-entire-vector") == 0) {
char*cp = strchr(warning_flags, 'v');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else if (strcmp(name,"no-sensitivity-entire-array") == 0) {
char*cp = strchr(warning_flags, 'a');
if (cp) while (*cp) {
cp[0] = cp[1];
cp += 1;
}
} else {
fprintf(stderr, "Ignoring unknown warning class "
"%s\n", name);
}
}
@@ -599,16 +516,6 @@ void process_define(const char*name)
fprintf(defines_file,"D:%s\n", name);
}
void process_parameter(const char*name)
{
fprintf(iconfig_file,"defparam:%s\n", name);
}
void process_timescale(const char*ts_string)
{
fprintf(iconfig_file, "timescale:%s\n", ts_string);
}
/*
* This function is called while processing a file name in a command
* file, or a file name on the command line. Look to see if there is a
@@ -628,7 +535,7 @@ void process_file_name(const char*name, int lib_flag)
}
}
static int process_generation(const char*name)
int process_generation(const char*name)
{
if (strcmp(name,"1995") == 0)
generation = "1995";
@@ -636,21 +543,9 @@ static int process_generation(const char*name)
else if (strcmp(name,"2001") == 0)
generation = "2001";
else if (strcmp(name,"2001-noconfig") == 0)
generation = "2001-noconfig";
else if (strcmp(name,"2005") == 0)
generation = "2005";
else if (strcmp(name,"2005-sv") == 0)
generation = "2005-sv";
else if (strcmp(name,"2009") == 0)
generation = "2009";
else if (strcmp(name,"2012") == 0)
generation = "2012";
else if (strcmp(name,"1") == 0) { /* Deprecated: use 1995 */
generation = "1995";
gen_xtypes = "no-xtypes";
@@ -684,42 +579,18 @@ static int process_generation(const char*name)
else if (strcmp(name,"no-specify") == 0)
gen_specify = "no-specify";
else if (strcmp(name,"assertions") == 0)
gen_assertions = "assertions";
else if (strcmp(name,"no-assertions") == 0)
gen_assertions = "no-assertions";
else if (strcmp(name,"std-include") == 0)
gen_std_include = 1;
else if (strcmp(name,"no-std-include") == 0)
gen_std_include = 0;
else if (strcmp(name,"relative-include") == 0)
gen_relative_include = 1;
else if (strcmp(name,"no-relative-include") == 0)
gen_relative_include = 0;
else if (strcmp(name,"io-range-error") == 0)
gen_io_range_error = "io-range-error";
else if (strcmp(name,"no-io-range-error") == 0)
gen_io_range_error = "no-io-range-error";
else if (strcmp(name,"strict-ca-eval") == 0)
gen_strict_ca_eval = "strict-ca-eval";
else if (strcmp(name,"no-strict-ca-eval") == 0)
gen_strict_ca_eval = "no-strict-ca-eval";
else if (strcmp(name,"strict-expr-width") == 0)
gen_strict_expr_width = "strict-expr-width";
else if (strcmp(name,"no-strict-expr-width") == 0)
gen_strict_expr_width = "no-strict-expr-width";
else if (strcmp(name,"verilog-ams") == 0)
gen_verilog_ams = "verilog-ams";
@@ -730,64 +601,26 @@ static int process_generation(const char*name)
fprintf(stderr, "Unknown/Unsupported Language generation "
"%s\n\n", name);
fprintf(stderr, "Supported generations are:\n");
fprintf(stderr, " 1995 -- IEEE1364-1995\n"
" 2001 -- IEEE1364-2001\n"
" 2005 -- IEEE1364-2005\n"
" 2005-sv -- IEEE1800-2005\n"
" 2009 -- IEEE1800-2009\n"
" 2012 -- IEEE1800-2012\n"
fprintf(stderr, " 1995 -- IEEE1364-1995\n"
" 2001 -- IEEE1364-2001\n"
" 2005 -- IEEE1364-2005\n"
"Other generation flags:\n"
" specify | no-specify\n"
" verilog-ams | no-verilog-ams\n"
" std-include | no-std-include\n"
" relative-include | no-relative-include\n"
" xtypes | no-xtypes\n"
" icarus-misc | no-icarus-misc\n"
" io-range-error | no-io-range-error\n"
" strict-ca-eval | no-strict-ca-eval\n"
" strict-expr-width | no-strict-expr-width\n");
" io-range-error | no-io-range-error\n");
return 1;
}
return 0;
}
static int process_depfile(const char*name)
{
const char*cp = strchr(name, '=');
if (cp) {
int match_length = (int)(cp - name) + 1;
if (strncmp(name, "all=", match_length) == 0) {
depmode = 'a';
} else if (strncmp(name, "include=", match_length) == 0) {
depmode = 'i';
} else if (strncmp(name, "module=", match_length) == 0) {
depmode = 'm';
} else if (strncmp(name, "prefix=", match_length) == 0) {
depmode = 'p';
} else {
fprintf(stderr, "Unknown dependency file mode '%.*s'\n\n",
match_length - 1, name);
fprintf(stderr, "Supported modes are:\n");
fprintf(stderr, " all\n");
fprintf(stderr, " include\n");
fprintf(stderr, " module\n");
fprintf(stderr, " prefix\n");
return -1;
}
depfile = cp + 1;
} else {
depmode = 'a';
depfile = name;
}
return 0;
}
/*
* If it exists add the SFT file for the given module.
*/
static void add_sft_file(const char *module)
void add_sft_file(const char *module)
{
char *file;
@@ -802,45 +635,37 @@ int main(int argc, char **argv)
{
int e_flag = 0;
int version_flag = 0;
int opt;
int opt, idx, rc;
#ifdef __MINGW32__
/* Calculate the ivl_root from the path to the command. This
is necessary because of the installation process on
Windows. Mostly, it is those darn drive letters, but oh
well. We know the command path is formed like this:
{ char * s;
char basepath[1024];
GetModuleFileName(NULL,basepath,1024);
D:\iverilog\bin\iverilog.exe
/* Calculate the ivl_root from the path to the command. This
is necessary because of the installation process in
Windows. Mostly, it is those darn drive letters, but oh
well. We know the command path is formed like this:
The module path in a Windows installation is the path:
D:\iverilog\bin\iverilog.exe
D:\iverilog\lib\ivl$(suffix)
The IVL_ROOT in a Windows installation is the path:
so we chop the file name and the last directory by
turning the last two \ characters to null. Then we append
the lib\ivl$(suffix) to finish. */
char *s;
char tmppath[MAXSIZE];
GetModuleFileName(NULL, tmppath, sizeof tmppath);
/* Convert to a short name to remove any embedded spaces. */
GetShortPathName(tmppath, ivl_root, sizeof ivl_root);
s = strrchr(ivl_root, sep);
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing first %c in exe path!\n",
argv[0], sep);
exit(1);
D:\iverilog\lib\ivl
so we chop the file name and the last directory by
turning the last two \ characters to null. Then we append
the lib\ivl to finish. */
strncpy(ivl_root, basepath, MAXSIZE);
s = strrchr(ivl_root, sep);
if (s) *s = 0;
s = strrchr(ivl_root, sep);
if (s) *s = 0;
strcat(ivl_root, "\\lib\\ivl");
base = ivl_root;
}
s = strrchr(ivl_root, sep);
if (s) *s = 0;
else {
fprintf(stderr, "%s: Missing second %c in exe path!\n",
argv[0], sep);
exit(1);
}
strcat(ivl_root, "\\lib\\ivl" IVL_SUFFIX);
base = ivl_root;
#else
/* In a UNIX environment, the IVL_ROOT from the Makefile is
@@ -910,24 +735,18 @@ int main(int argc, char **argv)
}
}
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hI:M:m:N:o:P:p:Ss:T:t:vVW:y:Y:")) != EOF) {
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hI:M:m:N::o:p:Ss:T:t:vVW:y:Y:")) != EOF) {
switch (opt) {
case 'B':
/* The individual components can be located by a
single base, or by individual bases. The first
character of the path indicates which path the
user is specifying. */
switch (optarg[0]) {
case 'P': /* Path for the ivlpp preprocessor */
ivlpp_dir = optarg+1;
break;
case 'V': /* Path for the vhdlpp VHDL processor */
vhdlpp_dir = optarg+1;
break;
default: /* Otherwise, this is a default base. */
/* Undocumented feature: The preprocessor itself
may be located at a different location. If the
base starts with a 'P', set this special base
instead of the main base. */
if (optarg[0] == 'P') {
pbase = optarg+1;
} else {
base=optarg;
break;
}
break;
case 'c':
@@ -940,12 +759,6 @@ int main(int argc, char **argv)
case 'E':
e_flag = 1;
break;
case 'P':
defparm_size += 1;
defparm_base = (const char**)realloc(defparm_base,
defparm_size*sizeof(char*));
defparm_base[defparm_size-1] = optarg;
break;
case 'p':
fprintf(iconfig_file, "flag:%s\n", optarg);
break;
@@ -954,7 +767,8 @@ int main(int argc, char **argv)
break;
case 'g':
if (process_generation(optarg) != 0)
rc = process_generation(optarg);
if (rc != 0)
return -1;
break;
case 'h':
@@ -966,8 +780,7 @@ int main(int argc, char **argv)
break;
case 'M':
if (process_depfile(optarg) != 0)
return -1;
depfile = optarg;
break;
case 'm':
@@ -1022,38 +835,22 @@ int main(int argc, char **argv)
break;
case '?':
default:
fclose(source_file);
remove(source_path);
free(source_path);
fclose(defines_file);
remove(defines_path);
free(defines_path);
fclose(iconfig_file);
remove(iconfig_path);
free(iconfig_path);
remove(compiled_defines_path);
free(compiled_defines_path);
while( (command_filename = get_cmd_file()) ) {
free(command_filename);
}
return 1;
}
}
if (ivlpp_dir == 0)
ivlpp_dir = base;
if (vhdlpp_dir == 0)
vhdlpp_dir = base;
if (pbase == 0)
pbase = base;
if (version_flag || verbose_flag) {
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
printf("Copyright 1998-2015 Stephen Williams\n\n");
printf("Copyright 1998-2008 Stephen Williams\n");
puts(NOTICE);
}
/* Make a common conf file path to reflect the target. */
snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf",
base, sep, targ, synth_flag? "-s" : "");
sprintf(iconfig_common_path, "%s%c%s%s.conf",
base,sep, targ, synth_flag? "-s" : "");
/* Write values to the iconfig file. */
fprintf(iconfig_file, "basedir:%s\n", base);
@@ -1062,13 +859,10 @@ int main(int argc, char **argv)
describes the system functions so that elaboration knows
how to handle them. */
fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
fprintf(iconfig_file, "sys_func:%s%cvhdl_sys.sft\n", base, sep);
/* If verilog-2005/09/12 is enabled or icarus-misc or verilog-ams,
/* If verilog-2005 is enabled or icarus-misc or verilog-ams,
* then include the v2005_math library. */
if (strcmp(generation, "2005") == 0 ||
strcmp(generation, "2009") == 0 ||
strcmp(generation, "2012") == 0 ||
strcmp(gen_icarus, "icarus-misc") == 0 ||
strcmp(gen_verilog_ams, "verilog-ams") == 0) {
fprintf(iconfig_file, "sys_func:%s%cv2005_math.sft\n", base, sep);
@@ -1081,31 +875,17 @@ int main(int argc, char **argv)
fprintf(iconfig_file, "sys_func:%s%cva_math.sft\n", base, sep);
fprintf(iconfig_file, "module:va_math\n");
}
/* If verilog-2009 (SystemVerilog) is enabled, then include the
v2009 module. */
if (strcmp(generation, "2005-sv") == 0 ||
strcmp(generation, "2009") == 0 ||
strcmp(generation, "2012") == 0) {
fprintf(iconfig_file, "sys_func:%s%cv2009.sft\n", base, sep);
fprintf(iconfig_file, "module:v2009\n");
}
if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
fprintf(iconfig_file, "generation:%s\n", generation);
fprintf(iconfig_file, "generation:%s\n", gen_specify);
fprintf(iconfig_file, "generation:%s\n", gen_assertions);
fprintf(iconfig_file, "generation:%s\n", gen_xtypes);
fprintf(iconfig_file, "generation:%s\n", gen_io_range_error);
fprintf(iconfig_file, "generation:%s\n", gen_strict_ca_eval);
fprintf(iconfig_file, "generation:%s\n", gen_strict_expr_width);
fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
fprintf(iconfig_file, "generation:%s\n", gen_icarus);
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
fprintf(iconfig_file, "out:%s\n", opath);
if (depfile) {
fprintf(iconfig_file, "depfile:%s\n", depfile);
fprintf(iconfig_file, "depmode:%c\n", depmode);
}
if (depfile) fprintf(iconfig_file, "depfile:%s\n", depfile);
while ( (command_filename = get_cmd_file()) ) {
int rc;
@@ -1124,46 +904,22 @@ int main(int argc, char **argv)
return 1;
}
free(command_filename);
fclose(fp);
}
destroy_lexor();
if (depfile) {
fprintf(defines_file, "M%c:%s\n", depmode, depfile);
fprintf(defines_file, "M:%s\n", depfile);
}
if (vhdlpp_work == 0)
vhdlpp_work = "ivl_vhdl_work";
fprintf(defines_file, "vhdlpp:%s%cvhdlpp\n", vhdlpp_dir, sep);
fprintf(defines_file, "vhdlpp-work:%s\n", vhdlpp_work);
for (unsigned idx = 0 ; idx < vhdlpp_libdir_cnt ; idx += 1)
fprintf(defines_file, "vhdlpp-libdir:%s\n", vhdlpp_libdir[idx]);
/* Process parameter definition from command line. The last
defined would override previous ones. */
int pitr;
for (pitr = 0; pitr < defparm_size; pitr++)
process_parameter(defparm_base[pitr]);
free(defparm_base);
defparm_base = 0;
defparm_size = 0;
/* Finally, process all the remaining words on the command
line as file names. */
for (int idx = optind ; idx < argc ; idx += 1)
for (idx = optind ; idx < argc ; idx += 1)
process_file_name(argv[idx], 0);
/* If the use of a default include directory is not
specifically disabled, then write that directory as the
very last include directory to use... always. */
if (gen_std_include) {
fprintf(defines_file, "I:%s%cinclude\n", base, sep);
}
if (gen_relative_include) {
fprintf(defines_file, "relative include:true\n");
} else {
fprintf(defines_file, "relative include:false\n");
fprintf(defines_file, "I:%s%cinclude", base, sep);
}
fclose(source_file);
@@ -1172,15 +928,6 @@ int main(int argc, char **argv)
fclose(defines_file);
defines_file = 0;
/* If we are planning on opening a dependencies file, then
open and truncate it here. The other phases of compilation
will append to the file, so this is necessary to make sure
it starts out empty. */
if (depfile) {
FILE*fd = fopen(depfile, "w");
fclose(fd);
}
if (source_count == 0 && !version_flag) {
fprintf(stderr, "%s: no source files.\n\n%s\n", argv[0], HELP);
return 1;
@@ -1188,13 +935,11 @@ int main(int argc, char **argv)
fprintf(iconfig_file, "iwidth:%u\n", integer_width);
fprintf(iconfig_file, "widthcap:%u\n", width_cap);
/* Write the preprocessor command needed to preprocess a
single file. This may be used to preprocess library
files. */
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F\"%s\" -P\"%s\"\n",
ivlpp_dir, sep, defines_path, compiled_defines_path);
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F%s -P%s\n",
pbase, sep, defines_path, compiled_defines_path);
/* Done writing to the iconfig file. Close it now. */
fclose(iconfig_file);
+34 -15
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002 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,14 +14,17 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: substit.c,v 1.5 2003/12/19 01:27:10 steve Exp $"
#endif
# include <string.h>
# include <stdlib.h>
# include <stdio.h>
# include "ivl_alloc.h"
# include "globals.h"
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
char* substitutions(const char*str)
@@ -32,13 +35,13 @@ char* substitutions(const char*str)
while (*str) {
if ((str[0] == '$') && ((str[1] == '(') || str[1] == '{')) {
/* If I find a $(x) or ${x} string in the source, replace
if ((str[0] == '$') && (str[1] == '(')) {
/* If I find a $(x) string in the source, replace
it in the destination with the contents of the
environment variable x. */
char*name;
char*value;
const char*ep = strchr(str, (str[1]=='(') ? ')' : '}');
const char*ep = strchr(str, ')');
str += 2;
name = malloc(ep-str+1);
@@ -48,14 +51,9 @@ char* substitutions(const char*str)
str = ep + 1;
value = getenv(name);
if (value == 0) {
fprintf(stderr, "Warning: environment variable "
"\"%s\" not found during command file "
"processing.\n", name);
free(name);
continue;
}
free(name);
if (value == 0)
continue;
if (strlen(value) >= (nbuf - (cp-buf))) {
size_t old_size = cp - buf;
@@ -94,3 +92,24 @@ char* substitutions(const char*str)
return buf;
}
/*
* $Log: substit.c,v $
* Revision 1.5 2003/12/19 01:27:10 steve
* Fix various unsigned compare warnings.
*
* Revision 1.4 2002/08/12 01:35:01 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/08/11 23:47:04 steve
* Add missing Log and Ident strings.
*
* Revision 1.2 2002/06/25 01:33:01 steve
* include malloc.h only when available.
*
* Revision 1.1 2002/06/23 20:10:51 steve
* Variable substitution in command files.
*
*/
+28 -190
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -14,14 +14,14 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "netlist.h"
# include <cassert>
# include <cstdlib>
# include <stdlib.h>
# include "ivl_assert.h"
NetEAccess* NetEAccess::dup_expr() const
@@ -32,122 +32,19 @@ NetEAccess* NetEAccess::dup_expr() const
return tmp;
}
NetEArrayPattern*NetEArrayPattern::dup_expr() const
{
vector<NetExpr*>tmp (items_.size());
for (size_t idx = 0 ; idx < tmp.size() ; idx += 1)
tmp[idx] = items_[idx]->dup_expr();
NetEArrayPattern*res = new NetEArrayPattern(net_type(), tmp);
res->set_line(*this);
return res;
}
NetEBinary* NetEBinary::dup_expr() const
{
ivl_assert(*this, 0);
return 0;
}
NetEBAdd* NetEBAdd::dup_expr() const
{
NetEBAdd*tmp = new NetEBAdd(op_, left_->dup_expr(), right_->dup_expr(),
expr_width(), has_sign());
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetEBBits* NetEBBits::dup_expr() const
{
NetEBBits*tmp = new NetEBBits(op_, left_->dup_expr(), right_->dup_expr(),
expr_width(), has_sign());
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetEBComp* NetEBComp::dup_expr() const
{
NetEBComp*tmp = new NetEBComp(op_, left_->dup_expr(), right_->dup_expr());
ivl_assert(*this, tmp);
NetEBComp*tmp = new NetEBComp(op_, left_->dup_expr(),
right_->dup_expr());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
NetEBDiv* NetEBDiv::dup_expr() const
{
NetEBDiv*tmp = new NetEBDiv(op_, left_->dup_expr(), right_->dup_expr(),
expr_width(), has_sign());
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetEBLogic* NetEBLogic::dup_expr() const
{
NetEBLogic*tmp = new NetEBLogic(op_, left_->dup_expr(), right_->dup_expr());
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetEBMult* NetEBMult::dup_expr() const
{
NetEBMult*tmp = new NetEBMult(op_, left_->dup_expr(), right_->dup_expr(),
expr_width(), has_sign());
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetEBPow* NetEBPow::dup_expr() const
{
NetEBPow*tmp = new NetEBPow(op_, left_->dup_expr(), right_->dup_expr(),
expr_width(), has_sign());
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetEBShift* NetEBShift::dup_expr() const
{
NetEBShift*tmp = new NetEBShift(op_, left_->dup_expr(), right_->dup_expr(),
expr_width(), has_sign());
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetEConcat* NetEConcat::dup_expr() const
{
NetEConcat*dup = new NetEConcat(parms_.size(), repeat_, expr_type_);
ivl_assert(*this, dup);
dup->set_line(*this);
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1)
if (parms_[idx]) {
NetExpr*tmp = parms_[idx]->dup_expr();
ivl_assert(*this, tmp);
dup->parms_[idx] = tmp;
}
dup->expr_width(expr_width());
return dup;
}
NetEConst* NetEConst::dup_expr() const
{
NetEConst*tmp = new NetEConst(value_);
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetEConstEnum* NetEConstEnum::dup_expr() const
{
NetEConstEnum*tmp = new NetEConstEnum(scope_, name_, enum_set_, value());
ivl_assert(*this, tmp);
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -155,15 +52,7 @@ NetEConstEnum* NetEConstEnum::dup_expr() const
NetEConstParam* NetEConstParam::dup_expr() const
{
NetEConstParam*tmp = new NetEConstParam(scope_, name_, value());
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetECReal* NetECReal::dup_expr() const
{
NetECReal*tmp = new NetECReal(value_);
ivl_assert(*this, tmp);
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -171,52 +60,20 @@ NetECReal* NetECReal::dup_expr() const
NetECRealParam* NetECRealParam::dup_expr() const
{
NetECRealParam*tmp = new NetECRealParam(scope_, name_, value());
ivl_assert(*this, tmp);
assert(tmp);
tmp->set_line(*this);
return tmp;
}
NetEEvent* NetEEvent::dup_expr() const
{
ivl_assert(*this, 0);
return 0;
}
NetELast* NetELast::dup_expr() const
{
NetELast*tmp = new NetELast(sig_);
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetENetenum* NetENetenum::dup_expr() const
{
ivl_assert(*this, 0);
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);
assert(0);
return 0;
}
NetEScope* NetEScope::dup_expr() const
{
ivl_assert(*this, 0);
assert(0);
return 0;
}
@@ -224,9 +81,8 @@ NetESelect* NetESelect::dup_expr() const
{
NetESelect*tmp = new NetESelect(expr_->dup_expr(),
base_? base_->dup_expr() : 0,
expr_width(), sel_type_);
ivl_assert(*this, tmp);
tmp->cast_signed(has_sign());
expr_width());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -234,11 +90,11 @@ NetESelect* NetESelect::dup_expr() const
NetESFunc* NetESFunc::dup_expr() const
{
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms());
ivl_assert(*this, tmp);
assert(tmp);
tmp->cast_signed(has_sign());
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
ivl_assert(*this, parm(idx));
assert(parm(idx));
tmp->parm(idx, parm(idx)->dup_expr());
}
@@ -246,18 +102,11 @@ NetESFunc* NetESFunc::dup_expr() const
return tmp;
}
NetEShallowCopy* NetEShallowCopy::dup_expr() const
{
ivl_assert(*this, 0);
return 0;
}
NetESignal* NetESignal::dup_expr() const
{
NetESignal*tmp = new NetESignal(net_, word_);
ivl_assert(*this, tmp);
assert(tmp);
tmp->expr_width(expr_width());
tmp->cast_signed(has_sign());
tmp->set_line(*this);
return tmp;
}
@@ -266,10 +115,8 @@ NetETernary* NetETernary::dup_expr() const
{
NetETernary*tmp = new NetETernary(cond_->dup_expr(),
true_val_->dup_expr(),
false_val_->dup_expr(),
expr_width(),
has_sign());
ivl_assert(*this, tmp);
false_val_->dup_expr());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -277,33 +124,32 @@ NetETernary* NetETernary::dup_expr() const
NetEUFunc* NetEUFunc::dup_expr() const
{
NetEUFunc*tmp;
vector<NetExpr*> tmp_parms (parms_.size());
svector<NetExpr*> tmp_parms (parms_.count());
for (unsigned idx = 0 ; idx < tmp_parms.size() ; idx += 1) {
ivl_assert(*this, parms_[idx]);
for (unsigned idx = 0 ; idx < tmp_parms.count() ; idx += 1) {
assert(parms_[idx]);
tmp_parms[idx] = parms_[idx]->dup_expr();
}
tmp = new NetEUFunc(scope_, func_, result_sig_->dup_expr(), tmp_parms,
need_const_);
tmp = new NetEUFunc(scope_, func_, result_sig_->dup_expr(), tmp_parms);
ivl_assert(*this, tmp);
assert(tmp);
tmp->set_line(*this);
return tmp;
}
NetEUBits* NetEUBits::dup_expr() const
{
NetEUBits*tmp = new NetEUBits(op_, expr_->dup_expr(), expr_width(), has_sign());
ivl_assert(*this, tmp);
NetEUBits*tmp = new NetEUBits(op_, expr_->dup_expr());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
NetEUnary* NetEUnary::dup_expr() const
{
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr(), expr_width(), has_sign());
ivl_assert(*this, tmp);
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -311,15 +157,7 @@ NetEUnary* NetEUnary::dup_expr() const
NetEUReduce* NetEUReduce::dup_expr() const
{
NetEUReduce*tmp = new NetEUReduce(op_, expr_->dup_expr());
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetECast* NetECast::dup_expr() const
{
NetECast*tmp = new NetECast(op_, expr_->dup_expr(), expr_width(), has_sign());
ivl_assert(*this, tmp);
assert(tmp);
tmp->set_line(*this);
return tmp;
}
+48 -1
View File
@@ -14,8 +14,11 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: elab_anet.cc,v 1.13 2007/03/22 16:08:14 steve Exp $"
#endif
# include "config.h"
@@ -164,3 +167,47 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
return sig;
}
/*
* $Log: elab_anet.cc,v $
* Revision 1.13 2007/03/22 16:08:14 steve
* Spelling fixes from Larry
*
* Revision 1.12 2006/05/01 20:47:58 steve
* More explicit datatype setup.
*
* Revision 1.11 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures.
*
* Revision 1.10 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.9 2003/09/19 03:50:12 steve
* Remove find_memory method from Design class.
*
* Revision 1.8 2003/06/21 01:21:43 steve
* Harmless fixup of warnings.
*
* Revision 1.7 2003/03/06 00:28:41 steve
* All NetObj objects have lex_string base names.
*
* Revision 1.6 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.3 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.2 2001/01/06 02:29:36 steve
* Support arrays of integers.
*
* Revision 1.1 2000/12/06 06:31:09 steve
* Check lvalue of procedural continuous assign (PR#29)
*
*/
+1512 -4618
View File
File diff suppressed because it is too large Load Diff
+125 -971
View File
File diff suppressed because it is too large Load Diff
+125 -532
View File
@@ -1,6 +1,5 @@
/*
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -15,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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
@@ -23,8 +22,6 @@
# include "PExpr.h"
# include "netlist.h"
# include "netmisc.h"
# include "netstruct.h"
# include "netvector.h"
# include "compiler.h"
# include <cstdlib>
@@ -44,7 +41,7 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
{
assert(scope);
svector<NetNet*>nets (parms_.size());
svector<NetNet*>nets (parms_.count());
unsigned width = 0;
unsigned errors = 0;
@@ -75,21 +72,18 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
} else {
nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
}
if (nets[idx] == 0) {
errors += 1;
} else if (nets[idx]->data_type() == IVL_VT_REAL) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can no be real: "
<< *parms_[idx] << endl;
if (nets[idx] == 0)
errors += 1;
continue;
} else {
width += nets[idx]->vector_width();
}
else
width += nets[idx]->vector_width();
}
/* If any of the sub expressions failed to elaborate, then
delete all those that did and abort myself. */
if (errors) {
for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
if (nets[idx]) delete nets[idx];
}
des->errors += errors;
return 0;
}
@@ -99,12 +93,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, tmp2_vec);
NetNet::IMPLICIT, width);
/* 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);
@@ -155,6 +149,8 @@ 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;
}
@@ -168,26 +164,27 @@ NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope) const
return elaborate_lnet_common_(des, scope, true);
}
bool PEConcat::is_collapsible_net(Design*des, NetScope*scope) const
/*
* A private method to create an implicit net.
*/
NetNet* PEIdent::make_implicit_net_(Design*des, NetScope*scope) const
{
assert(scope);
NetNet::Type nettype = scope->default_nettype();
assert(nettype != NetNet::NONE);
// Repeat concatenations are not currently supported.
if (repeat_)
return false;
NetNet*sig = new NetNet(scope, peek_tail_name(path_),
NetNet::IMPLICIT, 1);
sig->set_line(*this);
/* Implicit nets are always scalar logic. */
sig->data_type(IVL_VT_LOGIC);
// Test the operands of the concatenation.
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
// Empty expressions are not allowed in concatenations
if (parms_[idx] == 0)
return false;
if (!parms_[idx]->is_collapsible_net(des, scope))
return false;
if (warn_implicit) {
cerr << get_fileline() << ": warning: implicit "
"definition of wire logic " << scope_path(scope)
<< "." << peek_tail_name(path_) << "." << endl;
}
return true;
return sig;
}
/*
@@ -200,15 +197,11 @@ bool PEConcat::is_collapsible_net(Design*des, NetScope*scope) const
bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
long&midx, long&lidx) const
{
list<long> prefix_indices;
bool rc = calculate_packed_indices_(des, scope, sig, prefix_indices);
ivl_assert(*this, rc);
const name_component_t&name_tail = path_.back();
// 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->unpacked_dimensions()) {
if (name_tail.index.size() <= sig->array_dimensions()) {
midx = sig->vector_width()-1;
lidx = 0;
return true;
@@ -227,7 +220,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
case index_component_t::SEL_IDX_DO:
case index_component_t::SEL_IDX_UP: {
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1, true);
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) {
cerr << get_fileline() << ": error: indexed part select of "
@@ -237,38 +230,20 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
return 0;
}
long midx_val = tmp->value().as_long();
midx = sig->sb_to_idx(midx_val);
delete tmp_ex;
/* The width (a constant) is calculated here. */
unsigned long wid = 0;
bool flag = calculate_up_do_width_(des, scope, wid);
if (! flag) return false;
/* We have an undefined index and that is out of range. */
if (! tmp->value().is_defined()) {
if (warn_ob_select) {
cerr << get_fileline() << ": warning: "
<< sig->name();
if (sig->unpacked_dimensions() > 0) cerr << "[]";
cerr << "['bx";
if (index_tail.sel ==
index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is always outside the vector."
<< endl;
}
if (! flag)
return false;
}
long midx_val = tmp->value().as_long();
midx = sig->sb_to_idx(prefix_indices, midx_val);
delete tmp_ex;
if (index_tail.sel == index_component_t::SEL_IDX_UP)
lidx = sig->sb_to_idx(prefix_indices, midx_val+wid-1);
lidx = sig->sb_to_idx(midx_val+wid-1);
else
lidx = sig->sb_to_idx(prefix_indices, midx_val-wid+1);
lidx = sig->sb_to_idx(midx_val-wid+1);
if (midx < lidx) {
long tmpx = midx;
@@ -277,20 +252,10 @@ 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->unpacked_dimensions() > 0) cerr << "[]";
cerr << "[" << midx_val;
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting before vector." << endl;
}
if (warn_ob_select && (midx >= (long)sig->vector_width())) {
cerr << get_fileline() << ": warning: " << sig->name();
if (sig->unpacked_dimensions() > 0) {
if (midx >= (long)sig->vector_width() || lidx < 0) {
cerr << get_fileline() << ": warning: Indexed part "
"select " << sig->name();
if (sig->array_dimensions() > 0) {
cerr << "[]";
}
cerr << "[" << midx_val;
@@ -299,7 +264,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
} else {
cerr << "-:";
}
cerr << wid << "] is selecting after vector." << endl;
cerr << wid << "] is out of range." << endl;
}
/* This is completely out side the signal so just skip it. */
@@ -313,23 +278,10 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
case index_component_t::SEL_PART: {
long msb, lsb;
bool part_defined_flag;
/* bool flag = */ calculate_parts_(des, scope, msb, lsb, part_defined_flag);
/* bool flag = */ calculate_parts_(des, scope, msb, lsb);
/* We have an undefined index and that is out of range. */
if (!part_defined_flag) {
if (warn_ob_select) {
cerr << get_fileline() << ": warning: "
<< sig->name();
if (sig->unpacked_dimensions() > 0) cerr << "[]";
cerr << "['bx] is always outside the vector."
<< endl;
}
return false;
}
long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb);
long midx_tmp = sig->sb_to_idx(prefix_indices, msb);
long lidx_tmp = sig->sb_to_idx(lsb);
long midx_tmp = sig->sb_to_idx(msb);
/* Detect reversed indices of a part select. */
if (lidx_tmp > midx_tmp) {
cerr << get_fileline() << ": error: Part select "
@@ -348,11 +300,16 @@ 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->unpacked_dimensions() > 0) {
if (sig->array_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) {
@@ -365,43 +322,30 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
}
case index_component_t::SEL_BIT:
if (name_tail.index.size() > sig->unpacked_dimensions()) {
long msb;
bool bit_defined_flag;
/* bool flag = */ calculate_bits_(des, scope, msb, bit_defined_flag);
/* We have an undefined index and that is out of range. */
if (!bit_defined_flag) {
if (warn_ob_select) {
cerr << get_fileline() << ": warning: "
<< sig->name();
if (sig->unpacked_dimensions() > 0) cerr << "[]";
cerr << "['bx] is always outside the vector."
<< endl;
}
if (name_tail.index.size() > sig->array_dimensions()) {
verinum*mval = index_tail.msb->eval_const(des, scope);
if (mval == 0) {
cerr << get_fileline() << ": error: Index of " << path_ <<
" needs to be constant in this context." <<
endl;
cerr << get_fileline() << ": : Index expression is: "
<< *index_tail.msb << endl;
cerr << get_fileline() << ": : Context scope is: "
<< scope_path(scope) << endl;
des->errors += 1;
return false;
}
assert(mval);
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;
midx = sig->sb_to_idx(mval->as_long());
if (midx >= (long)sig->vector_width()) {
cerr << get_fileline() << ": error: Index " << sig->name()
<< "[" << mval->as_long() << "] is out of range."
<< endl;
des->errors += 1;
midx = 0;
}
lidx = midx;
} else {
cerr << get_fileline() << ": internal error: "
@@ -429,7 +373,6 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
NetNet* sig = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
perm_string method_name;
symbol_search(this, des, scope, path_, sig, par, eve);
@@ -441,35 +384,6 @@ 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) {
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;
}
}
if (sig == 0) {
cerr << get_fileline() << ": error: Net " << path_
<< " is not defined in this context." << endl;
@@ -479,15 +393,6 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
assert(sig);
/* If this is SystemVerilog and the variable is not yet
assigned by anything, then convert it to an unresolved
wire. */
if (gn_var_can_be_uwire()
&& (sig->type() == NetNet::REG)
&& (sig->peek_lref() == 0) ) {
sig->type(NetNet::UNRESOLVED_WIRE);
}
/* Don't allow registers as assign l-values. */
if (sig->type() == NetNet::REG) {
cerr << get_fileline() << ": error: reg " << sig->name()
@@ -497,207 +402,64 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
return 0;
}
if (sig->port_type() == NetNet::PINPUT) {
cerr << get_fileline() << ": warning: L-value ``"
<< sig->name() << "'' is also an input port." << endl;
cerr << sig->get_fileline() << ": warning: input "
<< sig->name() << "; is coerced to inout." << endl;
sig->port_type(NetNet::PINOUT);
}
// Default part select is the entire word.
unsigned midx = sig->vector_width()-1, lidx = 0;
// The default word select is the first.
long widx = 0;
// Set this to true if we calculate the word index. This is
// used to distinguish between unpacked array assignment and
// array word assignment.
bool widx_flag = false;
unsigned widx = 0;
list<long> unpacked_indices_const;
const name_component_t&name_tail = path_.back();
const netstruct_t*struct_type = 0;
if ((struct_type = sig->struct_type()) && !method_name.nil()) {
if (sig->array_dimensions() > 0) {
// Detect the variable is a structure and there was a
// 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() << ": PEIdent::elaborate_lnet_common_: "
<< "Signal " << sig->name() << " is a structure, "
<< "try to match member " << method_name << endl;
unsigned long member_off = 0;
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 type " << *member->net_type << "." << 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->net_type->packed_width() - 1;
// 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 dimensions: one for the struct
// members and two actual packed dimensions.
ivl_assert(*this, path_prefix.back().index.size()+1 == sig->packed_dimensions());
// 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() << ": PEIdent::elaborate_lnet_common_: "
<< "packed_base=" << *packed_base
<< ", member_off=" << member_off << endl;
}
}
long tmp;
if (packed_base && eval_as_long(tmp, packed_base)) {
lidx = tmp;
midx = lidx + member->net_type->packed_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.
//XXXXivl_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 (gn_system_verilog() && sig->unpacked_dimensions() > 0 && path_tail.index.empty()) {
// In this case, we are doing a continuous assignment to
// an unpacked array. The NetNet representation is a
// NetNet with a pin for each array element, so there is
// nothing more needed here.
//
// This can come up from code like this:
// logic [...] data [0:3];
// assign data = ...;
// In this case, "sig" is "data", and sig->pin_count()
// is 4 to account for the unpacked size.
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
<< "Net assign to unpacked array \"" << sig->name()
<< "\" with " << sig->pin_count() << " elements." << endl;
}
} 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() << ". (net)" << endl;
if (name_tail.index.empty()) {
cerr << get_fileline() << ": error: array " << sig->name()
<< " must be used with an index." << endl;
des->errors += 1;
return 0;
}
// Evaluate all the index expressions into an
// "unpacked_indices" array.
list<NetExpr*>unpacked_indices;
indices_flags flags;
indices_to_expressions(des, scope, this,
path_tail.index, sig->unpacked_dimensions(),
true,
flags,
unpacked_indices,
unpacked_indices_const);
if (flags.invalid) {
return 0;
} else if (flags.variable) {
cerr << get_fileline() << ": error: array '" << sig->name()
<< "' index must be a constant in this context." << endl;
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;
} else if (flags.undefined) {
cerr << get_fileline() << ": warning: "
<< "ignoring undefined l-value array access "
<< sig->name() << as_indices(unpacked_indices)
<< "." << endl;
widx = -1;
widx_flag = true;
} 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) {
cerr << get_fileline() << ": warning: "
<< "ignoring out of bounds l-value array access "
<< sig->name() << as_indices(unpacked_indices_const)
<< "." << endl;
widx = -1;
widx_flag = true;
} else {
NetEConst*canon_const = dynamic_cast<NetEConst*>(canon_index);
ivl_assert(*this, canon_const);
widx = canon_const->value().as_long();
widx_flag = true;
delete canon_index;
}
}
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
if (!tmp) {
cerr << get_fileline() << ": error: array " << sig->name()
<< " index must be a constant in this context." << endl;
des->errors += 1;
return 0;
}
long widx_val = tmp->value().as_long();
widx = sig->array_index_to_address(widx_val);
delete tmp_ex;
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 (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()
<< as_indices(unpacked_indices_const) << endl;
des->errors += 1;
return 0;
}
if (name_tail.index.size() > sig->array_dimensions()) {
long midx_tmp, lidx_tmp;
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
return 0;
if (lidx_tmp < 0) {
cerr << get_fileline() << ": sorry: part selects "
cerr << get_fileline() << ": sorry: part selects "
"straddling the start of signal (" << path_
<< ") are not currently supported." << endl;
des->errors += 1;
@@ -706,34 +468,13 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
midx = midx_tmp;
lidx = lidx_tmp;
}
} else if (!path_tail.index.empty()) {
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
<< "path_tail.index.size()=" << path_tail.index.size()
<< endl;
}
// There are index expressions on the name, so this is a
// bit/slice select of the name. Calculate a canonical
// part select.
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 << sig->name() << endl;
des->errors += 1;
return 0;
}
} else if (!name_tail.index.empty()) {
long midx_tmp, lidx_tmp;
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
return 0;
if (lidx_tmp < 0) {
cerr << get_fileline() << ": sorry: part selects "
cerr << get_fileline() << ": sorry: part selects "
"straddling the start of signal (" << path_
<< ") are not currently supported." << endl;
des->errors += 1;
@@ -745,46 +486,22 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
unsigned subnet_wid = midx-lidx+1;
/* Check if the l-value bits are double-driven. */
if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->test_and_set_part_driver(midx,lidx, widx_flag? widx : 0)) {
cerr << get_fileline() << ": error: Unresolved net/uwire "
<< sig->name() << " cannot have multiple drivers." << endl;
if (debug_elaborate) {
cerr << get_fileline() << ": : Overlap in "
<< "[" << midx << ":" << lidx << "] (canonical)"
<< ", widx=" << (widx_flag? widx : 0)
<< ", vector width=" << sig->vector_width()
<< endl;
}
des->errors += 1;
return 0;
}
if (sig->pin_count() > 1) {
assert(widx < sig->pin_count());
if (sig->pin_count() > 1 && widx_flag) {
if (widx < 0 || widx >= (long) sig->pin_count())
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(), tmp2_vec);
sig->type(), sig->vector_width());
tmp->set_line(*this);
tmp->local_flag(true);
tmp->data_type( sig->data_type() );
connect(sig->pin(widx), tmp->pin(0));
sig = tmp;
} else if (sig->pin_count() > 1) {
// If this turns out to be an l-value unpacked array,
// then let the caller handle it. It will probably be
// converted into an array of assignments.
return sig;
}
/* If the desired l-value vector is narrower than the
/* If the desired l-value vector is narrower then the
signal itself, then use a NetPartSelect node to
arrange for connection to the desired bits. All this
can be skipped if the desired width matches the
can be skipped if the desired with matches the
original vector. */
if (subnet_wid != sig->vector_width()) {
@@ -800,11 +517,10 @@ 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, tmp2_vec);
NetNet::WIRE, subnet_wid);
subsig->data_type( sig->data_type() );
subsig->local_flag(true);
subsig->set_line(*this);
@@ -824,7 +540,6 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
des->add_node(sub);
sub->set_line(*this);
connect(sub->pin(0), subsig->pin(0));
collapse_partselect_pv_to_concat(des, sig);
}
sig = subsig;
}
@@ -854,9 +569,8 @@ NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
* instantiation (PGModule::elaborate_mod_) to get NetNet objects for
* the port.
*/
NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
{
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_
@@ -871,7 +585,6 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
case NetNet::PINPUT:
case NetNet::POUTPUT:
case NetNet::PINOUT:
case NetNet::PREF:
break;
/* If the name matches, but the signal is not a port,
@@ -901,33 +614,6 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
long midx;
long lidx;
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_subport: "
<< "path_ = \"" << path_
<< "\", unpacked_dimensions=" << sig->unpacked_dimensions()
<< ", port_type()=" << sig->port_type() << endl;
}
if (sig->unpacked_dimensions() && !gn_system_verilog()) {
cerr << get_fileline() << ": error: "
<< "Ports cannot be unpacked arrays. Try enabling SystemVerilog support." << endl;
des->errors += 1;
return 0;
}
// There cannot be parts to an unpacked array, so process this
// simply as an unpacked array.
if (sig->unpacked_dimensions()) {
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_subport: "
<< "path_=\"" << path_
<< "\" is an unpacked array with " << sig->pin_count()
<< " elements." << endl;
}
scope->add_module_port_net(sig);
return sig;
}
/* Evaluate the part/bit select expressions, to get the part
select of the signal that attaches to the port. Also handle
range and direction checking here. */
@@ -935,106 +621,13 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
if (! eval_part_select_(des, scope, sig, midx, lidx))
return 0;
/* 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_net(sig);
return sig;
unsigned swid = midx - lidx + 1;
if (swid < sig->vector_width()) {
cerr << get_fileline() << ": XXXX: Forgot to implement part select"
<< " of signal port." << endl;
}
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, tmp2_vec);
tmp->port_type(sig->port_type());
tmp->set_line(*this);
tmp->local_flag(true);
NetNode*ps = 0;
switch (sig->port_type()) {
case NetNet::PINPUT:
ps = new NetPartSelect(sig, lidx, swid, NetPartSelect::PV);
connect(tmp->pin(0), ps->pin(0));
sig = tmp;
break;
case NetNet::POUTPUT:
ps = new NetPartSelect(sig, lidx, swid, NetPartSelect::VP);
connect(tmp->pin(0), ps->pin(0));
sig = tmp;
break;
case NetNet::PREF:
// For the purposes of module ports, treat ref ports
// just like inout ports.
case NetNet::PINOUT:
ps = new NetTran(scope, scope->local_symbol(), sig->vector_width(),
swid, lidx);
connect(sig->pin(0), ps->pin(0));
connect(tmp->pin(0), ps->pin(1));
sig = tmp;
break;
default:
ivl_assert(*this, 0);
break;
}
ps->set_line(*this);
des->add_node(ps);
scope->add_module_port_net(sig);
return sig;
}
NetNet*PEIdent::elaborate_unpacked_net(Design*des, NetScope*scope) const
{
NetNet* sig = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
perm_string method_name;
symbol_search(this, des, scope, path_, sig, par, eve);
ivl_assert(*this, sig);
return sig;
}
bool PEIdent::is_collapsible_net(Design*des, NetScope*scope) const
{
assert(scope);
NetNet* sig = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(this, des, scope, path_, sig, par, eve);
if (eve != 0)
return false;
if (sig == 0)
return false;
assert(sig);
/* If this is SystemVerilog and the variable is not yet
assigned by anything, then convert it to an unresolved
wire. */
if (gn_var_can_be_uwire()
&& (sig->type() == NetNet::REG)
&& (sig->peek_eref() == 0) ) {
sig->type(NetNet::UNRESOLVED_WIRE);
}
if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->pin(0).is_linked())
return false;
if (sig->type() == NetNet::REG)
return false;
return true;
}
+440
View File
@@ -0,0 +1,440 @@
/*
* Copyright (c) 2000-2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "PExpr.h"
# include "compiler.h"
# include "util.h"
# include "netmisc.h"
# include <cstdlib>
# include <iostream>
# include "ivl_assert.h"
NetExpr*PExpr::elaborate_pexpr(Design*des, NetScope*sc) const
{
cerr << get_fileline() << ": error: invalid parameter expression: "
<< *this << endl;
des->errors += 1;
return 0;
}
/*
* Binary operators have sub-expressions that must be elaborated as
* parameter expressions. If either of them fail, then give up. Once
* they are taken care of, make the base object just as in any other
* expression.
*/
NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
{
NetExpr*lp = left_->elaborate_pexpr(des, scope);
NetExpr*rp = right_->elaborate_pexpr(des, scope);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
return 0;
}
NetExpr*tmp = elaborate_expr_base_(des, lp, rp, -2);
return tmp;
}
NetExpr*PEBComp::elaborate_pexpr(Design*des, NetScope*scope) const
{
NetExpr*lp = left_->elaborate_pexpr(des, scope);
NetExpr*rp = right_->elaborate_pexpr(des, scope);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
return 0;
}
suppress_binary_operand_sign_if_needed_(lp, rp);
NetEBComp*tmp = new NetEBComp(op_, lp, rp);
tmp->set_line(*this);
bool flag = tmp->set_width(1);
if (flag == false) {
cerr << get_fileline() << ": internal error: "
"expression bit width of comparison != 1." << endl;
des->errors += 1;
}
return tmp;
}
NetExpr*PEBLogic::elaborate_pexpr(Design*des, NetScope*scope) const
{
NetExpr*lp = left_->elaborate_pexpr(des, scope);
NetExpr*rp = right_->elaborate_pexpr(des, scope);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
return 0;
}
NetEBLogic*tmp = new NetEBLogic(op_, lp, rp);
tmp->set_line(*this);
bool flag = tmp->set_width(1);
if (flag == false) {
cerr << get_fileline() << ": internal error: "
"expression bit width of comparison != 1." << endl;
des->errors += 1;
}
return tmp;
}
/*
* Event though parameters are not generally sized, parameter
* expressions can include concatenation expressions. This requires
* that the subexpressions all have well-defined size (in spite of
* being in a parameter expression) in order to get a defined
* value. The sub-expressions themselves must also be value parameter
* expressions.
*/
NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
{
NetExpr* repeat = 0;
/* If there is a repeat expression, then evaluate the constant
value and set the repeat count. */
if (repeat_) {
repeat = repeat_->elaborate_pexpr(des, scope);
if (repeat == 0) {
cerr << get_fileline() << ": error: "
"concatenation repeat expression cannot be evaluated."
<< endl;
des->errors += 1;
return 0;
}
/* continue on even if the repeat expression doesn't
work, as we can find more errors. */
}
/* Make the empty concat expression. */
NetEConcat*tmp = new NetEConcat(parms_.count(), repeat);
tmp->set_line(*this);
/* Elaborate all the operands and attach them to the concat
node. Use the elaborate_pexpr method instead of the
elaborate_expr method. */
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
if (ex == 0) continue;
ex->set_line(*parms_[idx]);
if (dynamic_cast<NetEParam*>(ex)) {
/* If this parameter is a NetEParam, then put off
the width check for later. */
} else if (! ex->has_width()) {
cerr << ex->get_fileline() << ": error: operand of "
<< "concatenation has indefinite width: "
<< *ex << endl;
des->errors += 1;
delete tmp;
return 0;
}
tmp->set(idx, ex);
}
return tmp;
}
NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
{
return elaborate_expr(des, scope, -1, false);
}
/*
* Parameter expressions may reference other parameters, but only in
* the current scope. Preserve the parameter reference in the
* parameter expression I'm generating, instead of evaluating it now,
* because the referenced parameter may yet be overridden.
*/
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
{
pform_name_t oldpath = path_;
name_component_t name_tail = path_.back();
oldpath.pop_back();
NetScope*pscope = scope;
if (path_.size() > 0) {
list<hname_t> tmp = eval_scope_path(des, scope, oldpath);
pscope = des->find_scope(scope, tmp);
}
const NetExpr*ex_msb;
const NetExpr*ex_lsb;
const NetExpr*ex = 0;
// Look up the parameter name in the current scope. If the
// name is not found in the pscope, look in containing scopes,
// but do not go outside the containing module instance.
for (;;) {
ex = pscope->get_parameter(name_tail.name, ex_msb, ex_lsb);
if (ex != 0)
break;
if (pscope->type() == NetScope::MODULE)
break;
pscope = pscope->parent();
ivl_assert(*this, pscope);
}
if (ex == 0) {
cerr << get_fileline() << ": error: identifier ``" << name_tail.name <<
"'' is not a parameter in "<< scope_path(scope)<< "." << endl;
des->errors += 1;
return 0;
}
NetExpr*res = new NetEParam(des, pscope, name_tail.name);
res->set_line(*this);
assert(res);
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
switch (use_sel) {
case index_component_t::SEL_NONE:
break;
default:
case index_component_t::SEL_PART:
cerr << get_fileline() << ": sorry: Cannot part select "
"bits of parameters." << endl;
des->errors += 1;
delete res;
return 0;
case index_component_t::SEL_BIT:
/* We have here a bit select. Insert a NetESelect node
to handle it. */
NetExpr*tmp = name_tail.index.back().msb->elaborate_pexpr(des, scope);
if (tmp == 0) {
delete res;
return 0;
}
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Bit select [" << *tmp << "]"
<< " in parameter expression." << endl;
res = new NetESelect(res, tmp, 1);
res->set_line(*this);
break;
}
return res;
}
/*
* Simple numbers can be elaborated by the elaborate_expr method.
*/
NetExpr*PENumber::elaborate_pexpr(Design*des, NetScope*sc) const
{
return elaborate_expr(des, sc, -1, false);
}
NetEConst* PEString::elaborate_pexpr(Design*des, NetScope*scope) const
{
return elaborate_expr(des, scope, -1, false);
}
NetETernary* PETernary::elaborate_pexpr(Design*des, NetScope*scope) const
{
NetExpr*c = expr_->elaborate_pexpr(des, scope);
NetExpr*t = tru_->elaborate_pexpr(des, scope);
NetExpr*f = fal_->elaborate_pexpr(des, scope);
if (c == 0 || t == 0 || f == 0) return 0;
NetETernary*tmp = new NetETernary(c, t, f);
tmp->set_line(*this);
return tmp;
}
NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
{
NetExpr*ip = expr_->elaborate_pexpr(des, scope);
if (ip == 0) return 0;
/* Should we evaluate expressions ahead of time,
* just like in PEBinary::elaborate_expr() ?
*/
NetEUnary*tmp;
switch (op_) {
default:
tmp = new NetEUnary(op_, ip);
tmp->set_line(*this);
break;
case '~':
tmp = new NetEUBits(op_, ip);
tmp->set_line(*this);
break;
case '!': // Logical NOT
case '&': // Reduction AND
case '|': // Reduction OR
case '^': // Reduction XOR
case 'A': // Reduction NAND (~&)
case 'N': // Reduction NOR (~|)
case 'X': // Reduction NXOR (~^)
tmp = new NetEUReduce(op_, ip);
tmp->set_line(*this);
break;
}
return tmp;
}
NetExpr* PECallFunction::elaborate_pexpr(Design*des, NetScope*scope) const
{
/* Only $clog2 and the builtin mathematical functions can
* be a constant system function. */
perm_string nm = peek_tail_name(path_);
if (nm[0] == '$' && (generation_flag >= GN_VER2005 ||
gn_icarus_misc_flag || gn_verilog_ams_flag)) {
if (nm == "$clog2" ||
nm == "$ln" ||
nm == "$log10" ||
nm == "$exp" ||
nm == "$sqrt" ||
nm == "$floor" ||
nm == "$ceil" ||
nm == "$sin" ||
nm == "$cos" ||
nm == "$tan" ||
nm == "$asin" ||
nm == "$acos" ||
nm == "$atan" ||
nm == "$sinh" ||
nm == "$cosh" ||
nm == "$tanh" ||
nm == "$asinh" ||
nm == "$acosh" ||
nm == "$atanh") {
if (parms_.size() != 1 || parms_[0] == 0) {
cerr << get_fileline() << ": error: " << nm
<< " takes a single argument." << endl;
des->errors += 1;
return 0;
}
NetExpr*arg = parms_[0]->elaborate_pexpr(des, scope);
if (arg == 0) return 0;
NetESFunc*rtn;
if (nm == "$clog2") {
rtn = new NetESFunc(nm, IVL_VT_BOOL, integer_width, 1);
} else {
rtn = new NetESFunc(nm, IVL_VT_REAL, 1, 1);
}
rtn->set_line(*this);
rtn->cast_signed(true);
rtn->parm(0, arg);
return rtn;
}
if (nm == "$pow" ||
nm == "$atan2" ||
nm == "$hypot") {
if (parms_.size() != 2 || parms_[0] == 0 || parms_[1] == 0) {
cerr << get_fileline() << ": error: " << nm
<< " takes two arguments." << endl;
des->errors += 1;
return 0;
}
NetExpr*arg0 = parms_[0]->elaborate_pexpr(des, scope);
NetExpr*arg1 = parms_[1]->elaborate_pexpr(des, scope);
if (arg0 == 0 || arg1 == 0) return 0;
NetESFunc*rtn = new NetESFunc(nm, IVL_VT_REAL, 1, 2);
rtn->set_line(*this);
rtn->cast_signed(true);
rtn->parm(0, arg0);
rtn->parm(1, arg1);
return rtn;
}
/* These are only available with verilog-ams or icarus-misc. */
if ((gn_icarus_misc_flag || gn_verilog_ams_flag) &&
(nm == "$log" || nm == "$abs")) {
if (parms_.size() != 1 || parms_[0] == 0) {
cerr << get_fileline() << ": error: " << nm
<< " takes a single argument." << endl;
des->errors += 1;
return 0;
}
NetExpr*arg = parms_[0]->elaborate_pexpr(des, scope);
if (arg == 0) return 0;
NetESFunc*rtn;
if (nm == "$log") {
rtn = new NetESFunc(nm, IVL_VT_REAL, 1, 1);
} else {
/* This can return either a real or an arbitrary
* width vector, so set things to fail if this
* does not get replaced with a constant during
* elaboration. */
rtn = new NetESFunc(nm, IVL_VT_NO_TYPE, 0, 1);
}
rtn->set_line(*this);
rtn->cast_signed(true);
rtn->parm(0, arg);
return rtn;
}
if ((gn_icarus_misc_flag || gn_verilog_ams_flag) &&
(nm == "$min" || nm == "$max")) {
if (parms_.size() != 2 || parms_[0] == 0 || parms_[1] == 0) {
cerr << get_fileline() << ": error: " << nm
<< " takes two arguments." << endl;
des->errors += 1;
return 0;
}
NetExpr*arg0 = parms_[0]->elaborate_pexpr(des, scope);
NetExpr*arg1 = parms_[1]->elaborate_pexpr(des, scope);
if (arg0 == 0 || arg1 == 0) return 0;
/* See $log above for why this has no type or width. */
NetESFunc*rtn = new NetESFunc(nm, IVL_VT_NO_TYPE, 0, 2);
rtn->set_line(*this);
rtn->cast_signed(true);
rtn->parm(0, arg0);
rtn->parm(1, arg1);
return rtn;
}
cerr << get_fileline() << ": error: this is not a constant "
"system function (" << *this << ")." << endl;
des->errors += 1;
return 0;
}
/* Constant user function code goes here. */
cerr << get_fileline() << ": sorry: constant user functions are not "
"currently supported." << endl;
des->errors += 1;
return 0;
}
+323 -1159
View File
File diff suppressed because it is too large Load Diff
+449 -722
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
-259
View File
@@ -1,259 +0,0 @@
/*
* Copyright (c) 2012-2014 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 "netclass.h"
# include "netdarray.h"
# include "netenum.h"
# include "netparray.h"
# include "netscalar.h"
# include "netstruct.h"
# include "netvector.h"
# include "netmisc.h"
# include <typeinfo>
# include "ivl_assert.h"
using namespace std;
/*
* Some types have a list of ranges that need to be elaborated. This
* function elaborates the ranges referenced by "dims" into the vector
* "ranges".
*/
static void elaborate_array_ranges(Design*des, NetScope*scope,
vector<netrange_t>&ranges,
const list<pform_range_t>*dims)
{
if (dims == 0)
return;
for (list<pform_range_t>::const_iterator cur = dims->begin()
; cur != dims->end() ; ++ cur) {
NetExpr*me = elab_and_eval(des, scope, cur->first, 0, true);
NetExpr*le = elab_and_eval(des, scope, cur->second, 0, true);
/* If elaboration failed for either expression, we
should have already reported the error, so just
skip the following evaluation to recover. */
long mnum = 0, lnum = 0;
if ( me && ! eval_as_long(mnum, me) ) {
assert(0);
des->errors += 1;
}
if ( le && ! eval_as_long(lnum, le) ) {
assert(0);
des->errors += 1;
}
ranges.push_back(netrange_t(mnum, lnum));
}
}
/*
* Elaborations of types may vary depending on the scope that it is
* done in, so keep a per-scope cache of the results.
*/
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope)
{
Definitions*use_definitions = scope;
if (use_definitions == 0)
use_definitions = des;
map<Definitions*,ivl_type_s*>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
if (pos != cache_type_elaborate_.end() && pos->first == use_definitions)
return pos->second;
ivl_type_s*tmp = elaborate_type_raw(des, scope);
cache_type_elaborate_.insert(pos, pair<NetScope*,ivl_type_s*>(scope, tmp));
return tmp;
}
ivl_type_s* data_type_t::elaborate_type_raw(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_raw(Design*des, NetScope*) const
{
switch (type_code) {
case 64:
if (signed_flag)
return &netvector_t::atom2s64;
else
return &netvector_t::atom2u64;
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;
}
}
ivl_type_s* class_type_t::elaborate_type_raw(Design*, NetScope*) const
{
ivl_assert(*this, save_elaborated_type);
return save_elaborated_type;
}
/*
* elaborate_type_raw for enumerations is actually mostly performed
* during scope elaboration so that the enumeration literals are
* available at the right time. At that time, the netenum_t* object is
* stashed in the scope so that I can retrieve it here.
*/
ivl_type_s* enum_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
ivl_assert(*this, scope);
ivl_type_s*tmp = scope->enumeration_for_key(this);
if (tmp) return tmp;
tmp = des->enumeration_for_key(this);
return tmp;
}
ivl_type_s* vector_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
vector<netrange_t> packed;
elaborate_array_ranges(des, scope, packed, pdims.get());
netvector_t*tmp = new netvector_t(packed, base_type);
tmp->set_signed(signed_flag);
tmp->set_isint(integer_flag);
return tmp;
}
ivl_type_s* real_type_t::elaborate_type_raw(Design*, NetScope*) const
{
switch (type_code) {
case REAL:
return &netreal_t::type_real;
case SHORTREAL:
return &netreal_t::type_shortreal;
}
return 0;
}
ivl_type_s* string_type_t::elaborate_type_raw(Design*, NetScope*) const
{
return &netstring_t::type_string;
}
ivl_type_s* parray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
vector<netrange_t>packed;
elaborate_array_ranges(des, scope, packed, dims.get());
ivl_type_t etype = base_type->elaborate_type(des, scope);
return new netparray_t(packed, etype);
}
netstruct_t* struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
netstruct_t*res = new netstruct_t;
res->packed(packed_flag);
if (union_flag)
res->union_flag(true);
for (list<struct_member_t*>::iterator cur = members->begin()
; cur != members->end() ; ++ cur) {
// Elaborate the type of the member.
struct_member_t*curp = *cur;
ivl_type_t mem_vec = curp->type->elaborate_type(des, scope);
if (mem_vec == 0)
continue;
// There may be several names that are the same type:
// <data_type> name1, name2, ...;
// Process all the member, and give them a type.
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.net_type = mem_vec;
res->append_member(des, memb);
}
}
return res;
}
ivl_type_s* uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
ivl_type_t btype = base_type->elaborate_type(des, scope);
assert(dims->size() >= 1);
list<pform_range_t>::const_iterator cur = dims->begin();
// Special case: if the dimension is nil:nil, this is a
// dynamic array. Note that we only know how to handle dynamic
// arrays with 1 dimension at a time.
if (cur->first==0 && cur->second==0) {
assert(dims->size()==1);
ivl_type_s*res = new netdarray_t(btype);
return res;
}
vector<netrange_t> dimensions;
bool bad_range = evaluate_ranges(des, scope, dimensions, *dims);
if (bad_range) {
cerr << get_fileline() << " : warning: "
<< "Bad dimensions for type here." << endl;
}
ivl_assert(*this, btype);
ivl_type_s*res = new netuarray_t(dimensions, btype);
return res;
}
+673 -2697
View File
File diff suppressed because it is too large Load Diff
+7 -15
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008-2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
@@ -31,31 +31,23 @@ NetProc* AContrib::elaborate(Design*des, NetScope*scope) const
NetExpr*lval = elab_and_eval(des, scope, lval_, -1);
NetExpr*rval = elab_and_eval(des, scope, rval_, -1);
NetEAccess*lacc = dynamic_cast<NetEAccess*> (lval);
if (lacc == 0) {
cerr << get_fileline() << ": error: The l-value of a contribution"
<< " statement must be a branch probe access function." << endl;
des->errors += 1;
return 0;
}
NetContribution*st = new NetContribution(lacc, rval);
NetContribution*st = new NetContribution(lval, rval);
st->set_line(*this);
return st;
}
bool AProcess::elaborate(Design*des, NetScope*scope) const
{
NetProc*estatement = statement_->elaborate(des, scope);
if (estatement == 0)
NetProc*statement = statement_->elaborate(des, scope);
if (statement == 0)
return false;
NetAnalogTop*top = new NetAnalogTop(scope, type_, estatement);
NetAnalogTop*top = new NetAnalogTop(scope, type_, statement);
// 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;
struct attrib_list_t*attrib_list = 0;
unsigned attrib_list_n = 0;
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope);
+32 -184
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
@@ -26,14 +26,12 @@
* target.
*/
# include "target.h"
# include "netclass.h"
# include "netlist.h"
# include "compiler.h"
# include <typeinfo>
# include <cassert>
# include <cstring>
bool NetNode::emit_node(struct target_t*) const
bool NetNode::emit_node(struct target_t*tgt) const
{
cerr << "EMIT: Gate type? " << typeid(*this).name() << endl;
return false;
@@ -74,14 +72,9 @@ bool NetCaseCmp::emit_node(struct target_t*tgt) const
return true;
}
bool NetCastInt2::emit_node(struct target_t*tgt) const
bool NetCastInt::emit_node(struct target_t*tgt) const
{
return tgt->lpm_cast_int2(this);
}
bool NetCastInt4::emit_node(struct target_t*tgt) const
{
return tgt->lpm_cast_int4(this);
return tgt->lpm_cast_int(this);
}
bool NetCastReal::emit_node(struct target_t*tgt) const
@@ -167,11 +160,6 @@ bool NetSignExtend::emit_node(struct target_t*tgt) const
return tgt->sign_extend(this);
}
bool NetSubstitute::emit_node(struct target_t*tgt) const
{
return tgt->substitute(this);
}
bool NetUReduce::emit_node(struct target_t*tgt) const
{
return tgt->ureduce(this);
@@ -204,10 +192,12 @@ bool NetProcTop::emit(struct target_t*tgt) const
bool NetAnalogTop::emit(struct target_t*tgt) const
{
return tgt->process(this);
cerr << get_fileline() << ": sorry: "
<< "I don't know how to emit for analog processes." << endl;
return false;
}
bool NetProc::emit_proc(struct target_t*) const
bool NetProc::emit_proc(struct target_t*tgt) const
{
cerr << "EMIT: Proc type? " << typeid(*this).name() << endl;
return false;
@@ -251,11 +241,6 @@ bool NetCondit::emit_proc(struct target_t*tgt) const
return tgt->proc_condit(this);
}
bool NetContribution::emit_proc(struct target_t*tgt) const
{
return tgt->proc_contribution(this);
}
bool NetDeassign::emit_proc(struct target_t*tgt) const
{
return tgt->proc_deassign(this);
@@ -266,17 +251,6 @@ bool NetDisable::emit_proc(struct target_t*tgt) const
return tgt->proc_disable(this);
}
bool NetDoWhile::emit_proc(struct target_t*tgt) const
{
tgt->proc_do_while(this);
return true;
}
void NetDoWhile::emit_proc_recurse(struct target_t*tgt) const
{
proc_->emit_proc(tgt);
}
bool NetForce::emit_proc(struct target_t*tgt) const
{
return tgt->proc_force(this);
@@ -288,11 +262,6 @@ bool NetForever::emit_proc(struct target_t*tgt) const
return true;
}
bool NetForLoop::emit_proc(struct target_t*tgt) const
{
return tgt->proc_block(as_block_);
}
bool NetFree::emit_proc(struct target_t*tgt) const
{
tgt->proc_free(this);
@@ -339,11 +308,6 @@ bool NetWhile::emit_proc(struct target_t*tgt) const
return true;
}
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
{
proc_->emit_proc(tgt);
}
void NetBlock::emit_recurse(struct target_t*tgt) const
{
if (last_ == 0)
@@ -406,39 +370,18 @@ void NetRepeat::emit_recurse(struct target_t*tgt) const
statement_->emit_proc(tgt);
}
void netclass_t::emit_scope(struct target_t*tgt) const
{
class_scope_->emit_scope(tgt);
}
void NetScope::emit_scope(struct target_t*tgt) const
{
if (debug_emit) {
cerr << "NetScope::emit_scope: "
<< "Emit scope " << scope_path(this) << endl;
}
tgt->scope(this);
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) {
cur->second->emit_scope(tgt);
tgt->class_type(this, cur->second);
}
for (map<const enum_type_t*,netenum_t*>::const_iterator cur = enum_sets_.begin()
; cur != enum_sets_.end() ; ++cur)
tgt->enumeration(this, cur->second);
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; ++ cur )
cur->second->emit_scope(tgt);
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->emit_scope(tgt);
for (signals_map_iter_t cur = signals_map_.begin()
; cur != signals_map_.end() ; ++ cur ) {
; cur != signals_map_.end() ; cur ++) {
tgt->signal(cur->second);
}
@@ -448,32 +391,21 @@ void NetScope::emit_scope(struct target_t*tgt) const
// in the list. We can do it here because delay paths are
// always connected within the scope.
for (signals_map_iter_t cur = signals_map_.begin()
; cur != signals_map_.end() ; ++ cur) {
; cur != signals_map_.end() ; cur ++) {
tgt->signal_paths(cur->second);
}
if (type_ == MODULE) tgt->convert_module_ports(this);
}
bool NetScope::emit_defs(struct target_t*tgt) const
{
bool flag = true;
if (debug_emit) {
cerr << "NetScope::emit_defs: "
<< "Emit definitions for " << scope_path(this) << endl;
}
switch (type_) {
case PACKAGE:
case MODULE:
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; ++ cur )
flag &= cur->second->emit_defs(tgt);
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
; cur != classes_.end() ; ++ cur)
flag &= cur->second->emit_defs(tgt);
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
flag &= cur->emit_defs(tgt);
break;
case FUNC:
@@ -483,18 +415,17 @@ bool NetScope::emit_defs(struct target_t*tgt) const
tgt->task_def(this);
break;
default: /* BEGIN_END and FORK_JOIN, GENERATE... */
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; ++ cur )
flag &= cur->second->emit_defs(tgt);
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
flag &= cur->emit_defs(tgt);
break;
}
return flag;
}
bool netclass_t::emit_defs(struct target_t*tgt) const
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
{
return class_scope_->emit_defs(tgt);
proc_->emit_proc(tgt);
}
int Design::emit(struct target_t*tgt) const
@@ -504,31 +435,11 @@ int Design::emit(struct target_t*tgt) const
if (tgt->start_design(this) == false)
return -2;
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
; scope != root_tasks_.end() ; ++ scope) {
scope->first->emit_scope(tgt);
scope->first->emit_defs(tgt);
}
// enumerate package scopes
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
; scope != packages_.end() ; ++ scope) {
scope->second->emit_scope(tgt);
}
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
; cur != classes_.end() ; ++cur) {
const NetScope*use_scope = cur->second->class_scope();
cur->second->emit_scope(tgt);
tgt->class_type(use_scope, cur->second);
cur->second->emit_defs(tgt);
}
// enumerate root scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end(); ++ scope ) {
// enumerate the scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
(*scope)->emit_scope(tgt);
}
// emit nodes
bool nodes_rc = true;
@@ -541,18 +452,10 @@ int Design::emit(struct target_t*tgt) const
}
bool branches_rc = true;
for (NetBranch*cur = branches_ ; cur ; cur = cur->next_) {
branches_rc = tgt->branch(cur) && branches_rc;
}
// emit task and function definitions
bool tasks_rc = true;
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
; scope != packages_.end() ; ++ scope )
tasks_rc &= scope->second->emit_defs(tgt);
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
; scope != root_scopes_.end(); ++ scope )
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); scope++)
tasks_rc &= (*scope)->emit_defs(tgt);
@@ -563,15 +466,6 @@ int Design::emit(struct target_t*tgt) const
for (const NetAnalogTop*idx = aprocs_ ; idx ; idx = idx->next_)
proc_rc &= idx->emit(tgt);
if (nodes_rc == false)
tgt->errors += 1;
if (tasks_rc == false)
tgt->errors += 1;
if (proc_rc == false)
tgt->errors += 1;
if (branches_rc == false)
tgt->errors += 1;
rc = tgt->end_design(this);
if (nodes_rc == false)
@@ -579,9 +473,7 @@ int Design::emit(struct target_t*tgt) const
if (tasks_rc == false)
return -2;
if (proc_rc == false)
return -3;
if (branches_rc == false)
return -4;
return -3;
return rc;
}
@@ -591,11 +483,6 @@ void NetEAccess::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_access_func(this);
}
void NetEArrayPattern::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_array_pattern(this);
}
void NetEBinary::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_binary(this);
@@ -611,11 +498,6 @@ void NetEConst::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_const(this);
}
void NetEConstEnum::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_const(this);
}
void NetEConstParam::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_param(this);
@@ -631,36 +513,17 @@ void NetECRealParam::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_rparam(this);
}
void NetEParam::expr_scan(struct expr_scan_t*tgt) const
{
cerr << get_fileline() << ":internal error: unexpected NetEParam."
<< endl;
}
void NetEEvent::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_event(this);
}
void NetELast::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_last(this);
}
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);
@@ -676,21 +539,6 @@ void NetESFunc::expr_scan(struct expr_scan_t*tgt) const
tgt->expr_sfunc(this);
}
void NetEShallowCopy::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_scopy(this);
}
void NetEShallowCopy::expr_scan_oper1(struct expr_scan_t*tgt) const
{
arg1_->expr_scan(tgt);
}
void NetEShallowCopy::expr_scan_oper2(struct expr_scan_t*tgt) const
{
arg2_->expr_scan(tgt);
}
void NetEUFunc::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_ufunc(this);
+4 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-1999 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
@@ -44,14 +44,6 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
verinum*res;
switch (op_) {
case 'p': {
if (l->is_defined() && r->is_defined()) {
res = new verinum(pow(*l, *r));
} else {
res = new verinum(verinum::Vx, l->len());
}
break;
}
case '+': {
if (l->is_defined() && r->is_defined()) {
res = new verinum(*l + *r);
@@ -155,7 +147,7 @@ verinum* PEConcat::eval_const(Design*des, NetScope*scope) const
if (accum == 0)
return 0;
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
verinum*tmp = parms_[idx]->eval_const(des, scope);
if (tmp == 0) {
@@ -269,7 +261,7 @@ verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
for (unsigned idx = 0 ; idx < val->len() ; idx += 1)
tmp.set(idx, val->get(idx));
*val = -tmp;
*val = v_not(tmp) + verinum(verinum::V1, 1);
val->has_sign(true);
return val;
}
+43 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2004 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,15 +14,18 @@
*
* 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.
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_attrib.cc,v 1.9 2007/06/04 19:14:06 steve Exp $"
#endif
# include "config.h"
# include "util.h"
# include "PExpr.h"
# include "netlist.h"
# include <iostream>
# include <cassert>
# include <assert.h>
/*
* The evaluate_attributes function evaluates the attribute
@@ -43,7 +46,7 @@ attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
unsigned idx = 0;
typedef map<perm_string,PExpr*>::const_iterator iter_t;
for (iter_t cur = att.begin() ; cur != att.end() ; ++ cur , idx += 1) {
for (iter_t cur = att.begin() ; cur != att.end() ; cur ++, idx++) {
table[idx].key = (*cur).first;
PExpr*exp = (*cur).second;
@@ -72,3 +75,39 @@ attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
assert(idx == natt);
return table;
}
/*
* $Log: eval_attrib.cc,v $
* Revision 1.9 2007/06/04 19:14:06 steve
* Build errors in picky GCC compilers.
*
* Revision 1.8 2005/11/27 17:01:57 steve
* Fix for stubborn compiler.
*
* Revision 1.7 2004/02/20 18:53:35 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.6 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.5 2002/08/12 01:34:59 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/08/10 21:59:39 steve
* The default attribute value is 1.
*
* Revision 1.3 2002/06/06 18:57:18 steve
* Use standard name for iostream.
*
* Revision 1.2 2002/06/03 03:55:14 steve
* compile warnings.
*
* Revision 1.1 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
*/
+1085 -1434
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More