Compare commits

..
7 Commits
Author SHA1 Message Date
Stephen Williams afa2478801 Merge branch 'master' of ssh://[email protected]/home/u/icarus/steve/git/verilog 2008-06-09 16:58:21 -07:00
Stephen Williams 79feb44f10 Turn of concat output scheduling.
We really want lazy processing of concatenation because it has multiple
inputs and lazy processing should (in theory) prevent redundant and
useless propagations through the net.

But enabling it seems to cause many tests in the regression test suite
to fail to compare their results. There are races in many tests that
are interacting badly with this feature. So for now, ifdef it out.
2008-06-09 16:57:51 -07:00
Stephen Williams c03d76a0d7 Do not do lazy processing of part selects.
It doesn't really make any sense to do lazy processing of part selects,
but it is possible to use the part select position to more toroughly
check for changes in output and suppress non-changes. In particular,
we only need to check that the output part actually changes, and by the
way we only need to save those bits for the next go-round.

We do want to make sure that the very first input causes an output,
though, so that time-0 values get propagated.
2008-06-09 16:46:06 -07:00
Stephen Williams d0f303463d ASSIGN transfer data to scheduler efficiently/permalloc vvp_net_t objects.
The vvp_net_t objects are never deleted, so overload the new operator
to do a more space efficient permanent allocation.

The %assign/v instruction copied the vvp_vector4_t object needlessly
on its way to the scheduler. Eliminate that duplication.
2008-06-06 19:50:44 -07:00
Stephen Williams 35fe8fae00 Have vvp_vector8_t avoid allocating tiny scalar arrays. 2008-06-06 16:36:43 -07:00
Stephen Williams 2e95a740da Rework scheduling of concat, part, buf/not and resolv for efficiency.
The concat and resolv functors are best evaluated lazily, because each
evaluation is costly and there is a high probability that an evaluation
will be invalidated when new input comes in.

Also optimization the recv_vec4_pv method of the resolver, which is
commonly used, and adjust the order of handling of vvp_fun_part to
work more efficiently.
2008-06-06 15:31:22 -07:00
Stephen Williams 2f4e5bf5b6 Obvious optimizations of vvp_vector8_t handling.
The vvp_vector8_t constructor and destructor involve memory allocation
so it is best to pass these objects by reference as much as possible.

Also rework the resolver functor to only perform resolution after inputs
are in so that it doesn't get needlessly repeated. This eliminates many
resolve function calls, as well as activations throughout the net.

