Compare commits

..
652 changed files with 36376 additions and 92715 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
-110
View File
@@ -1,110 +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-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
# 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"
+1 -1
View File
@@ -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>
+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.
*
*/
+33 -3
View File
@@ -1,7 +1,7 @@
#ifndef __Attrib_H
#define __Attrib_H
/*
* Copyright (c) 2000-2009 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&);
};
/*
* $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
+2 -3
View File
@@ -2,8 +2,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
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.
@@ -306,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
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.
-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!
+66 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2012 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: HName.cc,v 1.8 2007/06/02 03:42:12 steve Exp $"
#endif
# include "config.h"
# include "HName.h"
@@ -23,6 +26,9 @@
# include <cstring>
# include <cstdlib>
# include <climits>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
hname_t::hname_t()
@@ -31,19 +37,21 @@ hname_t::hname_t()
}
hname_t::hname_t(perm_string text)
: name_(text)
{
name_ = text;
number_ = INT_MIN;
}
hname_t::hname_t(perm_string text, int num)
: name_(text), number_(num)
{
name_ = text;
number_ = num;
}
hname_t::hname_t(const hname_t&that)
: name_(that.name_), number_(that.number_)
{
name_ = that.name_;
number_ = that.number_;
}
hname_t& hname_t::operator = (const hname_t&that)
@@ -53,6 +61,25 @@ hname_t& hname_t::operator = (const hname_t&that)
return *this;
}
hname_t::~hname_t()
{
}
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());
@@ -76,6 +103,9 @@ bool operator == (const hname_t&l, const hname_t&r)
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) {
@@ -89,3 +119,34 @@ ostream& operator<< (ostream&out, const hname_t&that)
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.
*
*/
+5 -27
View File
@@ -1,7 +1,7 @@
#ifndef __HName_H
#define __HName_H
/*
* Copyright (c) 2001-2010 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,13 +16,12 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 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 "StringHeap.h"
# include <climits>
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
@@ -64,40 +63,19 @@ class hname_t {
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() const
{
return number_;
}
inline bool hname_t::has_number() const
{
return number_ != INT_MIN;
}
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;
}
+3 -3
View File
@@ -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 "LineInfo.h"
# include <sstream>
using namespace std;
LineInfo::LineInfo()
: lineno_(0)
{
+4 -4
View File
@@ -1,7 +1,7 @@
#ifndef __LineInfo_H
#define __LineInfo_H
/*
* Copyright (c) 1999-2011 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,11 +36,11 @@ using namespace std;
class LineInfo {
public:
LineInfo();
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
+163 -220
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 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@ @CFLAGS@
CC = @CC@
CXX = @CXX@
DLLTOOL = @DLLTOOL@
INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -83,127 +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@ @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 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 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 \
--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
@@ -211,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
@@ -219,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,$$ -L ANSI-C -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=`$(GIT) --git-dir $(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 -31
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,27 +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) {
/* It is possible to have undeclared ports. These
are ports that are skipped in the declaration,
for example like so: module foo(x ,, y); The
port between x and y is unnamed and thus
inaccessible to binding by name. */
return perm_string::literal("");
}
return ports[idx]->name;
}
PGate* Module::get_gate(perm_string name)
{
for (list<PGate*>::iterator cur = gates_.begin()
; cur != gates_.end() ; ++ cur ) {
; cur != gates_.end()
; cur ++ ) {
if ((*cur)->get_name() == name)
return *cur;
@@ -123,3 +100,4 @@ const list<PGate*>& Module::get_gates() const
{
return gates_;
}
+22 -30
View File
@@ -1,7 +1,7 @@
#ifndef __Module_H
#define __Module_H
/*
* Copyright (c) 1998-2010,2012 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
*/
@@ -49,7 +49,7 @@ class NetScope;
* therefore the handle for grasping the described circuit.
*/
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
@@ -65,7 +65,7 @@ class Module : public PScopeExtra, public LineInfo {
public:
/* The name passed here is the module name, not the instance
name. This make must be a permallocated string. */
explicit Module(LexicalScope*parent, perm_string name);
explicit Module(perm_string name);
~Module();
/* Initially false. This is set to true if the module has been
@@ -74,20 +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;
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
@@ -95,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,
@@ -114,17 +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;
list<PSpecPath*> specify_paths;
// The mod_name() is the name of the module type.
@@ -136,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;
@@ -146,15 +136,17 @@ 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&);
-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)
{
}
PClass::~PClass()
{
}
-45
View File
@@ -1,45 +0,0 @@
#ifndef __PClass_H
#define __PClass_H
/*
* 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 "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 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
+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);
+36 -6
View File
@@ -1,7 +1,7 @@
#ifndef __PDelays_H
#define __PDelays_H
/*
* Copyright (c) 1999-2010 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&);
/*
* $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.
*
*/
+38 -1
View File
@@ -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&);
};
/*
* $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
+20 -196
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2012 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"
@@ -23,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;
@@ -55,27 +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;
}
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r)
{
@@ -85,33 +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()
{
}
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
l_width_ = 0;
r_width_ = 0;
}
PEBComp::~PEBComp()
@@ -128,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)
{
}
@@ -179,37 +128,20 @@ PECallFunction::PECallFunction(perm_string n)
}
// NOTE: Anachronism. Try to work all use of svector out.
PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
: 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)
: 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;
@@ -219,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()
@@ -237,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_)
@@ -281,14 +198,6 @@ PExpr* PEEvent::expr() const
return expr_;
}
PENull::PENull(void)
{
}
PENull::~PENull()
{
}
PEFNumber::PEFNumber(verireal*v)
: value_(v)
{
@@ -305,12 +214,11 @@ const verireal& PEFNumber::value() const
}
PEIdent::PEIdent(const pform_name_t&that)
: path_(that), no_implicit_sig_(false)
: path_(that)
{
}
PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
: no_implicit_sig_(no_implicit_sig)
PEIdent::PEIdent(perm_string s)
{
path_.push_back(name_component_t(s));
}
@@ -319,50 +227,6 @@ 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;
@@ -371,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();
@@ -379,24 +243,6 @@ bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
return false;
}
PENew::PENew(PExpr*size_expr)
: size_(size_expr)
{
}
PENew::~PENew()
{
delete size_;
}
PENewClass::PENewClass(void)
{
}
PENewClass::~PENewClass()
{
}
PENumber::PENumber(verinum*vp)
: value_(vp)
{
@@ -446,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_);
@@ -471,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()
{
}
+162 -384
View File
@@ -1,7 +1,7 @@
#ifndef __PExpr_H
#define __PExpr_H
/*
* Copyright (c) 1998-2011 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,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 <string>
# include <vector>
# include <valarray>
# include "netlist.h"
# include "verinum.h"
# include "LineInfo.h"
@@ -29,7 +28,6 @@
class Design;
class Module;
class LexicalScope;
class NetNet;
class NetExpr;
class NetScope;
@@ -43,99 +41,72 @@ class NetScope;
class PExpr : public LineInfo {
public:
enum width_mode_t { SIZED, EXPAND, LOSSLESS, UNSIZED };
// Flag values that can be passed to elaborate_expr.
static const unsigned NO_FLAGS = 0x0;
static const unsigned NEED_CONST = 0x1;
static const unsigned SYS_TASK_ARG = 0x2;
static const unsigned ANNOTATABLE = 0x4;
PExpr();
virtual ~PExpr();
virtual void dump(ostream&) const;
// This method tests whether the expression contains any identifiers
// that have not been previously declared in the specified scope or
// in any containing scope. Any such identifiers are added to the
// specified scope as scalar nets of the specified type.
//
// This operation must be performed by the parser, to ensure that
// subsequent declarations do not affect the decision to create an
// implicit net.
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
// This method tests whether the expression contains any
// references to automatically allocated variables.
virtual bool has_aa_term(Design*des, NetScope*scope) const;
// This method tests the type and width that the expression wants
// to be. It should be called before elaborating an expression to
// figure out the type and width of the expression. It also figures
// out the minimum width that can be used to evaluate the expression
// without changing the result. This allows the expression width to
// be pruned when not all bits of the result are used.
// This method tests the width that the expression wants to
// be. It is used by elaboration of assignments to figure out
// the width of the expression.
//
// Normally mode should be initialised to SIZED before starting to
// test the width of an expression. In SIZED mode the expression
// width will be calculated strictly according to the IEEE standard
// rules for expression width.
// If the expression contains an unsized literal, mode will be
// changed to LOSSLESS. In LOSSLESS mode the expression width will
// be calculated as the minimum width necessary to avoid arithmetic
// overflow or underflow.
// If the expression both contains an unsized literal and contains
// an operation that coerces a vector operand to a different type
// (signed <-> unsigned), mode is changed to UNSIZED. UNSIZED mode
// is the same as LOSSLESS, except that the final expression width
// will be forced to be at least integer_width. This is necessary
// to ensure compatibility with the IEEE standard, which requires
// unsized literals to be treated as having the same width as an
// integer. The lossless width calculation is inadequate in this
// case because coercing an operand to a different type means that
// the expression no longer obeys the normal rules of arithmetic.
// The "min" is the width of the local context, so is the
// minimum width that this function should return. Initially
// this is the same as the lval width.
//
// If mode is initialised to EXPAND instead of SIZED, the expression
// width will be calculated as the minimum width necessary to avoid
// arithmetic overflow or underflow, even if it contains no unsized
// literals. mode will be changed LOSSLESS or UNSIZED as described
// above. This supports a non-standard mode of expression width
// calculation.
// The "lval" is the width of the destination where this
// result is going to go. This can be used to constrain the
// amount that an expression can reasonably expand. For
// example, there is no point expanding an addition to beyond
// the lval. This extra bit of information allows the
// expression to optimize itself a bit. If the lval==0, then
// the subexpression should not make l-value related
// optimizations.
//
// When the final value of mode is UNSIZED, the width returned by
// this method is the calculated lossless width, but the width
// returned by a subsequent call to the expr_width method will be
// the final expression width.
// The expr_type is an output argument that gives the
// calculated type for the expression.
//
// The unsized_flag is set to true if the expression is
// unsized and therefore expandable. This happens if a
// sub-expression is an unsized literal. Some expressions make
// special use of that.
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
// After the test_width method is complete, these methods
// return valid results.
ivl_variable_type_t expr_type() const { return expr_type_; }
unsigned expr_width() const { return expr_width_; }
unsigned min_width() const { return min_width_; }
bool has_sign() const { return signed_flag_; }
// This method allows the expression type (signed/unsigned)
// to be propagated down to any context-dependant operands.
void cast_signed(bool flag) { signed_flag_ = flag; }
// This is the more generic form of the elaborate_expr method
// below. The plan is to replace the simpler elaborate_expr
// method with this version, which can handle more advanced
// types. But for now, this is only implemented in special cases.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
// During the elaborate_sig phase, we may need to scan
// expressions to find implicit net declarations.
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
// Procedural elaboration of the expression. The expr_width is
// the required width of the expression.
// the width of the context of the expression (i.e. the
// l-value width of an assignment),
//
// ... or -1 if the expression is self-determined. or
// ... or -2 if the expression is losslessly
// self-determined. This can happen in situations where the
// result is going to a pseudo-infinitely wide context.
//
// The sys_task_arg flag is true if expressions are allowed to
// be incomplete.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
int expr_width, bool sys_task_arg) const;
// Elaborate expressions that are the r-value of parameter
// assignments. This elaboration follows the restrictions of
// constant expressions and supports later overriding and
// evaluation of parameters.
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments.
@@ -161,25 +132,17 @@ class PExpr : public LineInfo {
// evaluated, return 0.
virtual verinum* eval_const(Design*des, NetScope*sc) const;
// This method returns true if the expression represents a
// structural net that can have multiple drivers. This is
// used to test whether an input port connection can be
// collapsed to a single wire.
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
// This method returns true if that expression is the same as
// this expression. This method is used for comparing
// expressions that must be structurally "identical".
virtual bool is_the_same(const PExpr*that) const;
protected:
unsigned fix_width_(width_mode_t mode);
// The derived class test_width methods should fill these in.
ivl_variable_type_t expr_type_;
unsigned expr_width_;
unsigned min_width_;
bool signed_flag_;
static void suppress_binary_operand_sign_if_needed_(NetExpr*lp, NetExpr*rp);
private: // not implemented
PExpr(const PExpr&);
@@ -191,38 +154,34 @@ ostream& operator << (ostream&, const PExpr&);
class PEConcat : public PExpr {
public:
PEConcat(const list<PExpr*>&p, PExpr*r =0);
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
~PEConcat();
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid,
unsigned flags) const;
int expr_width, bool sys_task_arg) const;
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const;
private:
vector<PExpr*>parms_;
std::valarray<width_mode_t>width_modes_;
svector<PExpr*>parms_;
PExpr*repeat_;
NetScope*tested_scope_;
unsigned repeat_count_;
};
/*
@@ -271,10 +230,12 @@ class PEFNumber : public PExpr {
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid,
unsigned flags) const;
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
@@ -285,7 +246,7 @@ class PEFNumber : public PExpr {
class PEIdent : public PExpr {
public:
explicit PEIdent(perm_string, bool no_implicit_sig=false);
explicit PEIdent(perm_string);
explicit PEIdent(const pform_name_t&);
~PEIdent();
@@ -295,12 +256,14 @@ class PEIdent : public PExpr {
virtual void dump(ostream&) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
// Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
@@ -312,200 +275,95 @@ class PEIdent : public PExpr {
NetScope*scope,
bool is_force) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid,
unsigned flags) const;
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// Elaborate the PEIdent as a port to a module. This method
// only applies to Ident expressions.
NetNet* elaborate_subport(Design*des, NetScope*sc) const;
NetNet* elaborate_port(Design*des, NetScope*sc) const;
verinum* eval_const(Design*des, NetScope*sc) const;
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
const pform_name_t& path() const { return path_; }
private:
pform_name_t path_;
bool no_implicit_sig_;
private:
// Common functions to calculate parts of part/bit
// selects. These methods return true if the expressions
// elaborate/calculate, or false if there is some sort of
// source error.
bool calculate_bits_(Design*, NetScope*, long&msb, bool&defined) const;
// The calculate_parts_ method calculates the range
// expressions of a part select for the current object. The
// part select expressions are elaborated and evaluated, and
// the values written to the msb/lsb arguments. If there are
// invalid bits (xz) in either expression, then the defined
// flag is set to *false*.
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const;
// Common functions to calculate parts of part/bit selects.
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb) const;
NetExpr* calculate_up_do_base_(Design*, NetScope*) const;
bool calculate_param_range_(Design*, NetScope*,
const NetExpr*msb_ex, long&msb,
const NetExpr*lsb_ex, long&lsb,
long length) const;
const NetExpr*lsb_ex, long&lsb) const;
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
// Evaluate the prefix indices. All but the final index in a
// chain of indices must be a single value and must evaluate
// to constants at compile time. For example:
// [x] - OK
// [1][2][x] - OK
// [1][x:y] - OK
// [2:0][x] - BAD
// [y][x] - BAD
// Leave the last index for special handling.
bool calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net,
std::list<long>&prefix_indices) const;
private:
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*) const;
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
index_component_t::ctype_t) const;
bool elaborate_lval_net_class_member_(Design*, NetScope*,
NetAssign_*,
const perm_string&) const;
bool elaborate_lval_net_packed_member_(Design*, NetScope*,
NetAssign_*,
const perm_string&) const;
bool elaborate_lval_darray_bit_(Design*, NetScope*,
NetAssign_*) const;
private:
NetExpr*elaborate_expr_param_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found_in,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb,
unsigned expr_wid,
unsigned flags) const;
int expr_wid) const;
NetExpr*elaborate_expr_param_part_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found_in,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb,
unsigned expr_wid) const;
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_param_idx_up_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found_in,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb,
bool need_const) const;
NetExpr*elaborate_expr_param_idx_do_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found_in,
const NetExpr*par_msb,
const NetExpr*par_lsb,
bool need_const) const;
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_net(Design*des,
NetScope*scope,
NetNet*net,
NetScope*found,
unsigned expr_wid,
unsigned flags) const;
bool sys_task_arg) const;
NetExpr*elaborate_expr_net_word_(Design*des,
NetScope*scope,
NetNet*net,
NetScope*found,
unsigned expr_wid,
unsigned flags) const;
bool sys_task_arg) const;
NetExpr*elaborate_expr_net_part_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found,
unsigned expr_wid) const;
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_idx_up_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found,
bool need_const) const;
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_idx_do_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found,
bool need_const) const;
NetScope*scope,
NetESignal*net,
NetScope*found) const;
NetExpr*elaborate_expr_net_bit_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found,
bool need_const) const;
NetScope*scope,
NetESignal*net,
NetScope*found) const;
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const;
NetNet*make_implicit_net_(Design*des, NetScope*scope) const;
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
long&midx, long&lidx) const;
};
class PENew : public PExpr {
public:
explicit PENew (PExpr*s);
~PENew();
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid,
unsigned flags) const;
private:
PExpr*size_;
};
class PENewClass : public PExpr {
public:
explicit PENewClass ();
~PENewClass();
virtual void dump(ostream&) const;
// Class objects don't have a useful width, but the expression
// is IVL_VT_CLASS.
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
// Note that class (new) expressions only appear in context
// that uses this form of the elaborate_expr method. In fact,
// the type argument is going to be a netclas_t object.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
private:
};
class PENull : public PExpr {
public:
explicit PENull();
~PENull();
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid,
unsigned flags) const;
};
class PENumber : public PExpr {
public:
@@ -516,10 +374,13 @@ class PENumber : public PExpr {
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned) const;
int expr_width, bool) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const;
@@ -549,10 +410,13 @@ class PEString : public PExpr {
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned) const;
int expr_width, bool) const;
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
verinum* eval_const(Design*, NetScope*) const;
private:
@@ -567,24 +431,22 @@ class PEUnary : public PExpr {
virtual void dump(ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid,
unsigned flags) const;
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
public:
inline char get_op() const { return op_; }
inline PExpr*get_expr() const { return expr_; }
private:
NetExpr* elaborate_expr_bits_(NetExpr*operand, unsigned expr_wid) const;
NetExpr* elaborate_expr_bits_(NetExpr*operand, int expr_wid) const;
private:
char op_;
@@ -599,16 +461,18 @@ class PEBinary : public PExpr {
virtual void dump(ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid,
unsigned flags) const;
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
protected:
@@ -616,19 +480,15 @@ class PEBinary : public PExpr {
PExpr*left_;
PExpr*right_;
NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const;
NetExpr*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const;
NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_bits_(Design*, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const;
NetExpr*elaborate_expr_base_div_(Design*, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const;
NetExpr*elaborate_expr_base_mult_(Design*, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const;
NetExpr*elaborate_expr_base_add_(Design*, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const;
NetExpr*elaborate_expr_base_bits_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_div_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_lshift_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_rshift_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_mult_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
NetExpr*elaborate_expr_base_add_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
};
@@ -643,14 +503,13 @@ class PEBComp : public PEBinary {
~PEBComp();
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&flag);
NetExpr* elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const;
private:
unsigned l_width_;
unsigned r_width_;
int expr_width, bool sys_task_arg) const;
NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
};
/*
@@ -663,53 +522,27 @@ class PEBLogic : public PEBinary {
~PEBLogic();
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&flag);
NetExpr* elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const;
int expr_width, bool sys_task_arg) const;
NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
};
/*
* A couple of the binary operands have a special sub-expression rule
* where the expression width is carried entirely by the left
* expression, and the right operand is self-determined.
*/
class PEBLeftWidth : public PEBinary {
public:
explicit PEBLeftWidth(char op, PExpr*l, PExpr*r);
~PEBLeftWidth() =0;
virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const =0;
protected:
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
};
class PEBPower : public PEBLeftWidth {
public:
explicit PEBPower(char op, PExpr*l, PExpr*r);
~PEBPower();
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const;
};
class PEBShift : public PEBLeftWidth {
class PEBShift : public PEBinary {
public:
explicit PEBShift(char op, PExpr*l, PExpr*r);
~PEBShift();
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&flag);
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
};
/*
@@ -724,23 +557,20 @@ class PETernary : public PExpr {
virtual void dump(ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid,
unsigned flags) const;
int expr_width, bool sys_task_arg) const;
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual verinum* eval_const(Design*des, NetScope*sc) const;
private:
NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope,
PExpr*expr, unsigned expr_wid,
unsigned flags) const;
private:
PExpr*expr_;
PExpr*tru_;
@@ -760,23 +590,23 @@ class PECallFunction : public PExpr {
explicit PECallFunction(perm_string n);
// svector versions. Should be removed!
explicit PECallFunction(const pform_name_t&n, const list<PExpr *> &parms);
explicit PECallFunction(perm_string n, const list<PExpr *> &parms);
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
~PECallFunction();
virtual void dump(ostream &) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
int expr_wid, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
private:
pform_name_t path_;
@@ -784,64 +614,12 @@ class PECallFunction : public PExpr {
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const;
NetExpr*elaborate_expr_method_(Design*des, NetScope*scope,
unsigned expr_wid) const;
#if 0
NetExpr*elaborate_expr_string_method_(Design*des, NetScope*scope) const;
NetExpr*elaborate_expr_enum_method_(Design*des, NetScope*scope,
unsigned expr_wid) const;
#endif
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
NetExpr* elaborate_access_func_(Design*des, NetScope*scope, ivl_nature_t,
unsigned expr_wid) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const;
NetExpr* elaborate_access_func_(Design*des, NetScope*scope, int expr_wid) const;
unsigned test_width_sfunc_(Design*des, NetScope*scope,
width_mode_t&mode);
unsigned test_width_method_(Design*des, NetScope*scope,
width_mode_t&mode);
};
/*
* Support the SystemVerilog cast to size.
*/
class PECastSize : public PExpr {
public:
explicit PECastSize(unsigned expr_wid, PExpr*base);
~PECastSize();
void dump(ostream &out) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
private:
unsigned size_;
PExpr* base_;
};
/*
* This class is used for error recovery. All methods do nothing and return
* null or default values.
*/
class PEVoid : public PExpr {
public:
explicit PEVoid();
~PEVoid();
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
};
#endif
+3 -3
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,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 "PTask.h"
PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
PFunction::PFunction(perm_string name, PScope*parent, bool is_auto__)
: PScope(name, parent), ports_(0), statement_(0)
{
is_auto_ = is_auto__;
+86 -154
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2010 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,106 +196,8 @@ 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), 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;
@@ -268,23 +205,17 @@ PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
PGModule::PGModule(perm_string type, perm_string name,
named<PExpr*>*pins, unsigned npins)
: PGate(name, 0), bound_type_(0), overrides_(0), pins_(pins),
: PGate(name, 0), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
type_ = type;
}
PGModule::PGModule(Module*type, perm_string name)
: PGate(name, 0), bound_type_(type), overrides_(0), pins_(0),
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
}
PGModule::~PGModule()
{
}
void PGModule::set_parameters(list<PExpr*>*o)
void PGModule::set_parameters(svector<PExpr*>*o)
{
assert(overrides_ == 0);
overrides_ = o;
@@ -307,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_;
}
+36 -45
View File
@@ -1,7 +1,7 @@
#ifndef __PGate_H
#define __PGate_H
/*
* Copyright (c) 1998-2011 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;
@@ -147,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;
@@ -166,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_;
@@ -194,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
@@ -223,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_;
@@ -243,16 +240,10 @@ 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,
+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;
}
+5 -26
View File
@@ -1,7 +1,7 @@
#ifndef __PGenerate_H
#define __PGenerate_H
/*
* Copyright (c) 2006-2010,2012 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
-30
View File
@@ -1,30 +0,0 @@
/*
* Copyright (c) 2012 Picture Elements, Inc.
* 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()
{
}
-40
View File
@@ -1,40 +0,0 @@
#ifndef __PPackage_H
#define __PPackage_H
/*
* 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 "PScope.h"
# include "LineInfo.h"
# include "StringHeap.h"
/*
* SystemVerilog supports class declarations with their own lexical
* scope, etc. The parser arranges for these to be created and
* collected.
*/
class PPackage : public PScopeExtra, public LineInfo {
public:
explicit PPackage (perm_string name, LexicalScope*parent);
~PPackage();
};
#endif
+5 -20
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,18 +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
*/
# 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)
{
}
@@ -41,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()
{
}
+6 -47
View File
@@ -1,7 +1,7 @@
#ifndef __PScope_H
#define __PScope_H
/*
* 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
@@ -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"
@@ -27,11 +27,8 @@
class PEvent;
class PExpr;
class PFunction;
class AProcess;
class PProcess;
class PClass;
class PTask;
class PWire;
class Design;
@@ -49,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() { }
@@ -86,9 +83,6 @@ 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;
@@ -96,35 +90,20 @@ class LexicalScope {
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.
list<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 {
@@ -138,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;
@@ -151,28 +131,7 @@ class PScope : public LexicalScope {
private:
perm_string name_;
};
/*
* 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;
protected:
void dump_classes_(ostream&out, unsigned indent) const;
PScope*parent_;
};
#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()
+6 -14
View File
@@ -1,7 +1,7 @@
#ifndef __PSpec_H
#define __PSpec_H
/*
* 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
@@ -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
+3 -3
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,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 "PTask.h"
PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__)
PTask::PTask(perm_string name, PScope*parent, bool is_auto__)
: PScope(name, parent), ports_(0), statement_(0)
{
is_auto_ = is_auto__;
+6 -12
View File
@@ -1,7 +1,7 @@
#ifndef __PTask_H
#define __PTask_H
/*
* Copyright (c) 1999-2008,2010,2012 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 "LineInfo.h"
@@ -24,8 +24,6 @@
# include "svector.h"
# include "StringHeap.h"
# include <string>
# include <vector>
# include <list>
class Design;
class NetScope;
class PWire;
@@ -39,16 +37,12 @@ enum PTaskFuncEnum {
PTF_INTEGER,
PTF_REAL,
PTF_REALTIME,
PTF_TIME,
PTF_ATOM2,
PTF_ATOM2_S,
PTF_STRING,
PTF_VOID
PTF_TIME
};
struct PTaskFuncArg {
PTaskFuncEnum type;
std::list<pform_range_t>*range;
svector<PExpr*>*range;
};
/*
@@ -57,7 +51,7 @@ struct PTaskFuncArg {
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);
@@ -99,7 +93,7 @@ class PTask : public PScope, public LineInfo {
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);
+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.
*
*/
+56 -5
View File
@@ -1,7 +1,7 @@
#ifndef __PUdp_H
#define __PUdp_H
/*
* Copyright (c) 1998-2011 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&);
};
/*
* $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
+20 -81
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) {
@@ -143,14 +135,8 @@ bool PWire::get_isint() const
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_) {
@@ -158,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;
@@ -168,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;
@@ -185,80 +175,29 @@ 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;
lidx_ = ldx;
ridx_ = rdx;
}
}
void PWire::set_data_type(data_type_t*type)
{
assert(set_data_type_ == 0);
set_data_type_ = type;
}
void PWire::set_discipline(ivl_discipline_t d)
{
assert(discipline_ == 0);
+13 -24
View File
@@ -1,7 +1,7 @@
#ifndef __PWire_H
#define __PWire_H
/*
* Copyright (c) 1998-2009,2012 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_;
+32 -16
View File
@@ -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.
+16 -39
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008,2010,2012 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"
@@ -51,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)
{
}
@@ -98,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)
{
}
@@ -110,42 +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];
}
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;
}
PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
: path_(n), parms_(p.size())
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
: path_(n), 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(perm_string n, const list<PExpr*>&p)
: 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());
path_.push_back(name_component_t(n));
}
@@ -283,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)
{
}
+29 -35
View File
@@ -1,7 +1,7 @@
#ifndef __Statement_H
#define __Statement_H
/*
* Copyright (c) 1998-2008,2012 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
@@ -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"
@@ -42,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,10 +104,6 @@ class PAssign_ : public Statement {
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
NetExpr* elaborate_rval_(Design*, NetScope*, unsigned lv_width,
ivl_variable_type_t type) const;
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const;
NetExpr* elaborate_rval_obj_(Design*, NetScope*,
ivl_variable_type_t type) const;
PExpr* delay_;
PEventStatement*event_;
@@ -124,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);
@@ -139,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_ {
@@ -169,21 +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_; }
// 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);
void set_statement(const svector<Statement*>&st);
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
@@ -191,19 +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(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;
@@ -211,17 +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) const;
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;
};
@@ -401,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;
@@ -415,7 +408,8 @@ class PForStatement : public Statement {
PExpr*cond_;
Statement*step_;
PExpr* name2_;
PExpr* expr2_;
Statement*statement_;
};
+35 -41
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,11 +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.
*
*/
+31 -7
View File
@@ -1,7 +1,7 @@
#ifndef __StringHeap_H
#define __StringHeap_H
/*
* Copyright (c) 2002-2009 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); }
@@ -60,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
@@ -106,7 +107,6 @@ class StringHeapLex : private StringHeap {
unsigned add_count() const;
unsigned add_hit_count() const;
void cleanup();
private:
enum { HASH_SIZE = 4096 };
@@ -120,4 +120,28 @@ class StringHeapLex : private StringHeap {
StringHeapLex& operator= (const StringHeapLex&);
};
/*
* $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
+42 -1
View File
@@ -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
/*
* $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
+83 -2
View File
@@ -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
@@ -229,7 +232,7 @@ 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_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);
@@ -270,4 +273,82 @@ extern char* acc_version(void);
EXTERN_C_END
/*
* $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
+35 -84
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"
;;
@@ -229,28 +205,3 @@ case "${host}" in
;;
esac
])# AX_CPP_PRECOMP
# AX_C99_STRTOD
# -------------
AC_DEFUN([AX_C99_STRTOD],
[# On MinGW we need to jump through hoops to get a C99 compliant strtod().
case "${host}" in
*-*-mingw*)
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
;;
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
+4 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-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 "functor.h"
# include "netlist.h"
# include <cassert>
# include <assert.h>
bool NetAssign::is_asynchronous()
{
@@ -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 -4
View File
@@ -2,12 +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
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 lexor_keyword.gperf"
gperf -o -i 7 -C -k 1-4,6,9,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
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@ @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:
+39 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003 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,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);
@@ -83,3 +87,34 @@ 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)
+20 -1
View File
@@ -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
/*
* $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
+8 -80
View File
@@ -1,7 +1,7 @@
#ifndef __compiler_H
#define __compiler_H
/*
* Copyright (c) 1999-2011 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
@@ -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,12 +36,6 @@
*/
extern unsigned integer_width;
/*
* 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
@@ -74,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;
@@ -81,20 +76,9 @@ 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 anochronisms. */
extern bool warn_anachronisms;
/* This is true if verbose output is requested. */
extern bool verbose_flag;
@@ -103,12 +87,7 @@ extern bool debug_eval_tree;
extern bool debug_elaborate;
extern bool debug_synth2;
extern bool debug_optimizer;
/* Possibly temporary flag to control virtualization of pin arrays */
extern bool disable_virtual_pins;
/* 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;
@@ -122,12 +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_DEFAULT = 4
GN_VER2001 = 2,
GN_VER2005 = 3,
GN_DEFAULT = 3
};
extern generation_t generation_flag;
@@ -149,39 +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)
return true;
return false;
}
static inline bool gn_system_verilog(void)
{
if (generation_flag == GN_VER2005_SV ||
generation_flag == GN_VER2009)
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
@@ -191,8 +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_ICARUS = 0x8000
};
extern int lexor_keyword_mask;
@@ -215,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
@@ -247,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
+384 -581
View File
File diff suppressed because it is too large Load Diff
+44 -13
View File
@@ -1,7 +1,7 @@
#ifndef __config_H /* -*- c++ -*- */
#define __config_H
/*
* Copyright (c) 2001-2012 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 /* __config_H */
Vendored
+93 -322
View File
@@ -1,10 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
# 2000, 2001, 2002 Free Software Foundation, Inc.
timestamp='2009-04-17'
timestamp='2002-07-03'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -22,15 +21,14 @@ timestamp='2009-04-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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <[email protected]>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
@@ -72,8 +70,8 @@ Report bugs and patches to <[email protected]>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -85,11 +83,11 @@ Try \`$me --help' for more information."
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit ;;
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit ;;
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
@@ -101,7 +99,7 @@ while test $# -gt 0 ; do
*local*)
# First pass through any local machine types.
echo $1
exit ;;
exit 0;;
* )
break ;;
@@ -120,10 +118,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -149,7 +144,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray)
-apple | -axis)
os=
basic_machine=$1
;;
@@ -174,10 +169,6 @@ case $os in
-hiux*)
os=-hiuxwe2
;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -194,10 +185,6 @@ case $os in
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -241,57 +228,40 @@ case $basic_machine in
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| bfin \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fido | fr30 | frv \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
| ip2k \
| m32r | m68000 | m68k | m88k | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nios | nios2 \
| ns16k | ns32k \
| or32 \
| openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
| z8k | z80)
| x86 | xscale | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
@@ -301,9 +271,6 @@ case $basic_machine in
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
ms1)
basic_machine=mt-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
@@ -323,67 +290,48 @@ case $basic_machine in
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c54x-* \
| clipper-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| ip2k-* \
| m32r-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
| mips64r5900-* | mips64r5900el-* \
| mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nios-* | nios2-* \
| mipstx39 | mipstx39el \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
| tron-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa*-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-* | z80-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -401,9 +349,6 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
@@ -418,12 +363,6 @@ case $basic_machine in
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@@ -447,10 +386,6 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -459,22 +394,10 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -499,27 +422,12 @@ case $basic_machine in
basic_machine=j90-cray
os=-unicos
;;
craynv)
basic_machine=craynv-cray
os=-unicosmp
;;
cr16)
basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
basic_machine=m68k-crds
;;
crisv32 | crisv32-* | etraxfs*)
basic_machine=crisv32-axis
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
crx)
basic_machine=crx-unknown
os=-elf
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
@@ -542,14 +450,6 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
@@ -700,14 +600,6 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -723,10 +615,6 @@ case $basic_machine in
basic_machine=i386-pc
os=-mingw32
;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -740,6 +628,10 @@ case $basic_machine in
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
mmix*)
basic_machine=mmix-knuth
os=-mmixware
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
@@ -752,9 +644,6 @@ case $basic_machine in
basic_machine=i386-pc
os=-msdos
;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
mvs)
basic_machine=i370-ibm
os=-mvs
@@ -830,12 +719,9 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
openrisc | openrisc-*)
or32 | or32-*)
basic_machine=or32-unknown
;;
os400)
basic_machine=powerpc-ibm
os=-os400
os=-coff
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
@@ -853,75 +739,55 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pc98)
basic_machine=i386-pc
;;
pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon | athlon_*)
pentiumpro | p6 | 6x86 | athlon)
basic_machine=i686-pc
;;
pentiumii | pentium2 | pentiumiii | pentium3)
pentiumii | pentium2)
basic_machine=i686-pc
;;
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
pentiumii-* | pentium2-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
@@ -932,10 +798,6 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos)
basic_machine=i386-pc
os=-rdos
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
@@ -956,20 +818,6 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
@@ -977,12 +825,6 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
@@ -1041,7 +883,7 @@ case $basic_machine in
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
sv1)
basic_machine=sv1-cray
os=-unicos
;;
@@ -1049,6 +891,10 @@ case $basic_machine in
basic_machine=i386-sequent
os=-dynix
;;
t3d)
basic_machine=alpha-cray
os=-unicos
;;
t3e)
basic_machine=alphaev5-cray
os=-unicos
@@ -1061,18 +907,6 @@ case $basic_machine in
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tile*)
basic_machine=tile-unknown
os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
;;
@@ -1086,10 +920,6 @@ case $basic_machine in
tower | tower-32)
basic_machine=m68k-ncr
;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k)
basic_machine=a29k-amd
os=-udi
@@ -1111,8 +941,8 @@ case $basic_machine in
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -1133,11 +963,11 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
xbox)
basic_machine=i686-pc
os=-mingw32
windows32)
basic_machine=i386-pc
os=-windows32-msvcrt
;;
xps | xps100)
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
@@ -1148,10 +978,6 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
@@ -1171,9 +997,6 @@ case $basic_machine in
romp)
basic_machine=romp-ibm
;;
mmix)
basic_machine=mmix-knuth
;;
rs6000)
basic_machine=rs6000-ibm
;;
@@ -1190,13 +1013,16 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
cydra)
basic_machine=cydra-cydrome
;;
orion)
@@ -1211,6 +1037,10 @@ case $basic_machine in
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
c4x*)
basic_machine=c4x-none
os=-coff
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
@@ -1262,28 +1092,22 @@ case $os in
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -kopensolaris* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -mingw32* | -linux* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1295,24 +1119,16 @@ case $os in
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
os=-nto-qnx
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
@@ -1322,9 +1138,6 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
os=-os400
;;
-wince*)
os=-wince
;;
@@ -1346,9 +1159,6 @@ case $os in
-atheos*)
os=-atheos
;;
-syllable*)
os=-syllable
;;
-386bsd)
os=-bsd
;;
@@ -1359,7 +1169,7 @@ case $os in
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
os=-nextstep2
;;
-nsk*)
os=-nsk
@@ -1371,9 +1181,6 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
os=-tpf
;;
-triton*)
os=-sysv3
;;
@@ -1401,20 +1208,8 @@ case $os in
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-none)
;;
@@ -1438,12 +1233,6 @@ else
# system, and we'll never get to this point.
case $basic_machine in
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn)
os=-riscix1.2
;;
@@ -1453,14 +1242,11 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
pdp11-*)
os=-none
;;
*-dec | vax-*)
@@ -1481,9 +1267,6 @@ case $basic_machine in
m68*-cisco)
os=-aout
;;
mep-*)
os=-elf
;;
mips*-cisco)
os=-elf
;;
@@ -1502,15 +1285,9 @@ case $basic_machine in
*-be)
os=-beos
;;
*-haiku)
os=-haiku
;;
*-ibm)
os=-aix
;;
*-knuth)
os=-mmixware
;;
*-wec)
os=-proelf
;;
@@ -1562,19 +1339,19 @@ case $basic_machine in
*-next)
os=-nextstep3
;;
*-gould)
*-gould)
os=-sysv
;;
*-highlevel)
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
*-sgi)
os=-irix
;;
*-siemens)
*-siemens)
os=-sysv4
;;
*-masscomp)
@@ -1643,15 +1420,9 @@ case $basic_machine in
-mvs* | -opened*)
vendor=ibm
;;
-os400*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
@@ -1676,7 +1447,7 @@ case $basic_machine in
esac
echo $basic_machine$os
exit
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
+8 -209
View File
@@ -2,31 +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.
# If you must use an older version then comment out the following two
# lines, but be warned that there could be issues with finding the
# nan(), etc. functions. It is really best to upgrade to a supported
# version of autoconf.
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)
@@ -36,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 ""
@@ -64,86 +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 -Wshadow"])
AC_SUBST(WARNING_FLAGS_CXX, ["$iverilog_wextra_flag"])
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)
@@ -156,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>
@@ -196,21 +84,14 @@ 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.
@@ -220,68 +101,6 @@ AX_C_PICFLAG
# may modify CPPFLAGS and CFLAGS
AX_CPP_PRECOMP
# may modify LDFLAGS
AX_C99_STRTOD
# Processor specific compile flags
case "${host}" in
alpha*-*-linux*)
CPPFLAGS="-mieee $CPPFLAGS"
CFLAGS="-mieee $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)])
# Linker option used when compiling the target
AX_LD_RDYNAMIC
@@ -300,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)
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:4430
thisSubtraction:netlist.h:4439
+767 -73
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2010 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"
@@ -25,7 +25,7 @@
# include "functor.h"
# include "compiler.h"
# include "ivl_assert.h"
# include <vector>
/*
@@ -48,11 +48,11 @@ struct cprop_functor : public functor_t {
virtual void lpm_mux(Design*des, NetMux*obj);
};
void cprop_functor::signal(Design*, NetNet*)
void cprop_functor::signal(Design*des, NetNet*obj)
{
}
void cprop_functor::lpm_add_sub(Design*, NetAddSub*)
void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
{
}
@@ -70,11 +70,132 @@ void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
}
}
void cprop_functor::lpm_compare_eq_(Design*, NetCompare*)
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
{
#if 0
/* XXXX Need to reimplement this code to account for vectors. */
NetScope*scope = obj->scope();
unsigned const_count = 0;
bool unknown_flag = false;
/* First, look for the case where constant bits on matching A
and B inputs are different. This this is so, the device can
be completely eliminated and replaced with a constant 0. */
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! obj->pin_DataA(idx).nexus()->drivers_constant())
continue;
if (! obj->pin_DataB(idx).nexus()->drivers_constant())
continue;
const_count += 1;
verinum::V abit = obj->pin_DataA(idx).nexus()->driven_value();
verinum::V bbit = obj->pin_DataB(idx).nexus()->driven_value();
if ((abit == verinum::V0) && (bbit == verinum::V0))
continue;
if ((abit == verinum::V1) && (bbit == verinum::V1))
continue;
unknown_flag = true;
if ((abit == verinum::Vz) || (abit == verinum::Vx))
continue;
if ((bbit == verinum::Vz) || (bbit == verinum::Vx))
continue;
NetConst*zero = new NetConst(scope, obj->name(), verinum::V0);
connect(zero->pin(0), obj->pin_AEB());
delete obj;
des->add_node(zero);
count += 1;
return;
}
/* If all the inputs are constant, then at this point the
result is either V1 or Vx. */
if (const_count == obj->width()) {
NetConst*val = new NetConst(scope, obj->name(),
unknown_flag
? verinum::Vx
: verinum::V1);
connect(val->pin(0), obj->pin_AEB());
delete obj;
des->add_node(val);
count += 1;
return;
}
/* Still may need the gate. Run through the inputs again, and
look for pairs of constants. Those inputs can be removed. */
unsigned top = obj->width();
for (unsigned idx = 0 ; idx < top ; ) {
if (! obj->pin_DataA(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (! obj->pin_DataB(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
obj->pin_DataA(idx).unlink();
obj->pin_DataB(idx).unlink();
top -= 1;
for (unsigned jj = idx ; jj < top ; jj += 1) {
connect(obj->pin_DataA(jj), obj->pin_DataA(jj+1));
connect(obj->pin_DataB(jj), obj->pin_DataB(jj+1));
obj->pin_DataA(jj+1).unlink();
obj->pin_DataB(jj+1).unlink();
}
}
/* If we wound up disconnecting all the inputs, then remove
the device and replace it with a constant. */
if (top == 0) {
NetConst*one = new NetConst(scope, obj->name(), verinum::V1);
connect(one->pin(0), obj->pin_AEB());
delete obj;
des->add_node(one);
count += 1;
return;
}
/* If there is only one bit left, then replace the comparator
with a simple XOR gate. */
if (top == 1) {
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
NetLogic::XNOR, 1);
connect(tmp->pin(0), obj->pin_AEB());
connect(tmp->pin(1), obj->pin_DataA(0));
connect(tmp->pin(2), obj->pin_DataB(0));
delete obj;
des->add_node(tmp);
count += 1;
return;
}
if (top == obj->width())
return;
NetCompare*tmp = new NetCompare(scope, obj->name(), top);
connect(tmp->pin_AEB(), obj->pin_AEB());
for (unsigned idx = 0 ; idx < top ; idx += 1) {
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx));
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx));
}
delete obj;
des->add_node(tmp);
count += 1;
#endif
}
void cprop_functor::lpm_ff(Design*, NetFF*obj)
void cprop_functor::lpm_ff(Design*des, NetFF*obj)
{
// Look for and count unlinked FF outputs. Note that if the
// Data and Q pins are connected together, they can be removed
@@ -91,10 +212,577 @@ void cprop_functor::lpm_ff(Design*, NetFF*obj)
}
}
void cprop_functor::lpm_logic(Design*, NetLogic*)
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
{
#if 0
NetScope*scope = obj->scope();
#endif
switch (obj->type()) {
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::NAND:
case NetLogic::AND: {
unsigned top = obj->pin_count();
unsigned idx = 1;
unsigned xs = 0;
/* Eliminate all the 1 inputs. They have no effect
on the output of an AND gate. */
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value()==verinum::V1) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
connect(obj->pin(idx), obj->pin(top));
obj->pin(top).unlink();
}
continue;
}
if (obj->pin(idx).nexus()->driven_value() != verinum::V0) {
idx += 1;
xs += 1;
continue;
}
/* Oops! We just stumbled on a driven-0 input
to the AND gate. That means we can replace
the whole bloody thing with a constant
driver and exit now. */
NetConst*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
case NetLogic::NAND:
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If all the inputs were eliminated, then replace
the gate with a constant 1 and I am done. */
if (top == 1) {
NetConst*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
case NetLogic::NAND:
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If all the inputs are unknowns, then replace the
gate with a Vx. */
if (xs == (top-1)) {
NetConst*tmp;
tmp = new NetConst(scope, obj->name(), verinum::Vx);
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If we are down to only one input, then replace
the AND with a BUF and exit now. */
if (top == 2) {
NetLogic*tmp;
switch (obj->type()) {
case NetLogic::AND:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
break;
case NetLogic::NAND:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
connect(obj->pin(1), tmp->pin(1));
delete obj;
count += 1;
return;
}
/* Finally, this cleans up the gate by creating a
new [N]AND gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
for (unsigned idx = 0 ; idx < top ; idx += 1)
connect(tmp->pin(idx), obj->pin(idx));
delete obj;
count += 1;
return;
}
break;
}
#endif
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::NOR:
case NetLogic::OR: {
unsigned top = obj->pin_count();
unsigned idx = 1;
/* Eliminate all the 0 inputs. They have no effect
on the output of an OR gate. */
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
connect(obj->pin(idx), obj->pin(top));
obj->pin(top).unlink();
}
continue;
}
if (obj->pin(idx).nexus()->driven_value() != verinum::V1) {
idx += 1;
continue;
}
/* Oops! We just stumbled on a driven-1 input
to the OR gate. That means we can replace
the whole bloody thing with a constant
driver and exit now. */
NetConst*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
case NetLogic::NOR:
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If all the inputs were eliminated, then replace
the gate with a constant 0 and I am done. */
if (top == 1) {
NetConst*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetConst(scope, obj->name(), verinum::V0);
break;
case NetLogic::NOR:
tmp = new NetConst(scope, obj->name(), verinum::V1);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If we are down to only one input, then replace
the OR with a BUF and exit now. */
if (top == 2) {
NetLogic*tmp;
switch (obj->type()) {
case NetLogic::OR:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
break;
case NetLogic::NOR:
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
break;
default:
assert(0);
}
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
connect(obj->pin(1), tmp->pin(1));
delete obj;
count += 1;
return;
v }
/* Finally, this cleans up the gate by creating a
new [N]OR gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
for (unsigned idx = 0 ; idx < top ; idx += 1)
connect(tmp->pin(idx), obj->pin(idx));
delete obj;
count += 1;
return;
}
break;
}
#endif
#if 0
/* XXXX This old code assumed that the individual bit
slices could be replaced with different gates. They
cannot when the device takes atomic vectors, so this
needs to be rewritten. XXXX */
case NetLogic::XNOR:
case NetLogic::XOR: {
unsigned top = obj->pin_count();
unsigned idx = 1;
/* Eliminate all the 0 inputs. They have no effect
on the output of an XOR gate. The eliminate works
by unlinking the current input and relinking the
last input to this position. It's like bubbling
all the 0 inputs to the end. */
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
connect(obj->pin(idx), obj->pin(top));
obj->pin(top).unlink();
}
} else {
idx += 1;
}
}
/* Look for pairs of constant 1 inputs. If I find a
pair, then eliminate both. Each iteration through
the loop, the `one' variable holds the index to
the previous V1, or 0 if there is none.
The `ones' variable counts the number of V1
inputs. After this loop completes, `ones' will be
0 or 1. */
unsigned one = 0, ones = 0;
idx = 1;
while (idx < top) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (obj->pin(idx).nexus()->driven_value() == verinum::V1) {
if (one == 0) {
one = idx;
ones += 1;
idx += 1;
continue;
}
/* Here we found two constant V1
inputs. Unlink both. */
obj->pin(idx).unlink();
top -= 1;
if (idx < top) {
connect(obj->pin(idx), obj->pin(top));
obj->pin(top).unlink();
}
obj->pin(one).unlink();
top -= 1;
if (one < top) {
connect(obj->pin(one), obj->pin(top));
obj->pin(top).unlink();
}
/* Reset ones counter and one index,
start looking for the next pair. */
assert(ones == 1);
ones = 0;
one = 0;
continue;
}
idx += 1;
}
/* If all the inputs were eliminated, then replace
the gate with a constant value and I am done. */
if (top == 1) {
verinum::V out = obj->type()==NetLogic::XNOR
? verinum::V1
: verinum::V0;
NetConst*tmp = new NetConst(scope, obj->name(), out);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
delete obj;
count += 1;
return;
}
/* If there is a stray V1 input and only one other
input, then replace the gate with an inverter and
we are done. */
if ((top == 3) && (ones == 1)) {
unsigned save;
if (! obj->pin(1).nexus()->drivers_constant())
save = 1;
else if (obj->pin(1).nexus()->driven_value() != verinum::V1)
save = 1;
else
save = 2;
NetLogic*tmp;
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
else
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
connect(obj->pin(save), tmp->pin(1));
delete obj;
count += 1;
return;
}
/* If we are down to only one input, then replace
the XOR with a BUF and exit now. */
if (top == 2) {
NetLogic*tmp;
if (obj->type() == NetLogic::XOR)
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::BUF, 1);
else
tmp = new NetLogic(scope,
obj->name(), 2,
NetLogic::NOT, 1);
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
connect(obj->pin(0), tmp->pin(0));
connect(obj->pin(1), tmp->pin(1));
delete obj;
count += 1;
return;
}
/* Finally, this cleans up the gate by creating a
new XOR gate that has the right number of
inputs, connected in the right place. */
if (top < obj->pin_count()) {
NetLogic*tmp = new NetLogic(scope,
obj->name(), top,
obj->type(), 1);
des->add_node(tmp);
tmp->pin(0).drive0(obj->pin(0).drive0());
tmp->pin(0).drive1(obj->pin(0).drive1());
for (unsigned idx = 0 ; idx < top ; idx += 1)
connect(tmp->pin(idx), obj->pin(idx));
delete obj;
count += 1;
return;
}
break;
}
#endif
default:
break;
}
}
#if 0
static void replace_with_mos(Design*des, NetMux*obj, NetLogic::TYPE type)
{
NetScope*scope = obj->scope();
NetLogic*tmp = new NetLogic(obj->scope(),
scope->local_symbol(),
3, type, obj->width());
des->add_node(tmp);
connect(obj->pin_Result(), tmp->pin(0));
connect(obj->pin_Data(type==NetLogic::PMOS? 0 : 1), tmp->pin(1));
if (obj->width() == 1) {
/* Special case that the expression is 1 bit
wide. Connect the select directly to the enable. */
connect(obj->pin_Sel(), tmp->pin(2));
} else {
/* General case that the expression is arbitrarily
wide. Replicate the enable signal (which we
assume is 1 bit wide) to match the expression,
and connect the enable vector to the enable
input of the gate. */
NetReplicate*rtmp = new NetReplicate(scope,
scope->local_symbol(),
obj->width(),
obj->width());
des->add_node(rtmp);
connect(obj->pin_Sel(), rtmp->pin(1));
connect(tmp->pin(2), rtmp->pin(0));
NetNet*rsig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, obj->width());
rsig->local_flag(true);
rsig->data_type(IVL_VT_LOGIC);
connect(tmp->pin(2), rsig->pin(0));
}
delete obj;
}
#endif
/*
* This detects the case where the mux selects between a value and
* Vz. In this case, replace the device with a mos with the sel
@@ -107,47 +795,57 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
if (obj->sel_width() != 1)
return;
Nexus*sel_nex = obj->pin_Sel().nexus();
#if 0
/*
* This is slower than the actual MUXZ so we are skipping this for now.
* If we had a half mux functor this could be faster and more compact
* so I'm leaving the code for future reference.
*/
/* If the first input is all constant Vz, then replace the
NetMux with an array of NMOS devices, with the enable
connected to the select input. */
if (obj->pin_Data(0).nexus()->drivers_constant() &&
obj->pin_Data(0).nexus()->driven_value() == verinum::Vz) {
replace_with_mos(des, obj, NetLogic::NMOS);
count += 1;
return;
}
/* If instead the second input is all constant Vz, replace the
NetMux with an array of PMOS devices. */
if (obj->pin_Data(1).nexus()->drivers_constant() &&
obj->pin_Data(1).nexus()->driven_value() == verinum::Vz) {
replace_with_mos(des, obj, NetLogic::PMOS);
count += 1;
return;
}
#endif
/* If the select input is constant, then replace with a BUFZ */
bool flag = obj->pin_Sel().nexus()->drivers_constant();
verinum::V sel_val = flag? obj->pin_Sel().nexus()->driven_value() : verinum::Vx;
if ((sel_val != verinum::Vz) && (sel_val != verinum::Vx)) {
NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width());
tmp->set_line(*obj);
// If the select is not constant, there is nothing we can do.
if (! sel_nex->drivers_constant())
return;
if (debug_optimizer)
cerr << obj->get_fileline() << ": debug: "
<< "Replace binary MUX with constant select=" << sel_val
<< " with a BUFZ to the selected input." << endl;
// If the select input is assigned or forced, then again there
// is nothing we can do here.
if (sel_nex->assign_lval())
return;
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
// If the constant select is 'bz or 'bx, then give up.
verinum::V sel_val = sel_nex->driven_value();
if (sel_val == verinum::Vz || sel_val == verinum::Vx)
return;
// The Select input must be a defined constant value, so we
// can replace the device with a BUFZ.
NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width(), true);
tmp->set_line(*obj);
if (debug_optimizer)
cerr << obj->get_fileline() << ": debug: "
<< "Replace binary MUX with constant select=" << sel_val
<< " with a BUFZ to the selected input." << endl;
tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
connect(tmp->pin(0), obj->pin_Result());
if (sel_val == verinum::V1)
connect(tmp->pin(1), obj->pin_Data(1));
else
connect(tmp->pin(1), obj->pin_Data(0));
delete obj;
des->add_node(tmp);
count += 1;
connect(tmp->pin(0), obj->pin_Result());
if (sel_val == verinum::V1)
connect(tmp->pin(1), obj->pin_Data(1));
else
connect(tmp->pin(1), obj->pin_Data(0));
delete obj;
des->add_node(tmp);
count += 1;
}
}
/*
@@ -161,13 +859,7 @@ struct cprop_dc_functor : public functor_t {
virtual void lpm_const(Design*des, NetConst*obj);
};
struct nexus_info_s {
Nexus*nex;
unsigned inp;
unsigned out;
};
void cprop_dc_functor::lpm_const(Design*, NetConst*obj)
void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
{
// 'bz constant values drive high impedance to whatever is
// connected to it. In other words, it is a noop. But that is
@@ -186,27 +878,40 @@ void cprop_dc_functor::lpm_const(Design*, NetConst*obj)
}
}
std::vector<nexus_info_s> nexus_info (obj->pin_count());
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
nexus_info[idx].nex = obj->pin(idx).nexus();
unsigned inputs = 0, outputs = 0;
nexus_info[idx].nex -> count_io(inputs, outputs);
nexus_info[idx].inp = inputs;
nexus_info[idx].out = outputs;
// For each bit, if this is the only driver, then set the
// initial value of all the signals to this value.
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
if (count_outputs(obj->pin(idx)) > 1)
continue;
Nexus*nex = obj->pin(idx).nexus();
for (Link*clnk = nex->first_nlink()
; clnk ; clnk = clnk->next_nlink()) {
NetPins*cur;
unsigned pin;
clnk->cur_link(cur, pin);
NetNet*tmp = dynamic_cast<NetNet*>(cur);
if (tmp == 0)
continue;
tmp->pin(pin).set_init(obj->value(idx));
}
}
// If there are any links that take input, the constant is
// used structurally somewhere.
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1)
if (nexus_info[idx].inp > 0)
if (count_inputs(obj->pin(idx)) > 0)
return;
// Look for signals that have NetESignal nodes attached to
// them. If I find any, then this constant is used by a
// behavioral expression somewhere.
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
for (Link*clnk = nexus_info[idx].nex->first_nlink()
Nexus*nex = obj->pin(idx).nexus();
for (Link*clnk = nex->first_nlink()
; clnk ; clnk = clnk->next_nlink()) {
NetPins*cur;
@@ -242,7 +947,7 @@ void cprop_dc_functor::lpm_const(Design*, NetConst*obj)
}
}
// Done. Found no reason to keep this object, so delete it.
// Done. Delete me.
delete obj;
}
@@ -255,19 +960,8 @@ void cprop(Design*des)
do {
prop.count = 0;
des->functor(&prop);
if (verbose_flag) {
cout << " ... Iteration detected "
<< prop.count << " optimizations." << endl << flush;
}
} while (prop.count > 0);
if (verbose_flag) {
cout << " ... Look for dangling constants" << endl << flush;
}
cprop_dc_functor dc;
des->functor(&dc);
if (verbose_flag) {
cout << " ... done" << endl << flush;
}
}
+113 -267
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2012 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"
@@ -28,10 +28,7 @@
# include "netlist.h"
# include "compiler.h"
# include "discipline.h"
# include "netdarray.h"
# include "netvector.h"
# include "ivl_assert.h"
# include "PExpr.h"
static ostream& operator<< (ostream&o, NetBlock::Type t)
{
@@ -42,41 +39,26 @@ static ostream& operator<< (ostream&o, NetBlock::Type t)
case NetBlock::PARA:
o << "fork";
break;
case NetBlock::PARA_JOIN_NONE:
o << "fork-join_none";
break;
case NetBlock::PARA_JOIN_ANY:
o << "fork-join_any";
break;
}
return o;
}
ostream& operator << (ostream&o, ivl_drive_t str)
ostream& operator << (ostream&o, Link::strength_t str)
{
switch (str) {
case IVL_DR_HiZ:
case Link::HIGHZ:
o << "highz";
break;
case IVL_DR_SMALL:
o << "small";
break;
case IVL_DR_MEDIUM:
o << "medium";
break;
case IVL_DR_WEAK:
case Link::WEAK:
o << "weak";
break;
case IVL_DR_LARGE:
o << "large";
break;
case IVL_DR_PULL:
case Link::PULL:
o << "pull";
break;
case IVL_DR_STRONG:
case Link::STRONG:
o << "strong";
break;
case IVL_DR_SUPPLY:
case Link::SUPPLY:
o << "supply";
break;
default:
@@ -103,15 +85,6 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
case IVL_VT_LOGIC:
o << "logic";
break;
case IVL_VT_STRING:
o << "string";
break;
case IVL_VT_DARRAY:
o << "darray";
break;
case IVL_VT_CLASS:
o << "class";
break;
}
return o;
}
@@ -144,28 +117,9 @@ ostream& operator << (ostream&o, ivl_switch_type_t val)
return o;
}
ostream& ivl_type_s::debug_dump(ostream&o) const
{
o << typeid(*this).name();
return o;
}
ostream& netdarray_t::debug_dump(ostream&o) const
{
o << "dynamic array of " << *element_type();
return o;
}
ostream& netvector_t::debug_dump(ostream&o) const
{
o << type_ << (signed_? " signed" : " unsigned") << packed_dims_;
return o;
}
static inline void dump_scope_path(ostream&o, const NetScope*scope)
{
const NetScope*parent = scope->parent();
if (parent) {
if (const NetScope*parent = scope->parent()) {
dump_scope_path(o, parent);
o << ".";
}
@@ -182,17 +136,6 @@ ostream& operator <<(ostream&o, struct __ScopePathManip marg)
return o;
}
void NetBranch::dump(ostream&o, unsigned ind) const
{
static const char*pin_names[2] = {
"terminal0",
"terminal1" };
o << setw(ind) << "" << "branch island=" << get_island();
o << " // " << get_fileline() << endl;
dump_node_pins(o, ind+4, pin_names);
}
void NetDelaySrc::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "specify delay";
@@ -219,42 +162,16 @@ void NetDelaySrc::dump(ostream&o, unsigned ind) const
dump_node_pins(o, ind+4);
}
static inline ostream&operator<<(ostream&out, const netrange_t&that)
{
if (that.defined())
out << "[" << that.get_msb() << ":" << that.get_lsb() << "]";
else
out << "[]";
return out;
}
ostream&operator<<(ostream&out, const list<netrange_t>&rlist)
{
for (list<netrange_t>::const_iterator cur = rlist.begin()
; cur != rlist.end() ; ++cur) {
out << *cur;
}
return out;
}
ostream&operator<<(ostream&out, const vector<netrange_t>&rlist)
{
for (vector<netrange_t>::const_iterator cur = rlist.begin()
; cur != rlist.end() ; ++cur) {
out << *cur;
}
return out;
}
/* Dump a net. This can be a wire or register. */
void NetNet::dump_net(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << type() << ": " << name()
<< unpacked_dims_ << " unpacked dims=" << unpacked_dimensions();
o << " pin_count=" << pin_count();
<< "[" << s0_ << ":" << e0_ << " count=" << pin_count() << "]";
if (local_flag_)
o << " (local)";
o << " " << data_type_;
if (signed_)
o << " signed";
switch (port_type_) {
case NetNet::NOT_A_PORT:
break;
@@ -270,27 +187,25 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
case NetNet::PINOUT:
o << " inout";
break;
case NetNet::PREF:
o <<" ref";
break;
}
if (ivl_discipline_t dis = get_discipline())
o << " discipline=" << dis->name();
if (net_type_) o << " " << *net_type_;
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
if (scope())
o << " scope=" << scope_path(scope());
o << " #(" << rise_time() << "," << fall_time() << ","
<< decay_time() << ") vector_width=" << vector_width()
<< " pin_count=" << pin_count();
if (pins_are_virtual()) {
o << " pins_are_virtual" << endl;
return;
}
o << endl;
<< " pin_count=" << pin_count()
<< " init=";
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
o << pin(idx-1).get_init();
o << " (";
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
o << pin(idx-1).nexus()->get_init();
o << ")" << endl;
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
if (! pin(idx).is_linked())
@@ -402,17 +317,9 @@ void NetArrayDq::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetCastInt2::dump_node(ostream&o, unsigned ind) const
void NetCastInt::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Cast to int2. (NetCastInt2): " <<
name() << " width=" << width() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetCastInt4::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Cast to int4. (NetCastInt4): " <<
o << setw(ind) << "" << "Cast to int. (NetCastInt): " <<
name() << " width=" << width() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
@@ -502,8 +409,7 @@ void NetBUFZ::dump_node(ostream&o, unsigned ind) const
o << setw(ind) << "" << "NetBUFZ: " << name()
<< " scope=" << scope_path(scope())
<< " delay=(" << rise_time() << "," << fall_time() << "," <<
decay_time() << ") width=" << width()
<< (transparent()? " " : " non-") << "transparent" << endl;
decay_time() << ") width=" << width() << endl;
dump_node_pins(o, ind+4);
}
@@ -735,8 +641,7 @@ void NetUserFunc::dump_node(ostream&o, unsigned ind) const
if (rise_time())
o << " #(" <<*rise_time()
<<","<<*fall_time()
<< "," <<*decay_time() << ")";
o << endl;
<< "," <<*decay_time() << ")" << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -773,20 +678,13 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
void NetTran::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << type_ << " " << name()
<< " island " << get_island();
<< " island " << island;
if (type_ == IVL_SW_TRAN_VP) {
o << " width=" << vector_width()
<< " part=" << part_width()
<< " offset=" << part_offset();
}
o << " delay=(";
if (rise_time())
o << *rise_time() << "," << *fall_time() << ","
<< *decay_time();
else
o << "0,0,0";
o << ")" << endl;
o << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -812,10 +710,6 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
o << "always /* " << get_fileline() << " in "
<< scope_path(scope_) << " */" << endl;
break;
case IVL_PR_FINAL:
o << "final /* " << get_fileline() << " in "
<< scope_path(scope_) << " */" << endl;
break;
}
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) {
@@ -838,11 +732,6 @@ void NetAnalogTop::dump(ostream&o, unsigned ind) const
o << "analog /* " << get_fileline() << " in "
<< scope_path(scope_) << " */" << endl;
break;
case IVL_PR_FINAL:
o << "analog final /* " << get_fileline() << " in "
<< scope_path(scope_) << " */" << endl;
break;
}
statement_->dump(o, ind+2);
@@ -857,9 +746,6 @@ void NetAssign_::dump_lval(ostream&o) const
{
if (sig_) {
o << sig_->name();
if (! member_.nil()) {
o << "." << member_;
}
if (word_) {
o << "[word=" << *word_ << "]";
}
@@ -890,10 +776,7 @@ void NetAssign::dump(ostream&o, unsigned ind) const
o << setw(ind) << "";
dump_lval(o);
if (op_)
o << " " << op_ << "= ";
else
o << " = ";
o << " = ";
if (const NetExpr*de = get_delay())
o << "#(" << *de << ") ";
@@ -1111,7 +994,8 @@ void NetFuncDef::dump(ostream&o, unsigned ind) const
if (result_sig_) {
o << setw(ind+2) << "" << "Return signal: ";
if (result_sig_->get_signed()) o << "+";
o << result_sig_->name() << endl;
o << result_sig_->name() << "[" << result_sig_->msb() << ":"
<< result_sig_->lsb() << "]" << endl;
}
o << setw(ind+2) << "" << "Arguments: ";
if (port_count() == 0) o << "<none>";
@@ -1133,7 +1017,8 @@ void NetFuncDef::dump(ostream&o, unsigned ind) const
break;
}
if (port(idx)->get_signed()) o << "+";
o << port(idx)->name() << endl;
o << port(idx)->name() << "[" << port(idx)->msb() << ":"
<< port(idx)->lsb() << "]" << endl;
}
if (statement_)
statement_->dump(o, ind+2);
@@ -1174,14 +1059,29 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
void NetScope::dump(ostream&o) const
{
/* This is a constructed hierarchical name. */
o << scope_path(this) << " ";
o << scope_path(this);
print_type(o);
switch (type_) {
case BEGIN_END:
o << " sequential block";
break;
case FORK_JOIN:
o << " parallel block";
break;
case FUNC:
o << " function";
break;
case MODULE:
o << " module <" << (module_name_? module_name_.str() : "") << ">";
break;
case TASK:
o << " task";
break;
case GENBLOCK:
o << " generate block";
break;
}
if (is_auto()) o << " (automatic)";
if (is_cell()) o << " (cell)";
if (nested_module()) o << " (nested)";
if (program_block()) o << " (program)";
o << endl;
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
@@ -1195,11 +1095,8 @@ void NetScope::dump(ostream&o) const
{
map<perm_string,param_expr_t>::const_iterator pp;
for (pp = parameters.begin()
; pp != parameters.end() ; ++ pp ) {
if ((*pp).second.is_annotatable)
o << " specparam ";
else
o << " parameter ";
; pp != parameters.end() ; pp ++) {
o << " parameter ";
o << pp->second.type << " ";
@@ -1210,11 +1107,7 @@ void NetScope::dump(ostream&o) const
o << "[" << *(*pp).second.msb
<< ":" << *(*pp).second.lsb << "] ";
o << (*pp).first << " = ";
if (pp->second.val)
o << *(*pp).second.val;
else
o << "<nil>";
o << (*pp).first << " = " << *(*pp).second.expr;
for (range_t*ran = (*pp).second.range ; ran ; ran = ran->next) {
if (ran->exclude_flag)
@@ -1246,44 +1139,33 @@ void NetScope::dump(ostream&o) const
o << ";" << endl;
}
for (pp = localparams.begin()
; pp != localparams.end() ; pp ++) {
o << " localparam " << (*pp).first << " = " <<
*(*pp).second.expr << ";" << endl;
}
}
/* Dump the saved defparam assignments here. */
{
list<pair<pform_name_t,PExpr*> >::const_iterator pp;
list<pair<pform_name_t,NetExpr*> >::const_iterator pp;
for (pp = defparams.begin()
; pp != defparams.end() ; ++ pp ) {
; pp != defparams.end() ; pp ++ ) {
o << " defparam " << (*pp).first << " = " <<
*(*pp).second << ";" << endl;
}
}
{
list<pair<list<hname_t>,PExpr*> >::const_iterator pp;
list<pair<list<hname_t>,NetExpr*> >::const_iterator pp;
for (pp = defparams_later.begin()
; pp != defparams_later.end() ; ++ pp ) {
; pp != defparams_later.end() ; pp ++ ) {
o << " defparam(later) " << pp->first << " = " <<
*(pp->second) << ";" << endl;
}
}
o << " enum sets {" << endl;
/* Dump the enumerations and enum names in this scope. */
for (list<netenum_t*>::const_iterator cur = enum_sets_.begin()
; cur != enum_sets_.end() ; ++ cur) {
o << " " << *cur << endl;
}
o << " }" << endl;
o << " enum names {" << endl;
for (map<perm_string,NetEConstEnum*>::const_iterator cur = enum_names_.begin()
; cur != enum_names_.end() ; ++ cur) {
o << " " << cur->first << " = " << cur->second->value()
<< " from " << cur->second->enumeration() << endl;
}
o << " }" << endl;
/* Dump the events in this scope. */
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
o << " event " << cur->name() << "; nprobe="
@@ -1293,10 +1175,31 @@ void NetScope::dump(ostream&o) const
// Dump the signals,
for (signals_map_iter_t cur = signals_map_.begin()
; cur != signals_map_.end() ; ++ cur) {
; cur != signals_map_.end() ; cur ++) {
cur->second->dump_net(o, 4);
}
// Dump specparams
typedef map<perm_string,spec_val_t>::const_iterator specparam_it_t;
for (specparam_it_t cur = specparams.begin()
; cur != specparams.end() ; cur ++ ) {
o << " specparam " << (*cur).first
<< " = ";
spec_val_t value = (*cur).second;
switch (value.type) {
case IVL_VT_REAL:
o << "R:" << value.real_val;
break;
case IVL_VT_BOOL:
o << "I:" << value.integer;
break;
default:
o << "<bad type>";
break;
}
o << endl;
}
switch (type_) {
case FUNC:
if (func_def())
@@ -1315,21 +1218,20 @@ void NetScope::dump(ostream&o) const
}
/* Dump any sub-scopes. */
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
; cur != children_.end() ; ++ cur )
cur->second->dump(o);
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
cur->dump(o);
}
void NetSTask::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << name_;
if (! parms_.empty()) {
if (parms_.count() > 0) {
o << "(";
if (parms_[0])
parms_[0]->dump(o);
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
o << ", ";
if (parms_[idx])
parms_[idx]->dump(o);
@@ -1401,9 +1303,6 @@ void NetEBinary::dump(ostream&o) const
case 'a':
o << "&&";
break;
case 'A':
o << "~&";
break;
case 'E':
o << "===";
break;
@@ -1451,15 +1350,19 @@ void NetEBinary::dump(ostream&o) const
void NetEConcat::dump(ostream&o) const
{
if (repeat_ != 1)
o << repeat_;
if (repeat_calculated_) {
if (repeat_value_ != 1)
o << repeat_value_;
} else if (repeat_) {
o << "<" << *repeat_ << ">";
}
if (parms_[0])
o << "{" << *parms_[0];
else
o << "{";
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
if (parms_[idx])
o << ", " << *parms_[idx];
else
@@ -1476,13 +1379,6 @@ void NetEConst::dump(ostream&o) const
o << value_;
}
void NetEConstEnum::dump(ostream&o) const
{
o << "<" << name_ << "=";
NetEConst::dump(o);
o << ", wid=" << expr_width() << ">";
}
void NetEConstParam::dump(ostream&o) const
{
o << "<" << name_ << "=";
@@ -1507,26 +1403,6 @@ void NetEEvent::dump(ostream&o) const
o << "<event=" << event_->name() << ">";
}
void NetENetenum::dump(ostream&o) const
{
o << "<netenum=" << netenum_ << ">";
}
void NetENew::dump(ostream&o) const
{
o << "new <type>";
}
void NetENull::dump(ostream&o) const
{
o << "<null>";
}
void NetEProperty::dump(ostream&o) const
{
o << net_->name() << ".<" << pidx_ << ">";
}
void NetEScope::dump(ostream&o) const
{
o << "<scope=" << scope_path(scope_) << ">";
@@ -1548,14 +1424,7 @@ void NetESelect::dump(ostream&o) const
else
o << "(0)";
o << "+:" << expr_width() << "]";
if (ivl_type_t nt = net_type()) {
o << " net_type=(" << *nt << ")";
} else {
o << " expr_type=" << expr_type();
}
o << ">";
o << "+:" << expr_width() << "]>";
}
void NetESFunc::dump(ostream&o) const
@@ -1574,8 +1443,15 @@ void NetESignal::dump(ostream&o) const
o << "+";
o << name();
if (word_) o << "[word=" << *word_ << "]";
vector<netrange_t>tmp = net_->net_type()->slice_dimensions();
o << tmp;
o << "[" << msi()<<":"<<lsi() << "]";
}
void NetEParam::dump(ostream&o) const
{
if (scope_ != 0)
o << "<" << scope_path(scope_) << "." << (*reference_).first << ">";
else
o << "<" << (*reference_).first << ">";
}
void NetETernary::dump(ostream&o) const
@@ -1587,9 +1463,9 @@ void NetETernary::dump(ostream&o) const
void NetEUFunc::dump(ostream&o) const
{
o << func_->basename() << "(";
if (! parms_.empty()) {
if (parms_.count() > 0) {
parms_[0]->dump(o);
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
o << ", ";
parms_[idx]->dump(o);
}
@@ -1600,27 +1476,12 @@ void NetEUFunc::dump(ostream&o) const
void NetEUnary::dump(ostream&o) const
{
switch (op_) {
case 'A':
o << "~&";
break;
case 'm':
o << "abs";
break;
case 'N':
o << "~|";
break;
case 'X':
o << "~^";
break;
case 'I':
o << "++";
break;
case 'D':
o << "--";
break;
case 'i':
case 'd':
break;
default:
o << op_;
break;
@@ -1628,14 +1489,6 @@ void NetEUnary::dump(ostream&o) const
o << "(";
expr_->dump(o);
o << ")";
switch (op_) {
case 'i':
o << "++";
break;
case 'd':
o << "--";
break;
}
}
void Design::dump(ostream&o) const
@@ -1643,7 +1496,7 @@ void Design::dump(ostream&o) const
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
o << "SCOPES:" << endl;
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); ++ scope )
scope != root_scopes_.end(); scope++)
(*scope)->dump(o);
o << "ELABORATED NODES:" << endl;
@@ -1658,13 +1511,6 @@ void Design::dump(ostream&o) const
} while (cur != nodes_->node_next_);
}
o << "ELABORATED BRANCHES:" << endl;
if (branches_) {
for (NetBranch*cur = branches_ ; cur ; cur = cur->next_)
cur->dump(o, 0);
}
o << "ELABORATED PROCESSES:" << endl;
// Dump the processes.
+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__)
{
}
+12 -12
View File
@@ -1,7 +1,7 @@
#ifndef __discipline_H
#define __discipline_H
/*
* Copyright (c) 2008-2010 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
@@ -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
+25 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001 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,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 -39
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,68 +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@ @CFLAGS@
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;@IVLCFLAGS@;@CXXFLAGS@;' \
-e 's;@SHARED@;@shared@;' $< > $@
# Windows specific...
res.rc: $(srcdir)/res.rc.in ../version.exe
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%m,%n,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 -2
View File
@@ -5,5 +5,4 @@
#define IVERILOG_VPI_CXX "@IVLCXX@"
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@"
#define IVERILOG_VPI_LDFLAGS "@SHARED@"
#define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@"
#define IVERILOG_SUFFIX "@SUFFIX@"
#define IVERILOG_VPI_LDLIBS "-lveriuser -lvpi"
+24 -36
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
*/
/*
@@ -87,9 +87,9 @@ static void myExit(int exitVal)
static void usage()
{
fprintf(stderr,"usage: iverilog-vpi" IVERILOG_SUFFIX " [src and obj files]...\n");
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -ivl=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);
}
@@ -154,15 +154,12 @@ static int startsWith (char *prefix, char *str)
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) {
if (*ptr == NULL) {
fprintf(stderr,"error: out of memory\n");
free(*ptr);
myExit(4);
}
*ptr = nptr;
if (count)
strncat(*ptr,app,count);
@@ -190,14 +187,12 @@ static void appendBackSlash(char **str)
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) {
if (*ptr == NULL) {
fprintf(stderr,"error: out of memory\n");
free(*ptr);
myExit(4);
}
*ptr = nptr;
if (count) {
strncpy(*ptr,str,count);
@@ -241,9 +236,7 @@ static int GetRegistryKey(char *key, char **value)
}
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);
@@ -276,9 +269,7 @@ static void SetRegistryKey(char *key, char *value)
&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);
@@ -393,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
@@ -422,18 +413,11 @@ static void checkMingwDir(char *root)
int irv;
struct _stat stat_buf;
char *path, *comp, *cp;
char *path;
initDynString(&path);
assign(&path,gstr.pMINGW);
appendBackSlash(&path);
append(&path,"bin\\");
/* Get just the compiler name (the first word) */
comp = strdup(IVERILOG_VPI_CC);
cp = strchr(comp, ' ');
if (cp != NULL) *cp = '\0';
append(&path, comp);
append(&path,".exe");
free(comp);
append(&path,"bin\\" IVERILOG_VPI_CC ".exe");
irv = _stat(path,&stat_buf);
deInitDynString(path);
@@ -460,14 +444,14 @@ static void checkIvlDir(char *root)
initDynString(&path);
assign(&path,gstr.pIVL);
appendBackSlash(&path);
append(&path,"bin\\vvp" IVERILOG_SUFFIX ".exe");
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" IVERILOG_SUFFIX " to\n");
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");
@@ -519,7 +503,7 @@ static void setup_ivl_environment()
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" IVERILOG_SUFFIX " to point to the Icarus Verilog root directory.\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");
@@ -527,16 +511,20 @@ static void setup_ivl_environment()
}
/* Build up the CFLAGS option string */
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I\"");
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS);
append(&gstr.pCFLAGS," -I");
append(&gstr.pCFLAGS,gstr.pIVL);
appendBackSlash(&gstr.pCFLAGS);
append(&gstr.pCFLAGS,"\\include\\\\iverilog\"" IVERILOG_SUFFIX);
append(&gstr.pCFLAGS, "\\");
append(&gstr.pCFLAGS,"include");
/* Build up the LDFLAGS option string */
assign(&gstr.pLDLIBS,"-L\"");
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 */
+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 -66
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,108 +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@ @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 $(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 -27
View File
@@ -1,10 +1,10 @@
%option prefix="cf"
%option nounput
%option noinput
%{
/*
* 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
@@ -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,21 +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; }
"+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+]* {
@@ -195,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) "
@@ -212,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. */
@@ -241,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()
{
# 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
}
+10 -38
View File
@@ -1,6 +1,6 @@
%{
/*
* Copyright (c) 2001-2011 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,8 +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_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
%token TOK_INTEGER_WIDTH
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%%
@@ -137,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. */
+2 -3
View File
@@ -1,7 +1,7 @@
#ifndef __cfparse_misc_H
#define __cfparse_misc_H
/*
* Copyright (c) 2001-2009 Picture Elements, Inc.
* Copyright (c) 2001 Picture Elements, Inc.
* Stephen Williams (steve@picturel.com)
*
* 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();
char *current_file;
#endif
+69 -10
View File
@@ -1,7 +1,7 @@
#ifndef __globals_H
#define __globals_H
/*
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000 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,18 +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;
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);
@@ -45,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[];
/* -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
+57 -143
View File
@@ -1,14 +1,13 @@
.TH iverilog 1 "February 27th, 2011" "" "Version %M.%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|\-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,13 +18,14 @@ 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
@@ -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,25 +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
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, or \fIIEEE1800\-2009\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
@@ -92,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
@@ -111,47 +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.
.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
@@ -171,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.
@@ -179,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
@@ -217,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
@@ -247,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
@@ -258,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
@@ -276,15 +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 implicit, portbind, select\-range, timescale, and
sensitivity\-entire\-array warning categories.
This enables all supported warning categories.
.TP 8
.B implicit
@@ -298,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
@@ -316,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).
@@ -327,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
@@ -384,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.
@@ -399,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.
@@ -410,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
@@ -427,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
@@ -462,8 +377,7 @@ integer 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
@@ -476,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
@@ -493,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
@@ -512,7 +426,7 @@ Tips on using, debugging, and developing the compiler can be found at
.SH COPYRIGHT
.nf
Copyright \(co 2002\-2011 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
+93 -336
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
* 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
@@ -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] [-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,13 +60,11 @@ 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>
#if HAVE_GETOPT_H
#include <getopt.h>
@@ -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,37 +100,24 @@ 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_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;
@@ -158,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;
@@ -178,12 +160,6 @@ 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. */
void add_cmd_file(const char* filename)
{
@@ -219,6 +195,8 @@ char *get_cmd_file()
}
#ifdef __MINGW32__
# include <io.h>
# include <fcntl.h>
static FILE*fopen_safe(const char*path)
{
FILE*file = 0;
@@ -231,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;
@@ -244,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;
@@ -289,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;
}
@@ -304,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);
@@ -337,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);
}
@@ -356,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);
@@ -381,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);
}
@@ -410,12 +360,14 @@ static int t_compile()
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);
@@ -430,25 +382,35 @@ static int t_compile()
}
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);
@@ -491,24 +453,15 @@ static int t_compile()
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");
@@ -517,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) {
@@ -541,30 +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;
}
}
}
@@ -593,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
@@ -630,18 +543,9 @@ 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,"1") == 0) { /* Deprecated: use 1995 */
generation = "1995";
gen_xtypes = "no-xtypes";
@@ -681,30 +585,12 @@ int process_generation(const char*name)
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";
@@ -715,59 +601,22 @@ 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"
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;
}
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.
*/
@@ -786,45 +635,37 @@ int main(int argc, char **argv)
{
int e_flag = 0;
int version_flag = 0;
int opt, idx;
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
@@ -894,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':
@@ -924,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;
@@ -938,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':
@@ -950,8 +780,7 @@ int main(int argc, char **argv)
break;
case 'M':
if (process_depfile(optarg) != 0)
return -1;
depfile = optarg;
break;
case 'm':
@@ -1006,47 +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-2011 Stephen Williams\n\n");
printf("Copyright 1998-2008 Stephen Williams\n");
puts(NOTICE);
}
if (synth_flag) {
fprintf(stderr, "Warning: Synthesis is not currently being "
"maintained and may not\n");
fprintf(stderr, " function correctly. V0.8 was the "
"last release branch to\n");
fprintf(stderr, " have active synthesis development "
"and support!\n");
}
/* 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);
@@ -1055,12 +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/9 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(gen_icarus, "icarus-misc") == 0 ||
strcmp(gen_verilog_ams, "verilog-ams") == 0) {
fprintf(iconfig_file, "sys_func:%s%cv2005_math.sft\n", base, sep);
@@ -1073,29 +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) {
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_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;
@@ -1114,30 +904,12 @@ 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 (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 (idx = optind ; idx < argc ; idx += 1)
@@ -1147,13 +919,7 @@ int main(int argc, char **argv)
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);
@@ -1162,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;
@@ -1181,8 +938,8 @@ int main(int argc, char **argv)
/* 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 -14
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,13 +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"
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
char* substitutions(const char*str)
@@ -31,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);
@@ -47,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;
@@ -93,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 -163
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2011 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,111 +32,19 @@ NetEAccess* NetEAccess::dup_expr() const
return tmp;
}
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;
}
@@ -144,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;
}
@@ -160,44 +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;
}
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;
}
@@ -205,8 +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);
expr_width());
assert(tmp);
tmp->set_line(*this);
return tmp;
}
@@ -214,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());
}
@@ -229,7 +105,7 @@ NetESFunc* NetESFunc::dup_expr() const
NetESignal* NetESignal::dup_expr() const
{
NetESignal*tmp = new NetESignal(net_, word_);
ivl_assert(*this, tmp);
assert(tmp);
tmp->expr_width(expr_width());
tmp->set_line(*this);
return tmp;
@@ -239,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;
}
@@ -250,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;
}
@@ -284,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)
*
*/
+1375 -3006
View File
File diff suppressed because it is too large Load Diff
+110 -522
View File
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
* 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
@@ -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 "netclass.h"
# include "compiler.h"
# include <cstdlib>
# include <iostream>
@@ -59,7 +56,7 @@
* l-value.
*
* This last case can turn up in statements like: {a, b[1]} = c;
* rather than create a NetAssign_ for each item in the concatenation,
* rather then create a NetAssign_ for each item in the concatenation,
* elaboration makes a single NetAssign_ and connects it up properly.
*/
@@ -69,7 +66,9 @@
* is to try to make a net elaboration, and see if the result is
* suitable for assignment.
*/
NetAssign_* PExpr::elaborate_lval(Design*, NetScope*, bool) const
NetAssign_* PExpr::elaborate_lval(Design*des,
NetScope*scope,
bool is_force) const
{
NetNet*ll = 0;
if (ll == 0) {
@@ -108,7 +107,7 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
NetAssign_*res = 0;
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
if (parms_[idx] == 0) {
cerr << get_fileline() << ": error: Empty expressions "
@@ -122,17 +121,14 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
/* If the l-value doesn't elaborate, the error was
already detected and printed. We just skip it and let
the compiler catch more errors. */
if (tmp == 0) continue;
if (tmp->expr_type() == IVL_VT_REAL) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can not be real: "
<< *parms_[idx] << endl;
des->errors += 1;
if (tmp == 0)
continue;
}
assert(tmp);
/* Link the new l-value to the previous one. */
NetAssign_*last = tmp;
while (last->more)
last = last->more;
@@ -155,31 +151,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
NetNet* reg = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
perm_string method_name;
symbol_search(this, des, scope, path_, reg, par, eve);
/* 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 (reg == 0 && path_.size() >= 2) {
pform_name_t use_path = path_;
perm_string tmp_name = peek_tail_name(use_path);
use_path.pop_back();
symbol_search(this, des, scope, use_path, reg, par, eve);
if (reg && reg->struct_type()) {
method_name = tmp_name;
} else if (reg && reg->class_type()) {
method_name = tmp_name;
} else {
reg = 0;
}
}
if (reg == 0) {
cerr << get_fileline() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope_path(scope) <<
@@ -190,76 +163,25 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
}
ivl_assert(*this, reg);
// We are processing the tail of a string of names. For
// example, the verilog may be "a.b.c", so we are processing
// "c" at this point. (Note that if method_name is not nil,
// then this is "a.b.c.method" and "a.b.c" is a struct or class.)
const name_component_t&name_tail = path_.back();
// Use the last index to determine what kind of select
// (bit/part/etc) we are processing. For example, the verilog
// may be "a.b.c[1][2][<index>]". All but the last index must
// be simple expressions, only the <index> may be a part
// select etc., so look at it to determine how we will be
// proceeding.
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
// Special case: The l-value is an entire memory, or array
// slice. This is, in fact, an error in l-values. Detect the
// situation by noting if the index count is less than the
// array dimensions (unpacked).
if (reg->unpacked_dimensions() > name_tail.index.size()) {
// This is the special case that the l-value is an entire
// memory. This is, in fact, an error.
if (reg->array_dimensions() > 0 && name_tail.index.empty()) {
cerr << get_fileline() << ": error: Cannot assign to array "
<< path_ << ". Did you forget a word index?" << endl;
des->errors += 1;
return 0;
}
/* Get the signal referenced by the identifier, and make sure
it is a register. Wires are not allowed in this context,
unless this is the l-value of a force. */
if ((reg->type() != NetNet::REG) && !is_force) {
cerr << get_fileline() << ": error: " << path_ <<
" is not a valid l-value in " << scope_path(scope) <<
"." << endl;
cerr << reg->get_fileline() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
des->errors += 1;
return 0;
}
if (reg->struct_type() && !method_name.nil()) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_packed_member_(des, scope, lv, method_name);
return lv;
}
if (reg->class_type() && !method_name.nil() && gn_system_verilog()) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_class_member_(des, scope, lv, method_name);
return lv;
}
// Past this point, we should have taken care of the cases
// where the name is a member/method of a struct/class.
ivl_assert(*this, method_name.nil());
if (reg->unpacked_dimensions() > 0)
if (reg->array_dimensions() > 0)
return elaborate_lval_net_word_(des, scope, reg);
// This must be after the array word elaboration above!
if (reg->get_scalar() &&
use_sel != index_component_t::SEL_NONE) {
cerr << get_fileline() << ": error: can not select part of ";
if (reg->data_type() == IVL_VT_REAL) cerr << "real: ";
else cerr << "scalar: ";
cerr << reg->name() << endl;
des->errors += 1;
return 0;
}
if (use_sel == index_component_t::SEL_PART) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_part_(des, scope, lv);
@@ -273,17 +195,24 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
return lv;
}
/* Get the signal referenced by the identifier, and make sure
it is a register. Wires are not allows in this context,
unless this is the l-value of a force. */
if ((reg->type() != NetNet::REG) && !is_force) {
cerr << get_fileline() << ": error: " << path_ <<
" is not a valid l-value in " << scope_path(scope) <<
"." << endl;
cerr << reg->get_fileline() << ": : " << path_ <<
" is declared here as " << reg->type() << "." << endl;
des->errors += 1;
return 0;
}
if (use_sel == index_component_t::SEL_BIT) {
if (reg->darray_type()) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_darray_bit_(des, scope, lv);
return lv;
} else {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_bit_(des, scope, lv);
return lv;
}
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_bit_(des, scope, lv);
return lv;
}
ivl_assert(*this, use_sel == index_component_t::SEL_NONE);
@@ -302,15 +231,6 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
if (name_tail.index.size() < reg->unpacked_dimensions()) {
cerr << get_fileline() << ": error: Array " << reg->name()
<< " needs " << reg->unpacked_dimensions() << " indices,"
<< " but got only " << name_tail.index.size() << "." << endl;
des->errors += 1;
return 0;
}
// Make sure there are enough indices to address an array element.
const index_component_t&index_head = name_tail.index.front();
if (index_head.sel == index_component_t::SEL_PART) {
cerr << get_fileline() << ": error: cannot perform a part "
@@ -319,63 +239,48 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
return 0;
}
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
ivl_assert(*this, index_head.msb != 0);
ivl_assert(*this, index_head.lsb == 0);
// Evaluate all the index expressions into an
// "unpacked_indices" array.
list<NetExpr*>unpacked_indices;
list<long> unpacked_indices_const;
bool flag = indices_to_expressions(des, scope, this,
name_tail.index, reg->unpacked_dimensions(),
false,
unpacked_indices,
unpacked_indices_const);
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
NetExpr*canon_index = 0;
if (flag) {
ivl_assert(*this, unpacked_indices_const.size() == reg->unpacked_dimensions());
canon_index = normalize_variable_unpacked(reg, unpacked_indices_const);
if (canon_index == 0) {
cerr << get_fileline() << ": warning: "
<< "ignoring out of bounds l-value array access " << reg->name();
for (list<long>::const_iterator cur = unpacked_indices_const.begin()
; cur != unpacked_indices_const.end() ; ++cur) {
cerr << "[" << *cur << "]";
}
cerr << "." << endl;
}
} else {
ivl_assert(*this, unpacked_indices.size() == reg->unpacked_dimensions());
canon_index = normalize_variable_unpacked(reg, unpacked_indices);
// If there is a non-zero base to the memory, then build an
// expression to calculate the canonical address.
if (long base = reg->array_first()) {
word = make_add_expr(word, 0-base);
eval_expr(word);
}
NetAssign_*lv = new NetAssign_(reg);
lv->set_word(canon_index);
lv->set_word(word);
if (debug_elaborate)
cerr << get_fileline() << ": debug: Set array word=" << *canon_index << endl;
cerr << get_fileline() << ": debug: Set array word=" << *word << endl;
// Test for the case that the index is a constant, and is out
// of bounds. The "word" expression is the word index already
// converted to canonical address, so this just needs to check
// that the address is not too big.
if (NetEConst*word_const = dynamic_cast<NetEConst*>(word)) {
verinum word_val = word_const->value();
long index = word_val.as_long();
assert (reg->array_count() <= LONG_MAX);
if (index < 0 || index >= (long) reg->array_count()) {
cerr << get_fileline() << ": warning: Constant array index "
<< (index + reg->array_first())
<< " is out of range for array "
<< reg->name() << "." << endl;
}
}
/* An array word may also have part selects applied to them. */
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (name_tail.index.size() > reg->unpacked_dimensions())
if (name_tail.index.size() > 1)
use_sel = name_tail.index.back().sel;
if (reg->get_scalar() &&
use_sel != index_component_t::SEL_NONE) {
cerr << get_fileline() << ": error: can not select part of ";
if (reg->data_type() == IVL_VT_REAL) cerr << "real";
else cerr << "scalar";
cerr << " array word: " << reg->name()
<< "[" << *canon_index << "]" << endl;
des->errors += 1;
return 0;
}
if (use_sel == index_component_t::SEL_BIT)
elaborate_lval_net_bit_(des, scope, lv);
if (use_sel == index_component_t::SEL_PART)
elaborate_lval_net_part_(des, scope, lv);
@@ -390,13 +295,7 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
list<long>prefix_indices;
bool rc = calculate_packed_indices_(des, scope, lv->sig(), prefix_indices);
if (!rc) return false;
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb == 0);
@@ -414,59 +313,23 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
mux = 0;
}
if (prefix_indices.size()+2 <= reg->packed_dims().size()) {
// Special case: this is a slice of a multi-dimensional
// packed array. For example:
// reg [3:0][7:0] x;
// x[2] = ...
// This shows up as the prefix_indices being too short
// for the packed dimensions of the vector. What we do
// here is convert to a "slice" of the vector.
if (mux == 0) {
long loff;
unsigned long lwid;
bool rcl = reg->sb_to_slice(prefix_indices, lsb, loff, lwid);
ivl_assert(*this, rcl);
lv->set_part(new NetEConst(verinum(loff)), lwid);
} else {
unsigned long lwid;
mux = normalize_variable_slice_base(prefix_indices, mux,
reg, lwid);
lv->set_part(mux, lwid);
}
} else if (reg->data_type() == IVL_VT_STRING) {
// Special case: This is a select of a string
// variable. The target of the assignment is a character
// select of a string. Force the r-value to be an 8bit
// vector and set the "part" to be the character select
// expression. The code generator knows what to do with
// this.
if (debug_elaborate) {
cerr << get_fileline() << ": debug: "
<< "Bit select of string becomes character select." << endl;
}
if (mux)
lv->set_part(mux, 8);
else
lv->set_part(new NetEConst(verinum(lsb)), 8);
} else if (mux) {
if (mux) {
// Non-constant bit mux. Correct the mux for the range
// of the vector, then set the l-value part select
// expression.
mux = normalize_variable_bit_base(prefix_indices, mux, reg);
// of the vector, then set the l-value part select expression.
if (reg->msb() < reg->lsb())
mux = make_sub_expr(reg->lsb(), mux);
else if (reg->lsb() != 0)
mux = make_add_expr(mux, - reg->lsb());
lv->set_part(mux, 1);
} else if (reg->vector_width() == 1 && reg->sb_is_valid(prefix_indices,lsb)) {
} else if (lsb == reg->msb() && lsb == reg->lsb()) {
// Constant bit mux that happens to select the only bit
// of the l-value. Don't bother with any select at all.
} else {
// Constant bit select that does something useful.
long loff = reg->sb_to_idx(prefix_indices,lsb);
long loff = reg->sb_to_idx(lsb);
if (loff < 0 || loff >= (long)reg->vector_width()) {
cerr << get_fileline() << ": error: bit select "
@@ -482,90 +345,54 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
return true;
}
bool PEIdent::elaborate_lval_darray_bit_(Design*des, NetScope*scope, NetAssign_*lv)const
{
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
// For now, only support single-dimension dynamic arrays.
ivl_assert(*this, name_tail.index.size() == 1);
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb == 0);
// Evaluate the select expression...
NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1);
lv->set_word(mux);
return true;
}
bool PEIdent::elaborate_lval_net_part_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
list<long> prefix_indices;
bool rc = calculate_packed_indices_(des, scope, lv->sig(), prefix_indices);
ivl_assert(*this, rc);
// The range expressions of a part select must be
// constant. The calculate_parts_ function calculates the
// values into msb and lsb.
long msb, lsb;
bool parts_defined_flag;
bool flag = calculate_parts_(des, scope, msb, lsb, parts_defined_flag);
bool flag = calculate_parts_(des, scope, msb, lsb);
if (!flag)
return false;
ivl_assert(*this, parts_defined_flag);
NetNet*reg = lv->sig();
ivl_assert(*this, reg);
assert(reg);
const vector<netrange_t>&packed = reg->packed_dims();
if (msb == reg->msb() && lsb == reg->lsb()) {
// Part selects cannot select slices. So there must be enough
// prefix_indices to get all the way to the final dimension.
if (prefix_indices.size()+1 < packed.size()) {
cerr << get_fileline() << ": error: Cannot select a range "
<< "of slices from a packed array." << endl;
des->errors += 1;
return false;
/* Part select covers the entire vector. Simplest case. */
} else {
/* Get the canonical offsets into the vector. */
long loff = reg->sb_to_idx(lsb);
long moff = reg->sb_to_idx(msb);
long wid = moff - loff + 1;
if (moff < loff) {
cerr << get_fileline() << ": error: part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is reversed." << endl;
des->errors += 1;
return false;
}
/* If the part select extends beyond the extremes of the
variable, then report an error. Note that loff is
converted to normalized form so is relative the
variable pins. */
if (loff < 0 || moff >= (signed)reg->vector_width()) {
cerr << get_fileline() << ": warning: Part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
}
lv->set_part(new NetEConst(verinum(loff)), wid);
}
long loff = reg->sb_to_idx(prefix_indices,lsb);
long moff = reg->sb_to_idx(prefix_indices,msb);
long wid = moff - loff + 1;
if (moff < loff) {
cerr << get_fileline() << ": error: part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is reversed." << endl;
des->errors += 1;
return false;
}
// Special case: The range winds up selecting the entire
// vector. Treat this as no part select at all.
if (loff == 0 && moff == (long)(reg->vector_width()-1)) {
return true;
}
/* If the part select extends beyond the extremes of the
variable, then report an error. Note that loff is
converted to normalized form so is relative the
variable pins. */
if (loff < 0 || moff >= (long)reg->vector_width()) {
cerr << get_fileline() << ": warning: Part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
}
lv->set_part(new NetEConst(verinum(loff)), wid);
return true;
}
@@ -574,10 +401,6 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
NetAssign_*lv,
index_component_t::ctype_t use_sel) const
{
list<long>prefix_indices;
bool rc = calculate_packed_indices_(des, scope, lv->sig(), prefix_indices);
ivl_assert(*this, rc);
const name_component_t&name_tail = path_.back();;
ivl_assert(*this, !name_tail.index.empty());
@@ -602,261 +425,26 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
calculate_up_do_width_(des, scope, wid);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
ivl_select_type_t sel_type = IVL_SEL_OTHER;
// Handle the special case that the base is constant. For this
// case we can reduce the expression.
if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
// For the undefined case just let the constant pass and
// we will handle it in the code generator.
if (base_c->value().is_defined()) {
long lsv = base_c->value().as_long();
long offset = 0;
// Get the signal range.
const vector<netrange_t>&packed = reg->packed_dims();
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
/* Correct the mux for the range of the vector. */
if (reg->msb() < reg->lsb())
base = make_sub_expr(reg->lsb(), base);
else if (reg->lsb() != 0)
base = make_add_expr(base, - reg->lsb());
// We want the last range, which is where we work.
const netrange_t&rng = packed.back();
if (((rng.get_msb() < rng.get_lsb()) &&
use_sel == index_component_t::SEL_IDX_UP) ||
((rng.get_msb() > rng.get_lsb()) &&
use_sel == index_component_t::SEL_IDX_DO)) {
offset = -wid + 1;
}
delete base;
long rel_base = reg->sb_to_idx(prefix_indices,lsv) + offset;
/* If we cover the entire lvalue just skip the select. */
if (rel_base == 0 && wid == reg->vector_width()) return true;
base = new NetEConst(verinum(rel_base));
if (warn_ob_select) {
if (rel_base < 0) {
cerr << get_fileline() << ": warning: " << reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << "[" << lsv;
if (use_sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting before vector." << endl;
}
if (rel_base + wid > reg->vector_width()) {
cerr << get_fileline() << ": warning: " << reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << "[" << lsv;
if (use_sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is selecting after vector." << endl;
}
}
} else {
if (warn_ob_select) {
cerr << get_fileline() << ": warning: " << reg->name();
if (reg->unpacked_dimensions() > 0) cerr << "[]";
cerr << "['bx";
if (use_sel == index_component_t::SEL_IDX_UP) {
cerr << "+:";
} else {
cerr << "-:";
}
cerr << wid << "] is always outside vector." << endl;
}
}
} else {
ivl_assert(*this, prefix_indices.size()+1 == reg->packed_dims().size());
/* Correct the mux for the range of the vector. */
if (use_sel == index_component_t::SEL_IDX_UP) {
base = normalize_variable_part_base(prefix_indices, base,
reg, wid, true);
sel_type = IVL_SEL_IDX_UP;
} else {
// This is assumed to be a SEL_IDX_DO.
base = normalize_variable_part_base(prefix_indices, base,
reg, wid, false);
sel_type = IVL_SEL_IDX_DOWN;
}
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1 ) {
base = make_add_expr(base, 1-(long)wid);
}
if (debug_elaborate)
cerr << get_fileline() << ": debug: Set part select width="
<< wid << ", base=" << *base << endl;
lv->set_part(base, wid, sel_type);
lv->set_part(base, wid);
return true;
}
bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*,
NetAssign_*lv,
const perm_string&method_name) const
{
if (debug_elaborate) {
cerr << get_fileline() << ": elaborate_lval_net_class_member_: "
<< "l-value is property " << method_name
<< " of " << lv->sig()->name() << "." << endl;
}
netclass_t*class_type = lv->sig()->class_type();
ivl_assert(*this, class_type);
/* Make sure the property is really present in the class. If
not, then generate an error message and return an error. */
const ivl_type_s*ptype = class_type->get_property(method_name);
if (ptype == 0) {
cerr << get_fileline() << ": error: Class " << class_type->get_name()
<< " does not have a property " << method_name << "." << endl;
des->errors += 1;
return false;
}
lv->set_property(method_name);
return true;
}
bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
NetAssign_*lv,
const perm_string&member_name) const
{
NetNet*reg = lv->sig();
ivl_assert(*this, reg);
const netstruct_t*struct_type = reg->struct_type();
ivl_assert(*this, struct_type);
if (debug_elaborate) {
cerr << get_fileline() << ": debug: elaborate lval packed member: "
<< "path_=" << path_ << endl;
}
if (! struct_type->packed()) {
cerr << get_fileline() << ": sorry: Only packed structures "
<< "are supported in l-value." << endl;
des->errors += 1;
return false;
}
// Shouldn't be seeing unpacked arrays of packed structs...
ivl_assert(*this, reg->unpacked_dimensions() == 0);
// This is a packed member, so the name is of the form
// "a.b[...].c[...]" which means that the path_ must have at
// least 2 components. We are processing "c[...]" at that
// point (otherwise known as member_name) so we'll save a
// reference to it in name_tail. We are also processing "b[]"
// so save that as name_base.
ivl_assert(*this, path_.size() >= 2);
pform_name_t::const_reverse_iterator name_idx = path_.rbegin();
ivl_assert(*this, name_idx->name == member_name);
const name_component_t&name_tail = *name_idx;
++ name_idx;
const name_component_t&name_base = *name_idx;
// Calculate the offset within the packed structure of the
// member, and any indices. We will add in the offset of the
// struct into the packed array later.
unsigned long off;
const netstruct_t::member_t* member = struct_type->packed_member(member_name, off);
if (member == 0) {
cerr << get_fileline() << ": error: Member " << member_name
<< " is not a member of variable " << reg->name() << endl;
des->errors += 1;
return false;
}
unsigned long use_width = member->width();
if (name_tail.index.size() > member->packed_dims.size()) {
cerr << get_fileline() << ": error: Too many index expressions for member." << endl;
des->errors += 1;
return false;
}
// Get the index component type. At this point, we only
// support bit select or none.
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty())
use_sel = name_tail.index.back().sel;
ivl_assert(*this, use_sel == index_component_t::SEL_NONE || use_sel == index_component_t::SEL_BIT);
if (! name_tail.index.empty()) {
// Evaluate all but the last index expression, into prefix_indices.
list<long>prefix_indices;
bool rc = evaluate_index_prefix(des, scope, prefix_indices, name_tail.index);
ivl_assert(*this, rc);
// Evaluate the last index expression into a constant long.
NetExpr*texpr = elab_and_eval(des, scope, name_tail.index.back().msb, -1, true);
long tmp;
if (texpr == 0 || !eval_as_long(tmp, texpr)) {
cerr << get_fileline() << ": error: "
"Array index expressions must be constant here." << endl;
des->errors += 1;
return false;
}
delete texpr;
// Now use the prefix_to_slice function to calculate the
// offset and width of the addressed slice of the member.
long loff;
unsigned long lwid;
prefix_to_slice(member->packed_dims, prefix_indices, tmp, loff, lwid);
off += loff;
use_width = lwid;
}
// The dimenions in the expression must match the packed
// dimensions that are declared for the variable. For example,
// if foo is a packed array of struct, then this expression
// must be "b[n][m]" with the right number of dimensions to
// match the declaration of "b".
// Note that one of the packed dimensions is the packed struct
// itself.
ivl_assert(*this, name_base.index.size()+1 == reg->packed_dimensions());
// Generate an expression that takes the input array of
// expressions and generates a canonical offset into the
// packed array.
NetExpr*packed_base = 0;
if (reg->packed_dimensions() > 1) {
list<index_component_t>tmp_index = name_base.index;
index_component_t member_select;
member_select.sel = index_component_t::SEL_BIT;
member_select.msb = new PENumber(new verinum(off));
tmp_index.push_back(member_select);
packed_base = collapse_array_indices(des, scope, reg, tmp_index);
}
long tmp;
if (packed_base && eval_as_long(tmp, packed_base)) {
off = tmp;
delete packed_base;
packed_base = 0;
}
if (packed_base == 0) {
lv->set_part(new NetEConst(verinum(off)), use_width);
return true;
}
// Oops, packed_base is not fully evaluated, so I don't know
// yet what to do with it.
cerr << get_fileline() << ": internal error: "
<< "I don't know how to handle this index expression? " << *packed_base << endl;
ivl_assert(*this, 0);
return false;
}
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
{
cerr << get_fileline() << ": error: Constant values not allowed "
+124 -407
View File
@@ -1,6 +1,5 @@
/*
* Copyright (c) 1999-2012 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 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,12 +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);
ivl_assert(*this, part_defined_flag);
/* bool flag = */ calculate_parts_(des, scope, msb, lsb);
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 "
@@ -337,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) {
@@ -354,31 +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);
ivl_assert(*this, bit_defined_flag);
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;
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);
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: "
@@ -406,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);
@@ -418,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;
@@ -456,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()
@@ -474,167 +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;
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 packed dimensions " << member->packed_dims << "." << endl;
cerr << get_fileline() << ": : "
<< "Tail name has " << path_tail.index.size() << " indices." << endl;
}
// Rewrite a member select of a packed structure as a
// part select of the base variable.
lidx = member_off;
midx = lidx + member->width() - 1;
// The dimensions of the tail of the prefix must match
// the dimensions of the signal at this point. (The sig
// has a packed dimension for the packed struct size.)
// For example, if the path_=a[<m>][<n>].member, then
// sig must have 3 packed dimenions: one for the struct
// members and two actual packed dimensions.
ivl_assert(*this, path_prefix.back().index.size()+1 == sig->packed_dimensions());
// Elaborate an expression from the packed indices and
// the member offset (into the structure) to get a
// canonical expression into the packed signal vector.
NetExpr*packed_base = 0;
if (sig->packed_dimensions() > 1) {
list<index_component_t>tmp_index = path_prefix.back().index;
index_component_t member_select;
member_select.sel = index_component_t::SEL_BIT;
member_select.msb = new PENumber(new verinum(member_off));
tmp_index.push_back(member_select);
packed_base = collapse_array_indices(des, scope, sig, tmp_index);
if (debug_elaborate) {
cerr << get_fileline() << ": debug: "
<< "packed_base expression = " << *packed_base << endl;
}
}
long tmp;
if (packed_base && eval_as_long(tmp, packed_base)) {
lidx = tmp;
midx = lidx + member->width() - 1;
delete packed_base;
packed_base = 0;
}
// Currently, only support const dimensions here.
ivl_assert(*this, packed_base == 0);
// Now the lidx/midx values get us to the member. Next
// up, deal with bit/part selects from the member
// itself.
ivl_assert(*this, member->packed_dims.size() <= 1);
ivl_assert(*this, path_tail.index.size() <= 1);
if (! path_tail.index.empty()) {
long tmp_off;
unsigned long tmp_wid;
const index_component_t&tail_sel = path_tail.index.back();
ivl_assert(*this, tail_sel.sel == index_component_t::SEL_PART || tail_sel.sel == index_component_t::SEL_BIT);
bool rc = calculate_part(this, des, scope, tail_sel, tmp_off, tmp_wid);
ivl_assert(*this, rc);
if (debug_elaborate)
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
<< "tmp_off=" << tmp_off << ", tmp_wid=" << tmp_wid << endl;
lidx += tmp_off;
midx = lidx + tmp_wid - 1;
}
} else if (sig->unpacked_dimensions() > 0) {
// Make sure there are enough indices to address an array element.
if (path_tail.index.size() < sig->unpacked_dimensions()) {
cerr << get_fileline() << ": error: Array " << path()
<< " needs " << sig->unpacked_dimensions() << " indices,"
<< " but got only " << path_tail.index.size() << "." << endl;
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;
bool flag = indices_to_expressions(des, scope, this,
path_tail.index, sig->unpacked_dimensions(),
true,
unpacked_indices,
unpacked_indices_const);
// Note that !flag includes that there were any other
// elaboration errors generating the unpacked_indices list.
if (!flag) {
const index_component_t&index_head = name_tail.index.front();
if (index_head.sel == index_component_t::SEL_PART) {
cerr << get_fileline() << ": error: cannot perform a part "
<< "select on array " << sig->name() << "." << endl;
des->errors += 1;
return 0;
}
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
NetExpr*tmp_ex = elab_and_eval(des, scope, index_head.msb, -1);
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;
}
NetExpr*canon_index = 0;
ivl_assert(*this, unpacked_indices_const.size() == sig->unpacked_dimensions());
canon_index = normalize_variable_unpacked(sig, unpacked_indices_const);
if (canon_index == 0) {
// Normalize detected an out-of-bounds
// index. Indicate that by setting the generated
// widx to -1.
widx = -1;
} else {
NetEConst*canon_const = dynamic_cast<NetEConst*>(canon_index);
ivl_assert(*this, canon_const);
widx = canon_const->value().as_long();
delete canon_index;
}
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;
@@ -643,24 +468,13 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
midx = midx_tmp;
lidx = lidx_tmp;
}
} else if (!path_tail.index.empty()) {
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;
@@ -672,36 +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_part_lref(midx,lidx)) {
cerr << get_fileline() << ": error: Unresolved net/uwire "
<< sig->name() << " cannot have multiple drivers." << endl;
des->errors += 1;
return 0;
}
if (sig->pin_count() > 1) {
if (widx < 0 || widx >= (long) sig->pin_count()) {
cerr << get_fileline() << ": warning: ignoring out of "
"bounds l-value array access "
<< sig->name() << as_indices(unpacked_indices_const) << "." << endl;
return 0;
}
assert(widx < sig->pin_count());
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;
}
/* 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()) {
@@ -717,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);
@@ -741,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;
}
@@ -771,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_
@@ -788,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,
@@ -825,92 +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;
}
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;
}
+301 -754
View File
File diff suppressed because it is too large Load Diff
+318 -578
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"
-64
View File
@@ -1,64 +0,0 @@
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "pform_types.h"
# include "netlist.h"
# include "netvector.h"
# include <typeinfo>
# include "ivl_assert.h"
using namespace std;
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*) const
{
cerr << get_fileline() << ": internal error: "
<< "Elaborate method not implemented for " << typeid(*this).name()
<< "." << endl;
des->errors += 1;
return 0;
}
ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const
{
switch (type_code) {
case 32:
if (signed_flag)
return &netvector_t::atom2s32;
else
return &netvector_t::atom2u32;
case 16:
if (signed_flag)
return &netvector_t::atom2s16;
else
return &netvector_t::atom2u16;
case 8:
if (signed_flag)
return &netvector_t::atom2s8;
else
return &netvector_t::atom2u8;
default:
cerr << get_fileline() << ": internal error: "
<< "atom2_type_t type_code=" << type_code << "." << endl;
des->errors += 1;
return 0;
}
}
+546 -1390
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);
+25 -71
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2011 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"
@@ -31,7 +31,7 @@
# 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;
@@ -72,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
@@ -197,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;
@@ -244,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);
@@ -385,20 +377,11 @@ void NetScope::emit_scope(struct target_t*tgt) const
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
tgt->event(cur);
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
; cur != classes_.end() ; ++cur)
tgt->class_type(this, cur->second);
for (list<netenum_t*>::const_iterator cur = enum_sets_.begin()
; cur != enum_sets_.end() ; ++cur)
tgt->enumeration(this, *cur);
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);
}
@@ -408,12 +391,11 @@ 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
@@ -422,9 +404,8 @@ bool NetScope::emit_defs(struct target_t*tgt) const
switch (type_) {
case MODULE:
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;
case FUNC:
@@ -434,9 +415,8 @@ 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;
}
@@ -457,7 +437,7 @@ int Design::emit(struct target_t*tgt) const
// enumerate the scopes
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); ++ scope )
scope != root_scopes_.end(); scope++)
(*scope)->emit_scope(tgt);
@@ -472,15 +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 (list<NetScope*>::const_iterator scope = root_scopes_.begin();
scope != root_scopes_.end(); ++ scope )
scope != root_scopes_.end(); scope++)
tasks_rc &= (*scope)->emit_defs(tgt);
@@ -499,8 +474,6 @@ int Design::emit(struct target_t*tgt) const
return -2;
if (proc_rc == false)
return -3;
if (branches_rc == false)
return -4;
return rc;
}
@@ -525,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);
@@ -545,31 +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 NetENetenum::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_netenum(this);
}
void NetENew::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_new(this);
}
void NetENull::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_null(this);
}
void NetEProperty::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_property(this);
}
void NetEScope::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_scope(this);
+2 -2
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"
@@ -147,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) {
+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.
*
*/
+846 -881
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
,*
hello_vpi.vpi
show_vcd.vcd
+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
*/
/*

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