Also have the islands take more care not to perform resolution if the
inputs aren't really different.
2008-06-06 11:12:07 -07:00
458 changed files with 31143 additions and 49383 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
-83
View File
@@ -1,83 +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.
# Object files and libraries
*.[oa]
*~
# From autoconf
configure
config.log
config.status
Makefile
/_pli_types.h
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
/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
/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
-85
View File
@@ -1,85 +0,0 @@
#ifndef __AStatement_H
#define __AStatement_H
/*
* 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
* 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 <map>
# include "ivl_target.h"
# include "StringHeap.h"
# include "LineInfo.h"
# include "Statement.h"
# include "PExpr.h"
class PExpr;
class NetAnalog;
class NetScope;
class Design;
/*
* A contribution statement is like an assignment: there is an l-value
* expression and an r-value expression. The l-value is a branch probe
* expression.
*/
class AContrib : public Statement {
public:
AContrib(PExpr*lval, PExpr*rval);
~AContrib();
virtual void dump(ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private:
PExpr*lval_;
PExpr*rval_;
};
/*
* An analog process is not a statement, but contains an analog
* statement. The process is where we attach process characteristics
* such as initial vs. always, attributes....
*/
class AProcess : public LineInfo {
public:
AProcess(ivl_process_type_t t, Statement*st)
: type_(t), statement_(st) { }
~AProcess();
bool elaborate(Design*des, NetScope*scope) const;
ivl_process_type_t type() const { return type_; }
Statement*statement() { return statement_; }
map<perm_string,PExpr*> attributes;
// Dump the analog process
void dump(ostream&out, unsigned ind) const;
private:
ivl_process_type_t type_;
Statement*statement_;
private: // not implemented
AProcess(const AProcess&);
AProcess& operator= (const AProcess&);
};
#endif
+39 -2
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
@@ -16,11 +16,14 @@
* along with this program; if not, write to the Free Software
* 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.
*
*/
+32 -2
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
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* 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
+68 -62
View File
@@ -4,24 +4,23 @@ HOW TO REPORT BUGS
Before I can fix an error, I need to understand what the problem
is. Try to explain what is wrong and why you think it is wrong. Please
try to include sample code that demonstrates the problem. Include a
description of what Icarus Verilog does that is wrong, and what you
expect should happen. And include the command line flags passed to the
compiler to make the error happen. (This is often overlooked, and
sometimes important.)
description of what ivl does that is wrong, and what you expect should
happen. And include the command line flags passed to the compiler to make
the error happen. (This is often overlooked, and sometimes important.)
* The Compiler Doesn't Compile
If Icarus Verilog doesn't compile, I need to know about the
If the Icarus Verilog don't compile, I need to know about the
compilation tools you are using. Specifically, I need to know:
- Operating system and processor type,
- Compiler w/ version,
- Versions of any libraries being linked, and
- Library version, and
- anything else you think relevant.
Be aware that I do not have at my disposal a porting lab. I have the
workstation on my desk, a Mac laptop, and the Linux/Intel box with a
logic analyzer and 'scope hanging off it.
alpha on my desk, and the Linux/Intel box with a logic analyzer and
'scope hanging off it.
* The Compiler Crashes
@@ -29,26 +28,26 @@ No compiler should crash, no matter what kind of garbage is fed to
it. If the compiler crashes, you definitely found a bug and I need to
know about it.
Icarus Verilog internally checks its state while it works, and if it
detects something wrong that it cannot recover from, it will abort
Ivl internally checks its state while it works, and if it detects
something wrong that it cannot recover from, it will abort
intentionally. The "assertion failure" message that the program
prints in the process of dying is very important. It tells me where in
the source the bad thing happened. Include that message in the bug
report.
If there are no assertion messages, I need to know that as well.
If there are not assertion messages, I need to know that as well.
I also need a complete test program that demonstrates the crash.
* It Doesn't Like My Perfectly Valid Program(tm)
I need to know what you think is right that Icarus Verilog gets
wrong. Does it reject your "Perfectly Valid Program(tm)" or does it
compile it but give incorrect results? The latter is the most
insidious as it doesn't scream out to be fixed unless someone is
watching closely. However, if I get a sample program from you, and I
can compile it, and I run it and nuclear junk doesn't fall from the
sky, I'm moving on to the next problem.
I need to know what you think is right that ivl gets wrong. Does it
reject your "Perfectly Valid Program(tm)" or does it compile it but
give incorrect results? The latter is the most insidious as it doesn't
scream out to be fixed unless someone is watching closely. However, if
I get a sample program from you, and I can compile it, and I run it
and nuclear junk doesn't fall from the sky, I'm moving on to the next
problem.
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).
@@ -58,25 +57,24 @@ 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
take your sample program and work on Icarus Verilog until it gets the
proper results. For this to work, of course, I first need to know what
is wrong with the output. Spell it out, because I've been known to
miss the obvious. Compiler writers often get buried in the details of
the wrong problem.
take your sample program and work on ivl until it gets the proper
results. For this to work, of course, I first need to know what is
wrong with the output. Spell it out, because I've been known to miss
the obvious. Compiler writers often get buried in the details of the
wrong problem.
* It Generates Incorrect Target Code
* It Generates Incorrect Target Code (XNF, EDIF/LPM, etc.)
As Icarus Verilog adds target code generators, there will be cases
where errors in the output netlist format occur. This is a tough nut
because I might not have all the tools to test the target format you
are reporting problems with. However, if you clearly explain what is
right and wrong about the generated output, I will probably be able
to fix the problem. It may take a few iterations.
As ivl adds target code generators, there will be cases where errors
in the output netlist format occur. This is a tough nut because I
might not have all the tools to test the target format you are
reporting problems with. However, if you clearly explain what is right
and wrong about the generated netlist, I will probably be able to fix
the problem. It may take a few iterations.
In this case, if possible include not only the sample Verilog program,
but the generated netlist file(s) and a clear indication of what went
wrong or what is expected. If it is not clear to me, I will ask for
clarification.
wrong. If it is not clear to me, I will ask for clarification.
* The Output is Correct, But Less Than Ideal
@@ -93,13 +91,13 @@ demonstrates the problem. If the error occurs after elaboration,
please include a top level module in the program that is suitable for
the target format. If I have to write the module myself, I might not
write it in a way that tickles the bug. So please, send all the
Verilog source that I need to invoke the error.
Verilog source (after preprocessing) that I need to invoke the error.
Also, include the command line you use to invoke the compiler. For
example:
iverilog -o foo.out -tvvp foo.v
iverilog foo.vl -s starthere
ivl foo.vl -o foo.cc -tvvm
ivl foo.vl -s starthere
If the error occurs with the null target (``-tnull'') then a top level
module may not be needed as long as the ``-s <name>'' switch is
@@ -110,19 +108,15 @@ invoke the error without any Verilog other than what is included?" And
while we are at it, please place a copyright notice in your test
program and include a GPL license statement if you can. Your test
program may find its way into the test suite, and the notices will
make it all nice and legal. Please look at the existing tests in the
test suite <http://sourceforge.net/ivtest> for examples of good test
programs.
make it all nice and legal.
RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS
The URL <http://sourceforge.net/tracker/?group_id=149850> is the main
bug tracking system. Once you believe you have found a bug, you may
browse the bugs database for existing bugs that may be related to
yours. You might find that your bug has already been fixed in a later
release or snapshot. If that's the case, then you are set. Also,
consider if you are reporting a bug or really asking for a new
feature, and use the appropriate tracker.
The URL <http://www.icarus.com/cgi-bin/ivl-bugs> is the main bug
tracking system. Once you believe you have found a bug, you may browse
the bugs database for existing bugs that may be related to yours. You
might find that your bug has already been fixed in a later release or
snapshot. If that's the case, then you are set.
The bug database supports basic keyword searches, and you can
optionally limit your search to active bugs, or fixed bugs. You may
@@ -131,7 +125,8 @@ broken. You may for example find a related bug that explains your
symptom.
The root page of the bug report database describes how to submit your
completed bug report.
completed bug report. You may submit it via the web form, or via
e-mail.
HOW TO SEND PATCHES
@@ -139,26 +134,21 @@ Bug reports with patches are very welcome, especially if they are
formatted such that I can inspect them, decide that they are obviously
correct, and apply them without worry.
I prefer patches generated by the git source code tracking system. If
you are editing the source, you really should be using the latest
version from git. Please see the developer documentation for more
detailed instructions -- <http://iverilog.wikia.com/wiki/>.
I prefer context diffs as emitted by diff from GNU diffutils. Human
beings can read such things, and they are resilient to changing
originals. A good set of flags to diff are ``diff -cNB''. With such
diffs, I can look at the changes you are offering and probably tell at
a glance that they are plausible. Then I can use patch(1) to apply
them. Or I can apply them by hand.
When you make a patch, submit it to the "Patches" tracker at
<http://sourceforge.net/tracker/?group_id=149850>. Patches added to
the "Patches" tracker enter the developer workflow, are checked,
applied to the appropriate git branch, and are pushed. Then the
tracker item is closed.
If you send patches, *please* tell me what this patch is supposed to
accomplish, which branch you intended to be patched, and if
appropriate include a test program that demonstrates the efficacy of
the patch. (If I have no idea what the patch is for, I will ask for
clarification before applying it.)
However, if you send patches, *please* tell me what this patch is
supposed to accomplish, and if appropriate include a test program that
demonstrates the efficacy of the patch. (If I have no idea what the
patch is for, I will ask for clarification before applying it.)
COPYRIGHT ISSUES
Icarus Verilog is Copyright (c) 1998-2008 Stephen Williams except
Icarus Verilog is Copyright (c) 1998-2003 Stephen Williams except
where otherwise noted. Minor patches are covered as derivative works
(or editorial comment or whatever the appropriate legal term is) and
folded into the rest of ivl. However, if a submission can reasonably
@@ -168,3 +158,19 @@ then falls under the "otherwise noted" category.
I must insist that any copyright material submitted for inclusion
include the GPL license notice as shown in the rest of the source.
$Id: BUGS.txt,v 1.5 2007/03/22 16:08:14 steve Exp $
$Log: BUGS.txt,v $
Revision 1.5 2007/03/22 16:08:14 steve
Spelling fixes from Larry
Revision 1.4 2003/02/19 04:36:31 steve
Notes on hte bug database.
Revision 1.3 2003/01/30 16:23:07 steve
Spelling fixes.
Revision 1.2 1999/08/06 04:05:28 steve
Handle scope of parameters.
+38 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2010 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,6 +16,9 @@
* along with this program; if not, write to the Free Software
* 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()
@@ -113,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.
*
*/
+31 -15
View File
@@ -1,7 +1,7 @@
#ifndef __HName_H
#define __HName_H
/*
* Copyright (c) 2001-2008 Stephen Williams ([email protected])
* Copyright (c) 2001-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
@@ -18,9 +18,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.h,v 1.7 2007/06/02 03:42:12 steve Exp $"
#endif
# include <iostream>
# include <list>
# include "StringHeap.h"
#ifdef __GNUC__
#if __GNUC__ > 2
@@ -55,7 +57,7 @@ class hname_t {
private:
perm_string name_;
// If the number is anything other than INT_MIN, then this is
// If the number is anything other then INT_MIN, then this is
// the numeric part of the name. Otherwise, it is not part of
// the name at all.
int number_;
@@ -68,16 +70,30 @@ 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 ostream& operator<< (ostream&out, const list<hname_t>&ll)
{
list<hname_t>::const_iterator cur = ll.begin();
out << *cur;
cur ++;
while (cur != ll.end()) {
out << "." << *cur;
cur ++;
}
return out;
}
/*
* $Log: HName.h,v $
* Revision 1.7 2007/06/02 03:42:12 steve
* Properly evaluate scope path expressions.
*
* Revision 1.6 2007/05/16 19:12:33 steve
* Fix hname_t use of space for 1 perm_string.
*
* Revision 1.5 2007/04/26 03:06:21 steve
* Rework hname_t to use perm_strings.
*
* Revision 1.4 2002/11/02 03:27:51 steve
* Allow named events to be referenced by
* hierarchical names.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/
#endif
+2 -2
View File
@@ -1,7 +1,7 @@
#ifndef __LineInfo_H
#define __LineInfo_H
/*
* Copyright (c) 1999-2009 Stephen Williams ([email protected])
* Copyright (c) 1999 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
@@ -36,7 +36,7 @@ using namespace std;
class LineInfo {
public:
LineInfo();
virtual ~LineInfo();
~LineInfo();
// Get a fully formatted file/lineno
string get_fileline() const;
+126 -164
View File
@@ -18,53 +18,29 @@
#
SHELL = /bin/sh
# The interesting make targets are:
#
# make version
# Force the version_tag.h file to be rebuilt. Otherwise, it will only
# be built if it is missing.
#
# make all
# make install
#
# 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@
# 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 vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
tgt-vhdl 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).
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@
CC = @CC@
HOSTCC = @CC@
CXX = @CXX@
INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -76,104 +52,73 @@ MAN = @MAN@
PS2PDF = @PS2PDF@
GIT = @GIT@
CPPFLAGS = @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
CXXFLAGS = @WARNING_FLAGS@ @CXXFLAGS@
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
CXXFLAGS = -Wall @CXXFLAGS@
PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@
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) $@); done
for dir in ivlpp ; \
do (cd $$dir ; $(MAKE) $@); 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: dep dosify.exe
dosify.exe: $(srcdir)/dosify.c
$(CC) -o dosify.exe $(srcdir)/dosify.c
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 parse.output
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 -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.h 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
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
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
O = main.o async.o design_dump.o discipline.o dup_expr.o \
elaborate.o elab_expr.o elaborate_analog.o \
O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o elab_expr.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 \
elab_sig.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 \
load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.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 \
parse.o parse_misc.o pform.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 \
verinum.o verireal.o target.o targets.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 \
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
$(FF) $(TT)
Makefile: $(srcdir)/Makefile.in config.status
./config.status --file=$@
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
@@ -189,32 +134,28 @@ ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
ifeq (@MINGW32@,no)
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@;$(CXXFLAGS);' \
-e 's;@INCLUDEDIR@;$(includedir);' \
-e 's;@INCLUDEDIR@;@includedir@;' \
-e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
$(HOSTCC) @WARNING_FLAGS@ -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
@@ -232,15 +173,11 @@ lexor.cc: $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
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
@@ -248,108 +185,133 @@ iverilog-vpi.pdf: iverilog-vpi.ps
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
# version.h file in the source tree (included in snapshots and releases), and
# finally use nothing.
.PHONY: version.h
# "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"; \
tag=`$(GIT) --git-dir $(srcdir)/.git describe`; \
tmp=`printf "#ifndef VERSION_TAG\n#define VERSION_TAG \"$$tag\"\n#endif\n"`; \
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; \
tmp=`$(GIT) --git-dir $(srcdir)/.git describe \
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
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"; \
tmp=`printf "#ifndef VERSION_TAG\n#define VERSION_TAG \"\"\n#endif\n"`; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
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)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf
$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
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
$(libdir)/ivl$(suffix)/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@"
$(bindir)/iverilog-vpi: ./iverilog-vpi
$(INSTALL_SCRIPT) ./iverilog-vpi $(DESTDIR)$(bindir)/iverilog-vpi
$(libdir)/ivl$(suffix)/include/constants.vams: $(srcdir)/constants.vams
$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(DESTDIR)$(libdir)/ivl/ivl@EXEEXT@
$(libdir)/ivl$(suffix)/include/disciplines.vams: $(srcdir)/disciplines.vams
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"
$(libdir)/ivl/include/constants.vams: $(srcdir)/constants.vams
$(INSTALL_DATA) $(srcdir)/constants.vams $@
$(libdir)/ivl/include/disciplines.vams: $(srcdir)/disciplines.vams
$(INSTALL_DATA) $(srcdir)/disciplines.vams $@
$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(DESTDIR)$(libdir)/ivl/xnf-s.conf
$(libdir)/ivl/xnf.conf: $(srcdir)/xnf.conf
$(INSTALL_DATA) $(srcdir)/xnf.conf $(DESTDIR)$(libdir)/ivl/xnf.conf
$(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"
$(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 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 dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
for f in xnf.conf xnf-s.conf ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
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
-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)$(includedir)/$$f; done
rm -f $(DESTDIR)$(mandir)/man1/iverilog-vpi.1 $(DESTDIR)$(prefix)/iverilog-vpi.pdf
-include $(patsubst %.o, dep/%.d, $O)
+19 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2009 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
@@ -22,17 +22,14 @@
# include "Module.h"
# include "PGate.h"
# include "PWire.h"
# include <cassert>
# include <assert.h>
/* n is a permallocated string. */
Module::Module(perm_string n)
: PScope(n)
: PScope(n, 0)
{
library_flag = false;
is_cell = false;
uc_drive = UCD_NONE;
default_nettype = NetNet::NONE;
timescale_warn_done = false;
}
Module::~Module()
@@ -44,9 +41,19 @@ void Module::add_gate(PGate*gate)
gates_.push_back(gate);
}
void Module::add_task(perm_string name, PTask*task)
{
tasks_[name] = task;
}
void Module::add_function(perm_string name, PFunction *func)
{
funcs_[name] = func;
}
unsigned Module::port_count() const
{
return ports.size();
return ports.count();
}
/*
@@ -54,10 +61,10 @@ unsigned Module::port_count() const
* module. If the port is internally unconnected, return an empty
* array.
*/
const vector<PEIdent*>& Module::get_port(unsigned idx) const
const svector<PEIdent*>& Module::get_port(unsigned idx) const
{
assert(idx < ports.size());
static const vector<PEIdent*> zero;
assert(idx < ports.count());
static svector<PEIdent*> zero;
if (ports[idx])
return ports[idx]->expr;
@@ -68,7 +75,7 @@ const vector<PEIdent*>& Module::get_port(unsigned idx) const
unsigned Module::find_port(const char*name) const
{
assert(name != 0);
for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) {
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
if (ports[idx] == 0) {
/* It is possible to have undeclared ports. These
are ports that are skipped in the declaration,
@@ -82,7 +89,7 @@ unsigned Module::find_port(const char*name) const
return idx;
}
return ports.size();
return ports.count();
}
+45 -20
View File
@@ -1,7 +1,7 @@
#ifndef __Module_H
#define __Module_H
/*
* Copyright (c) 1998-2009 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
@@ -22,8 +22,7 @@
# include <list>
# include <map>
# include <vector>
# include <utility>
# include "svector.h"
# include "StringHeap.h"
# include "HName.h"
# include "named.h"
@@ -59,7 +58,7 @@ class Module : public PScope, public LineInfo {
public:
struct port_t {
perm_string name;
vector<PEIdent*> expr;
svector<PEIdent*> expr;
};
public:
@@ -74,13 +73,42 @@ class Module : public PScope, public LineInfo {
other effect. */
bool library_flag;
bool is_cell;
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
UCDriveType uc_drive;
NetNet::Type default_nettype;
struct range_t {
// True if this is an exclude
bool exclude_flag;
// lower bound
// If low_open_flag is false and low_expr=0, then use -inf
bool low_open_flag;
PExpr*low_expr;
// upper bound
// If high_open_flag is false and high_expr=0, then use +inf
bool high_open_flag;
PExpr*high_expr;
// Next range description in list
struct range_t*next;
};
/* The module has parameters that are evaluated when the
module is elaborated. During parsing, I put the parameters
into this map. */
struct param_expr_t : public LineInfo {
param_expr_t() : type(IVL_VT_NO_TYPE), msb(0), lsb(0), signed_flag(false), expr(0), range(0) { }
// Type information
ivl_variable_type_t type;
PExpr*msb;
PExpr*lsb;
bool signed_flag;
// Value expression
PExpr*expr;
// If there are range constrants, list them here
range_t*range;
};
map<perm_string,param_expr_t>parameters;
map<perm_string,param_expr_t>localparams;
/* specparams are simpler then other params, in that they have
no type information. They are merely constant
expressions. */
@@ -90,8 +118,7 @@ class Module : public PScope, public LineInfo {
new parameters within the module, but may be used to set
values within this module (when instantiated) or in other
instantiated modules. */
typedef pair<pform_name_t,PExpr*> named_expr_t;
list<named_expr_t>defparms;
map<pform_name_t,PExpr*>defparms;
/* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names,
@@ -103,19 +130,13 @@ class Module : public PScope, public LineInfo {
/* This is an array of port descriptors, which is in turn a
named array of PEident pointers. */
vector<port_t*> ports;
svector<port_t*> ports;
map<perm_string,PExpr*> attributes;
/* 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;
/* 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. */
@@ -131,9 +152,11 @@ class Module : public PScope, public LineInfo {
perm_string mod_name() const { return pscope_name(); }
void add_gate(PGate*gate);
void add_task(perm_string name, PTask*def);
void add_function(perm_string name, PFunction*def);
unsigned port_count() const;
const vector<PEIdent*>& get_port(unsigned idx) const;
const svector<PEIdent*>& get_port(unsigned idx) const;
unsigned find_port(const char*name) const;
PGate* get_gate(perm_string name);
@@ -144,12 +167,14 @@ class Module : public PScope, public LineInfo {
bool elaborate(Design*, NetScope*scope) const;
typedef map<perm_string,NetExpr*> replace_t;
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep);
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep) const;
bool elaborate_sig(Design*, NetScope*scope) const;
private:
list<PGate*> gates_;
map<perm_string,PTask*> tasks_;
map<perm_string,PFunction*> funcs_;
static void elaborate_parm_item_(perm_string name, const param_expr_t&cur,
Design*des, NetScope*scope);
+16 -50
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2009 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
@@ -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;
@@ -65,28 +60,12 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
delete_flag_ = df;
}
static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
{
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
bool tmp_flag = false;
expr->test_width(des, scope, 0, 0, tmp_type, tmp_flag);
NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
eval_expr(dex);
/* 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;
}
/* 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. */
@@ -95,7 +74,7 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
verireal fn = tmp->value();
int shift = scope->time_unit() - des->get_precision();
int64_t delay = fn.as_long64(shift);
long delay = fn.as_long(shift);
if (delay < 0)
delay = 0;
@@ -109,7 +88,8 @@ 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));
@@ -121,7 +101,7 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
return dex;
}
static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
static NetExpr* make_delay_nets(Design*des, NetExpr*expr)
{
if (dynamic_cast<NetESignal*> (expr))
return expr;
@@ -129,7 +109,7 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
if (dynamic_cast<NetEConst*> (expr))
return expr;
NetNet*sig = expr->synthesize(des, scope, expr);
NetNet*sig = expr->synthesize(des);
if (sig == 0) {
cerr << expr->get_fileline() << ": error: Expression " << *expr
<< " is not suitable for delay expression." << endl;
@@ -140,20 +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;
}
cerr << fall->get_fileline() << ": sorry: can not calculate the "
<< "decay time from " << *rise << " and " << *fall << endl;
return 0;
}
void PDelays::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
@@ -166,23 +132,23 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
if (delay_[0]) {
rise_time = calculate_val(des, scope, delay_[0]);
if (as_nets_flag)
rise_time = make_delay_nets(des, scope, rise_time);
rise_time = make_delay_nets(des, rise_time);
if (delay_[1]) {
fall_time = calculate_val(des, scope, delay_[1]);
if (as_nets_flag)
fall_time = make_delay_nets(des, scope, fall_time);
fall_time = make_delay_nets(des, fall_time);
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, 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);
+33
View File
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* 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>
@@ -69,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
+26
View File
@@ -16,6 +16,9 @@
* along with this program; if not, write to the Free Software
* 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.
*
*/
+37
View File
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* 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
+66 -100
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 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
@@ -21,31 +21,28 @@
# include <iostream>
# include "compiler.h"
# include "PExpr.h"
# include "Module.h"
# include "netmisc.h"
# include <typeinfo>
PExpr::PExpr()
{
expr_type_ = IVL_VT_NO_TYPE;
}
PExpr::~PExpr()
{
}
bool PExpr::has_aa_term(Design*, NetScope*) const
{
return false;
}
bool PExpr::is_the_same(const PExpr*that) const
{
return typeid(this) == typeid(that);
}
bool PExpr::is_constant(Module*) const
{
return false;
}
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
{
cerr << get_fileline() << ": error: expression not valid in assign l-value: "
@@ -70,53 +67,22 @@ PEBinary::~PEBinary()
{
}
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
bool PEBinary::is_constant(Module*mod) const
{
assert(left_ && right_);
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
return left_->is_constant(mod) && right_->is_constant(mod);
}
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
left_width_ = 0;
right_width_ = 0;
}
PEBComp::~PEBComp()
{
}
PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
assert(op == 'a' || op == 'o');
}
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)
{
}
@@ -124,7 +90,7 @@ PEBShift::~PEBShift()
{
}
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(parms)
{
}
@@ -137,7 +103,7 @@ static pform_name_t pn_from_ps(perm_string n)
return tmp;
}
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(parms)
{
}
@@ -147,33 +113,22 @@ PECallFunction::PECallFunction(perm_string n)
{
}
// NOTE: Anachronism. Try to work all use of svector out.
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
: path_(n), parms_(vector_from_svector(parms))
{
}
PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(vector_from_svector(parms))
{
}
PECallFunction::~PECallFunction()
{
}
bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
PEConcat::PEConcat(const svector<PExpr*>&p, PExpr*r)
: parms_(p), repeat_(r)
{
bool flag = false;
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
flag = parms_[idx]->has_aa_term(des, scope) || flag;
}
return flag;
}
PEConcat::PEConcat(const svector<PExpr*>&p, PExpr*r)
: parms_(p), tested_widths_(p.count()), repeat_(r)
bool PEConcat::is_constant(Module *mod) const
{
bool constant = repeat_? repeat_->is_constant(mod) : true;
for (unsigned i = 0; constant && i < parms_.count(); ++i) {
constant = constant && parms_[i]->is_constant(mod);
}
return constant;
}
PEConcat::~PEConcat()
@@ -181,18 +136,6 @@ PEConcat::~PEConcat()
delete repeat_;
}
bool PEConcat::has_aa_term(Design*des, NetScope*scope) const
{
bool flag = false;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
flag = parms_[idx]->has_aa_term(des, scope) || flag;
}
if (repeat_)
flag = repeat_->has_aa_term(des, scope) || flag;
return flag;
}
PEEvent::PEEvent(PEEvent::edge_t t, PExpr*e)
: type_(t), expr_(e)
{
@@ -207,12 +150,6 @@ PEEvent::edge_t PEEvent::type() const
return type_;
}
bool PEEvent::has_aa_term(Design*des, NetScope*scope) const
{
assert(expr_);
return expr_->has_aa_term(des, scope);
}
PExpr* PEEvent::expr() const
{
return expr_;
@@ -233,6 +170,11 @@ const verireal& PEFNumber::value() const
return *value_;
}
bool PEFNumber::is_constant(Module*) const
{
return true;
}
PEIdent::PEIdent(const pform_name_t&that)
: path_(that)
{
@@ -247,20 +189,35 @@ PEIdent::~PEIdent()
{
}
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
/*
* An identifier can be in a constant expression if (and only if) it is
* a parameter or genvar.
*
* NOTE: This test does not work if the name is hierarchical!
*/
bool PEIdent::is_constant(Module*mod) const
{
NetNet* net = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
if (mod == 0) return false;
const NetExpr*ex1, *ex2;
/* */
perm_string tmp = path_.back().name;
scope = symbol_search(0, des, scope, path_, net, par, eve, ex1, ex2);
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
cur = mod->parameters.find(tmp);
if (cur != mod->parameters.end()) return true;
}
if (scope)
return scope->is_auto();
else
return false;
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
cur = mod->localparams.find(tmp);
if (cur != mod->localparams.end()) return true;
}
{ map<perm_string,LineInfo*>::const_iterator cur;
cur = mod->genvars.find(tmp);
if (cur != mod->genvars.end()) return true;
}
return false;
}
PENumber::PENumber(verinum*vp)
@@ -288,6 +245,11 @@ bool PENumber::is_the_same(const PExpr*that) const
return *value_ == *obj->value_;
}
bool PENumber::is_constant(Module*) const
{
return true;
}
PEString::PEString(char*s)
: text_(s)
{
@@ -303,6 +265,11 @@ string PEString::value() const
return text_;
}
bool PEString::is_constant(Module*) const
{
return true;
}
PETernary::PETernary(PExpr*e, PExpr*t, PExpr*f)
: expr_(e), tru_(t), fal_(f)
{
@@ -312,12 +279,11 @@ PETernary::~PETernary()
{
}
bool PETernary::has_aa_term(Design*des, NetScope*scope) const
bool PETernary::is_constant(Module*m) const
{
assert(expr_ && tru_ && fal_);
return expr_->has_aa_term(des, scope)
|| tru_->has_aa_term(des, scope)
|| fal_->has_aa_term(des, scope);
return expr_->is_constant(m)
&& tru_->is_constant(m)
&& fal_->is_constant(m);
}
PEUnary::PEUnary(char op, PExpr*ex)
@@ -329,8 +295,8 @@ PEUnary::~PEUnary()
{
}
bool PEUnary::has_aa_term(Design*des, NetScope*scope) const
bool PEUnary::is_constant(Module*m) const
{
assert(expr_);
return expr_->has_aa_term(des, scope);
return expr_->is_constant(m);
}
+242 -193
View File
@@ -1,7 +1,7 @@
#ifndef __PExpr_H
#define __PExpr_H
/*
* 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
@@ -21,7 +21,6 @@
# include <string>
# include <vector>
# include <valarray>
# include "netlist.h"
# include "verinum.h"
# include "LineInfo.h"
@@ -37,6 +36,9 @@ class NetScope;
* The PExpr class hierarchy supports the description of
* expressions. The parser can generate expression objects from the
* source, possibly reducing things that it knows how to reduce.
*
* The elaborate_net method is used by structural elaboration to build
* up a netlist interpretation of the expression.
*/
class PExpr : public LineInfo {
@@ -47,15 +49,11 @@ class PExpr : public LineInfo {
virtual void dump(ostream&) const;
// 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 width that the expression wants to
// be. It is used by elaboration of assignments to figure out
// the width of the expression.
//
// The "min" is the width of the local context, so is the
// The "min" is the width of the local context, so it the
// minimum width that this function should return. Initially
// this is the same as the lval width.
//
@@ -68,22 +66,13 @@ class PExpr : public LineInfo {
// the subexpression should not make l-value related
// optimizations.
//
// 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
// The unsigned_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,
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_; }
bool&unsized_flag) const;
// During the elaborate_sig phase, we may need to scan
// expressions to find implicit net declarations.
@@ -109,6 +98,17 @@ class PExpr : public LineInfo {
// evaluation of parameters.
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
// This method elaborate the expression as gates, for use in a
// continuous assign or other wholly structural context.
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0 =Link::STRONG,
Link::strength_t drive1 =Link::STRONG)
const;
// This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
@@ -138,10 +138,11 @@ class PExpr : public LineInfo {
// expressions that must be structurally "identical".
virtual bool is_the_same(const PExpr*that) const;
protected:
// The derived class test_width methods should fill these in.
ivl_variable_type_t expr_type_;
unsigned expr_width_;
// Return true if this expression is a valid constant
// expression. the Module pointer is needed to find parameter
// identifiers and any other module specific interpretations
// of expressions.
virtual bool is_constant(Module*) const;
private: // not implemented
PExpr(const PExpr&);
@@ -159,29 +160,29 @@ class PEConcat : public PExpr {
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual void dump(ostream&) const;
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
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 NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
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_constant(Module*) const;
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const;
private:
svector<PExpr*>parms_;
std::valarray<unsigned>tested_widths_;
PExpr*repeat_;
};
@@ -207,8 +208,6 @@ class PEEvent : public PExpr {
virtual void dump(ostream&) const;
virtual bool has_aa_term(Design*des, NetScope*scope) const;
private:
edge_t type_;
PExpr *expr_;
@@ -230,14 +229,21 @@ class PEFNumber : public PExpr {
any rounding that is needed to get the value. */
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
/* A PEFNumber is a constant, so this returns true. */
virtual bool is_constant(Module*) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual void dump(ostream&) const;
private:
@@ -256,13 +262,9 @@ class PEIdent : public PExpr {
void append_name(perm_string);
virtual void dump(ostream&) const;
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
bool&unsized_flag) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
@@ -276,6 +278,15 @@ class PEIdent : public PExpr {
NetScope*scope,
bool is_force) const;
// Structural r-values are OK.
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
@@ -284,6 +295,7 @@ class PEIdent : public PExpr {
// only applies to Ident expressions.
NetNet* elaborate_port(Design*des, NetScope*sc) const;
virtual bool is_constant(Module*) const;
verinum* eval_const(Design*des, NetScope*sc) const;
const pform_name_t& path() const { return path_; }
@@ -292,41 +304,28 @@ class PEIdent : public PExpr {
pform_name_t path_;
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.
// 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;
// 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;
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;
private:
NetExpr*elaborate_expr_param_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb,
int expr_wid) const;
NetExpr*elaborate_expr_param(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_param_part_(Design*des,
NetScope*scope,
const NetExpr*par,
@@ -339,12 +338,6 @@ class PEIdent : public PExpr {
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_param_idx_do_(Design*des,
NetScope*scope,
const NetExpr*par,
NetScope*found,
const NetExpr*par_msb,
const NetExpr*par_lsb) const;
NetExpr*elaborate_expr_net(Design*des,
NetScope*scope,
NetNet*net,
@@ -372,6 +365,38 @@ class PEIdent : public PExpr {
NetESignal*net,
NetScope*found) const;
public:
NetNet* elaborate_net_array_(Design*des, NetScope*scope,
NetNet*sig, unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elaborate_net_net_(Design*des, NetScope*scope,
NetNet*sig, unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elaborate_net_net_idx_up_(Design*des, NetScope*scope,
NetNet*sig, unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope,
NetNet*sig,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag) const;
@@ -380,6 +405,8 @@ class PEIdent : public PExpr {
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
long&midx, long&lidx) const;
NetNet*process_select_(Design*des, NetScope*scope, NetNet*sig) const;
};
class PENumber : public PExpr {
@@ -393,9 +420,15 @@ class PENumber : public PExpr {
virtual void dump(ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
int expr_width, bool) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
@@ -406,6 +439,7 @@ class PENumber : public PExpr {
virtual verinum* eval_const(Design*des, NetScope*sc) const;
virtual bool is_the_same(const PExpr*that) const;
virtual bool is_constant(Module*) const;
private:
verinum*const value_;
@@ -429,14 +463,22 @@ class PEString : public PExpr {
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
bool&unsized_flag) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
int expr_width, bool) const;
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
verinum* eval_const(Design*, NetScope*) const;
virtual bool is_constant(Module*) const;
private:
char*text_;
};
@@ -449,22 +491,47 @@ class PEUnary : public PExpr {
virtual void dump(ostream&out) const;
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
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_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
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;
virtual bool is_constant(Module*) const;
private:
NetExpr* elaborate_expr_bits_(NetExpr*operand, int expr_wid) const;
NetNet* elab_net_uminus_const_logic_(Design*des, NetScope*scope,
NetEConst*expr,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elab_net_uminus_const_real_(Design*des, NetScope*scope,
NetECReal*expr,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
NetNet* elab_net_unary_real_(Design*des, NetScope*scope,
NetExpr*expr,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
private:
char op_;
@@ -477,17 +544,23 @@ class PEBinary : public PExpr {
explicit PEBinary(char op, PExpr*l, PExpr*r);
~PEBinary();
virtual void dump(ostream&out) const;
virtual bool is_constant(Module*) const;
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual void dump(ostream&out) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
bool&unsized_flag) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
@@ -498,21 +571,57 @@ class PEBinary : public PExpr {
PExpr*left_;
PExpr*right_;
NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp,
int use_wid, bool is_pexpr =false) const;
NetExpr*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp,
int use_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, int use_wid) const;
NetExpr*elaborate_expr_base_div_(Design*, NetExpr*lp, NetExpr*rp,
int use_wid, bool is_pexpr) 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, bool is_pexpr) const;
NetExpr*elaborate_expr_base_add_(Design*, NetExpr*lp, NetExpr*rp,
int use_wid, bool is_pexpr) const;
static void suppress_operand_sign_if_needed_(NetExpr*lp, NetExpr*rp);
private:
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_pow_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
unsigned lwidth,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay) const;
};
/*
@@ -527,82 +636,20 @@ class PEBComp : public PEBinary {
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&flag);
bool&flag) const;
NetExpr* elaborate_expr(Design*des, NetScope*scope,
int expr_width, bool sys_task_arg) const;
NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
private:
int left_width_;
int right_width_;
};
/*
* This derived class is for handling logical expressions: && and ||.
*/
class PEBLogic : public PEBinary {
public:
explicit PEBLogic(char op, PExpr*l, PExpr*r);
~PEBLogic();
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&flag);
NetExpr* elaborate_expr(Design*des, NetScope*scope,
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,
int expr_wid) const =0;
protected:
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*scope,
int expr_width, bool sys_task_arg) const;
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*scope) 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,
int 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,
int expr_wid) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval, bool&flag) const;
};
/*
@@ -615,26 +662,27 @@ class PETernary : public PExpr {
explicit PETernary(PExpr*e, PExpr*t, PExpr*f);
~PETernary();
virtual bool is_constant(Module*) const;
virtual void dump(ostream&out) const;
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
bool&unsized_flag) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetETernary*elaborate_expr(Design*des, NetScope*,
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, int use_wid) const;
private:
PExpr*expr_;
PExpr*tru_;
@@ -648,44 +696,45 @@ class PETernary : public PExpr {
*/
class PECallFunction : public PExpr {
public:
explicit PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms);
// Call of system function (name is not hierarchical)
explicit PECallFunction(perm_string n, const vector<PExpr *> &parms);
explicit PECallFunction(perm_string n);
// svector versions. Should be removed!
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
// Call of system function (name is not hierarchical)
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
explicit PECallFunction(perm_string n);
~PECallFunction();
virtual void dump(ostream &) const;
virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
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,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
bool&unsized_flag) const;
private:
pform_name_t path_;
vector<PExpr *> parms_;
svector<PExpr *> parms_;
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* cast_to_width_(NetExpr*expr, int wid, bool signed_flag) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, int expr_wid) const;
NetExpr* elaborate_access_func_(Design*des, NetScope*scope, ivl_nature_t) const;
NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
unsigned test_width_sfunc_(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type,
bool&unsized_flag);
bool&unsized_flag) const;
};
#endif
+1 -2
View File
@@ -21,10 +21,9 @@
#include "PTask.h"
PFunction::PFunction(perm_string name, PScope*parent, bool is_auto__)
PFunction::PFunction(perm_string name, PScope*parent)
: PScope(name, parent), ports_(0), statement_(0)
{
is_auto_ = is_auto__;
return_type_.type = PTF_NONE;
}
+56 -2
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
@@ -22,7 +22,7 @@
# include "PGate.h"
# include "PExpr.h"
# include "verinum.h"
# include <cassert>
# include <assert.h>
PGate::PGate(perm_string name,
svector<PExpr*>*pins,
@@ -99,6 +99,59 @@ void PGate::eval_delays(Design*des, NetScope*scope,
as_net_flag);
}
void PGate::eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const
{
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(svector<PExpr*>*pins)
: PGate(perm_string(), pins)
{
@@ -189,3 +242,4 @@ perm_string PGModule::get_type()
{
return type_;
}
+16 -14
View File
@@ -1,7 +1,7 @@
#ifndef __PGate_H
#define __PGate_H
/*
* Copyright (c) 1998-2008 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
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGate.h,v 1.32 2006/04/10 00:37:42 steve Exp $"
#endif
# include "svector.h"
# include "StringHeap.h"
@@ -62,6 +65,15 @@ class PGate : public LineInfo {
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,
@@ -71,7 +83,7 @@ class PGate : public LineInfo {
bool as_net_flag =false) const;
unsigned pin_count() const { return pins_? pins_->count() : 0; }
PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
const PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
strength_t strength0() const;
strength_t strength1() const;
@@ -158,16 +170,8 @@ class PGBuiltin : public PGate {
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private:
unsigned calculate_array_count_(Design*, NetScope*,
long&high, long&low) const;
unsigned calculate_output_count_(void) const;
NetNode* create_gate_for_output_(Design*, NetScope*,
perm_string gate_name,
unsigned instance_width) const;
Type type_;
PExpr*msb_;
PExpr*lsb_;
};
@@ -228,17 +232,15 @@ class PGModule : public PGate {
PExpr*msb_;
PExpr*lsb_;
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;
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;
bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const;
NetNet*resize_net_to_port_(Design*des, NetScope*scope,
NetNet*sig, unsigned port_wid,
NetNet::PortType dir, bool as_signed) const;
NetNet::PortType dir) const;
};
#endif
+15 -74
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006,2009 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,97 +16,38 @@
* along with this program; if not, write to the Free Software
* 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(unsigned id)
: id_number(id)
{
direct_nested_ = false;
parent = 0;
lexical_scope = 0;
}
PGenerate::~PGenerate()
{
}
PWire* PGenerate::get_wire(perm_string name) const
{
map<perm_string,PWire*>::const_iterator obj = wires.find(name);
if (obj == wires.end())
return 0;
else
return (*obj).second;
}
void PGenerate::add_gate(PGate*gate)
{
gates.push_back(gate);
}
void PGenerate::probe_for_direct_nesting_(void)
void PGenerate::add_behavior(PProcess*proc)
{
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.size() > 0) return;
if (funcs.size() > 0) return;
if (gates.size() > 0) return;
if (parameters.size() > 0) return;
if (localparams.size() > 0) return;
if (events.size() > 0) return;
if (wires.size() > 0) return;
if (genvars.size() > 0) return;
if (behaviors.size() > 0) return;
if (analog_behaviors.size() > 0) return;
if (generate_schemes.size() == 0) 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;
behaviors.push_back(proc);
}
+13 -37
View File
@@ -1,7 +1,7 @@
#ifndef __PGenerate_H
#define __PGenerate_H
/*
* Copyright (c) 2006-2009 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
@@ -18,22 +18,21 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGenerate.h,v 1.4 2007/06/02 03:42:12 steve Exp $"
#endif
# include "LineInfo.h"
# include "StringHeap.h"
# include "HName.h"
# include "PScope.h"
# include <list>
# include <map>
# include <valarray>
# include "pform_types.h"
class Design;
class NetScope;
class PExpr;
class PFunction;
class PProcess;
class PTask;
class PGate;
class PWire;
@@ -50,10 +49,10 @@ class PWire;
* The parent points to the GS_CASE that contains this item.
* the loop_test is compared with the parent->loop_test expression.
*/
class PGenerate : public LineInfo, public LexicalScope {
class PGenerate : public LineInfo {
public:
explicit PGenerate(unsigned id_number);
PGenerate(unsigned id_number);
~PGenerate();
// Generate schemes have an ID number, for when the scope is
@@ -61,12 +60,8 @@ class PGenerate : public LineInfo, public LexicalScope {
const unsigned id_number;
perm_string scope_name;
// This is used during parsing to stack lexical scopes within
// this generate scheme.
PScope*lexical_scope;
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE,
GS_CASE, GS_CASE_ITEM, GS_NBLOCK};
GS_CASE, GS_CASE_ITEM};
scheme_t scheme_type;
// generate loops have an index variable and three
@@ -75,23 +70,17 @@ 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;
map<perm_string,PWire*>wires;
PWire* get_wire(perm_string name) const;
list<PGate*> gates;
void add_gate(PGate*);
// Tasks instantiated within this scheme.
map<perm_string,PTask*> tasks;
map<perm_string,PFunction*>funcs;
list<PProcess*> behaviors;
void add_behavior(PProcess*behave);
// genvars declared within this scheme.
map<perm_string,LineInfo*> genvars;
// Generate schemes can contain further generate schemes.
list<PGenerate*> generate_schemes;
list<PGenerate*> generates;
PGenerate*parent;
// This method is called by the elaboration of a module to
@@ -110,32 +99,19 @@ class PGenerate : public LineInfo, public LexicalScope {
bool generate_scope_loop_(Design*des, NetScope*container);
bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag);
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
+3 -8
View File
@@ -19,13 +19,8 @@
# include "PScope.h"
PScope::PScope(perm_string n, PScope*parent)
: name_(n), parent_(parent)
{
}
PScope::PScope(perm_string n)
: name_(n), parent_(0)
PScope::PScope(perm_string n, PScope*p)
: name_(n), parent_(p)
{
}
@@ -33,7 +28,7 @@ PScope::~PScope()
{
}
PWire* LexicalScope::wires_find(perm_string name)
PWire* PScope::wires_find(perm_string name)
{
map<perm_string,PWire*>::const_iterator cur = wires.find(name);
if (cur == wires.end())
+14 -71
View File
@@ -19,15 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "LineInfo.h"
# include "StringHeap.h"
# include "pform_types.h"
# include "ivl_target.h"
# include <map>
class PEvent;
class PExpr;
class AProcess;
class PProcess;
class PWire;
@@ -39,74 +35,10 @@ class NetScope;
* represents lexical scope. For example, a module, a function/task, a
* named block is derived from a PScope.
*
* NOTE: This is not the same concept as the "scope" of an elaborated
* NOTE: This is note the same concept as the "scope" of an elaborated
* hierarchy. That is represented by NetScope objects after elaboration.
*/
class LexicalScope {
public:
explicit LexicalScope() { }
// A virtual destructor is so that dynamic_cast can work.
virtual ~LexicalScope() { }
struct range_t {
// True if this is an exclude
bool exclude_flag;
// lower bound
// If low_open_flag is false and low_expr=0, then use -inf
bool low_open_flag;
PExpr*low_expr;
// upper bound
// If high_open_flag is false and high_expr=0, then use +inf
bool high_open_flag;
PExpr*high_expr;
// Next range description in list
struct range_t*next;
};
/* The scope has parameters that are evaluated when the scope
is elaborated. During parsing, I put the parameters into
this map. */
struct param_expr_t : public LineInfo {
param_expr_t() : type(IVL_VT_NO_TYPE), msb(0), lsb(0), signed_flag(false), expr(0), range(0) { }
// Type information
ivl_variable_type_t type;
PExpr*msb;
PExpr*lsb;
bool signed_flag;
// Value expression
PExpr*expr;
// If there are range constraints, list them here
range_t*range;
};
map<perm_string,param_expr_t>parameters;
map<perm_string,param_expr_t>localparams;
// Named events in the scope.
map<perm_string,PEvent*>events;
// Nets and variables (wires) in the scope
map<perm_string,PWire*>wires;
PWire* wires_find(perm_string name);
// Behaviors (processes) in this scope
list<PProcess*> behaviors;
list<AProcess*> analog_behaviors;
protected:
void dump_parameters_(ostream&out, unsigned indent) const;
void dump_localparams_(ostream&out, unsigned indent) const;
void dump_events_(ostream&out, unsigned indent) const;
void dump_wires_(ostream&out, unsigned indent) const;
private:
};
class PScope : public LexicalScope {
class PScope {
public:
// When created, a scope has a name and a parent. The name is
@@ -118,13 +50,24 @@ class PScope : public LexicalScope {
// modules. Scopes for tasks and functions point to their
// containing module.
PScope(perm_string name, PScope*parent);
PScope(perm_string name);
virtual ~PScope();
perm_string pscope_name() const { return name_; }
PScope* pscope_parent() { return parent_; }
// Nets an variables (wires) in the scope
map<perm_string,PWire*>wires;
PWire* wires_find(perm_string name);
// Named events in the scope.
map<perm_string,PEvent*>events;
// Behaviors (processes) in this scope
list<PProcess*> behaviors;
protected:
void dump_wires_(ostream&out, unsigned indent) const;
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
bool elaborate_behaviors_(Design*des, NetScope*scope) const;
+3
View File
@@ -16,6 +16,9 @@
* along with this program; if not, write to the Free Software
* 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"
+3
View File
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* 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"
+29 -2
View File
@@ -21,10 +21,9 @@
# include "PTask.h"
PTask::PTask(perm_string name, PScope*parent, bool is_auto__)
PTask::PTask(perm_string name, PScope*parent)
: PScope(name, parent), ports_(0), statement_(0)
{
is_auto_ = is_auto__;
}
PTask::~PTask()
@@ -42,3 +41,31 @@ void PTask::set_statement(Statement*s)
assert(statement_ == 0);
statement_ = s;
}
/*
* $Log: PTask.cc,v $
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 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.5 2001/04/19 03:04:47 steve
* Spurious assert of empty statemnt.
*
* Revision 1.4 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.3 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/07/24 02:11:19 steve
* Elaborate task input ports.
*
* Revision 1.1 1999/07/03 02:12:51 steve
* Elaborate user defined tasks.
*
*/
+2 -8
View File
@@ -51,7 +51,7 @@ struct PTaskFuncArg {
class PTask : public PScope, public LineInfo {
public:
explicit PTask(perm_string name, PScope*parent, bool is_auto);
explicit PTask(perm_string name, PScope*parent);
~PTask();
void set_ports(svector<PWire *>*p);
@@ -69,14 +69,11 @@ class PTask : public PScope, public LineInfo {
// Elaborate the statement to finish off the task definition.
void elaborate(Design*des, NetScope*scope) const;
bool is_auto() const { return is_auto_; };
void dump(ostream&, unsigned) const;
private:
svector<PWire*>*ports_;
Statement*statement_;
bool is_auto_;
private: // Not implemented
PTask(const PTask&);
@@ -93,7 +90,7 @@ class PTask : public PScope, public LineInfo {
class PFunction : public PScope, public LineInfo {
public:
explicit PFunction(perm_string name, PScope*parent, bool is_auto);
explicit PFunction(perm_string name, PScope*parent);
~PFunction();
void set_ports(svector<PWire *>*p);
@@ -108,15 +105,12 @@ class PFunction : public PScope, public LineInfo {
/* Elaborate the behavioral statement. */
void elaborate(Design *des, NetScope*) const;
bool is_auto() const { return is_auto_; };
void dump(ostream&, unsigned) const;
private:
PTaskFuncArg return_type_;
svector<PWire *> *ports_;
Statement *statement_;
bool is_auto_;
};
#endif
+16
View File
@@ -16,6 +16,9 @@
* along with this program; if not, write to the Free Software
* 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.
*
*/
+52
View File
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* 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 "StringHeap.h"
@@ -75,4 +78,53 @@ class PUdp {
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
+7 -15
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
@@ -20,7 +20,7 @@
# include "config.h"
# include "PWire.h"
# include "PExpr.h"
# include <cassert>
# include <assert.h>
PWire::PWire(perm_string n,
NetNet::Type t,
@@ -29,8 +29,8 @@ PWire::PWire(perm_string n,
: name_(n), type_(t), port_type_(pt), data_type_(dt),
signed_(false), isint_(false),
port_msb_(0), port_lsb_(0), port_set_(false),
net_msb_(0), net_lsb_(0), net_set_(false), is_scalar_(false),
error_cnt_(0), lidx_(0), ridx_(0), discipline_(0)
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;
@@ -135,12 +135,7 @@ bool PWire::get_isint() const
return isint_;
}
bool PWire::get_scalar() const
{
return is_scalar_;
}
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
{
switch (type) {
case SR_PORT:
@@ -152,7 +147,6 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
port_msb_ = m;
port_lsb_ = l;
port_set_ = true;
is_scalar_ = is_scalar;
}
return;
@@ -165,7 +159,6 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
net_msb_ = m;
net_lsb_ = l;
net_set_ = true;
is_scalar_ = is_scalar;
}
return;
@@ -188,7 +181,6 @@ void PWire::set_range(PExpr*m, PExpr*l, PWSRType type, bool is_scalar)
net_msb_ = m;
net_lsb_ = l;
net_set_ = true;
is_scalar_ = is_scalar;
}
return;
}
@@ -206,13 +198,13 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
}
}
void PWire::set_discipline(ivl_discipline_t d)
void PWire::set_discipline(discipline_t*d)
{
assert(discipline_ == 0);
discipline_ = d;
}
ivl_discipline_t PWire::get_discipline(void) const
discipline_t* PWire::get_discipline(void) const
{
return discipline_;
}
+9 -7
View File
@@ -1,7 +1,7 @@
#ifndef __PWire_H
#define __PWire_H
/*
* Copyright (c) 1998-2009 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
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PWire.h,v 1.21 2007/05/24 04:07:11 steve Exp $"
#endif
# include "netlist.h"
# include "LineInfo.h"
@@ -33,6 +36,7 @@ class ostream;
class PExpr;
class Design;
class discipline_t;
/*
* The different type of PWire::set_range() calls.
@@ -70,17 +74,16 @@ 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(PExpr*msb, PExpr*lsb, PWSRType type, bool is_scalar);
void set_range(PExpr*msb, PExpr*lsb, PWSRType type);
void set_memory_idx(PExpr*ldx, PExpr*rdx);
void set_discipline(ivl_discipline_t);
ivl_discipline_t get_discipline(void) const;
void set_discipline(discipline_t*);
discipline_t* get_discipline(void) const;
map<perm_string,PExpr*> attributes;
@@ -105,7 +108,6 @@ class PWire : public LineInfo {
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
@@ -113,7 +115,7 @@ class PWire : public LineInfo {
PExpr*lidx_;
PExpr*ridx_;
ivl_discipline_t discipline_;
discipline_t*discipline_;
private: // not implemented
PWire(const PWire&);
+31 -14
View File
@@ -12,7 +12,10 @@ home page at <http://www.icarus.com/eda/verilog>.
Icarus Verilog is not aimed at being a simulator in the traditional
sense, but a compiler that generates code employed by back-end
tools.
tools. These back-end tools currently include a simulator engine
called VVP, an XNF (Xilinx Netlist Format) generator and an EDIF FPGA
netlist generator. In the future, backends are expected for EDIF/LPM,
structural Verilog, VHDL, etc.
For instructions on how to run Icarus Verilog,
see the ``iverilog'' man page.
@@ -85,6 +88,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 +102,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 +174,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
+56 -37
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-1999 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,6 +16,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: Statement.cc,v 1.30 2007/05/24 04:07:11 steve Exp $"
#endif
# include "config.h"
@@ -26,20 +29,20 @@ Statement::~Statement()
{
}
PAssign_::PAssign_(PExpr*lval__, PExpr*ex, bool is_constant)
: event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(is_constant)
PAssign_::PAssign_(PExpr*lval, PExpr*ex)
: event_(0), lval_(lval), rval_(ex)
{
delay_ = 0;
}
PAssign_::PAssign_(PExpr*lval__, PExpr*de, PExpr*ex)
: event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(false)
PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex)
: event_(0), lval_(lval), rval_(ex)
{
delay_ = de;
}
PAssign_::PAssign_(PExpr*lval__, PExpr*cnt, PEventStatement*ev, PExpr*ex)
: event_(ev), count_(cnt), lval_(lval__), rval_(ex), is_constant_(false)
PAssign_::PAssign_(PExpr*lval, PEventStatement*ev, PExpr*ex)
: event_(ev), lval_(lval), rval_(ex)
{
delay_ = 0;
}
@@ -50,23 +53,18 @@ PAssign_::~PAssign_()
delete rval_;
}
PAssign::PAssign(PExpr*lval__, PExpr*ex)
: PAssign_(lval__, ex, false)
PAssign::PAssign(PExpr*lval, PExpr*ex)
: PAssign_(lval, ex)
{
}
PAssign::PAssign(PExpr*lval__, PExpr*d, PExpr*ex)
: PAssign_(lval__, d, ex)
PAssign::PAssign(PExpr*lval, PExpr*d, PExpr*ex)
: PAssign_(lval, d, ex)
{
}
PAssign::PAssign(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
: PAssign_(lval__, cnt, d, ex)
{
}
PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant)
: PAssign_(lval__, ex, is_constant)
PAssign::PAssign(PExpr*lval, PEventStatement*d, PExpr*ex)
: PAssign_(lval, d, ex)
{
}
@@ -74,18 +72,13 @@ PAssign::~PAssign()
{
}
PAssignNB::PAssignNB(PExpr*lval__, PExpr*ex)
: PAssign_(lval__, ex, false)
PAssignNB::PAssignNB(PExpr*lval, PExpr*ex)
: PAssign_(lval, ex)
{
}
PAssignNB::PAssignNB(PExpr*lval__, PExpr*d, PExpr*ex)
: PAssign_(lval__, d, ex)
{
}
PAssignNB::PAssignNB(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
: PAssign_(lval__, cnt, d, ex)
PAssignNB::PAssignNB(PExpr*lval, PExpr*d, PExpr*ex)
: PAssign_(lval, d, ex)
{
}
@@ -99,7 +92,7 @@ PBlock::PBlock(perm_string n, PScope*parent, BL_TYPE t)
}
PBlock::PBlock(BL_TYPE t)
: PScope(perm_string()), bl_type_(t)
: PScope(perm_string(),0), bl_type_(t)
{
}
@@ -228,15 +221,6 @@ void PEventStatement::set_statement(Statement*st)
statement_ = st;
}
bool PEventStatement::has_aa_term(Design*des, NetScope*scope)
{
bool flag = false;
for (unsigned idx = 0 ; idx < expr_.count() ; idx += 1) {
flag = expr_[idx]->has_aa_term(des, scope) || flag;
}
return flag;
}
PForce::PForce(PExpr*l, PExpr*r)
: lval_(l), expr_(r)
{
@@ -314,3 +298,38 @@ PWhile::~PWhile()
delete cond_;
delete statement_;
}
/*
* $Log: Statement.cc,v $
* Revision 1.30 2007/05/24 04:07:11 steve
* Rework the heirarchical identifier parse syntax and pform
* to handle more general combinations of heirarch and bit selects.
*
* Revision 1.29 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.28 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.27 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
* at run time.
*
* Revision 1.26 2002/04/21 04:59:07 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.
* Get case and assignment statements working.
*
* Revision 1.25 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.24 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.23 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)
*/
+9 -23
View File
@@ -20,7 +20,6 @@
*/
# include <string>
# include "ivl_target.h"
# include "svector.h"
# include "StringHeap.h"
# include "PDelays.h"
@@ -47,14 +46,16 @@ class NetScope;
class PProcess : public LineInfo {
public:
PProcess(ivl_process_type_t t, Statement*st)
enum Type { PR_INITIAL, PR_ALWAYS };
PProcess(Type t, Statement*st)
: type_(t), statement_(st) { }
virtual ~PProcess();
bool elaborate(Design*des, NetScope*scope) const;
ivl_process_type_t type() const { return type_; }
Type type() const { return type_; }
Statement*statement() { return statement_; }
map<perm_string,PExpr*> attributes;
@@ -62,7 +63,7 @@ class PProcess : public LineInfo {
virtual void dump(ostream&out, unsigned ind) const;
private:
ivl_process_type_t type_;
Type type_;
Statement*statement_;
};
@@ -81,8 +82,6 @@ class Statement : public LineInfo {
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
map<perm_string,PExpr*> attributes;
};
/*
@@ -92,27 +91,23 @@ class Statement : public LineInfo {
*/
class PAssign_ : public Statement {
public:
explicit PAssign_(PExpr*lval, PExpr*ex, bool is_constant);
explicit PAssign_(PExpr*lval, PExpr*ex);
explicit PAssign_(PExpr*lval, PExpr*de, PExpr*ex);
explicit PAssign_(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex);
explicit PAssign_(PExpr*lval, PEventStatement*de, PExpr*ex);
virtual ~PAssign_() =0;
const PExpr* lval() const { return lval_; }
PExpr* rval() const { return rval_; }
const PExpr* rval() const { return rval_; }
protected:
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
NetExpr* elaborate_rval_(Design*, NetScope*, unsigned lv_width,
ivl_variable_type_t type) const;
PExpr* delay_;
PEventStatement*event_;
PExpr* count_;
private:
PExpr* lval_;
PExpr* rval_;
bool is_constant_;
};
class PAssign : public PAssign_ {
@@ -120,8 +115,7 @@ class PAssign : public PAssign_ {
public:
explicit PAssign(PExpr*lval, 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);
explicit PAssign(PExpr*lval, PEventStatement*de, PExpr*ex);
~PAssign();
virtual void dump(ostream&out, unsigned ind) const;
@@ -135,7 +129,6 @@ class PAssignNB : public PAssign_ {
public:
explicit PAssignNB(PExpr*lval, PExpr*ex);
explicit PAssignNB(PExpr*lval, PExpr*de, PExpr*ex);
explicit PAssignNB(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex);
~PAssignNB();
virtual void dump(ostream&out, unsigned ind) const;
@@ -340,15 +333,10 @@ class PEventStatement : public Statement {
void set_statement(Statement*st);
virtual void dump(ostream&out, unsigned ind) const;
// Call this with a NULL statement only. It is used to print
// the event expression for inter-assignment event controls.
virtual void dump_inline(ostream&out) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
bool has_aa_term(Design*des, NetScope*scope);
// This method is used to elaborate, but attach a previously
// elaborated statement to the event.
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
@@ -360,8 +348,6 @@ class PEventStatement : public Statement {
Statement*statement_;
};
ostream& operator << (ostream&o, const PEventStatement&obj);
class PForce : public Statement {
public:
+35 -30
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2010 Stephen Williams ([email protected])
* Copyright (c) 2002-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,16 +16,17 @@
* along with this program; if not, write to the Free Software
* 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 <cstdlib>
# include <cstring>
# include <cassert>
#ifdef CHECK_WITH_VALGRIND
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()
{
@@ -48,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);
@@ -88,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_;
@@ -199,3 +178,29 @@ bool operator < (perm_string a, perm_string b)
return false;
}
/*
* $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.
*
*/
+29 -3
View File
@@ -1,7 +1,7 @@
#ifndef __StringHeap_H
#define __StringHeap_H
/*
* Copyright (c) 2002-2009 Stephen Williams ([email protected])
* Copyright (c) 2002-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
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* 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>
@@ -38,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); }
@@ -104,7 +107,6 @@ class StringHeapLex : private StringHeap {
unsigned add_count() const;
unsigned add_hit_count() const;
void cleanup();
private:
enum { HASH_SIZE = 4096 };
@@ -118,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
+41
View File
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* 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
+81
View File
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* 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
@@ -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
+33 -71
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.9'
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)
# ------------------------------
@@ -66,22 +72,17 @@ fi
# Combined check for several flavors of Microsoft Windows so
# 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,17 +205,3 @@ case "${host}" in
;;
esac
])# AX_CPP_PRECOMP
# 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
+32 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2010 Stephen Williams ([email protected])
* Copyright (c) 2002 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,12 +16,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: async.cc,v 1.7 2004/01/18 23:26:54 steve Exp $"
#endif
# include "config.h"
# include "functor.h"
# include "netlist.h"
# include <cassert>
# include <assert.h>
bool NetAssign::is_asynchronous()
{
@@ -84,8 +87,34 @@ bool NetProc::is_asynchronous()
bool NetProcTop::is_asynchronous()
{
if (type_ == IVL_PR_INITIAL)
if (type_ == NetProcTop::KINITIAL)
return false;
return statement_->is_asynchronous();
}
/*
* $Log: async.cc,v $
* Revision 1.7 2004/01/18 23:26:54 steve
* The is_combinational function really need not recurse.
*
* Revision 1.6 2003/12/20 00:33:39 steve
* More thorough check that NetEvWait is asynchronous.
*
* Revision 1.5 2003/09/04 20:28:05 steve
* Support time0 resolution of combinational threads.
*
* Revision 1.4 2002/08/18 22:07:16 steve
* Detect temporaries in sequential block synthesis.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2002/07/04 00:24:16 steve
* initial statements are not asynchronous.
*
* Revision 1.1 2002/06/30 02:21:31 steve
* Add structure for asynchronous logic synthesis.
*
*/
+6
View File
@@ -9,5 +9,11 @@
echo "Autoconf in root..."
autoconf -f
for dir in vpip vpi vvp tgt-vvp tgt-fpga tgt-stub 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,\$ -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
+12 -15
View File
@@ -18,7 +18,7 @@
#
SHELL = /bin/sh
suffix = @install_suffix@
VERSION = 0.9.devel
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -30,15 +30,15 @@ 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@
CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
SHARED = @shared@
@@ -54,14 +54,11 @@ dep:
mkdir dep
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $<
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $<
mv $*.d dep
O = cadpli.o
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=cadpli/$@
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
ifeq (@MINGW32@,yes)
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
@@ -71,21 +68,21 @@ cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
$(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
clean:
rm -rf *.o dep cadpli.vpl
rm -rf *.o dep cadpli.vpl bin32
distclean: clean
rm -f Makefile config.log
rm -f Makefile config.status config.log config.cache
install: all installdirs $(vpidir)/cadpli.vpl
install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32)
$(vpidir)/cadpli.vpl: ./cadpli.vpl
$(INSTALL_PROGRAM) ./cadpli.vpl "$(DESTDIR)$(vpidir)/cadpli.vpl"
$(INSTALL_PROGRAM) ./cadpli.vpl $(vpidir)/cadpli.vpl
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(vpidir)"
installdirs: ../mkinstalldirs
$(srcdir)/../mkinstalldirs $(vpidir)
uninstall: $(UNINSTALL32)
rm -f "$(DESTDIR)$(vpidir)/cadpli.vpl"
rm -f $(vpidir)/cadpli.vpl
uninstall32:
+38 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2010 Stephen Williams ([email protected])
* Copyright (c) 2003 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,13 +16,18 @@
* along with this program; if not, write to the Free Software
* 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"
typedef void* (*funcvp)(void);
@@ -82,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)
+30 -11
View File
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* 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>
@@ -32,16 +35,16 @@ typedef shl_t ivl_dll_t;
#endif
#if defined(__MINGW32__)
static __inline__ ivl_dll_t ivl_dlopen(const char *name)
static inline ivl_dll_t ivl_dlopen(const char *name)
{ return (void *)LoadLibrary(name); }
static __inline__ void *ivl_dlsym(ivl_dll_t dll, const char *nm)
static inline void *ivl_dlsym(ivl_dll_t dll, const char *nm)
{ return (void *)GetProcAddress((HINSTANCE)dll,nm);}
static __inline__ void ivl_dlclose(ivl_dll_t dll)
static inline void ivl_dlclose(ivl_dll_t dll)
{ (void)FreeLibrary((HINSTANCE)dll);}
static __inline__ const char *dlerror(void)
static inline const char *dlerror(void)
{
static char msg[256];
unsigned long err = GetLastError();
@@ -58,10 +61,10 @@ static __inline__ const char *dlerror(void)
}
#elif defined(HAVE_DLFCN_H)
static __inline__ ivl_dll_t ivl_dlopen(const char*name)
static inline ivl_dll_t ivl_dlopen(const char*name)
{ return dlopen(name,RTLD_LAZY); }
static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm)
static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{
void*sym = dlsym(dll, nm);
/* Not found? try without the leading _ */
@@ -70,25 +73,41 @@ static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm)
return sym;
}
static __inline__ void ivl_dlclose(ivl_dll_t dll)
static inline void ivl_dlclose(ivl_dll_t dll)
{ dlclose(dll); }
#elif defined(HAVE_DL_H)
static __inline__ ivl_dll_t ivl_dlopen(const char*name)
static inline ivl_dll_t ivl_dlopen(const char*name)
{ return shl_load(name, BIND_IMMEDIATE, 0); }
static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm)
static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
{
void*sym;
int rc = shl_findsym(&dll, nm, TYPE_PROCEDURE, &sym);
return (rc == 0) ? sym : 0;
}
static __inline__ void ivl_dlclose(ivl_dll_t dll)
static inline void ivl_dlclose(ivl_dll_t dll)
{ shl_unload(dll); }
static __inline__ const char*dlerror(void)
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
+4 -33
View File
@@ -1,7 +1,7 @@
#ifndef __compiler_H
#define __compiler_H
/*
* Copyright (c) 1999-2009 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
@@ -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
@@ -82,33 +76,18 @@ extern bool warn_timescale;
/* Warn about legal but questionable module port bindings. */
extern bool warn_portbinding;
/* Warn about constant out of bound selects. */
extern bool warn_ob_select;
/* Warn about structures that may have infinite loops. */
extern bool warn_inf_loop;
/* Warn about always @* statements where a part or word select causes
sensitivity to an entire vector or array. */
extern bool warn_sens_entire_vec;
extern bool warn_sens_entire_arr;
/* This is true if verbose output is requested. */
extern bool verbose_flag;
extern bool debug_scopes;
extern bool debug_eval_tree;
extern bool debug_elaborate;
extern bool debug_elab_pexpr;
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;
/* Path to a directory useful for finding subcomponents. */
extern const char*basedir;
@@ -121,10 +100,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_DEFAULT = 4
GN_VER2001 = 2,
GN_VER2005 = 3,
GN_DEFAULT = 3
};
extern generation_t generation_flag;
@@ -146,11 +124,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;
/* 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
@@ -160,7 +133,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_ICARUS = 0x8000
};
extern int lexor_keyword_mask;
@@ -210,6 +182,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();
#endif
+384 -581
View File
File diff suppressed because it is too large Load Diff
+44 -10
View File
@@ -1,7 +1,7 @@
#ifndef __config_H /* -*- c++ -*- */
#define __config_H
/*
* Copyright (c) 2001-2010 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
@@ -18,6 +18,9 @@
* along with this program; if not, write to the Free Software
* 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,6 +39,7 @@
# 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
@@ -49,14 +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
/*
* 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 */
#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)
+6 -165
View File
@@ -2,24 +2,11 @@ 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(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_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(STRIP, strip, true)
AC_CHECK_PROGS(XGPERF,gperf,none)
AC_CHECK_PROGS(MAN,man,none)
@@ -58,56 +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, [""])
else
AC_SUBST(DEPENDENCY_FLAG, [-MD])
AC_SUBST(WARNING_FLAGS, ["-Wall -Wshadow"])
fi
AC_LANG_CPLUSPLUS
AC_LANG(C++)
AC_CHECK_HEADERS(getopt.h malloc.h inttypes.h libiberty.h iosfwd sys/wait.h)
# 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
AC_CHECK_HEADERS(getopt.h inttypes.h libiberty.h iosfwd sys/wait.h)
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(z, gzwrite)
AC_CHECK_LIB(z, gzwrite, HAVE_LIBZ=yes, HAVE_LIBZ=no)
AC_SUBST(HAVE_LIBZ)
@@ -120,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>
@@ -163,13 +87,11 @@ AC_SUBST(DLLIB)
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.
@@ -179,65 +101,6 @@ AX_C_PICFLAG
# may modify CPPFLAGS and CFLAGS
AX_CPP_PRECOMP
# 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
@@ -256,31 +119,9 @@ AX_C_UNDERSCORES_TRAILING
## end of test for underscores
#######################
#######################
# Sanity check the configured results
#######################
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)
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)
AX_CPP_IDENT
# XXX disable tgt-fpga for the moment
AC_CONFIG_SUBDIRS(vvp vpi tgt-stub tgt-null tgt-vvp libveriuser cadpli)
AC_OUTPUT(Makefile ivlpp/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)
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
+1 -1
View File
@@ -3,7 +3,7 @@
`ifdef CONSTANTS_VAMS
`else
`define CONSTANTS_VAMS 1
// M_ is a mathematical constant
`define M_E 2.7182818284590452354
`define M_LOG2E 1.4426950408889634074
+34 -28
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
* Copyright (c) 1998-2005 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
@@ -739,8 +739,7 @@ v }
}
}
#if 0
static void replace_with_mos(Design*des, NetMux*obj, NetLogic::TYPE type)
static void replace_with_bufif(Design*des, NetMux*obj, NetLogic::TYPE type)
{
NetScope*scope = obj->scope();
NetLogic*tmp = new NetLogic(obj->scope(),
@@ -750,7 +749,7 @@ static void replace_with_mos(Design*des, NetMux*obj, NetLogic::TYPE type)
des->add_node(tmp);
connect(obj->pin_Result(), tmp->pin(0));
connect(obj->pin_Data(type==NetLogic::PMOS? 0 : 1), tmp->pin(1));
connect(obj->pin_Data(type==NetLogic::BUFIF0? 0 : 1), tmp->pin(1));
if (obj->width() == 1) {
/* Special case that the expression is 1 bit
@@ -781,11 +780,10 @@ static void replace_with_mos(Design*des, NetMux*obj, NetLogic::TYPE type)
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
* Vz. In this case, replace the device with a bufif with the sel
* input used to enable the output.
*/
void cprop_functor::lpm_mux(Design*des, NetMux*obj)
@@ -795,38 +793,45 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
if (obj->sel_width() != 1)
return;
#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
NetMux with an array of BUFIF1 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);
bool flag = true;
if (! obj->pin_Data(0).nexus()->drivers_constant()) {
flag = false;
}
if (flag && obj->pin_Data(0).nexus()->driven_value() != verinum::Vz) {
flag = false;
}
if (flag) {
replace_with_bufif(des, obj, NetLogic::BUFIF1);
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);
NetMux with an array of BUFIF0 devices. */
flag = true;
if (! obj->pin_Data(1).nexus()->drivers_constant()) {
flag = false;
}
if (flag && obj->pin_Data(1).nexus()->driven_value() != verinum::Vz) {
flag = false;
}
if (flag) {
replace_with_bufif(des, obj, NetLogic::BUFIF0);
count += 1;
return;
}
#endif
/* If the select input is constant, then replace with a BUFZ */
bool flag = obj->pin_Sel().nexus()->drivers_constant();
/* Note that this cannot be constant if there are assignments
to this nexus. (Assignments include "force" to nets.) */
flag &= !obj->pin_Sel().nexus()->assign_lval();
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());
@@ -892,7 +897,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
for (Link*clnk = nex->first_nlink()
; clnk ; clnk = clnk->next_nlink()) {
NetPins*cur;
NetObj*cur;
unsigned pin;
clnk->cur_link(cur, pin);
@@ -918,7 +923,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
for (Link*clnk = nex->first_nlink()
; clnk ; clnk = clnk->next_nlink()) {
NetPins*cur;
NetObj*cur;
unsigned pin;
clnk->cur_link(cur, pin);
@@ -969,3 +974,4 @@ void cprop(Design*des)
cprop_dc_functor dc;
des->functor(&dc);
}
+47 -181
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
@@ -27,7 +27,6 @@
# include <iomanip>
# include "netlist.h"
# include "compiler.h"
# include "discipline.h"
# include "ivl_assert.h"
static ostream& operator<< (ostream&o, NetBlock::Type t)
@@ -119,8 +118,7 @@ ostream& operator << (ostream&o, ivl_switch_type_t val)
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 << ".";
}
@@ -137,17 +135,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";
@@ -200,30 +187,19 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << " inout";
break;
}
if (ivl_discipline_t dis = get_discipline())
o << " discipline=" << dis->name();
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 << " init=";
<< " 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)
if (const Nexus*tmp = pin(idx-1).nexus())
o << tmp->get_init();
else
o << ".";
o << pin(idx-1).nexus()->get_init();
o << ")" << endl;
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
@@ -260,14 +236,11 @@ void NetNode::dump_node(ostream&o, unsigned ind) const
/* This is the generic dumping of all the signals connected to each
pin of the object. The "this" object is not printed, only the
signals connected to this. */
void NetPins::dump_node_pins(ostream&o, unsigned ind, const char**pin_names) const
void NetObj::dump_node_pins(ostream&o, unsigned ind) const
{
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
o << setw(ind) << "" << idx;
if (pin_names && pin_names[idx])
o << " " << pin_names[idx];
else
o << " pin" << idx;
o << setw(ind) << "" << idx << " " << pin(idx).get_name()
<< "<" << pin(idx).get_inst() << ">";
switch (pin(idx).get_dir()) {
case Link::PASSIVE:
@@ -316,14 +289,7 @@ void NetAddSub::dump_node(ostream&o, unsigned ind) const
o << setw(ind) << "" << "Adder (NetAddSub): " << name()
<< " width=" << width() << " pin_count=" << pin_count()
<< endl;
static const char* pin_names[] = {
"Cout ",
"DataA ",
"DataB ",
"Result"
};
dump_node_pins(o, ind+4, pin_names);
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -336,22 +302,6 @@ void NetArrayDq::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetCastInt::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Cast to int. (NetCastInt): " <<
name() << " width=" << width() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetCastReal::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Cast to real (NetCastReal): " <<
name() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetCLShift::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Combinatorial shift (NetCLShift): " <<
@@ -362,9 +312,7 @@ void NetCLShift::dump_node(ostream&o, unsigned ind) const
void NetCompare::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_COMPARE (NetCompare "
<< (get_signed()? "signed" : "unsigned") << "): "
<< name() << endl;
o << setw(ind) << "" << "LPM_COMPARE (NetCompare): " << name() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -598,14 +546,8 @@ void NetReplicate::dump_node(ostream&o, unsigned ind) const
void NetSignExtend::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "NetSignExtend: " << name();
if (rise_time())
o << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
else
o << " #(.,.,.)";
o << " output width=" << width_ << endl;
o << setw(ind) << "" << "NetSignExtend: "
<< name() << " output width=" << width_ << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -697,7 +639,7 @@ 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()
@@ -721,11 +663,11 @@ void NetUDP::dump_node(ostream&o, unsigned ind) const
void NetProcTop::dump(ostream&o, unsigned ind) const
{
switch (type_) {
case IVL_PR_INITIAL:
case NetProcTop::KINITIAL:
o << "initial /* " << get_fileline() << " in "
<< scope_path(scope_) << " */" << endl;
break;
case IVL_PR_ALWAYS:
case NetProcTop::KALWAYS:
o << "always /* " << get_fileline() << " in "
<< scope_path(scope_) << " */" << endl;
break;
@@ -739,28 +681,6 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
statement_->dump(o, ind+2);
}
void NetAnalogTop::dump(ostream&o, unsigned ind) const
{
switch (type_) {
case IVL_PR_INITIAL:
o << "analog initial /* " << get_fileline() << " in "
<< scope_path(scope_) << " */" << endl;
break;
case IVL_PR_ALWAYS:
o << "analog /* " << get_fileline() << " in "
<< scope_path(scope_) << " */" << endl;
break;
}
statement_->dump(o, ind+2);
}
void NetAlloc::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "// allocate storage : " << scope_path(scope_) << endl;
}
void NetAssign_::dump_lval(ostream&o) const
{
if (sig_) {
@@ -812,11 +732,6 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
if (const NetExpr*de = get_delay())
o << "#(" << *de << ") ";
if (count_)
o << "repeat(" << *count_ << ") ";
if (event_) {
o << *event_;
}
o << *rval() << ";" << endl;
@@ -904,15 +819,6 @@ void NetCondit::dump(ostream&o, unsigned ind) const
}
}
void NetContribution::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "";
lval_->dump(o);
o << " <+ ";
rval_->dump(o);
o << ";" << endl;
}
void NetDeassign::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "deassign ";
@@ -941,7 +847,7 @@ void NetEvProbe::dump_node(ostream&o, unsigned ind) const
o << "negedge ";
break;
}
o << setw(ind) << "" << "-> " << scope_path(event_->scope()) << "." << event_->name() << "; " << endl;
o << setw(ind) << "" << "-> " << event_->name() << "; " << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
@@ -957,10 +863,10 @@ void NetEvWait::dump(ostream&o, unsigned ind) const
o << setw(ind) <<"" << "@(";
if (nevents() > 0)
o << scope_path(event(0)->scope()) << "." << event(0)->name();
o << event(0)->name();
for (unsigned idx = 1 ; idx < nevents() ; idx += 1)
o << " or " << scope_path(event(idx)->scope()) << "." << event(idx)->name();
o << " or " << event(idx)->name();
o << ") // " << get_fileline() << endl;
@@ -970,25 +876,6 @@ void NetEvWait::dump(ostream&o, unsigned ind) const
o << setw(ind+2) << "" << "/* noop */ ;" << endl;
}
ostream& operator << (ostream&out, const NetEvWait&obj)
{
obj.dump_inline(out);
return out;
}
void NetEvWait::dump_inline(ostream&o) const
{
o << "@(";
if (nevents() > 0)
o << scope_path(event(0)->scope()) << "." << event(0)->name();
for (unsigned idx = 1 ; idx < nevents() ; idx += 1)
o << " or " << scope_path(event(idx)->scope())<<"."<<event(idx)->name();
o << ") ";
}
void NetForce::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "force ";
@@ -1002,11 +889,6 @@ void NetForever::dump(ostream&o, unsigned ind) const
statement_->dump(o, ind+2);
}
void NetFree::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "// free storage : " << scope_path(scope_) << endl;
}
void NetFuncDef::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "function definition for " << scope_path(scope_) << endl;
@@ -1078,11 +960,28 @@ 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);
if (is_auto()) o << " (automatic)";
if (is_cell()) o << " (cell)";
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;
}
o << endl;
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
@@ -1099,8 +998,6 @@ void NetScope::dump(ostream&o) const
; pp != parameters.end() ; pp ++) {
o << " parameter ";
o << pp->second.type << " ";
if ((*pp).second.signed_flag)
o << "signed ";
@@ -1108,11 +1005,7 @@ void NetScope::dump(ostream&o) const
o << "[" << *(*pp).second.msb
<< ":" << *(*pp).second.lsb << "] ";
o << (*pp).first << " = ";
if (pp->second.expr)
o << *(*pp).second.expr;
else
o << "<nil>";
o << (*pp).first << " = " << *(*pp).second.expr;
for (range_t*ran = (*pp).second.range ; ran ; ran = ran->next) {
if (ran->exclude_flag)
@@ -1154,7 +1047,7 @@ void NetScope::dump(ostream&o) const
/* Dump the saved defparam assignments here. */
{
list<pair<pform_name_t,NetExpr*> >::const_iterator pp;
map<pform_name_t,NetExpr*>::const_iterator pp;
for (pp = defparams.begin()
; pp != defparams.end() ; pp ++ ) {
o << " defparam " << (*pp).first << " = " <<
@@ -1162,15 +1055,6 @@ void NetScope::dump(ostream&o) const
}
}
{
list<pair<list<hname_t>,NetExpr*> >::const_iterator pp;
for (pp = defparams_later.begin()
; pp != defparams_later.end() ; pp ++ ) {
o << " defparam(later) " << pp->first << " = " <<
*(pp->second) << ";" << endl;
}
}
/* Dump the events in this scope. */
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
o << " event " << cur->name() << "; nprobe="
@@ -1179,9 +1063,12 @@ void NetScope::dump(ostream&o) const
}
// Dump the signals,
for (signals_map_iter_t cur = signals_map_.begin()
; cur != signals_map_.end() ; cur ++) {
cur->second->dump_net(o, 4);
if (signals_) {
NetNet*cur = signals_->sig_next_;
do {
cur->dump_net(o, 4);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
}
// Dump specparams
@@ -1270,18 +1157,6 @@ void NetExpr::dump(ostream&o) const
o << "(?" << typeid(*this).name() << "?)";
}
void NetEAccess::dump(ostream&o) const
{
o << nature_->name() << "." << nature_->access() << "(";
assert(branch_);
if (branch_->pin(0).is_linked())
o << branch_->pin(0).nexus()->name();
o << ", ";
if (branch_->pin(1).is_linked())
o << branch_->pin(1).nexus()->name();
o << ")";
}
void NetEBinary::dump(ostream&o) const
{
if (op_ == 'm' || op_ == 'M') {
@@ -1516,19 +1391,10 @@ 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.
for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
idx->dump(o, 0);
for (const NetAnalogTop*idx = aprocs_ ; idx ; idx = idx->next_)
idx->dump(o, 0);
}
-149
View File
@@ -1,149 +0,0 @@
Developer Quick Start for Icarus Verilog
The documentation for getting, building and installing Icarus Verilog
is kept and maintained at the iverilog documentation wiki at
<http://iverilog.wikia.com>. See the Installation Guide for getting
the current source from the git repository (and how to use the git
repository) and see the Developer Guide for instructions on
participating in the Icarus Verilog development process. That
information will not be repeated here.
What this documentation *will* cover is the gross structure of the
Icarus Verilog compiler source. This will help orient you to the
source code itself, so that you can find the global parts where you
can look for even better detail.
* Compiler Components
- The compiler driver (driver/)
This is the binary that is installed as "iverilog". This program takes
the command line arguments and assembles invocations of all the other
subcommands to perform the steps of compilation.
- The preprocessor (ivlpp/)
This implements the Verilog pre-processor. In Icarus Verilog, the
compiler directives `define, `include, `ifdef and etc. are implemented
in an external program. The ivlpp/ directory contains the source for
this program.
- The core compiler (this directory)
The "ivl" program is the core that does all the Verilog compiler
processing that is not handled elsewhere. This is the main core of the
Icarus Verilog compiler, not the runtime. See below for more details
on the core itself.
- The loadable code generators (tgt-*/)
This core compiler, after it is finished with parsing and semantic
analysis, uses loadable code generators to emit code for supported
targets. The tgt-*/ directories contains the source for the target
code generators that are bundled with Icarus Verilog. The tgt-vvp/
directory in particular contains the code generator for the vvp
runtime.
* Runtime Components
- The vvp runtime (vvp/)
This program implements the runtime environment for Icarus
Verilog. It implements the "vvp" command described in the user
documentation. See the vvp/ subdirectory for further developer
documentation.
- The system tasks implementations (vpi/)
The standard Verilog system tasks are implemented using VPI (PLI-2)
and the source is in this subdirectory.
- The PLI-1 compatibility library (libveriuser/)
The Icarus Verilog support for the deprecated PLI-1 is in this
subdirectory. The vvp runtime does not directly support the
PLI-1. Instead, the libveriuser library emulates it using the builtin
PLI-2 support.
- The Cadence PLI module compatibility module (cadpli/)
It is possible in some specialized situations to load and execute
PLI-1 code written for Verilog-XL. This directory contains the source
for the module that provides the Cadence PLI interface.
* The Core Compiler
The "ivl" binary is the core compiler that does the heavy lifting of
compiling the Verilog source (including libraries) and generating the
output. This is the most complex component of the Icarus Verilog
compilation system.
The process in the abstract starts with the Verilog lexical analysis
and parsing to generate an internal "pform". The pform is then
translated by elaboration into the "netlist" form. The netlist is
processed by some functors (which include some optimizations and
optional synthesis) then is translated into the ivl_target internal
form. And finally, the ivl_target form is passed via the ivl_target.h
API to the code generators.
- Lexical Analysis
Lexical analysis and parsing use the tools "flex", "gperf", and
"bison". The "flex" input file "lexor.lex" recognizes the tokens in
the input stream. This is called "lexical analysis". The lexical
analyzer also does some processing of compiler directives that are not
otherwise taken care of by the external preprocessor. The lexical
analyzer uses a table of keywords that is generated using the "gperf"
program and the input file "lexor_keywords.gperf". This table allows
the lexical analyzer to efficiently check input words with the rather
large set of potential keywords.
- Parsing
The parser input file "parse.y" is passed to the "bison" program to
generate the parser. The parser uses the functions in parse*.h,
parse*.cc, pform.h, and pform*.cc to generate the pform from the
stream of input tokens. The pform is what compiler writers call a
"decorated parse tree".
The pform itself is described by the classes in the header files
"PScope.h", "Module.h", "PGenerate.h", "Statement.h", and
"PExpr.h". The implementations of the classes in those header files
are in the similarly named C++ files.
- Elaboration
Elaboration transforms the pform to the netlist form. Elaboration is
conceptually divided into several major steps: Scope elaboration,
parameter overrides and defparam propagation, signal elaboration, and
statement and expression elaboration.
The elaboration of scopes and parameter overrides and defparam
propagation are conceptually separate, but are in practice
intermingled. The elaboration of scopes scans the pform to find and
instantiate all the scopes of the design. New scopes are created by
instantiation of modules (starting with the root instances) by user
defined tasks and functions, named blocks, and generate schemes. The
elaborate_scope methods implement scope elaboration, and the
elab_scope.cc source file has the implementations of those
methods.
The elaborate.cc source file contains the initial calls to the
elaborate_scope for the root scopes to get the process started. In
particular, see the "elaborate" function near the bottom of the
elaborate.cc source file. The calls to Design::make_root_scope create
the initial root scopes, and the creation and enqueue of the
elaborate_root_scope_t work items primes the scope elaboration work
list.
Intermingled in the work list are defparms work items that call the
Design::run_defparams and Design::evaluate_parameters methods that
override and evaluate parameters. The override and evaluation of
parameters must be intermingled with the elaboration of scopes because
the exact values of parameters may impact the scopes created (imagine
generate schemes and instance arrays) and the created scopes in turn
create new parameters that need override and evaluation.
+7 -7
View File
@@ -19,21 +19,21 @@
# include "discipline.h"
ivl_nature_s::ivl_nature_s(perm_string name__, perm_string access__)
: name_(name__), access_(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__)
: name_(name__), domain_(domain__), potential_(pot), flow_(flow__)
discipline_t::discipline_t(perm_string name, ddomain_t domain,
nature_t*pot, nature_t*flow)
: name_(name), domain_(domain), potential_(pot), flow_(flow)
{
}
ivl_discipline_s::~ivl_discipline_s()
discipline_t::~discipline_t()
{
}
+20 -22
View File
@@ -1,7 +1,7 @@
#ifndef __discipline_H
#define __discipline_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
@@ -28,15 +28,15 @@
# include "StringHeap.h"
# include <iostream>
# include <map>
# include "ivl_target.h"
# include "LineInfo.h"
extern std::ostream& operator << (std::ostream&, ivl_dis_domain_t);
typedef enum { DD_NONE, DD_DISCRETE, DD_CONTINUOUS } ddomain_t;
extern std::ostream& operator << (std::ostream&, ddomain_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
@@ -47,31 +47,29 @@ class ivl_nature_s : public LineInfo {
perm_string access_;
};
class ivl_discipline_s : public LineInfo {
class discipline_t : public LineInfo {
public:
explicit ivl_discipline_s (perm_string name, ivl_dis_domain_t dom,
ivl_nature_t pot, ivl_nature_t flow);
~ivl_discipline_s();
explicit discipline_t (perm_string name, ddomain_t dom,
nature_t*pot, nature_t*flow);
~discipline_t();
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_; }
ddomain_t domain() const { return domain_; }
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_;
ddomain_t domain_;
nature_t*potential_;
nature_t*flow_;
private: // not implemented
ivl_discipline_s(const ivl_discipline_s&);
ivl_discipline_s& operator = (const ivl_discipline_s&);
discipline_t(const discipline_t&);
discipline_t& operator = (const discipline_t&);
};
extern map<perm_string,ivl_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*> natures;
extern map<perm_string,discipline_t*> disciplines;
#endif
+24 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2009 Stephen Williams ([email protected])
* Copyright (c) 2001 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -16,6 +16,9 @@
* along with this program; if not, write to the Free Software
* 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
+16 -25
View File
@@ -18,7 +18,7 @@
#
SHELL = /bin/sh
suffix = @install_suffix@
VERSION = 0.9.devel
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -27,8 +27,6 @@ datarootdir = @datarootdir@
VPATH = $(srcdir)
suffix = @install_suffix@
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
includedir = $(prefix)/include
@@ -41,8 +39,8 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = -I. -I$(srcdir)/.. @CPPFLAGS@ @DEFS@
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
all: iverilog-vpi@EXEEXT@
@@ -50,45 +48,38 @@ 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
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=driver-vpi/$@
rm -f Makefile
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
#
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"
+19 -26
View File
@@ -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);
}
@@ -236,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);
@@ -271,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);
@@ -388,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
@@ -417,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);
@@ -455,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");
@@ -514,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");
@@ -522,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
+30 -46
View File
@@ -18,7 +18,7 @@
#
SHELL = /bin/sh
suffix = @install_suffix@
VERSION = 0.9.devel
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -41,24 +41,19 @@ INSTALL_DATA = @INSTALL_DATA@
MAN = @MAN@
PS2PDF = @PS2PDF@
CPPFLAGS = -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@
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
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=driver/$@
rm -f Makefile
O = main.o substit.o cflexor.o cfparse.o
@@ -71,62 +66,51 @@ cflexor.c: cflexor.lex
cfparse.h cfparse.c: cfparse.y
bison --verbose -t -d -o cfparse.c --name-prefix=cf $(srcdir)/cfparse.y
dep:
mkdir dep
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
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
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
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
cflexor.o: cflexor.c cfparse.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@ $(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 $(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 $(bindir) $(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 $(bindir)/iverilog@EXEEXT@
rm -f $(mandir)/man1/iverilog.1 $(prefix)/iverilog.pdf
+6 -19
View File
@@ -4,7 +4,7 @@
%{
/*
* Copyright (c) 2001-2010 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
@@ -21,6 +21,9 @@
* along with this program; if not, write to the Free Software
* 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,15 +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; }
"+timescale+" { BEGIN(PLUS_ARGS); return TOK_TIMESCALE; }
"+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+]* {
@@ -148,7 +149,7 @@ int cmdfile_stack_ptr = 0;
cflval.text = trim_trailing_white(yytext, 0);
BEGIN(0);
return TOK_STRING; }
/* Fallback match. */
. { return yytext[0]; }
@@ -235,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
}
+9 -12
View File
@@ -1,6 +1,6 @@
%{
/*
* Copyright (c) 2001-2010 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
@@ -17,6 +17,10 @@
* along with this program; if not, write to the Free Software
* 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"
@@ -37,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;
@@ -57,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_TIMESCALE
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
%token TOK_INTEGER_WIDTH
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
%%
@@ -135,13 +139,6 @@ item
free(tmp);
}
| TOK_TIMESCALE TOK_PLUSARG
{ char*tmp = substitutions($2);
process_timescale(tmp);
free($2);
free(tmp);
}
| TOK_DEFINE TOK_PLUSARG
{ process_define($2);
free($2);
+1 -2
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 ([email protected])
*
* This source code is free software; you can redistribute it
@@ -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 -3
View File
@@ -1,7 +1,7 @@
#ifndef __globals_H
#define __globals_H
/*
* 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
@@ -18,9 +18,37 @@
* along with this program; if not, write to the Free Software
* 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;
@@ -41,7 +69,45 @@ extern void process_include_dir(const char*name);
/* Add a new -D define. */
extern void process_define(const char*name);
/* Set the default timescale for the simulator. */
extern void process_timescale(const char*ts_string);
/* -v */
extern int verbose_flag;
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 -106
View File
@@ -1,30 +1,31 @@
.TH iverilog 1 "January 22nd, 2010" "" "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]] [\-pflag=value]
[\-dname] [\-g1995|\-g2001|\-g2005|\-g<feature>]
[\-Iincludedir] [\-mmodule] [\-Mfile] [\-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
\fIiverilog\fP is a compiler that translates Verilog source code into
executable programs for simulation, or other netlist formats for
further processing. The currently supported targets are \fIvvp\fP for
simulation, and \fIfpga\fP for synthesis. Other target
simulation, and \fIxnf\fP 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,7 +44,7 @@ Verilog source.
Defines macro \fImacro\fP as \fIdefn\fP.
.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.
@@ -54,21 +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
.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, or \fIIEEE1364\-2005\fP. Normally,
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
@@ -81,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
@@ -100,23 +93,13 @@ 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 -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
@@ -145,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.
@@ -153,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
@@ -191,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
@@ -221,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
@@ -234,29 +212,27 @@ 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.
.TP 8
.B xnf
This is the Xilinx Netlist Format used by many tools for placing
devices in FPGAs or other programmable devices. This target is
obsolete, use the \fBfpga\fP target instead.
.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.
.TP 8
.B vhdl
This target produces a VHDL translation of the Verilog netlist. The
output is a single file containing VHDL entities corresponding to
the modules in the Verilog source code. Note that only a subset of
the Verilog language is supported. See the wiki for more information.
implies the synthesis \fB-S\fP flag.
.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
@@ -270,12 +246,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
@@ -288,7 +258,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).
@@ -299,22 +269,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
@@ -356,14 +310,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.
@@ -371,7 +325,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.
@@ -382,12 +336,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
@@ -399,26 +353,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 +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
@@ -429,8 +376,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
@@ -443,12 +389,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
@@ -460,11 +406,16 @@ 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
To compile hello.v to a file in XNF-format called hello.xnf
iverilog -txnf -ohello.xnf hello.v
.SH "AUTHOR"
.nf
@@ -479,7 +430,7 @@ Tips on using, debugging, and developing the compiler can be found at
.SH COPYRIGHT
.nf
Copyright \(co 2002\-2010 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
+128 -313
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2010 Stephen Williams ([email protected])
* Copyright (c) 2000-2008 Stephen Williams ([email protected])
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@@ -18,8 +18,7 @@
*/
# 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,14 +31,13 @@ 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] [-g<feature>]\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"
@@ -53,7 +51,6 @@ const char HELP[] =
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/types.h>
@@ -109,22 +106,16 @@ const char*npath = 0;
const char*targ = "vvp";
const char*depfile = 0;
const char*generation = "2005";
const char*gen_specify = "no-specify";
const char*generation = "2x";
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_verilog_ams = "no-verilog-ams";
const char*gen_system_verilog = "no-system-verilog";
/* 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] = "";
unsigned integer_width = 32;
@@ -147,7 +138,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;
@@ -230,23 +222,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;
@@ -275,11 +250,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;
}
@@ -288,120 +259,19 @@ static const char*my_tempfile(const char*str, FILE**fout)
return pathbuf;
}
static int t_version_only(void)
{
int rc;
remove(source_path);
free(source_path);
fflush(0);
snprintf(tmp, sizeof tmp, "%s%civlpp -V", pbase, sep);
rc = system(tmp);
if (rc != 0) {
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
}
fflush(0);
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep,
iconfig_path, iconfig_common_path);
rc = system(tmp);
if (rc != 0) {
fprintf(stderr, "Unable to get version from \"%s\"\n", tmp);
}
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(iconfig_path);
free(iconfig_path);
remove(defines_path);
free(defines_path);
remove(compiled_defines_path);
free(compiled_defines_path);
}
return 0;
}
static void build_preprocess_command(int e_flag)
{
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);
}
static int t_preprocess_only(void)
{
int rc;
char*cmd;
unsigned ncmd;
build_preprocess_command(1);
ncmd = strlen(tmp);
cmd = malloc(ncmd+1);
strcpy(cmd, tmp);
if (strcmp(opath,"-") != 0) {
snprintf(tmp, sizeof tmp, " > \"%s\"", opath);
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
}
if (verbose_flag)
printf("preprocess: %s\n", cmd);
rc = system(cmd);
remove(source_path);
free(source_path);
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(iconfig_path);
free(iconfig_path);
remove(defines_path);
free(defines_path);
remove(compiled_defines_path);
free(compiled_defines_path);
}
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors preprocessing Verilog program.\n");
free(cmd);
return WEXITSTATUS(rc);
}
fprintf(stderr, "Command signaled: %s\n", cmd);
free(cmd);
return -1;
}
free(cmd);
return 0;
}
/*
* This is the default target type. It looks up the bits that are
* needed to run the command from the configuration file (which is
* already parsed for us) so we can handle must of the generic cases.
*/
static int t_compile()
static int t_default(char*cmd, unsigned ncmd)
{
unsigned rc;
/* Start by building the preprocess command line. */
build_preprocess_command(0);
size_t ncmd = strlen(tmp);
char*cmd = malloc(ncmd + 1);
strcpy(cmd, tmp);
#ifndef __MINGW32__
int rtn;
#ifdef __MINGW32__
unsigned ncmd_start = ncmd;
#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);
@@ -416,25 +286,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);
@@ -443,33 +323,28 @@ static int t_compile()
rc = system(cmd);
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(source_path);
free(source_path);
remove(iconfig_path);
free(iconfig_path);
remove(defines_path);
free(defines_path);
remove(compiled_defines_path);
free(compiled_defines_path);
}
#ifdef __MINGW32__ /* MinGW just returns the exit status, so return it! */
free(cmd);
return rc;
#else
rtn = 0;
if (rc != 0) {
if (rc == 127) {
fprintf(stderr, "Failed to execute: %s\n", cmd);
rtn = 1;
} else if (WIFEXITED(rc)) {
rtn = WEXITSTATUS(rc);
} else {
fprintf(stderr, "Command signaled: %s\n", cmd);
rtn = -1;
return 1;
}
if (WIFEXITED(rc))
return WEXITSTATUS(rc);
fprintf(stderr, "Command signaled: %s\n", cmd);
return -1;
}
free(cmd);
return rtn;
return 0;
#endif
}
@@ -479,18 +354,13 @@ static void process_warning_switch(const char*name)
if (strcmp(name,"all") == 0) {
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,"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");
@@ -499,12 +369,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-implicit") == 0) {
char*cp = strchr(warning_flags, 'i');
if (cp) while (*cp) {
@@ -517,30 +381,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;
}
}
}
@@ -569,11 +415,6 @@ void process_define(const char*name)
fprintf(defines_file,"D:%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
@@ -601,9 +442,6 @@ 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";
@@ -646,33 +484,18 @@ 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,"verilog-ams") == 0)
gen_verilog_ams = "verilog-ams";
else if (strcmp(name,"no-verilog-ams") == 0)
gen_verilog_ams = "no-verilog-ams";
else if (strcmp(name,"system-verilog") == 0)
gen_system_verilog = "system-verilog";
else {
fprintf(stderr, "Unknown/Unsupported Language generation "
"%s\n\n", name);
@@ -682,14 +505,11 @@ int process_generation(const char*name)
" 2005 -- IEEE1364-2005\n"
"Other generation flags:\n"
" specify | no-specify\n"
" verilog-ams | no-verilog-ams\n"
" verilog-ams | no-verinlog-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"
" system-verilog\n");
" io-range-error | no-io-range-error\n");
return 1;
}
@@ -702,7 +522,7 @@ int process_generation(const char*name)
void add_sft_file(const char *module)
{
char *file;
file = (char *) malloc(strlen(base)+1+strlen(module)+4+1);
sprintf(file, "%s%c%s.sft", base, sep, module);
if (access(file, R_OK) == 0)
@@ -712,36 +532,38 @@ void add_sft_file(const char *module)
int main(int argc, char **argv)
{
char*cmd;
unsigned ncmd;
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 basepath[4096], tmppath[4096];
GetModuleFileName(NULL, tmppath, sizeof tmppath);
/* Convert to a short name to remove any embedded spaces. */
GetShortPathName(tmppath, basepath, sizeof basepath);
strncpy(ivl_root, basepath, MAXSIZE);
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" IVL_SUFFIX);
strcat(ivl_root, "\\lib\\ivl");
base = ivl_root;
}
@@ -831,7 +653,7 @@ int main(int argc, char **argv)
case 'c':
case 'f':
add_cmd_file(optarg);
break;
break;
case 'D':
process_define(optarg);
break;
@@ -846,12 +668,13 @@ 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':
fprintf(stderr, "%s\n", HELP);
return 1;
case 'h':
fprintf(stderr, "%s\n", HELP);
return 1;
case 'I':
process_include_dir(optarg);
@@ -913,20 +736,6 @@ 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;
}
}
@@ -936,22 +745,16 @@ int main(int argc, char **argv)
if (version_flag || verbose_flag) {
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
printf("Copyright 1998-2010 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");
if (version_flag)
return 0;
}
/* 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);
@@ -961,18 +764,9 @@ int main(int argc, char **argv)
how to handle them. */
fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
/* If verilog-2005 is enabled or icarus-misc or verilog-ams,
* then include the v2005_math library. */
if (strcmp(generation, "2005") == 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);
fprintf(iconfig_file, "module:v2005_math\n");
}
/* If verilog-ams or icarus_misc is enabled, then include the
* va_math module as well. */
if (strcmp(gen_verilog_ams,"verilog-ams") == 0 ||
strcmp(gen_icarus, "icarus-misc") == 0) {
/* If verilog-ams is enabled, then include the va_math module
as well. */
if (strcmp(gen_verilog_ams,"verilog-ams") == 0) {
fprintf(iconfig_file, "sys_func:%s%cva_math.sft\n", base, sep);
fprintf(iconfig_file, "module:va_math\n");
}
@@ -982,10 +776,8 @@ int main(int argc, char **argv)
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_verilog_ams);
fprintf(iconfig_file, "generation:%s\n", gen_icarus);
fprintf(iconfig_file, "generation:%s\n", gen_system_verilog);
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
fprintf(iconfig_file, "out:%s\n", opath);
if (depfile) fprintf(iconfig_file, "depfile:%s\n", depfile);
@@ -1007,9 +799,7 @@ int main(int argc, char **argv)
return 1;
}
free(command_filename);
fclose(fp);
}
destroy_lexor();
if (depfile) {
fprintf(defines_file, "M:%s\n", depfile);
@@ -1024,13 +814,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);
@@ -1039,41 +823,72 @@ 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) {
if (source_count == 0) {
fprintf(stderr, "%s: no source files.\n\n%s\n", argv[0], HELP);
return 1;
}
/* Start building the preprocess command line. */
sprintf(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);
ncmd = strlen(tmp);
cmd = malloc(ncmd + 1);
strcpy(cmd, tmp);
/* If the -E flag was given on the command line, then all we
do is run the preprocessor and put the output where the
user wants it. */
if (e_flag) {
int rc;
if (strcmp(opath,"-") != 0) {
sprintf(tmp, " > %s", opath);
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
}
if (verbose_flag)
printf("preprocess: %s\n", cmd);
rc = system(cmd);
remove(source_path);
fclose(iconfig_file);
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(iconfig_path);
remove(defines_path);
remove(compiled_defines_path);
}
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors preprocessing Verilog program.\n");
return WEXITSTATUS(rc);
}
fprintf(stderr, "Command signaled: %s\n", cmd);
return -1;
}
return 0;
}
fprintf(iconfig_file, "iwidth:%u\n", integer_width);
/* 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",
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);
/* If we're only here for the version output, then we're done. */
if (version_flag)
return t_version_only();
return t_default(cmd, ncmd);
/* If the -E flag was given on the command line, then all we
do is run the preprocessor and put the output where the
user wants it. */
if (e_flag)
return t_preprocess_only();
/* Otherwise, this is a full compile. */
return t_compile();
return 0;
}
+33 -12
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
@@ -16,10 +16,15 @@
* along with this program; if not, write to the Free Software
* 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>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
char* substitutions(const char*str)
@@ -30,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);
@@ -46,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;
@@ -92,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.
*
*/
+3 -21
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2010 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
@@ -21,16 +21,6 @@
# include "netlist.h"
# include <cassert>
# include <cstdlib>
# include "ivl_assert.h"
NetEAccess* NetEAccess::dup_expr() const
{
NetEAccess*tmp = new NetEAccess(branch_, nature_);
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
NetEBComp* NetEBComp::dup_expr() const
{
@@ -94,8 +84,8 @@ NetESFunc* NetESFunc::dup_expr() const
tmp->cast_signed(has_sign());
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
assert(parm(idx));
tmp->parm(idx, parm(idx)->dup_expr());
assert(tmp->parm(idx));
tmp->parm(idx, tmp->parm(idx)->dup_expr());
}
tmp->set_line(*this);
@@ -138,14 +128,6 @@ NetEUFunc* NetEUFunc::dup_expr() const
return tmp;
}
NetEUBits* NetEUBits::dup_expr() const
{
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());
+49 -1
View File
@@ -16,6 +16,9 @@
* along with this program; if not, write to the Free Software
* 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"
@@ -112,7 +115,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(this, des, scope, path_, sig, mem, par, eve);
symbol_search(des, scope, path_, sig, mem, par, eve);
if (mem != 0) {
@@ -164,3 +167,48 @@ 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)
*
*/
+497 -2243
View File
File diff suppressed because it is too large Load Diff
+136 -210
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2010 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
@@ -118,20 +118,17 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force);
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;
continue;
}
/* 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 == 0)
continue;
assert(tmp);
/* Link the new l-value to the previous one. */
NetAssign_*last = tmp;
while (last->more)
last = last->more;
@@ -155,7 +152,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
const NetExpr*par = 0;
NetEvent* eve = 0;
symbol_search(this, des, scope, path_, reg, par, eve);
symbol_search(des, scope, path_, reg, par, eve);
if (reg == 0) {
cerr << get_fileline() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope_path(scope) <<
@@ -182,33 +179,9 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
return 0;
}
/* 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 (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);
@@ -222,18 +195,114 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
return lv;
}
if (use_sel == index_component_t::SEL_BIT) {
NetAssign_*lv = new NetAssign_(reg);
elaborate_lval_net_bit_(des, scope, lv);
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;
}
ivl_assert(*this, use_sel == index_component_t::SEL_NONE);
long msb, lsb;
NetExpr*mux;
/* No select expressions. */
if (use_sel == index_component_t::SEL_BIT) {
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb == 0);
/* If there is only a single select expression, it is a
bit select. Evaluate the constant value and treat it
as a part select with a bit width of 1. If the
expression it not constant, then return the
expression as a mux. */
NetExpr*index_expr = elab_and_eval(des, scope, index_tail.msb, -1);
if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
msb = index_con->value().as_long();
lsb = index_con->value().as_long();
mux = 0;
} else {
msb = 0;
lsb = 0;
mux = index_expr;
}
} else {
/* No select expressions, so presume a part select the
width of the register. */
msb = reg->msb();
lsb = reg->lsb();
mux = 0;
}
NetAssign_*lv;
if (mux) {
/* If there is a non-constant bit select, make a
NetAssign_ to the target reg and attach a
bmux to select the target bit. */
lv = new NetAssign_(reg);
/* Correct the mux for the range of the vector. */
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 (msb == reg->msb() && lsb == reg->lsb()) {
/* No bit select, and part select covers the entire
vector. Simplest case. */
lv = new NetAssign_(reg);
} else {
/* If the bit/part select is constant, then make the
NetAssign_ only as wide as it needs to be and connect
only to the selected bits of the reg. */
unsigned loff = reg->sb_to_idx(lsb);
unsigned moff = reg->sb_to_idx(msb);
unsigned wid = moff - loff + 1;
if (moff < loff) {
cerr << get_fileline() << ": error: part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is reversed." << endl;
des->errors += 1;
return 0;
}
/* If the part select extends beyond the extreme of the
variable, then report an error. Note that loff is
converted to normalized form so is relative the
variable pins. */
if ((wid + loff) > reg->vector_width()) {
cerr << get_fileline() << ": error: bit/part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
des->errors += 1;
return 0;
}
lv = new NetAssign_(reg);
lv->set_part(new NetEConst(verinum(loff)), wid);
}
NetAssign_*lv = new NetAssign_(reg);
return lv;
}
@@ -257,20 +326,13 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
ivl_assert(*this, index_head.msb != 0);
ivl_assert(*this, index_head.lsb == 0);
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
bool unsized_flag_tmp = false;
index_head.msb->test_width(des, scope, integer_width, integer_width,
expr_type_tmp, unsized_flag_tmp);
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
// If there is a non-zero base to the memory, then build an
// expression to calculate the canonical address.
if (long base = reg->array_first()) {
word = normalize_variable_array_base(word, base,
reg->array_count());
word = make_add_expr(word, 0-base);
eval_expr(word);
}
@@ -287,7 +349,7 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
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())
@@ -302,20 +364,6 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
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()
<< "[" << *word << "]" << 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);
@@ -326,91 +374,31 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
return lv;
}
bool PEIdent::elaborate_lval_net_bit_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
const name_component_t&name_tail = path_.back();
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb != 0);
ivl_assert(*this, index_tail.lsb == 0);
NetNet*reg = lv->sig();
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
bool unsized_flag_tmp = false;
index_tail.msb->test_width(des, scope, integer_width, integer_width,
expr_type_tmp, unsized_flag_tmp);
// Bit selects have a single select expression. Evaluate the
// constant value and treat it as a part select with a bit
// width of 1.
NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1);
long lsb = 0;
if (NetEConst*index_con = dynamic_cast<NetEConst*> (mux)) {
lsb = index_con->value().as_long();
mux = 0;
}
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_base(mux, reg->msb(), reg->lsb(), 1, true);
lv->set_part(mux, 1);
} 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(lsb);
if (loff < 0 || loff >= (long)reg->vector_width()) {
cerr << get_fileline() << ": error: bit select "
<< reg->name() << "[" <<lsb<<"]"
<< " is out of range." << endl;
des->errors += 1;
return 0;
}
lv->set_part(new NetEConst(verinum(loff)), 1);
}
return true;
}
bool PEIdent::elaborate_lval_net_part_(Design*des,
NetScope*scope,
NetAssign_*lv) const
{
// 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();
assert(reg);
if (msb == reg->msb() && lsb == reg->lsb()) {
/* Part select covers the entire vector. Simplest case. */
/* No bit select, and 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 the bit/part select is constant, then make the
NetAssign_ only as wide as it needs to be and connect
only to the selected bits of the reg. */
unsigned loff = reg->sb_to_idx(lsb);
unsigned moff = reg->sb_to_idx(msb);
unsigned wid = moff - loff + 1;
if (moff < loff) {
cerr << get_fileline() << ": error: part select "
@@ -420,15 +408,17 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
return false;
}
/* If the part select extends beyond the extremes of the
/* If the part select extends beyond the extreme 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 "
if ((wid + loff) > reg->vector_width()) {
cerr << get_fileline() << ": error: bit/part select "
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
<< " is out of range." << endl;
des->errors += 1;
return false;
}
lv->set_part(new NetEConst(verinum(loff)), wid);
@@ -465,80 +455,16 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
unsigned long wid;
calculate_up_do_width_(des, scope, wid);
// These are not used, but they need to have a default value.
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
bool unsized_flag_tmp = false;
index_tail.msb->test_width(des, scope, integer_width, integer_width,
expr_type_tmp, unsized_flag_tmp);
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
// 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;
if (((reg->msb() < reg->lsb()) &&
use_sel == index_component_t::SEL_IDX_UP) ||
((reg->msb() > reg->lsb()) &&
use_sel == index_component_t::SEL_IDX_DO)) {
offset = -wid + 1;
}
delete base;
long rel_base = reg->sb_to_idx(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->array_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->array_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->array_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 {
/* Correct the mux for the range of the vector. */
if (use_sel == index_component_t::SEL_IDX_UP) {
base = normalize_variable_base(base, reg->msb(), reg->lsb(),
wid, true);
} else {
// This is assumed to be a SEL_IDX_DO.
base = normalize_variable_base(base, reg->msb(), reg->lsb(),
wid, false);
}
/* 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());
if (use_sel == index_component_t::SEL_IDX_DO && wid > 1 ) {
base = make_add_expr(base, 1-(long)wid);
}
if (debug_elaborate)
+3117 -188
View File
File diff suppressed because it is too large Load Diff
+9 -254
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2010 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
@@ -53,65 +53,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
return 0;
}
NetExpr*tmp = elaborate_expr_base_(des, lp, rp, -2, true);
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;
}
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*PEBLeftWidth::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_leaf(des, lp, rp, -2);
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;
}
NetExpr*tmp = elaborate_expr_base_(des, lp, rp, -2);
return tmp;
}
@@ -150,19 +92,11 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
/* Elaborate all the operands and attach them to the concat
node. Use the elaborate_pexpr method instead of the
elaborate_expr method. */
bool fail = false;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
if (ex == 0) continue;
if (ex->expr_type() == IVL_VT_REAL) {
cerr << ex->get_fileline() << ": error: concatenation "
<< "operand can not be real: " << *ex << endl;
des->errors += 1;
fail = true;
continue;
}
ex->set_line(*parms_[idx]);
if (dynamic_cast<NetEParam*>(ex)) {
@@ -175,18 +109,13 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
<< "concatenation has indefinite width: "
<< *ex << endl;
des->errors += 1;
fail = true;
continue;
delete tmp;
return 0;
}
tmp->set(idx, ex);
}
if (fail) {
delete tmp;
return 0;
}
return tmp;
}
@@ -203,21 +132,13 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
*/
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
{
pform_name_t oldpath = path_;
pform_name_t path = path_;
name_component_t name_tail = path_.back();
oldpath.pop_back();
if (path_.size() > 1) {
cerr << get_fileline() << ": error: parameter r-value expression "
"does not support hierarchical references `" << path_
<< "`." << endl;
des->errors += 1;
return 0;
}
path.pop_back();
NetScope*pscope = scope;
if (path_.size() > 0) {
list<hname_t> tmp = eval_scope_path(des, scope, oldpath);
list<hname_t> tmp = eval_scope_path(des, scope, path);
pscope = des->find_scope(scope, tmp);
}
@@ -237,9 +158,8 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
ivl_assert(*this, pscope);
}
if (ex == 0) {
cerr << get_fileline() << ": error: identifier `"
<< name_tail.name << "` is not a parameter in "
<< scope_path(scope)<< "." << endl;
cerr << get_fileline() << ": error: identifier ``" << name_tail.name <<
"'' is not a parameter in "<< scope_path(scope)<< "." << endl;
des->errors += 1;
return 0;
}
@@ -347,168 +267,3 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
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;
}
/* This is only available with verilog-ams or icarus-misc. */
if ((gn_icarus_misc_flag || gn_verilog_ams_flag) &&
(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;
/* 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 $abs 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: " << nm << "() is not a "
"constant system function." << endl;
des->errors += 1;
return 0;
}
/* Constant user function code goes here. */
cerr << get_fileline() << ": sorry: constant user functions are not "
"currently supported: " << nm << "()." << endl;
des->errors += 1;
return 0;
}
void NetExpr::resolve_pexpr_type(void)
{
}
void NetEBinary::resolve_pexpr_type(void)
{
if (debug_elab_pexpr) {
cerr << get_fileline() << ": debug: "
<< "Resolve_pexpr_type for binary " << human_readable_op(op_)
<< "." << endl;
}
left_->resolve_pexpr_type();
right_->resolve_pexpr_type();
switch (op_) {
case '+':
case '-':
case '*':
case '/':
suppress_binary_operand_sign_if_needed(left_, right_);
cast_signed_base_(left_->has_sign() && right_->has_sign());
break;
default:
break;
}
}
void NetEParam::resolve_pexpr_type(void)
{
if (debug_elab_pexpr) {
cerr << get_fileline() << ": debug: "
<< "Resolve_pexpr_type for parameter " << reference_->first
<< "." << endl;
}
if (reference_->second.signed_flag) {
cast_signed_base_(true);
} else if (reference_->second.expr) {
cast_signed_base_( reference_->second.expr->has_sign() );
}
}
+216 -897
View File
File diff suppressed because it is too large Load Diff
+74 -253
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2009 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
@@ -35,14 +35,6 @@
# include "util.h"
# include "ivl_assert.h"
/*
* Set the following to true when you need to process an expression
* that is being done in a constant context. This allows the
* elaboration to explicitly say we do not currently support constant
* user functions when the function is not found.
*/
bool need_constant_expr = false;
static bool get_const_argument(NetExpr*exp, verinum&res)
{
switch (exp->expr_type()) {
@@ -92,10 +84,10 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
&& (sig->port_type() == NetNet::PINPUT)
&& (sig->type() == NetNet::REG)) {
cerr << cur->get_fileline() << ": error: Port "
<< cur->basename() << " of module "
cerr << cur->get_fileline() << ": error: "
<< cur->basename() << " in "
<< scope->module_name()
<< " is declared as input and as a reg type." << endl;
<< " declared as input and as a reg type." << endl;
des->errors += 1;
}
@@ -104,22 +96,10 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
&& (sig->port_type() == NetNet::PINOUT)
&& (sig->type() == NetNet::REG)) {
cerr << cur->get_fileline() << ": error: Port "
<< cur->basename() << " of module "
cerr << cur->get_fileline() << ": error: "
<< cur->basename() << " in "
<< scope->module_name()
<< " is declared as inout and as a reg type." << endl;
des->errors += 1;
}
if (sig && (sig->scope() == scope)
&& (scope->type() == NetScope::MODULE)
&& (sig->port_type() == NetNet::PINOUT)
&& (sig->data_type() == IVL_VT_REAL)) {
cerr << cur->get_fileline() << ": error: Port "
<< cur->basename() << " of module "
<< scope->module_name()
<< " is declared as a real inout port." << endl;
<< " declared as inout and as a reg type." << endl;
des->errors += 1;
}
@@ -128,49 +108,13 @@ bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const
return flag;
}
static void elaborate_sig_funcs(Design*des, NetScope*scope,
const map<perm_string,PFunction*>&funcs)
{
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
for (mfunc_it_t cur = funcs.begin()
; cur != funcs.end() ; cur ++) {
hname_t use_name ( (*cur).first );
NetScope*fscope = scope->child(use_name);
if (fscope == 0) {
cerr << (*cur).second->get_fileline() << ": internal error: "
<< "Child scope for function " << (*cur).first
<< " missing in " << scope_path(scope) << "." << endl;
des->errors += 1;
continue;
}
(*cur).second->elaborate_sig(des, fscope);
}
}
static void elaborate_sig_tasks(Design*des, NetScope*scope,
const map<perm_string,PTask*>&tasks)
{
typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
for (mtask_it_t cur = tasks.begin()
; cur != tasks.end() ; cur ++) {
NetScope*tscope = scope->child( hname_t((*cur).first) );
assert(tscope);
(*cur).second->elaborate_sig(des, tscope);
}
}
bool Module::elaborate_sig(Design*des, NetScope*scope) const
{
bool flag = true;
// Scan all the ports of the module, and make sure that each
// is connected to wires that have port declarations.
for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) {
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
Module::port_t*pp = ports[idx];
if (pp == 0)
continue;
@@ -179,7 +123,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
// expression are all identifiers that should reference
// wires within the scope.
map<perm_string,PWire*>::const_iterator wt;
for (unsigned cc = 0 ; cc < pp->expr.size() ; cc += 1) {
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
pform_name_t port_path (pp->expr[cc]->path());
// A concatenated wire of a port really should not
// have any hierarchy.
@@ -238,12 +182,38 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
flag &= (*gt)->elaborate_sig(des, scope);
}
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
for (mfunc_it_t cur = funcs_.begin()
; cur != funcs_.end() ; cur ++) {
hname_t use_name ( (*cur).first );
NetScope*fscope = scope->child(use_name);
if (scope == 0) {
cerr << (*cur).second->get_fileline() << ": internal error: "
<< "Child scope for function " << (*cur).first
<< " missing in " << scope_path(scope) << "." << endl;
des->errors += 1;
continue;
}
(*cur).second->elaborate_sig(des, fscope);
}
// After all the wires are elaborated, we are free to
// elaborate the ports of the tasks defined within this
// module. Run through them now.
elaborate_sig_funcs(des, scope, funcs);
elaborate_sig_tasks(des, scope, tasks);
typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
for (mtask_it_t cur = tasks_.begin()
; cur != tasks_.end() ; cur ++) {
NetScope*tscope = scope->child( hname_t((*cur).first) );
assert(tscope);
(*cur).second->elaborate_sig(des, tscope);
}
// initial and always blocks may contain begin-end and
// fork-join blocks that can introduce scopes. Therefore, I
@@ -286,7 +256,7 @@ bool PEIdent::elaborate_sig(Design*des, NetScope*scope) const
if (error_implicit)
return true;
symbol_search(this, des, scope, path_, sig, par, eve);
symbol_search(des, scope, path_, sig, par, eve);
if (eve != 0)
return false;
@@ -381,11 +351,11 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
continue;
flag = tmp->elaborate_sig(des, scope) && flag;
}
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
for (unsigned idx = 0 ; idx < instance.size() ; idx += 1) {
for (unsigned idx = 0 ; idx < instance.count() ; idx += 1) {
// I know a priori that the elaborate_scope created the scope
// already, so just look it up as a child of the current scope.
NetScope*my_scope = instance[idx];
@@ -432,9 +402,6 @@ bool PGModule::elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const
bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
{
if (direct_nested_)
return elaborate_sig_direct_(des, container);
bool flag = true;
// Handle the special case that this is a CASE scheme. In this
@@ -448,10 +415,10 @@ bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
<< scope_path(container) << "." << endl;
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++) {
for (generate_it_t cur = generates.begin()
; cur != generates.end() ; cur ++) {
PGenerate*item = *cur;
if (item->direct_nested_ || !item->scope_list_.empty()) {
if (! item->scope_list_.empty()) {
flag &= item->elaborate_sig(des, container);
}
}
@@ -477,32 +444,6 @@ bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
return flag;
}
bool PGenerate::elaborate_sig_direct_(Design*des, NetScope*container) const
{
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
<< "Direct nesting " << scope_name
<< " (scheme_type=" << scheme_type << ")"
<< " elaborate_sig in scope "
<< scope_path(container) << "." << endl;
// Elaborate_sig for a direct nested generated scheme knows
// that there are only sub_schemes to be elaborated. There
// should be exactly 1 active generate scheme, search for it
// using this loop.
bool flag = true;
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++) {
PGenerate*item = *cur;
if (item->direct_nested_ || !item->scope_list_.empty()) {
// Found the item, and it is direct nested.
flag &= item->elaborate_sig(des, container);
}
}
return flag;
}
bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
{
// Scan the declared PWires to elaborate the obvious signals
@@ -520,12 +461,9 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
cur->elaborate_sig(des, scope);
}
elaborate_sig_funcs(des, scope, funcs);
elaborate_sig_tasks(des, scope, tasks);
typedef list<PGenerate*>::const_iterator generate_it_t;
for (generate_it_t cur = generate_schemes.begin()
; cur != generate_schemes.end() ; cur ++ ) {
for (generate_it_t cur = generates.begin()
; cur != generates.end() ; cur ++ ) {
(*cur) -> elaborate_sig(des, scope);
}
@@ -535,13 +473,6 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
(*cur) ->elaborate_sig(des, scope);
}
typedef list<PProcess*>::const_iterator proc_it_t;
for (proc_it_t cur = behaviors.begin()
; cur != behaviors.end() ; cur ++ ) {
(*cur) -> statement() -> elaborate_sig(des, scope);
}
return true;
}
@@ -579,17 +510,12 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
case PTF_REG:
case PTF_REG_S:
if (return_type_.range) {
probe_expr_width(des, scope, (*return_type_.range)[0]);
probe_expr_width(des, scope, (*return_type_.range)[1]);
need_constant_expr = true;
NetExpr*me = elab_and_eval(des, scope,
(*return_type_.range)[0], -1);
assert(me);
NetExpr*le = elab_and_eval(des, scope,
(*return_type_.range)[1], -1);
assert(le);
need_constant_expr = false;
long mnum = 0, lnum = 0;
if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
@@ -611,11 +537,9 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
}
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
ret_sig->set_scalar(false);
} else {
ret_sig = new NetNet(scope, fname, NetNet::REG);
ret_sig->set_scalar(true);
}
ret_sig->set_line(*this);
ret_sig->set_signed(return_type_.type == PTF_REG_S);
@@ -628,7 +552,6 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this);
ret_sig->set_signed(true);
ret_sig->set_isint(true);
ret_sig->set_scalar(false);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC);
break;
@@ -638,7 +561,6 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this);
ret_sig->set_signed(false);
ret_sig->set_isint(false);
ret_sig->set_scalar(false);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_LOGIC);
break;
@@ -649,23 +571,14 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
ret_sig->set_line(*this);
ret_sig->set_signed(true);
ret_sig->set_isint(false);
ret_sig->set_scalar(true);
ret_sig->port_type(NetNet::POUTPUT);
ret_sig->data_type(IVL_VT_REAL);
break;
default:
if (ports_) {
cerr << get_fileline() << ": internal error: I don't know "
<< "how to deal with return type of function "
<< scope->basename() << "." << endl;
} else {
/* If we do not have any ports or a return type this
* is probably a bad function definition. */
cerr << get_fileline() << ": error: Bad definition for "
<< "function " << scope->basename() << "?" << endl;
return;
}
cerr << get_fileline() << ": internal error: I don't know how "
<< "to deal with return type of function "
<< scope->basename() << "." << endl;
}
svector<NetNet*>ports (ports_? ports_->count() : 0);
@@ -860,146 +773,79 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
/*
* Elaborate a source wire. The "wire" is the declaration of wires,
* registers, ports and memories. The parser has already merged the
* multiple properties of a wire (i.e., "input wire"), so come the
* elaboration this creates an object in the design that represents the
* multiple properties of a wire (i.e., "input wire") so come the
* elaboration this creates an object in the design that represent the
* defined item.
*/
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
{
NetNet::Type wtype = type_;
bool is_implicit_scalar = false;
if (wtype == NetNet::IMPLICIT) {
if (wtype == NetNet::IMPLICIT)
wtype = NetNet::WIRE;
is_implicit_scalar = true;
}
if (wtype == NetNet::IMPLICIT_REG) {
if (wtype == NetNet::IMPLICIT_REG)
wtype = NetNet::REG;
is_implicit_scalar = true;
}
unsigned wid = 1;
long lsb = 0, msb = 0;
des->errors += error_cnt_;
// A signal can not have the same name as a scope object.
const NetScope *child = scope->child(hname_t(name_));
if (child) {
cerr << get_fileline() << ": error: signal and ";
child->print_type(cerr);
cerr << " in '" << scope->fullname()
<< "' have the same name '" << name_ << "'." << endl;
des->errors += 1;
}
// A signal can not have the same name as a genvar.
const LineInfo *genvar = scope->find_genvar(name_);
if (genvar) {
cerr << get_fileline() << ": error: signal and genvar in '"
<< scope->fullname() << "' have the same name '" << name_
<< "'." << endl;
des->errors += 1;
}
// A signal can not have the same name as a parameter.
const NetExpr *ex_msb, *ex_lsb;
const NetExpr *parm = scope->get_parameter(name_, ex_msb, ex_lsb);
if (parm) {
cerr << get_fileline() << ": error: signal and parameter in '"
<< scope->fullname() << "' have the same name '" << name_
<< "'." << endl;
des->errors += 1;
}
// A signal can not have the same name as a named event.
const NetEvent *event = scope->find_event(name_);
if (event) {
cerr << get_fileline() << ": error: signal and named event in '"
<< scope->fullname() << "' have the same name '" << name_
<< "'." << endl;
des->errors += 1;
}
if (port_set_ || net_set_) {
long pmsb = 0, plsb = 0, nmsb = 0, nlsb = 0;
bool bad_lsb = false, bad_msb = false;
/* If they exist get the port definition MSB and LSB */
if (port_set_ && port_msb_ != 0) {
probe_expr_width(des, scope, port_msb_);
/* We do not currently support constant user function. */
need_constant_expr = true;
NetExpr*texpr = elab_and_eval(des, scope, port_msb_, -1);
need_constant_expr = false;
if (! eval_as_long(pmsb, texpr)) {
cerr << port_msb_->get_fileline() << ": error: "
"Range expressions must be constant." << endl;
cerr << port_msb_->get_fileline() << " : "
"This MSB expression violates the rule: "
<< *port_msb_ << endl;
"Unable to evaluate MSB constant expression ``"
<< *port_msb_ << "''." << endl;
des->errors += 1;
bad_msb = true;
return 0;
}
delete texpr;
probe_expr_width(des, scope, port_lsb_);
/* We do not currently support constant user function. */
need_constant_expr = true;
texpr = elab_and_eval(des, scope, port_lsb_, -1);
need_constant_expr = false;
if (! eval_as_long(plsb, texpr)) {
cerr << port_lsb_->get_fileline() << ": error: "
"Range expressions must be constant." << endl;
cerr << port_lsb_->get_fileline() << " : "
"This LSB expression violates the rule: "
<< *port_lsb_ << endl;
"Unable to evaluate LSB constant expression ``"
<< *port_lsb_ << "''." << endl;
des->errors += 1;
bad_lsb = true;
return 0;
}
delete texpr;
nmsb = pmsb;
nlsb = plsb;
/* An implicit port can have a range so note that here. */
is_implicit_scalar = false;
}
if (!port_set_) assert(port_msb_ == 0 && port_lsb_ == 0);
if (port_msb_ == 0) assert(port_lsb_ == 0);
if (port_lsb_ == 0) assert(port_msb_ == 0);
/* If they exist get the net/etc. definition MSB and LSB */
if (net_set_ && net_msb_ != 0 && !bad_msb && !bad_lsb) {
probe_expr_width(des, scope, net_msb_);
/* We do not currently support constant user function. */
need_constant_expr = true;
if (net_set_ && net_msb_ != 0) {
NetExpr*texpr = elab_and_eval(des, scope, net_msb_, -1);
need_constant_expr = false;
if (! eval_as_long(nmsb, texpr)) {
cerr << net_msb_->get_fileline() << ": error: "
"Range expressions must be constant." << endl;
cerr << net_msb_->get_fileline() << " : "
"This MSB expression violates the rule: "
<< *net_msb_ << endl;
"Unable to evaluate MSB constant expression ``"
<< *net_msb_ << "''." << endl;
des->errors += 1;
bad_msb = true;
return 0;
}
delete texpr;
probe_expr_width(des, scope, net_lsb_);
/* We do not currently support constant user function. */
need_constant_expr = true;
texpr = elab_and_eval(des, scope, net_lsb_, -1);
need_constant_expr = false;
if (! eval_as_long(nlsb, texpr)) {
cerr << net_lsb_->get_fileline() << ": error: "
"Range expressions must be constant." << endl;
cerr << net_lsb_->get_fileline() << " : "
"This LSB expression violates the rule: "
<< *net_lsb_ << endl;
"Unable to evaluate LSB constant expression ``"
<< *net_lsb_ << "''." << endl;
des->errors += 1;
bad_lsb = true;
return 0;
}
delete texpr;
@@ -1052,10 +898,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
}
}
/* Attempt to recover from errors. */
if (bad_lsb) nlsb = 0;
if (bad_msb) nmsb = nlsb;
lsb = nlsb;
msb = nmsb;
if (nmsb > nlsb)
@@ -1081,13 +923,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
if (lidx_ || ridx_) {
assert(lidx_ && ridx_);
probe_expr_width(des, scope, lidx_);
probe_expr_width(des, scope, ridx_);
need_constant_expr = true;
NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);
need_constant_expr = false;
if ((lexp == 0) || (rexp == 0)) {
cerr << get_fileline() << ": internal error: There is "
@@ -1105,18 +942,16 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
delete lexp;
if (!const_flag) {
cerr << get_fileline() << ": error: The indices "
cerr << get_fileline() << ": internal error: The indices "
<< "are not constant for array ``"
<< name_ << "''." << endl;
des->errors += 1;
/* Attempt to recover from error, */
array_s0 = 0;
array_e0 = 0;
} else {
array_s0 = lval.as_long();
array_e0 = rval.as_long();
}
return 0;
}
array_dimensions = 1;
array_s0 = lval.as_long();
array_e0 = rval.as_long();
}
/* If the net type is supply0 or supply1, replace it
@@ -1154,15 +989,9 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
}
if (debug_elaborate) {
cerr << get_fileline() << ": debug: Create signal " << wtype;
if (!get_scalar()) {
cerr << " ["<<msb<<":"<<lsb<<"]";
}
cerr << " " << name_;
if (array_dimensions > 0) {
cerr << " [" << array_s0 << ":" << array_e0 << "]" << endl;
}
cerr << " in scope " << scope_path(scope) << endl;
cerr << get_fileline() << ": debug: Create signal "
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name_
<< " in scope " << scope_path(scope) << endl;
}
@@ -1170,8 +999,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
? new NetNet(scope, name_, wtype, msb, lsb, array_s0, array_e0)
: new NetNet(scope, name_, wtype, msb, lsb);
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
ivl_variable_type_t use_data_type = data_type_;
if (use_data_type == IVL_VT_NO_TYPE) {
use_data_type = IVL_VT_LOGIC;
@@ -1188,12 +1015,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
sig->port_type(port_type_);
sig->set_signed(get_signed());
sig->set_isint(get_isint());
if (is_implicit_scalar) sig->set_scalar(true);
else sig->set_scalar(get_scalar());
if (ivl_discipline_t dis = get_discipline()) {
sig->set_discipline(dis);
}
if (pull)
connect(sig->pin(0), pull->pin(0));
-26
View File
@@ -1,26 +0,0 @@
/*
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "AStatement.h"
# include <cstdlib>
# include <iostream>
+801 -1530
View File
File diff suppressed because it is too large Load Diff
-74
View File
@@ -1,74 +0,0 @@
/*
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "AStatement.h"
# include "netlist.h"
# include "netmisc.h"
# include "util.h"
# include <typeinfo>
NetProc* AContrib::elaborate(Design*des, NetScope*scope) const
{
probe_expr_width(des, scope, lval_);
probe_expr_width(des, scope, rval_);
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);
st->set_line(*this);
return st;
}
bool AProcess::elaborate(Design*des, NetScope*scope) const
{
NetProc*estatement = statement_->elaborate(des, scope);
if (estatement == 0)
return false;
NetAnalogTop*top = new NetAnalogTop(scope, type_, estatement);
// Evaluate the attributes for this process, if there
// are any. These attributes are to be attached to the
// NetProcTop object.
struct attrib_list_t*attrib_list = 0;
unsigned attrib_list_n = 0;
attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope);
for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1)
top->attribute(attrib_list[adx].key,
attrib_list[adx].val);
delete[]attrib_list;
top->set_line(*this);
des->add_process(top);
return true;
}
+32 -60
View File
@@ -72,16 +72,6 @@ bool NetCaseCmp::emit_node(struct target_t*tgt) const
return true;
}
bool NetCastInt::emit_node(struct target_t*tgt) const
{
return tgt->lpm_cast_int(this);
}
bool NetCastReal::emit_node(struct target_t*tgt) const
{
return tgt->lpm_cast_real(this);
}
bool NetCLShift::emit_node(struct target_t*tgt) const
{
tgt->lpm_clshift(this);
@@ -190,26 +180,16 @@ bool NetProcTop::emit(struct target_t*tgt) const
return tgt->process(this);
}
bool NetAnalogTop::emit(struct target_t*tgt) const
{
return tgt->process(this);
}
bool NetProc::emit_proc(struct target_t*tgt) const
{
cerr << "EMIT: Proc type? " << typeid(*this).name() << endl;
return false;
}
bool NetAlloc::emit_proc(struct target_t*tgt) const
{
tgt->proc_alloc(this);
return true;
}
bool NetAssign::emit_proc(struct target_t*tgt) const
{
return tgt->proc_assign(this);
tgt->proc_assign(this);
return true;
}
bool NetAssignNB::emit_proc(struct target_t*tgt) const
@@ -239,11 +219,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);
@@ -265,12 +240,6 @@ bool NetForever::emit_proc(struct target_t*tgt) const
return true;
}
bool NetFree::emit_proc(struct target_t*tgt) const
{
tgt->proc_free(this);
return true;
}
bool NetPDelay::emit_proc(struct target_t*tgt) const
{
return tgt->proc_delay(this);
@@ -383,20 +352,23 @@ void NetScope::emit_scope(struct target_t*tgt) const
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 ++) {
tgt->signal(cur->second);
}
if (signals_) {
NetNet*cur = signals_->sig_next_;
do {
tgt->signal(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
// Run the signals again, but this time to connect the
// delay paths. This is done as a second pass because
// the paths reference other signals that may be later
// 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 ++) {
tgt->signal_paths(cur->second);
/* Run the signals again, but this time to connect the
delay paths. This is done as a second pass because
the paths reference other signals that may be later
in the list. We can do it here becase delay paths are
always connected within the scope. */
cur = signals_->sig_next_;
do {
tgt->signal_paths(cur);
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
}
}
@@ -455,11 +427,6 @@ 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();
@@ -471,8 +438,6 @@ int Design::emit(struct target_t*tgt) const
bool proc_rc = true;
for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
proc_rc &= idx->emit(tgt);
for (const NetAnalogTop*idx = aprocs_ ; idx ; idx = idx->next_)
proc_rc &= idx->emit(tgt);
rc = tgt->end_design(this);
@@ -482,17 +447,10 @@ int Design::emit(struct target_t*tgt) const
return -2;
if (proc_rc == false)
return -3;
if (branches_rc == false)
return -4;
return rc;
}
void NetEAccess::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_access_func(this);
}
void NetEBinary::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_binary(this);
@@ -568,3 +526,17 @@ void NetEUnary::expr_scan(struct expr_scan_t*tgt) const
{
tgt->expr_unary(this);
}
int emit(const Design*des, const char*type)
{
for (unsigned idx = 0 ; target_table[idx] ; idx += 1) {
const struct target*tgt = target_table[idx];
if (strcmp(tgt->name, type) == 0)
return des->emit(tgt->meth);
}
cerr << "error: Code generator type " << type
<< " not found." << endl;
return -1;
}
+1 -1
View File
@@ -185,7 +185,7 @@ verinum* PEIdent::eval_const(Design*des, NetScope*scope) const
return new verinum(scope->genvar_tmp_val);
}
symbol_search(this, des, scope, path_, net, expr, eve);
symbol_search(des, scope, path_, net, expr, eve);
if (expr == 0)
return 0;
+47 -12
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
@@ -16,13 +16,16 @@
* along with this program; if not, write to the Free Software
* 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
@@ -50,19 +53,14 @@ attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
/* If the attribute value is given in the source, then
evaluate it as a constant. If the value is not
given, then assume the value is 1. */
verinum*tmp = 0;
if (exp) {
verinum*tmp;
if (exp)
tmp = exp->eval_const(des, scope);
if (tmp == 0) {
cerr << exp->get_fileline() << ": error: ``"
<< *exp << "'' is not a constant expression."
<< endl;
des->errors += 1;
}
}
if (tmp == 0)
else
tmp = new verinum(1);
if (tmp == 0)
cerr << "internal error: no result for " << *exp << endl;
assert(tmp);
table[idx].val = *tmp;
@@ -72,3 +70,40 @@ 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.
*
*/
+142 -535
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2010 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
@@ -22,8 +22,6 @@
# include <iostream>
# include <cstdlib>
# include <cstring>
# include <cmath>
# include "netlist.h"
# include "ivl_assert.h"
@@ -129,30 +127,10 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
lc = se? dynamic_cast<NetEConst*>(se->right_) : 0;
if (lc != 0 && rc != 0) {
ivl_assert(*this, se != 0);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: "
<< "Partially evaluate " << *this
<< " using (a+2)-1 --> (a+1) transform." << endl;
}
assert(se != 0);
verinum lval = lc->value();
verinum rval = rc->value();
if (lval.len() < expr_width())
lval = pad_to_width(lval, expr_width());
if (rval.len() < expr_width())
rval = pad_to_width(rval, expr_width());
if (se->expr_width() > this->expr_width()) {
cerr << get_fileline() << ": internal error: "
<< "expr_width()=" << expr_width()
<< ", sub expr_width()=" << se->expr_width()
<< ", sub expression=" << *se << endl;
}
ivl_assert(*this, se->expr_width() <= this->expr_width());
verinum val;
if (op_ == se->op_) {
/* (a + lval) + rval --> a + (rval+lval) */
@@ -164,15 +142,6 @@ NetExpr* NetEBAdd::eval_tree(int prune_to_width)
val = rval - lval;
}
// Since we padded the operands above to be the minimum
// width, the val should also be at least expr_width().
ivl_assert(*this, val.len() >= expr_width());
if (val.len() > expr_width()) {
verinum tmp (val, expr_width());
tmp.has_sign(val.has_sign());
val = tmp;
}
NetEConst*tmp = new NetEConst(val);
left_ = se->left_->dup_expr();
delete se;
@@ -369,40 +338,47 @@ NetEConst* NetEBComp::eval_leeq_real_(NetExpr*le, NetExpr*ri, bool eq_flag)
switch (le->expr_type()) {
case IVL_VT_REAL:
rtmp = dynamic_cast<NetECReal*> (le);
if (rtmp == 0) return 0;
if (rtmp == 0)
return 0;
lv = rtmp->value().as_double();
break;
case IVL_VT_LOGIC:
case IVL_VT_BOOL:
vtmp = dynamic_cast<NetEConst*> (le);
if (vtmp == 0) return 0;
lv = vtmp->value().as_double();
if (vtmp == 0)
return 0;
lv = vtmp->value().as_long();
break;
default:
lv = 0.0;
cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << le->expr_type() << endl;
assert(0);
}
switch (ri->expr_type()) {
case IVL_VT_REAL:
rtmp = dynamic_cast<NetECReal*> (ri);
if (rtmp == 0) return 0;
if (rtmp == 0)
return 0;
rv = rtmp->value().as_double();
break;
case IVL_VT_LOGIC:
case IVL_VT_BOOL:
vtmp = dynamic_cast<NetEConst*> (ri);
if (vtmp == 0) return 0;
rv = vtmp->value().as_double();
if (vtmp == 0)
return 0;
rv = vtmp->value().as_long();
break;
default:
rv = 0.0;
cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << ri->expr_type() << endl;
assert(0);
@@ -503,6 +479,19 @@ NetEConst* NetEBComp::eval_gt_()
return tmp;
}
/* Compare with a real value. Do it as double precision. */
if (right_->expr_type() == IVL_VT_REAL) {
NetECReal*tmp = dynamic_cast<NetECReal*>(right_);
if (tmp == 0)
return 0;
double rr = tmp->value().as_double();
double ll = lv.has_sign()? lv.as_long() : lv.as_ulong();
verinum result ((ll > rr)? verinum::V1 : verinum::V0, 1, true);
return new NetEConst(result);
}
/* Now go on to the normal test of the values. */
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
@@ -541,6 +530,19 @@ NetEConst* NetEBComp::eval_gteq_()
return tmp;
}
/* Compare with a real value. Do it as double precision. */
if (right_->expr_type() == IVL_VT_REAL) {
NetECReal*tmp = dynamic_cast<NetECReal*>(right_);
if (tmp == 0)
return 0;
double rr = tmp->value().as_double();
double ll = lv.has_sign()? lv.as_long() : lv.as_ulong();
verinum result ((ll >= rr)? verinum::V1 : verinum::V0, 1, true);
return new NetEConst(result);
}
/* Now go on to the normal test of the values. */
NetEConst*r = dynamic_cast<NetEConst*>(right_);
if (r == 0) return 0;
@@ -559,75 +561,8 @@ NetEConst* NetEBComp::eval_gteq_()
}
}
/*
* Evaluate <A>==<B> or <A>!=<B>. The equality operator checks all the
* bits and returns true(false) if there are any bits in the vector
* that are defined (0 or 1) and different. If all the defined bits
* are equal, but there are are x/z bits, then the situation is
* ambiguous so the result is x.
*/
NetEConst* NetEBComp::eval_eqeq_real_(NetExpr*le, NetExpr*ri, bool ne_flag)
{
NetEConst*vtmp;
NetECReal*rtmp;
double lv, rv;
switch (le->expr_type()) {
case IVL_VT_REAL:
rtmp = dynamic_cast<NetECReal*> (le);
if (rtmp == 0) return 0;
lv = rtmp->value().as_double();
break;
case IVL_VT_LOGIC:
case IVL_VT_BOOL:
vtmp = dynamic_cast<NetEConst*> (le);
if (vtmp == 0) return 0;
lv = vtmp->value().as_double();
break;
default:
lv = 0.0;
cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << le->expr_type() << endl;
assert(0);
}
switch (ri->expr_type()) {
case IVL_VT_REAL:
rtmp = dynamic_cast<NetECReal*> (ri);
if (rtmp == 0) return 0;
rv = rtmp->value().as_double();
break;
case IVL_VT_LOGIC:
case IVL_VT_BOOL:
vtmp = dynamic_cast<NetEConst*> (ri);
if (vtmp == 0) return 0;
rv = vtmp->value().as_double();
break;
default:
rv = 0.0;
cerr << get_fileline() << ": internal error: "
<< "Unexpected expression type? " << ri->expr_type() << endl;
assert(0);
}
verinum result(((lv == rv) ^ ne_flag) ? verinum::V1 : verinum::V0, 1);
vtmp = new NetEConst(result);
vtmp->set_line(*this);
return vtmp;
}
NetEConst* NetEBComp::eval_eqeq_(bool ne_flag)
{
if (right_->expr_type() == IVL_VT_REAL)
return eval_eqeq_real_(right_, left_, ne_flag);
if (left_->expr_type() == IVL_VT_REAL)
return eval_eqeq_real_(right_, left_, ne_flag);
NetEConst*l = dynamic_cast<NetEConst*>(left_);
if (l == 0) return 0;
NetEConst*r = dynamic_cast<NetEConst*>(right_);
@@ -646,14 +581,11 @@ NetEConst* NetEBComp::eval_eqeq_(bool ne_flag)
for (unsigned idx = 0 ; idx < top ; idx += 1) {
bool x_bit_present = false;
switch (lv.get(idx)) {
case verinum::Vx:
case verinum::Vz:
res = verinum::Vx;
x_bit_present = true;
break;
default:
@@ -665,20 +597,17 @@ NetEConst* NetEBComp::eval_eqeq_(bool ne_flag)
case verinum::Vx:
case verinum::Vz:
res = verinum::Vx;
x_bit_present = true;
break;
default:
break;
}
if (x_bit_present)
continue;
if (rv.get(idx) != lv.get(idx)) {
res = ne_res;
if (res == verinum::Vx)
break;
}
if (rv.get(idx) != lv.get(idx))
res = ne_res;
}
if (res != verinum::Vx) {
@@ -822,32 +751,6 @@ NetEConst* NetEBComp::eval_tree(int prune_to_width)
}
}
NetExpr* NetEBDiv::eval_tree_real_()
{
verireal lval;
verireal rval;
bool flag = get_real_arguments_(lval, rval);
if (! flag) return 0;
NetECReal*res = 0;
switch (op_) {
case '/':
res = new NetECReal(lval / rval);
break;
case '%':
// Since this could/may be called early we don't want to
// leak functionality.
if (!gn_icarus_misc_flag) return 0;
res = new NetECReal(lval % rval);
break;
}
ivl_assert(*this, res);
res->set_line(*this);
return res;
}
/*
* The NetEBDiv operator includes the / and % operators. First evaluate
* the sub-expressions, then perform the required operation.
@@ -857,31 +760,75 @@ NetExpr* NetEBDiv::eval_tree(int prune_to_width)
eval_expr(left_);
eval_expr(right_);
if (expr_type() == IVL_VT_REAL) return eval_tree_real_();
if (expr_type() == IVL_VT_REAL) {
NetECReal*lc = dynamic_cast<NetECReal*>(left_);
if (lc == 0) return 0;
assert(expr_type() == IVL_VT_LOGIC);
verireal lval = lc->value();
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (lc == 0 || rc == 0) return 0;
if (NetECReal*rc = dynamic_cast<NetECReal*>(right_)) {
NetECReal*tmp = 0;
verireal rval = rc->value();
// Make sure the expression is evaluated at the
// expression width.
verinum lval = pad_to_width(lc->value(), expr_width());
verinum rval = pad_to_width(rc->value(), expr_width());
switch (op_) {
case '/':
tmp = new NetECReal(lval / rval);
break;
NetExpr*tmp = 0;
switch (op_) {
case '/':
tmp = new NetEConst(lval / rval);
break;
case '%':
tmp = new NetEConst(lval % rval);
break;
case '%':
tmp = new NetECReal(lval % rval);
}
assert(tmp);
tmp->set_line(*this);
return tmp;
} else if (NetEConst*rc = dynamic_cast<NetEConst*>(right_)) {
NetECReal*tmp = 0;
verinum rval = rc->value();
switch (op_) {
case '/':
tmp = new NetECReal(lval / rval);
break;
case '%':
tmp = new NetECReal(lval % rval);
}
assert(tmp);
tmp->set_line(*this);
return tmp;
}
} else {
assert(expr_type() == IVL_VT_LOGIC);
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
if (rc == 0) return 0;
verinum lval = lc->value();
verinum rval = rc->value();
NetExpr*tmp = 0;
switch (op_) {
case '/':
tmp = new NetEConst(lval / rval);
break;
case '%':
tmp = new NetEConst(lval % rval);
break;
}
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
}
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;
return 0;
}
NetEConst* NetEBLogic::eval_tree(int prune_to_width)
@@ -960,6 +907,7 @@ NetExpr* NetEBMult::eval_tree_real_()
bool flag = get_real_arguments_(lval, rval);
if (! flag) return 0;
NetECReal*res = new NetECReal(lval * rval);
res->set_line(*this);
return res;
@@ -970,7 +918,8 @@ NetExpr* NetEBMult::eval_tree(int prune_to_width)
eval_expr(left_);
eval_expr(right_);
if (expr_type() == IVL_VT_REAL) return eval_tree_real_();
if (expr_type() == IVL_VT_REAL)
return eval_tree_real_();
assert(expr_type() == IVL_VT_LOGIC);
@@ -1000,11 +949,6 @@ NetExpr* NetEBPow::eval_tree_real_()
NetECReal*res = new NetECReal( pow(lval,rval) );
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluate (real) "
<< lval << " ** " << rval << " --> " << *res << endl;
return res;
}
@@ -1025,14 +969,7 @@ NetExpr* NetEBPow::eval_tree(int prune_to_width)
verinum lval = lc->value();
verinum rval = rc->value();
NetEConst*res = new NetEConst( pow(lval,rval) );
res->set_line(*this);
if (debug_eval_tree)
cerr << get_fileline() << ": debug: Evaluate "
<< lval << " ** " << rval << " --> " << *res << endl;
return res;
return new NetEConst( pow(lval,rval) );
}
/*
@@ -1177,6 +1114,16 @@ NetEConst* NetEConcat::eval_tree(int prune_to_width)
if (local_errors > 0) return 0;
// Handle the special case that the repeat expression is
// zero. In this case, just return a 0 value with the expected
// width.
if (repeat_val == 0) {
verinum val (verinum::V0, expr_width());
NetEConst*res = new NetEConst(val);
res->set_width(val.len());
return res;
}
// At this point, the "gap" is the width of a single repeat of
// the concatenation. The total width of the result is the gap
// times the repeat count.
@@ -1206,11 +1153,6 @@ NetEConst* NetEConcat::eval_tree(int prune_to_width)
val = verinum(val.as_string());
}
// Normally, concatenations are unsigned. However, the
// $signed() function works by marking the expression as
// signed, so we really have to check.
val.has_sign( this->has_sign() );
NetEConst*res = new NetEConst(val);
res->set_width(val.len());
return res;
@@ -1228,52 +1170,38 @@ NetExpr* NetEParam::eval_tree(int prune_to_width)
<< *this << endl;
}
if (solving()) {
cerr << get_fileline() << ": warning: Recursive parameter "
"reference found involving " << *this << "." << endl;
return 0;
}
assert(scope_);
perm_string name = (*reference_).first;
const NetExpr*expr = (*reference_).second.expr;
// Since constant user functions are not supported we can get
// parameters/localparams that are not defined. For now generate
// an appropriate error message.
if (expr == NULL) {
cerr << get_fileline() << ": internal error: parameter/localparam "
<< *this << " cannot be evaluated." << endl;
return 0;
}
ivl_assert(*this, expr);
NetExpr*nexpr = expr->dup_expr();
assert(nexpr);
// If the parameter that I refer to is already evaluated, then
// return the constant value.
if (const NetEConst*tmp = dynamic_cast<const NetEConst*>(expr)) {
if (NetEConst*tmp = dynamic_cast<NetEConst*>(nexpr)) {
verinum val = tmp->value();
NetEConstParam*ptmp = new NetEConstParam(scope_, name, val);
ptmp->set_line(*this);
delete nexpr;
return ptmp;
}
if (const NetECReal*tmp = dynamic_cast<const NetECReal*>(expr)) {
if (NetECReal*tmp = dynamic_cast<NetECReal*>(nexpr)) {
verireal val = tmp->value();
NetECRealParam*ptmp = new NetECRealParam(scope_, name, val);
ptmp->set_line(*this);
delete nexpr;
return ptmp;
}
// Try to evaluate the expression. If I cannot, then the
// expression is not a constant expression and I fail here.
solving(true);
NetExpr*nexpr = expr->dup_expr();
assert(nexpr);
NetExpr*res = nexpr->eval_tree();
solving(false);
if (res == 0) {
cerr << get_fileline() << ": internal error: Unable to evaluate ";
if (expr_type() == IVL_VT_REAL) cerr << "real ";
cerr << "parameter " << name << " expression: "
cerr << get_fileline() << ": internal error: Unable to evaluate "
<< "parameter " << name << " expression: "
<< *nexpr << endl;
delete nexpr;
return 0;
@@ -1411,7 +1339,7 @@ NetExpr* NetETernary::eval_tree(int prune_to_width)
case C_0:
eval_expr(false_val_);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluate ternary with "
<< "constant condition value: ";
print_ternary_cond(cond_);
@@ -1482,9 +1410,7 @@ NetExpr* NetETernary::eval_tree(int prune_to_width)
<< "constant condition value: ";
print_ternary_cond(cond_);
cerr << get_fileline() << ": : Blending real cases "
<< "true=" << tv.as_double()
<< ", false=" << fv.as_double()
<< ", to get " << val << endl;
<< "to get " << val << endl;
}
NetECReal*rc = new NetECReal(val);
@@ -1611,7 +1537,6 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
verinum val = rval->value();
verinum::V res;
bool invert = false;
switch (op_) {
@@ -1640,8 +1565,6 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
break;
}
case 'A':
invert = true;
case '&': {
res = verinum::V1;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
@@ -1649,8 +1572,6 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
break;
}
case 'N':
invert = true;
case '|': {
res = verinum::V0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
@@ -1658,8 +1579,6 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
break;
}
case 'X':
invert = true;
case '^': {
/* Reduction XOR. */
unsigned ones = 0, unknown = 0;
@@ -1675,328 +1594,16 @@ NetEConst* NetEUReduce::eval_tree(int prune_to_width)
break;
}
if (unknown) res = verinum::Vx;
else if (ones%2) res = verinum::V1;
else res = verinum::V0;
break;
if (unknown)
return new NetEConst(verinum(verinum::Vx,1,true));
if (ones%2)
return new NetEConst(verinum(verinum::V1,1,true));
return new NetEConst(verinum(verinum::V0,1,true));
}
default:
return 0;
}
if (invert) res = ~res;
return new NetEConst(verinum(res, 1));
}
NetExpr* evaluate_clog2(NetExpr*&arg_)
{
eval_expr(arg_);
NetEConst*tmpi = dynamic_cast<NetEConst *>(arg_);
NetECReal*tmpr = dynamic_cast<NetECReal *>(arg_);
if (tmpi || tmpr) {
verinum arg;
if (tmpi) {
arg = tmpi->value();
} else {
arg = verinum(tmpr->value().as_double(), true);
}
/* If we have an x in the verinum we return 'bx. */
if (!arg.is_defined()) {
verinum tmp (verinum::Vx, integer_width);
tmp.has_sign(true);
NetEConst*rtn = new NetEConst(tmp);
return rtn;
}
bool is_neg = false;
uint64_t res = 0;
if (arg.is_negative()) {
is_neg = true;
// If the length is not defined, then work with
// the trimmed version of the number.
if (! arg.has_len())
arg = trim_vnum(arg);
}
arg.has_sign(false); // $unsigned()
if (!arg.is_zero()) {
arg = arg - verinum((uint64_t)1, 1);
while (!arg.is_zero()) {
res += 1;
arg = arg >> 1;
}
}
if (is_neg && res < integer_width)
res = integer_width;
verinum tmp (res, integer_width);
tmp.has_sign(true);
NetEConst*rtn = new NetEConst(tmp);
return rtn;
}
return 0;
}
NetExpr* evaluate_math_one_arg(NetExpr*&arg_, const char*name)
{
eval_expr(arg_);
NetEConst*tmpi = dynamic_cast<NetEConst *>(arg_);
NetECReal*tmpr = dynamic_cast<NetECReal *>(arg_);
if (tmpi || tmpr) {
double arg;
if (tmpi) {
arg = tmpi->value().as_double();
} else {
arg = tmpr->value().as_double();
}
if (strcmp(name, "$ln") == 0) {
return new NetECReal(verireal(log(arg)));
} else if (strcmp(name, "$log10") == 0) {
return new NetECReal(verireal(log10(arg)));
} else if (strcmp(name, "$exp") == 0) {
return new NetECReal(verireal(exp(arg)));
} else if (strcmp(name, "$sqrt") == 0) {
return new NetECReal(verireal(sqrt(arg)));
} else if (strcmp(name, "$floor") == 0) {
return new NetECReal(verireal(floor(arg)));
} else if (strcmp(name, "$ceil") == 0) {
return new NetECReal(verireal(ceil(arg)));
} else if (strcmp(name, "$sin") == 0) {
return new NetECReal(verireal(sin(arg)));
} else if (strcmp(name, "$cos") == 0) {
return new NetECReal(verireal(cos(arg)));
} else if (strcmp(name, "$tan") == 0) {
return new NetECReal(verireal(tan(arg)));
} else if (strcmp(name, "$asin") == 0) {
return new NetECReal(verireal(asin(arg)));
} else if (strcmp(name, "$acos") == 0) {
return new NetECReal(verireal(acos(arg)));
} else if (strcmp(name, "$atan") == 0) {
return new NetECReal(verireal(atan(arg)));
} else if (strcmp(name, "$sinh") == 0) {
return new NetECReal(verireal(sinh(arg)));
} else if (strcmp(name, "$cosh") == 0) {
return new NetECReal(verireal(cosh(arg)));
} else if (strcmp(name, "$tanh") == 0) {
return new NetECReal(verireal(tanh(arg)));
} else if (strcmp(name, "$asinh") == 0) {
return new NetECReal(verireal(asinh(arg)));
} else if (strcmp(name, "$acosh") == 0) {
return new NetECReal(verireal(acosh(arg)));
} else if (strcmp(name, "$atanh") == 0) {
return new NetECReal(verireal(atanh(arg)));
}
}
return 0;
}
NetExpr* evaluate_math_two_args(NetExpr*&arg0_, NetExpr*&arg1_, const char*name)
{
eval_expr(arg0_);
eval_expr(arg1_);
NetEConst*tmpi0 = dynamic_cast<NetEConst *>(arg0_);
NetECReal*tmpr0 = dynamic_cast<NetECReal *>(arg0_);
NetEConst*tmpi1 = dynamic_cast<NetEConst *>(arg1_);
NetECReal*tmpr1 = dynamic_cast<NetECReal *>(arg1_);
if ((tmpi0 || tmpr0) && (tmpi1 || tmpr1)) {
double arg0, arg1;
if (tmpi0) {
arg0 = tmpi0->value().as_double();
} else {
arg0 = tmpr0->value().as_double();
}
if (tmpi1) {
arg1 = tmpi1->value().as_double();
} else {
arg1 = tmpr1->value().as_double();
}
if (strcmp(name, "$pow") == 0) {
return new NetECReal(verireal(pow(arg0, arg1)));
} else if (strcmp(name, "$atan2") == 0) {
return new NetECReal(verireal(atan2(arg0, arg1)));
} else if (strcmp(name, "$hypot") == 0) {
return new NetECReal(verireal(hypot(arg0, arg1)));
}
}
return 0;
}
NetExpr* evaluate_abs(NetExpr*&arg_)
{
eval_expr(arg_);
NetEConst*tmpi = dynamic_cast<NetEConst *>(arg_);
if (tmpi) {
verinum arg = tmpi->value();
if (arg.is_negative()) {
arg = v_not(arg) + verinum(1);
}
return new NetEConst(arg);
}
NetECReal*tmpr = dynamic_cast<NetECReal *>(arg_);
if (tmpr) {
double arg = tmpr->value().as_double();
return new NetECReal(verireal(fabs(arg)));
}
return 0;
}
NetExpr* evaluate_min_max(NetExpr*&arg0_, NetExpr*&arg1_, const char*name)
{
eval_expr(arg0_);
eval_expr(arg1_);
NetEConst*tmpi0 = dynamic_cast<NetEConst *>(arg0_);
NetECReal*tmpr0 = dynamic_cast<NetECReal *>(arg0_);
NetEConst*tmpi1 = dynamic_cast<NetEConst *>(arg1_);
NetECReal*tmpr1 = dynamic_cast<NetECReal *>(arg1_);
if (tmpi0 && tmpi1) {
verinum arg0 = tmpi0->value();
verinum arg1 = tmpi1->value();
if (strcmp(name, "$min") == 0) {
return new NetEConst( arg0 < arg1 ? arg0 : arg1);
} else if (strcmp(name, "$max") == 0) {
return new NetEConst( arg0 < arg1 ? arg1 : arg0);
}
}
if ((tmpi0 || tmpr0) && (tmpi1 || tmpr1)) {
double arg0, arg1;
if (tmpi0) {
arg0 = tmpi0->value().as_double();
} else {
arg0 = tmpr0->value().as_double();
}
if (tmpi1) {
arg1 = tmpi1->value().as_double();
} else {
arg1 = tmpr1->value().as_double();
}
if (strcmp(name, "$min") == 0) {
return new NetECReal(verireal(arg0 < arg1 ? arg0 : arg1));
} else if (strcmp(name, "$max") == 0) {
return new NetECReal(verireal(arg0 < arg1 ? arg1 : arg0));
}
}
return 0;
}
NetExpr* NetESFunc::eval_tree(int prune_to_width)
{
/* If we are not targeting at least Verilog-2005, Verilog-AMS
* or using the Icarus misc flag then we do not support these
* functions as constant. */
if (generation_flag < GN_VER2005 &&
!gn_icarus_misc_flag && !gn_verilog_ams_flag) {
return 0;
}
const char*nm = name();
NetExpr*rtn = 0;
/* Only $clog2 and the builtin mathematical functions can
* be a constant system function. */
if (strcmp(nm, "$clog2") == 0 ||
strcmp(nm, "$ln") == 0 ||
strcmp(nm, "$log10") == 0 ||
strcmp(nm, "$exp") == 0 ||
strcmp(nm, "$sqrt") == 0 ||
strcmp(nm, "$floor") == 0 ||
strcmp(nm, "$ceil") == 0 ||
strcmp(nm, "$sin") == 0 ||
strcmp(nm, "$cos") == 0 ||
strcmp(nm, "$tan") == 0 ||
strcmp(nm, "$asin") == 0 ||
strcmp(nm, "$acos") == 0 ||
strcmp(nm, "$atan") == 0 ||
strcmp(nm, "$sinh") == 0 ||
strcmp(nm, "$cosh") == 0 ||
strcmp(nm, "$tanh") == 0 ||
strcmp(nm, "$asinh") == 0 ||
strcmp(nm, "$acosh") == 0 ||
strcmp(nm, "$atanh") == 0) {
if (nparms() != 1 || parm(0) == 0) {
cerr << get_fileline() << ": error: " << nm
<< " takes a single argument." << endl;
return 0;
}
NetExpr*arg = parm(0)->dup_expr();
if (strcmp(nm, "$clog2") == 0) {
rtn = evaluate_clog2(arg);
} else {
rtn = evaluate_math_one_arg(arg, nm);
}
delete arg;
}
if (strcmp(nm, "$pow") == 0 ||
strcmp(nm, "$atan2") == 0 ||
strcmp(nm, "$hypot") == 0) {
if (nparms() != 2 || parm(0) == 0 || parm(1) == 0) {
cerr << get_fileline() << ": error: " << nm
<< " takes two arguments." << endl;
return 0;
}
NetExpr*arg0 = parm(0)->dup_expr();
NetExpr*arg1 = parm(1)->dup_expr();
rtn = evaluate_math_two_args(arg0, arg1, nm);
delete arg0;
delete arg1;
}
if ((gn_icarus_misc_flag || gn_verilog_ams_flag) &&
(strcmp(nm, "$abs") == 0)) {
if (nparms() != 1 || parm(0) == 0) {
cerr << get_fileline() << ": error: " << nm
<< " takes a single argument." << endl;
return 0;
}
NetExpr*arg = parm(0)->dup_expr();
rtn = evaluate_abs(arg);
delete arg;
}
if ((gn_icarus_misc_flag || gn_verilog_ams_flag) &&
(strcmp(nm, "$min") == 0 || strcmp(nm, "$max") == 0)) {
if (nparms() != 2 || parm(0) == 0 || parm(1) == 0) {
cerr << get_fileline() << ": error: " << nm
<< " takes two arguments." << endl;
return 0;
}
NetExpr*arg0 = parm(0)->dup_expr();
NetExpr*arg1 = parm(1)->dup_expr();
rtn = evaluate_min_max(arg0, arg1, nm);
delete arg0;
delete arg1;
}
if (rtn != 0) {
rtn->set_line(*this);
if (debug_eval_tree) {
cerr << get_fileline() << ": debug: Evaluate constant "
<< nm << "." << endl;
}
}
return rtn;
}
NetExpr* NetEUFunc::eval_tree(int prune_to_width)
{
if (need_constant_expr) {
cerr << get_fileline() << ": sorry: constant user "
"functions are not currently supported: "
<< func_->basename() << "()." << endl;
}
return 0;
}
+3
View File
@@ -0,0 +1,3 @@
,*
hello_vpi.vpi
show_vcd.vcd
+1 -1
View File
@@ -154,7 +154,7 @@
*
* The POST_MAP compiler directive causes the GSR manipulations
* included in the test bench to be compiled in, to simulate the chip
* startup. Other than that, the test bench runs the post-map design
* startup. Other then that, the test bench runs the post-map design
* the same way the pre-synthesis design works.
*
* Run this design with the command:
+187 -503
View File
File diff suppressed because it is too large Load Diff
+13 -5
View File
@@ -111,12 +111,20 @@ void NetScope::run_functor(Design*des, functor_t*fun)
// apply to signals. Each iteration, allow for the possibility
// that the current signal deletes itself.
if (signals_) {
unsigned count = 0;
NetNet*cur = signals_->sig_next_;
do {
count += 1;
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
signals_map_iter_t cur = signals_map_.begin();
while (cur != signals_map_.end()) {
signals_map_iter_t tmp = cur;
cur ++;
fun->signal(des, tmp->second);
cur = signals_->sig_next_;
for (unsigned idx = 0 ; idx < count ; idx += 1) {
NetNet*tmp = cur->sig_next_;
fun->signal(des, cur);
cur = tmp;
}
}
}
+62
View File
@@ -499,3 +499,65 @@ already seems to exist amongst VCD viewers in the wild, this behavior
seems to be acceptable according to the standard, is a better mirror
of 4-value behavior in the dead zone, and appears more user friendly
when viewed by reasonable viewers.
$Id: ieee1364-notes.txt,v 1.19 2007/04/18 02:36:13 steve Exp $
$Log: ieee1364-notes.txt,v $
Revision 1.19 2007/04/18 02:36:13 steve
Put to iverilog wiki for further notes.
Revision 1.18 2007/03/22 16:08:16 steve
Spelling fixes from Larry
Revision 1.17 2003/07/15 03:49:22 steve
Spelling fixes.
Revision 1.16 2003/04/14 03:40:21 steve
Make some effort to preserve bits while
operating on constant values.
Revision 1.15 2003/02/16 23:39:08 steve
NaN in dead zones of VCD dumps.
Revision 1.14 2003/02/06 17:51:36 steve
Edge of vectors notes.
Revision 1.13 2002/08/20 04:11:53 steve
Support parameters with defined ranges.
Revision 1.12 2002/06/11 03:34:33 steve
Spelling patch (Larry Doolittle)
Revision 1.11 2002/04/27 02:38:04 steve
Support selecting bits from parameters.
Revision 1.10 2002/03/31 01:54:13 steve
Notes about scheduling
Revision 1.9 2002/01/26 02:08:07 steve
Handle x in l-value of set/x
Revision 1.8 2001/08/01 05:17:31 steve
Accept empty port lists to module instantiation.
Revision 1.7 2001/02/17 05:27:31 steve
I allow function ports to have types.
Revision 1.6 2001/02/12 16:48:04 steve
Rant about bit widths.
Revision 1.5 2001/01/02 17:28:08 steve
Resolve repeat ambiguity in favor of loop.
Revision 1.4 2001/01/01 19:12:35 steve
repeat loops ambiguity.
Revision 1.3 2000/12/15 00:21:46 steve
rounding of time and x in primitives.
Revision 1.2 2000/11/19 22:03:04 steve
Integer parameter comments.
Revision 1.1 2000/07/23 18:06:31 steve
Document ieee1364 issues.
+11 -10
View File
@@ -1,15 +1,15 @@
.TH iverilog-vpi 1 "April 17th, 2009" "" "Version %M.%m.%n %E"
.TH iverilog-vpi 1 "$Date: 2004/10/04 01:10:53 $" Version "$Date: 2004/10/04 01:10:53 $"
.SH NAME
iverilog-vpi - Compile front end for VPI modules
.SH SYNOPSIS
.B iverilog-vpi
[\-\-name=\fIname\fP]
[--name=\fIname\fP]
\fIsourcefile\fP...
.SH DESCRIPTION
.PP
\fIiverilog\-vpi\fP is a tool to simplify the compilation of VPI
\fIiverilog-vpi\fP is a tool to simplify the compilation of VPI
modules for use with Icarus Verilog. It takes on the command line a
list of C or C++ source files, and generates as output a linked VPI
module. See the \fBvvp\fP(1) man page for a description of how the
@@ -20,7 +20,8 @@ first source file is named \fIfoo.c\fP, the output becomes
\fIfoo.vpi\fP.
.SH OPTIONS
\fIiverilog\-vpi\fP accepts the following options:
.l
\fIiverilog-vpi\fP accepts the following options:
.TP 8
.B -l\fIlibrary\fP
Include the named library in the link of the VPI module. This allows
@@ -53,7 +54,7 @@ These flags provide compile time information.
.SH "PC-ONLY OPTIONS"
The PC port of \fIiverilog\-vpi\fP includes two special flags needed to
The PC port of \fIiverilog-vpi\fP includes two special flags needed to
support the more intractable development environment. These flags help
the program locate parts that it needs.
@@ -61,7 +62,7 @@ the program locate parts that it needs.
.B -mingw=\fIpath\fP
Tell the program the root of the Mingw compiler tool suite. The
\fBvvp\fP runtime is compiled with this compiler, and this is the
compiler that \fIiverilog\-vpi\fP expects to use to compile your source
compiler that \fIiverilog-vpi\fP expects to use to compile your source
code. This is normally not needed, and if you do use it, it is only
needed once. The compiler will save the \fIpath\fP in the registry for
use later.
@@ -75,7 +76,7 @@ stored in the registry for future use.
.SH "UNIX-ONLY OPTIONS"
The UNIX version of \fIiverilog\-vpi\fP includes additional flags to
The UNIX version of \fIiverilog-vpi\fP includes additional flags to
let Makefile gurus peek at the configuration of the \fIiverilog\fP
installation. This way, Makefiles can be written that handle complex VPI
builds natively, and without hard-coding values that depend on the
@@ -103,9 +104,9 @@ requests a 32bit vpi binary instead of the default 64bit binary.
.P
Example GNU makefile that takes advantage of these flags:
.IP "" 4
CFLAGS = \-Wall \-O $(CFLAGS_$@)
CFLAGS = -Wall -O $(CFLAGS_$@)
.br
VPI_CFLAGS := $(shell iverilog-vpi \-\-cflags)
VPI_CFLAGS := $(shell iverilog-vpi --cflags)
.br
CFLAGS_messagev.o = $(VPI_CFLAGS)
.br
@@ -128,7 +129,7 @@ iverilog(1), vvp(1),
.SH COPYRIGHT
.nf
Copyright \(co 2002\-2009 Stephen Williams
Copyright \(co 2002 Stephen Williams
This document can be freely redistributed according to the terms of the
GNU General Public License version 2.0
+4 -5
View File
@@ -17,18 +17,17 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: iverilog-vpi.sh,v 1.17 2007/02/06 05:07:31 steve Exp $"
# These are the variables used for compiling files
CC="@IVCC@"
CC=@IVCC@
CXX=@IVCXX@
CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@"
SUFFIX=@SUFFIX@
# These are used for linking...
LD=$CC
LDFLAGS="@SHARED@ -L@LIBDIR@"
LDLIBS="-lveriuser$SUFFIX -lvpi$SUFFIX"
LDLIBS="-lveriuser -lvpi"
CCSRC=
CXSRC=
@@ -102,7 +101,7 @@ do
;;
--install-dir)
echo "@LIBDIR@/ivl$SUFFIX"
echo "@LIBDIR@/ivl"
exit
;;
esac
-25
View File
@@ -1,12 +1,7 @@
EXPORTS
ivl_branch_island
ivl_branch_terminal
ivl_design_const
ivl_design_consts
ivl_design_discipline
ivl_design_disciplines
ivl_design_flag
ivl_design_process
ivl_design_root
@@ -20,11 +15,6 @@ ivl_const_signed
ivl_const_type
ivl_const_width
ivl_discipline_domain
ivl_discipline_flow
ivl_discipline_name
ivl_discipline_potential
ivl_event_any
ivl_event_basename
ivl_event_name
@@ -37,15 +27,12 @@ ivl_event_scope
ivl_expr_type
ivl_expr_bits
ivl_expr_branch
ivl_expr_def
ivl_expr_delay_val
ivl_expr_dvalue
ivl_expr_event
ivl_expr_file
ivl_expr_lineno
ivl_expr_name
ivl_expr_nature
ivl_expr_opcode
ivl_expr_oper1
ivl_expr_oper2
@@ -109,7 +96,6 @@ ivl_lpm_sset_value
ivl_lpm_string
ivl_lpm_sync_clr
ivl_lpm_sync_set
ivl_lpm_trigger
ivl_lpm_type
ivl_lpm_width
@@ -119,15 +105,12 @@ ivl_lval_part_off
ivl_lval_sig
ivl_lval_width
ivl_nature_name
ivl_nexus_get_private
ivl_nexus_name
ivl_nexus_ptrs
ivl_nexus_ptr
ivl_nexus_set_private
ivl_nexus_ptr_branch
ivl_nexus_ptr_con
ivl_nexus_ptr_drive0
ivl_nexus_ptr_drive1
@@ -160,8 +143,6 @@ ivl_scope_def_lineno
ivl_scope_event
ivl_scope_events
ivl_scope_file
ivl_scope_is_auto
ivl_scope_is_cell
ivl_scope_lineno
ivl_scope_logs
ivl_scope_log
@@ -182,7 +163,6 @@ ivl_scope_time_units
ivl_scope_type
ivl_scope_tname
ivl_signal_array_addr_swapped
ivl_signal_array_base
ivl_signal_array_count
ivl_signal_attr
@@ -191,7 +171,6 @@ ivl_signal_attr_val
ivl_signal_basename
ivl_signal_data_type
ivl_signal_dimensions
ivl_signal_discipline
ivl_signal_file
ivl_signal_integer
ivl_signal_lineno
@@ -210,11 +189,8 @@ ivl_signal_width
ivl_path_delay
ivl_path_source
ivl_process_analog
ivl_process_attr_cnt
ivl_process_attr_val
ivl_process_file
ivl_process_lineno
ivl_process_scope
ivl_process_stmt
ivl_process_type
@@ -236,7 +212,6 @@ ivl_stmt_delay_val
ivl_stmt_events
ivl_stmt_file
ivl_stmt_lineno
ivl_stmt_lexp
ivl_stmt_lval
ivl_stmt_lvals
ivl_stmt_lwidth
+5 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007-2010 Stephen Williams (steve@icarus.com)
* Copyright (c) 2007 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,11 +16,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_assert.h,v 1.1 2007/01/31 04:21:10 steve Exp $"
#endif
#ifndef __ivl_assert_h
#define __ivl_assert_h
# include <cassert>
# include <assert.h>
#define ivl_assert(tok, expression) \
do { \
+16 -139
View File
@@ -1,7 +1,7 @@
#ifndef __ivl_target_H
#define __ivl_target_H
/*
* Copyright (c) 2000-2009 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
@@ -29,9 +29,6 @@
#define _END_DECL
#endif
#ifndef __GNUC__
# define __attribute__(x)
#endif
_BEGIN_DECL
@@ -63,9 +60,6 @@ _BEGIN_DECL
* This object represent an array that can be a memory or a net
* array. (They are the same from the perspective of ivl_target.h.)
*
* ivl_branch_t
* this object represents an analog branch.
*
* ivl_design_t
* This object represents the entire elaborated design. Various
* global properties and methods are available from this.
@@ -155,10 +149,8 @@ _BEGIN_DECL
* throughout the design.
*/
typedef struct ivl_array_s *ivl_array_t;
typedef struct ivl_branch_s *ivl_branch_t;
typedef struct ivl_delaypath_s*ivl_delaypath_t;
typedef struct ivl_design_s *ivl_design_t;
typedef struct ivl_discipline_s*ivl_discipline_t;
typedef struct ivl_event_s *ivl_event_t;
typedef struct ivl_expr_s *ivl_expr_t;
typedef struct ivl_island_s *ivl_island_t;
@@ -167,7 +159,6 @@ typedef struct ivl_lval_s *ivl_lval_t;
typedef struct ivl_net_const_s*ivl_net_const_t;
typedef struct ivl_net_logic_s*ivl_net_logic_t;
typedef struct ivl_udp_s *ivl_udp_t;
typedef struct ivl_nature_s *ivl_nature_t;
typedef struct ivl_net_probe_s*ivl_net_probe_t;
typedef struct ivl_nexus_s *ivl_nexus_t;
typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t;
@@ -176,7 +167,7 @@ typedef struct ivl_process_s *ivl_process_t;
typedef struct ivl_scope_s *ivl_scope_t;
typedef struct ivl_signal_s *ivl_signal_t;
typedef struct ivl_switch_s *ivl_switch_t;
typedef struct ivl_memory_s *ivl_memory_t; //XXXX __attribute__((deprecated));
typedef struct ivl_memory_s *ivl_memory_t; /* DEPRECATED */
typedef struct ivl_statement_s*ivl_statement_t;
/*
@@ -185,12 +176,6 @@ typedef struct ivl_statement_s*ivl_statement_t;
* changes and additions to the enumerations.
*/
typedef enum ivl_dis_domain_e {
IVL_DIS_NONE = 0,
IVL_DIS_DISCRETE = 1,
IVL_DIS_CONTINUOUS = 2
} ivl_dis_domain_t;
typedef enum ivl_drive_e {
IVL_DR_HiZ = 0,
IVL_DR_SMALL = 1,
@@ -208,10 +193,8 @@ typedef enum ivl_drive_e {
typedef enum ivl_expr_type_e {
IVL_EX_NONE = 0,
IVL_EX_ARRAY = 18,
IVL_EX_BACCESS= 19,
IVL_EX_BINARY = 2,
IVL_EX_CONCAT = 3,
IVL_EX_DELAY = 20,
IVL_EX_EVENT = 17,
IVL_EX_MEMORY = 4,
IVL_EX_NUMBER = 5,
@@ -271,8 +254,6 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_ABS = 32,
IVL_LPM_ADD = 0,
IVL_LPM_ARRAY = 30,
IVL_LPM_CAST_INT = 34,
IVL_LPM_CAST_REAL = 33,
IVL_LPM_CONCAT = 16,
IVL_LPM_CMP_EEQ= 18, /* Case EQ (===) */
IVL_LPM_CMP_EQ = 10,
@@ -359,7 +340,6 @@ typedef enum ivl_signal_type_e {
typedef enum ivl_statement_type_e {
IVL_ST_NONE = 0,
IVL_ST_NOOP = 1,
IVL_ST_ALLOC = 25,
IVL_ST_ASSIGN = 2,
IVL_ST_ASSIGN_NB = 3,
IVL_ST_BLOCK = 4,
@@ -369,7 +349,6 @@ typedef enum ivl_statement_type_e {
IVL_ST_CASEZ = 7,
IVL_ST_CASSIGN = 8,
IVL_ST_CONDIT = 9,
IVL_ST_CONTRIB = 27,
IVL_ST_DEASSIGN = 10,
IVL_ST_DELAY = 11,
IVL_ST_DELAYX = 12,
@@ -377,7 +356,6 @@ typedef enum ivl_statement_type_e {
IVL_ST_FORCE = 14,
IVL_ST_FOREVER = 15,
IVL_ST_FORK = 16,
IVL_ST_FREE = 26,
IVL_ST_RELEASE = 17,
IVL_ST_REPEAT = 18,
IVL_ST_STASK = 19,
@@ -424,20 +402,6 @@ struct ivl_attribute_s {
};
typedef const struct ivl_attribute_s*ivl_attribute_t;
/* BRANCH
* Branches are analog constructs, a pair of terminals that is used in
* branch access functions. Terminal-1 is the reference node (The
* "ground") for the purposes of the access function that accesses it.
*
* SEMANTIC NOTES
* All the branches in an island are connected by terminals or by
* expressions. The island is the connection of branches that must be
* solved together.
*/
/* extern ivl_scope_t ivl_branch_scope(ivl_branch_t obj); */
extern ivl_nexus_t ivl_branch_terminal(ivl_branch_t obj, int idx);
extern ivl_island_t ivl_branch_island(ivl_branch_t obj);
/* DELAYPATH
* Delaypath objects represent delay paths called out by a specify
* block in the Verilog source file. The destination signal references
@@ -522,9 +486,6 @@ extern int ivl_design_time_precision(ivl_design_t des);
extern unsigned ivl_design_consts(ivl_design_t des);
extern ivl_net_const_t ivl_design_const(ivl_design_t, unsigned idx);
extern unsigned ivl_design_disciplines(ivl_design_t des);
extern ivl_discipline_t ivl_design_discipline(ivl_design_t des, unsigned idx);
/* LITERAL CONSTANTS
* Literal constants are nodes with no input and a single constant
* output. The form of the output depends on the type of the node.
@@ -538,8 +499,7 @@ extern ivl_discipline_t ivl_design_discipline(ivl_design_t des, unsigned idx);
* ivl_const_bits
* This returns a pointer to an array of constant characters,
* each byte a '0', '1', 'x' or 'z'. The array is *not* nul
* terminated. This value is only value if ivl_const_type is
* IVL_VT_LOGIC or IVL_VT_BOOL. It returns nil otherwise.
* terminated.
*
* ivl_const_nex
* Return the ivl_nexus_t of the output for the constant.
@@ -577,32 +537,6 @@ extern double ivl_const_real(ivl_net_const_t net);
/* extern ivl_nexus_t ivl_const_pin(ivl_net_const_t net, unsigned idx); */
/* extern unsigned ivl_const_pins(ivl_net_const_t net); */
/* DISCIPLINES
*
* Disciplines are Verilog-AMS construct. A discipline is a collection
* of attributes that can be attached to a signal.
*
* FUNCTION SUMMARY
*
* ivl_discipline_name
* This is the name of the discipline in the Verilog-AMS source.
*
* ivl_discipline_domain
* This is the domain: continuous or discrete.
*
* SEMANTIC NOTES
*
* The discipline domain will not be IVL_DIS_NONE. The "none" domain
* is a place-holder internally for incomplete parsing, and is also
* available for code generators to use.
*/
extern const char*ivl_discipline_name(ivl_discipline_t net);
extern ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net);
extern ivl_nature_t ivl_discipline_potential(ivl_discipline_t net);
extern ivl_nature_t ivl_discipline_flow(ivl_discipline_t net);
extern const char* ivl_nature_name(ivl_nature_t net);
/* EVENTS
*
* Events are a unification of named events and implicit events
@@ -746,18 +680,12 @@ extern unsigned ivl_expr_lineno(ivl_expr_t net);
/* IVL_EX_NUMBER */
extern const char* ivl_expr_bits(ivl_expr_t net);
/* IVL_EX_BACCESS */
extern ivl_branch_t ivl_expr_branch(ivl_expr_t net);
/* IVL_EX_UFUNC */
extern ivl_scope_t ivl_expr_def(ivl_expr_t net);
/* IVL_EX_DELAY */
extern uint64_t ivl_expr_delay_val(ivl_expr_t net);
/* IVL_EX_REALNUM */
extern double ivl_expr_dvalue(ivl_expr_t net);
/* IVL_EX_SIGNAL, IVL_EX_SFUNC, IVL_EX_VARIABLE */
extern const char* ivl_expr_name(ivl_expr_t net);
/* IVL_EX_BACCESS */
extern ivl_nature_t ivl_expr_nature(ivl_expr_t net);
/* IVL_EX_BINARY IVL_EX_UNARY */
extern char ivl_expr_opcode(ivl_expr_t net);
/* IVL_EX_BINARY IVL_EX_UNARY, IVL_EX_MEMORY IVL_EX_TERNARY */
@@ -1030,10 +958,6 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
* often the number of inputs per out, i.e., the number of inputs
* per bit for a MUX.
*
* ivl_lpm_trigger
* SFUNC and UFUNC devices may have a trigger that forces the
* function output to be re-evaluated.
*
* SEMANTIC NOTES
*
* - Concatenation (IVL_LPM_CONCAT)
@@ -1062,9 +986,8 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
* more than the width of the output, although the possibility of
* overflow exists at run time.
*
* The inputs are always treated as unsigned. If the expression is
* supposed to be signed, elaboration will generate the necessary sign
* extension, so the target need not (must not) consider signedness.
* Multiply may be signed. If so, the output should be sign extended
* to fill in its result.
*
* - Power (IVL_LPM_POW)
* The power takes two inputs and generates an output. Unlike other
@@ -1196,11 +1119,6 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
* function (i.e. "$display") that was found in the source code. The
* compiler does little checking of that name.
*
* The ivl_lpm_trigger function retrieves the trigger event that
* indicates when the system function needs to be re-evaluated. If
* there is no trigger event, the system function only needs to be
* re-evaluated when a change is detected on its input ports.
*
* - User Function Call (IVL_LPM_UFUNC)
* This device is special as it represents a call to a user defined
* function (behavioral code) within a netlist. The inputs to the
@@ -1219,11 +1137,6 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
* ports. The ivl_lpm_size function returns the number of inputs for
* the device, and the ivl_lpm_data() function index argument selects
* the port to retrieve. Each port is sized independently.
*
* The ivl_lpm_trigger function retrieves the trigger event that
* indicates when the user function needs to be re-evaluated. If
* there is no trigger event, the user function only needs to be
* re-evaluated when a change is detected on its input ports.
*/
extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */
@@ -1233,7 +1146,6 @@ extern ivl_scope_t ivl_lpm_scope(ivl_lpm_t net);
extern int ivl_lpm_signed(ivl_lpm_t net);
extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net);
extern unsigned ivl_lpm_width(ivl_lpm_t net);
extern ivl_event_t ivl_lpm_trigger(ivl_lpm_t net);
/* IVL_LPM_FF */
extern ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net);
@@ -1339,7 +1251,7 @@ extern const char*ivl_lpm_string(ivl_lpm_t net);
*/
extern unsigned ivl_lval_width(ivl_lval_t net);
extern ivl_expr_t ivl_lval_mux(ivl_lval_t net); /* XXXX Obsolete? */
extern ivl_expr_t ivl_lval_mux(ivl_lval_t net); // XXXX Obsolete?
extern ivl_expr_t ivl_lval_idx(ivl_lval_t net);
extern ivl_expr_t ivl_lval_part_off(ivl_lval_t net);
extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
@@ -1420,7 +1332,7 @@ extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
* width. The compiler will insure this is so.
*/
extern const char* ivl_nexus_name(ivl_nexus_t net) __attribute__((deprecated));
extern const char* ivl_nexus_name(ivl_nexus_t net);
extern unsigned ivl_nexus_ptrs(ivl_nexus_t net);
extern ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx);
@@ -1431,7 +1343,6 @@ extern void* ivl_nexus_get_private(ivl_nexus_t net);
extern ivl_drive_t ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net);
extern ivl_drive_t ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net);
extern unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net);
extern ivl_branch_t ivl_nexus_ptr_branch(ivl_nexus_ptr_t net);
extern ivl_net_const_t ivl_nexus_ptr_con(ivl_nexus_ptr_t net);
extern ivl_net_logic_t ivl_nexus_ptr_log(ivl_nexus_ptr_t net);
extern ivl_lpm_t ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net);
@@ -1534,12 +1445,6 @@ extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
* ivl_scope_lineno
* Returns the instantiation file and line for this scope.
*
* ivl_scope_is_auto
* Is the task or function declared to be automatic?
*
* ivl_scope_is_cell
* Is the module defined to be a cell?
*
* ivl_scope_var
* ivl_scope_vars
* REMOVED
@@ -1616,8 +1521,6 @@ extern unsigned ivl_scope_def_lineno(ivl_scope_t net);
extern unsigned ivl_scope_events(ivl_scope_t net);
extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx);
extern const char* ivl_scope_file(ivl_scope_t net);
extern unsigned ivl_scope_is_auto(ivl_scope_t net);
extern unsigned ivl_scope_is_cell(ivl_scope_t net);
extern unsigned ivl_scope_lineno(ivl_scope_t net);
extern unsigned ivl_scope_logs(ivl_scope_t net);
extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx);
@@ -1658,12 +1561,10 @@ extern int ivl_scope_time_units(ivl_scope_t net);
*
* ivl_signal_array_base
* ivl_signal_array_count
* ivl_signal_array_addr_swapped
* The signal may be arrayed. If so, the array_count is >1. Each
* word of the array has its own nexus. The array_base is the
* address in the Verilog source for the canonical zero word. This
* may be negative, positive or zero. The array addresses may be
* reversed/swapped.
* address is the Verilog source for the canonical zero word. This
* may be negative, positive or zero.
*
* Note that arraying of the signal into words is distinct from the
* vectors. The width of a signal is the width of a WORD.
@@ -1672,10 +1573,6 @@ extern int ivl_scope_time_units(ivl_scope_t net);
* The signal may be an array (of vectors) in which case this
* function returns >0, the number of dimensions of the array.
*
* ivl_signal_discipline
* If the signal has been declared with a domain (Verilog-AMS) then
* this function will return a non-nil ivl_discipline_t.
*
* ivl_signal_msb
* ivl_signal_lsb
* ivl_signal_width
@@ -1742,9 +1639,7 @@ extern int ivl_scope_time_units(ivl_scope_t net);
extern ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word);
extern int ivl_signal_array_base(ivl_signal_t net);
extern unsigned ivl_signal_array_count(ivl_signal_t net);
extern unsigned ivl_signal_array_addr_swapped(ivl_signal_t net);
extern unsigned ivl_signal_dimensions(ivl_signal_t net);
extern ivl_discipline_t ivl_signal_discipline(ivl_signal_t net);
extern int ivl_signal_msb(ivl_signal_t net);
extern int ivl_signal_lsb(ivl_signal_t net);
extern unsigned ivl_signal_width(ivl_signal_t net);
@@ -1775,16 +1670,12 @@ extern ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx);
* is translated into a type and a single statement. (The statement
* may be a compound statement.)
*
* ivl_process_type
* ivl_process_analog
* The ivl_process_type function returns the type of the process,
* an "initial" or "always" statement. The ivl_process_analog
* returns true if the process is analog.
* The ivl_process_type function gets the type of the process,
* an "initial" or "always" statement.
*
* ivl_process_scope
* A process is placed in a scope. The statement within the process
* operates within the scope of the process unless there are calls
* outside the scope.
* A process is placed in a scope. The statement within the process
* operates within the scope of the process unless there are calls
* outside the scope.
*
* The ivl_process_stmt function gets the statement that forms the
* process. See the statement related functions for how to manipulate
@@ -1794,7 +1685,6 @@ extern ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx);
* attr_val methods return those attributes.
*/
extern ivl_process_type_t ivl_process_type(ivl_process_t net);
extern int ivl_process_analog(ivl_process_t net);
extern ivl_scope_t ivl_process_scope(ivl_process_t net);
@@ -1803,9 +1693,6 @@ extern ivl_statement_t ivl_process_stmt(ivl_process_t net);
extern unsigned ivl_process_attr_cnt(ivl_process_t net);
extern ivl_attribute_t ivl_process_attr_val(ivl_process_t net, unsigned idx);
extern const char* ivl_process_file(ivl_process_t net);
extern unsigned ivl_process_lineno(ivl_process_t net);
/*
* These functions manage statements of various type. This includes
* all the different kinds of statements (as enumerated in
@@ -1890,12 +1777,6 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
* that constant value. If the expression is non-constant, the code
* generator is supposed to know what to do about that, too.
*
* - IVL_ST_CONTRIB
* This is an analog contribution statement. The ivl_stmt_lexp
* function returns the l-value expression which is guaranteed to be a
* branch access expression. The ivl_stmt_rval returns the r-value
* expression for the assignment.
*
* - IVL_ST_DELAY, IVL_ST_DELAYX
* These statement types are delay statements. They are a way to
* attach a delay to a statement. The ivl_stmt_sub_stmt() function
@@ -1961,8 +1842,6 @@ extern uint64_t ivl_stmt_delay_val(ivl_statement_t net);
/* IVL_ST_WAIT IVL_ST_TRIGGER */
extern unsigned ivl_stmt_nevent(ivl_statement_t net);
extern ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx);
/* IVL_ST_CONTRIB */
extern ivl_expr_t ivl_stmt_lexp(ivl_statement_t net);
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN
IVL_ST_FORCE IVL_ST_RELEASE */
extern ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx);
@@ -1977,8 +1856,7 @@ extern const char* ivl_stmt_name(ivl_statement_t net);
extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx);
/* IVL_ST_STASK */
extern unsigned ivl_stmt_parm_count(ivl_statement_t net);
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_CONTRIB
IVL_ST_FORCE */
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_FORCE */
extern ivl_expr_t ivl_stmt_rval(ivl_statement_t net);
/* IVL_ST_DELAY, IVL_ST_DELAYX, IVL_ST_FOREVER, IVL_ST_REPEAT
IVL_ST_WAIT, IVL_ST_WHILE */
@@ -2039,7 +1917,7 @@ extern unsigned ivl_switch_lineno(ivl_switch_t net);
#endif
extern DLLEXPORT int target_design(ivl_design_t des);
extern DLLEXPORT const char* target_query(const char*key);
/* target_design
@@ -2057,7 +1935,6 @@ extern DLLEXPORT const char* target_query(const char*key);
ivl core. This function is how the target module is invoked. */
typedef int (*target_design_f)(ivl_design_t des);
typedef const char* (*target_query_f) (const char*key);
_END_DECL

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