mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-25 23:36:19 +02:00
Compare commits
3
Commits
vec4-stack
..
v0_6_1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61d230c5b2 | ||
|
|
8f94545f2a | ||
|
|
6975707804 |
+19
@@ -0,0 +1,19 @@
|
||||
lexor_keyword.cc
|
||||
parse.h
|
||||
parse.cc
|
||||
parse.cc.output
|
||||
syn-rules.cc
|
||||
syn-rules.cc.output
|
||||
lexor.cc
|
||||
ivl
|
||||
ivl.exp
|
||||
dep
|
||||
configure
|
||||
Makefile
|
||||
check
|
||||
check.cc
|
||||
config.status
|
||||
config.log
|
||||
config.cache
|
||||
config.h
|
||||
dosify
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
# Lines that start with '#' are comments.
|
||||
#
|
||||
# This file is for the development branch of Icarus Verilog.
|
||||
#
|
||||
# The following files will be ignored by git.
|
||||
|
||||
# Normal editor rules
|
||||
*.swp
|
||||
*~
|
||||
|
||||
# Top level generic files
|
||||
tags
|
||||
TAGS
|
||||
cscope.*
|
||||
*.patch
|
||||
*.orig
|
||||
|
||||
# Object files and libraries
|
||||
*.[oa]
|
||||
|
||||
gmon*.out
|
||||
gmon*.txt
|
||||
|
||||
# From autoconf
|
||||
configure
|
||||
config.log
|
||||
config.status
|
||||
Makefile
|
||||
|
||||
/_pli_types.h
|
||||
config.h
|
||||
/tgt-pcb/pcb_config.h
|
||||
/tgt-pcb/fp.cc
|
||||
/tgt-pcb/fp.h
|
||||
/tgt-pcb/fp.output
|
||||
/tgt-pcb/fp_lex.cc
|
||||
/tgt-vvp/vvp_config.h
|
||||
/tgt-vhdl/vhdl_config.h
|
||||
/vpi/vpi_config.h
|
||||
stamp-*-h
|
||||
/version.h
|
||||
/version_tag.h
|
||||
|
||||
# Directories
|
||||
autom4te.cache
|
||||
dep
|
||||
|
||||
# Compiler back end and library files
|
||||
/tgt-vvp/*.conf
|
||||
*.tgt
|
||||
*.vpi
|
||||
/cadpli/cadpli.vpl
|
||||
|
||||
/tgt-blif/Makefile
|
||||
|
||||
# lex, yacc and gperf output
|
||||
/driver/cflexor.c
|
||||
/driver/cfparse.c
|
||||
/driver/cfparse.h
|
||||
/driver/cfparse.output
|
||||
|
||||
/ivlpp/lexor.c
|
||||
|
||||
/vhdlpp/lexor.cc
|
||||
/vhdlpp/lexor_keyword.cc
|
||||
/vhdlpp/parse.cc
|
||||
/vhdlpp/parse.h
|
||||
/vhdlpp/parse.output
|
||||
/vhdlpp/vhdlpp_config.h
|
||||
/vhdlpp/vhdlpp
|
||||
|
||||
/lexor.cc
|
||||
/lexor_keyword.cc
|
||||
/parse.cc
|
||||
/parse.h
|
||||
/parse.output
|
||||
/syn-rules.cc
|
||||
/syn-rules.output
|
||||
|
||||
/vpi/sdf_lexor.c
|
||||
/vpi/sdf_parse.c
|
||||
/vpi/sdf_parse.h
|
||||
/vpi/sdf_parse.output
|
||||
/vpi/sys_readmem_lex.c
|
||||
/vpi/table_mod_lexor.c
|
||||
/vpi/table_mod_parse.c
|
||||
/vpi/table_mod_parse.h
|
||||
/vpi/table_mod_parse.output
|
||||
|
||||
/vvp/dump.*
|
||||
/vvp/lexor.cc
|
||||
/vvp/parse.cc
|
||||
/vvp/parse.h
|
||||
/vvp/parse.output
|
||||
|
||||
# Program created files
|
||||
/vvp/tables.cc
|
||||
|
||||
/iverilog-vpi.man
|
||||
/driver-vpi/res.rc
|
||||
/driver/iverilog.man
|
||||
/vvp/vvp.man
|
||||
|
||||
# The executables.
|
||||
*.exe
|
||||
/driver/iverilog
|
||||
/iverilog-vpi
|
||||
/ivl
|
||||
/ivlpp/ivlpp
|
||||
/vvp/vvp
|
||||
|
||||
/ivl.exp
|
||||
/vvp/vvp.exp
|
||||
|
||||
# Check output
|
||||
/check.vvp
|
||||
@@ -1,85 +0,0 @@
|
||||
#ifndef IVL_AStatement_H
|
||||
#define IVL_AStatement_H
|
||||
/*
|
||||
* Copyright (c) 2008-2014 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <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 /* IVL_AStatement_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,13 +14,16 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: Attrib.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Attrib.h"
|
||||
# include <cassert>
|
||||
# include <assert.h>
|
||||
|
||||
Attrib::Attrib()
|
||||
{
|
||||
@@ -33,8 +36,23 @@ Attrib::~Attrib()
|
||||
delete[] list_;
|
||||
}
|
||||
|
||||
void Attrib::set_attributes(const map<string,string>&attr)
|
||||
{
|
||||
assert(list_ == 0);
|
||||
|
||||
const verinum& Attrib::attribute(perm_string key) const
|
||||
nlist_ = attr.size();
|
||||
list_ = new cell_[nlist_];
|
||||
|
||||
map<string,string>::const_iterator idx;
|
||||
unsigned jdx;
|
||||
for (idx = attr.begin(), jdx = 0 ; idx != attr.end() ; idx ++, jdx++) {
|
||||
struct cell_*tmp = list_ + jdx;
|
||||
tmp->key = (*idx).first;
|
||||
tmp->val = (*idx).second;
|
||||
}
|
||||
}
|
||||
|
||||
string Attrib::attribute(const string&key) const
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) {
|
||||
|
||||
@@ -42,11 +60,10 @@ const verinum& Attrib::attribute(perm_string key) const
|
||||
return list_[idx].val;
|
||||
}
|
||||
|
||||
static const verinum null;
|
||||
return null;
|
||||
return "";
|
||||
}
|
||||
|
||||
void Attrib::attribute(perm_string key, const verinum&value)
|
||||
void Attrib::attribute(const string&key, const string&value)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
@@ -75,7 +92,7 @@ bool Attrib::has_compat_attributes(const Attrib&that) const
|
||||
|
||||
for (idx = 0 ; idx < that.nlist_ ; idx += 1) {
|
||||
|
||||
verinum tmp = attribute(that.list_[idx].key);
|
||||
string tmp = attribute(that.list_[idx].key);
|
||||
if (tmp != that.list_[idx].val)
|
||||
return false;
|
||||
}
|
||||
@@ -83,19 +100,32 @@ bool Attrib::has_compat_attributes(const Attrib&that) const
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned Attrib::attr_cnt() const
|
||||
unsigned Attrib::size() const
|
||||
{
|
||||
return nlist_;
|
||||
}
|
||||
|
||||
perm_string Attrib::attr_key(unsigned idx) const
|
||||
string Attrib::key(unsigned idx) const
|
||||
{
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].key;
|
||||
}
|
||||
|
||||
const verinum& Attrib::attr_value(unsigned idx) const
|
||||
string Attrib::value(unsigned idx) const
|
||||
{
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].val;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: Attrib.cc,v $
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_Attrib_H
|
||||
#define IVL_Attrib_H
|
||||
#ifndef __Attrib_H
|
||||
#define __Attrib_H
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,11 +16,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: Attrib.h,v 1.1 2000/12/04 17:37:03 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "StringHeap.h"
|
||||
# include "verinum.h"
|
||||
# include <string>
|
||||
# include <map>
|
||||
|
||||
/*
|
||||
* This class keeps a map of key/value pairs. The map can be set from
|
||||
@@ -30,23 +33,23 @@ class Attrib {
|
||||
|
||||
public:
|
||||
Attrib();
|
||||
virtual ~Attrib();
|
||||
~Attrib();
|
||||
|
||||
const verinum&attribute(perm_string key) const;
|
||||
void attribute(perm_string key, const verinum&value);
|
||||
void set_attributes(const map<string,string>&attr);
|
||||
string attribute(const string&key) const;
|
||||
void attribute(const string&key, const string&value);
|
||||
bool has_compat_attributes(const Attrib&that) const;
|
||||
|
||||
|
||||
/* Provide a means of iterating over the entries in the map. */
|
||||
unsigned attr_cnt() const;
|
||||
perm_string attr_key(unsigned idx) const;
|
||||
const verinum& attr_value(unsigned idx) const;
|
||||
|
||||
unsigned size() const;
|
||||
string key(unsigned idx) const;
|
||||
string value(unsigned idx) const;
|
||||
|
||||
private:
|
||||
struct cell_ {
|
||||
perm_string key;
|
||||
verinum val;
|
||||
string key;
|
||||
string val;
|
||||
};
|
||||
|
||||
unsigned nlist_;
|
||||
@@ -57,4 +60,10 @@ class Attrib {
|
||||
Attrib& operator= (const Attrib&);
|
||||
};
|
||||
|
||||
#endif /* IVL_Attrib_H */
|
||||
/*
|
||||
* $Log: Attrib.h,v $
|
||||
* Revision 1.1 2000/12/04 17:37:03 steve
|
||||
* Add Attrib class for holding NetObj attributes.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
- anything else you think relevant.
|
||||
- Library version, and
|
||||
- anything else you think relevent.
|
||||
|
||||
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,62 +28,61 @@ 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).
|
||||
You tell me that it fails to compile for you, and I find that it
|
||||
compiles for me, then hooray I fixed it. It can happen, you
|
||||
know. What's on my disk is more recent than the latest snapshot.
|
||||
know. What's on my disk is more recent then the latest snapshot.
|
||||
|
||||
If your program does compile, but generates incorrect output, I need
|
||||
to know what it says and what you think it should say. From this I can
|
||||
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,
|
||||
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
|
||||
* The Output is Correct, But Less Then Ideal
|
||||
|
||||
If the output is strictly correct, but just not good enough for
|
||||
practical use, I would like to know. These sorts of problems are
|
||||
likely to be more subjective than a core dump, but are worthy of
|
||||
likely to be more subjective then a core dump, but are worthy of
|
||||
consideration. However, realize that outright errors will get more
|
||||
attention than missed optimizations.
|
||||
attention then missed optimizations.
|
||||
|
||||
THE MAKING OF A GOOD TEST PROGRAM
|
||||
|
||||
@@ -93,45 +91,24 @@ 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
|
||||
given.
|
||||
|
||||
So when you send a test case, ask yourself "Can poor overworked Steve
|
||||
invoke the error without any Verilog other than what is included?" And
|
||||
invoke the error without any Verilog other then 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.
|
||||
|
||||
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 bug database supports basic keyword searches, and you can
|
||||
optionally limit your search to active bugs, or fixed bugs. You may
|
||||
also browse the bug database, just to get an idea what is still
|
||||
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.
|
||||
make it all nice and legal.
|
||||
|
||||
HOW TO SEND PATCHES
|
||||
|
||||
@@ -139,26 +116,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-1999 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 +140,9 @@ 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.2 1999/08/06 04:05:28 steve Exp $
|
||||
$Log: BUGS.txt,v $
|
||||
Revision 1.2 1999/08/06 04:05:28 steve
|
||||
Handle scope of parameters.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@@ -225,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@@ -335,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
||||
-502
@@ -1,502 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,108 +14,254 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: HName.cc,v 1.3 2002/01/05 04:36:06 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "HName.h"
|
||||
# include <iostream>
|
||||
# include <cstring>
|
||||
# include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
hname_t::hname_t()
|
||||
{
|
||||
item_ = 0;
|
||||
count_ = 0;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text)
|
||||
: name_(text)
|
||||
{
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text, int num)
|
||||
: name_(text), number_(1)
|
||||
{
|
||||
number_[0] = num;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text, vector<int>&nums)
|
||||
: name_(text), number_(nums)
|
||||
hname_t::hname_t(const char*text)
|
||||
{
|
||||
item_ = strdup(text);
|
||||
count_ = 1;
|
||||
}
|
||||
|
||||
hname_t::hname_t(const hname_t&that)
|
||||
: name_(that.name_), number_(that.number_)
|
||||
{
|
||||
count_ = that.count_;
|
||||
switch (count_) {
|
||||
case 0:
|
||||
item_ = 0;
|
||||
break;
|
||||
case 1:
|
||||
item_ = strdup(that.item_);
|
||||
break;
|
||||
default:
|
||||
array_ = new char*[count_];
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
array_[idx] = strdup(that.array_[idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hname_t& hname_t::operator = (const hname_t&that)
|
||||
hname_t::~hname_t()
|
||||
{
|
||||
name_ = that.name_;
|
||||
number_ = that.number_;
|
||||
return *this;
|
||||
switch (count_) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
free(item_);
|
||||
break;
|
||||
default:
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
free(array_[idx]);
|
||||
delete[]array_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool hname_t::operator < (const hname_t&r) const
|
||||
void hname_t::append(const char*text)
|
||||
{
|
||||
int cmp = strcmp(name_, r.name_);
|
||||
if (cmp < 0) return true;
|
||||
if (cmp > 0) return false;
|
||||
char**tmp;
|
||||
|
||||
// The text parts are equal, so compare then number
|
||||
// parts. Finish as soon as we find one to be less or more
|
||||
// than the other.
|
||||
size_t idx = 0;
|
||||
while (number_.size() > idx || r.number_.size() > idx) {
|
||||
switch (count_) {
|
||||
case 0:
|
||||
count_ = 1;
|
||||
item_ = strdup(text);
|
||||
break;
|
||||
case 1:
|
||||
count_ = 2;
|
||||
tmp = new char*[2];
|
||||
tmp[0] = item_;
|
||||
tmp[1] = strdup(text);
|
||||
array_ = tmp;
|
||||
break;
|
||||
default:
|
||||
tmp = new char*[count_+1];
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
tmp[idx] = array_[idx];
|
||||
delete[]array_;
|
||||
array_ = tmp;
|
||||
array_[count_] = strdup(text);
|
||||
count_ += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Ran out of l numbers, so less.
|
||||
if (number_.size() <= idx)
|
||||
void hname_t::prepend(const char*text)
|
||||
{
|
||||
char**tmp;
|
||||
|
||||
switch (count_) {
|
||||
case 0:
|
||||
count_ = 1;
|
||||
item_ = strdup(text);
|
||||
break;
|
||||
case 1:
|
||||
count_ = 2;
|
||||
tmp = new char*[2];
|
||||
tmp[0] = strdup(text);
|
||||
tmp[1] = item_;
|
||||
array_ = tmp;
|
||||
break;
|
||||
default:
|
||||
tmp = new char*[count_+1];
|
||||
tmp[0] = strdup(text);
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
tmp[idx+1] = array_[idx];
|
||||
delete[]array_;
|
||||
array_ = tmp;
|
||||
count_ += 1;
|
||||
}
|
||||
}
|
||||
|
||||
char* hname_t::remove_tail_name()
|
||||
{
|
||||
if (count_ == 0)
|
||||
return 0;
|
||||
|
||||
if (count_ == 1) {
|
||||
char*tmp = item_;
|
||||
count_ = 0;
|
||||
item_ = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (count_ == 2) {
|
||||
char*tmp1 = array_[0];
|
||||
char*tmp2 = array_[1];
|
||||
delete[]array_;
|
||||
count_ = 1;
|
||||
item_ = tmp1;
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
char*tmpo = array_[count_-1];
|
||||
char**tmpa = new char*[count_-1];
|
||||
for (unsigned idx = 0 ; idx < count_-1 ; idx += 1)
|
||||
tmpa[idx] = array_[idx];
|
||||
|
||||
delete[]array_;
|
||||
array_ = tmpa;
|
||||
count_ -= 1;
|
||||
return tmpo;
|
||||
}
|
||||
|
||||
const char* hname_t::peek_name(unsigned idx) const
|
||||
{
|
||||
if (idx >= count_)
|
||||
return 0;
|
||||
|
||||
if (count_ == 1)
|
||||
return item_;
|
||||
|
||||
return array_[idx];
|
||||
}
|
||||
|
||||
const char* hname_t::peek_tail_name() const
|
||||
{
|
||||
switch (count_) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return item_;
|
||||
default:
|
||||
return array_[count_-1];
|
||||
}
|
||||
}
|
||||
|
||||
bool operator < (const hname_t&l, const hname_t&r)
|
||||
{
|
||||
unsigned idx = 0;
|
||||
const char*lc = l.peek_name(idx);
|
||||
const char*rc = r.peek_name(idx);
|
||||
|
||||
while (lc && rc) {
|
||||
int cmp = strcmp(lc, rc);
|
||||
if (cmp < 0)
|
||||
return true;
|
||||
|
||||
// Ran out of r numbers, so greater.
|
||||
if (r.number_.size() <= idx)
|
||||
if (cmp > 0)
|
||||
return false;
|
||||
|
||||
if (number_[idx] < r.number_[idx])
|
||||
return true;
|
||||
|
||||
if (number_[idx] > r.number_[idx])
|
||||
return false;
|
||||
|
||||
idx += 1;
|
||||
lc = l.peek_name(idx);
|
||||
rc = r.peek_name(idx);
|
||||
}
|
||||
|
||||
// Fall-through means that we are equal, including all the
|
||||
// number parts, so not less.
|
||||
if (lc && !rc)
|
||||
return false;
|
||||
if (rc && !lc)
|
||||
return true;
|
||||
|
||||
// Must be ==
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hname_t::operator == (const hname_t&r) const
|
||||
bool operator == (const hname_t&l, const hname_t&r)
|
||||
{
|
||||
if (name_ == r.name_) {
|
||||
if (number_.size() != r.number_.size())
|
||||
unsigned idx = 0;
|
||||
const char*lc = l.peek_name(idx);
|
||||
const char*rc = r.peek_name(idx);
|
||||
|
||||
while (lc && rc) {
|
||||
int cmp = strcmp(lc, rc);
|
||||
if (cmp != 0)
|
||||
return false;
|
||||
|
||||
for (size_t idx = 0 ; idx < number_.size() ; idx += 1)
|
||||
if (number_[idx] != r.number_[idx]) return false;
|
||||
|
||||
return true;
|
||||
idx += 1;
|
||||
lc = l.peek_name(idx);
|
||||
rc = r.peek_name(idx);
|
||||
}
|
||||
|
||||
return false;
|
||||
if (lc || rc)
|
||||
return false;
|
||||
|
||||
// Must be ==
|
||||
return true;
|
||||
}
|
||||
|
||||
ostream& operator<< (ostream&out, const hname_t&that)
|
||||
{
|
||||
if (that.peek_name() == 0) {
|
||||
switch (that.count_) {
|
||||
case 0:
|
||||
out << "";
|
||||
return out;
|
||||
case 1:
|
||||
out << that.item_;
|
||||
return out;
|
||||
|
||||
default:
|
||||
out << that.array_[0];
|
||||
for (unsigned idx = 1 ; idx < that.count_ ; idx += 1)
|
||||
out << "." << that.array_[idx];
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
out << that.peek_name();
|
||||
for (size_t idx = 0 ; idx < that.number_.size() ; idx += 1)
|
||||
out << "[" << that.number_[idx] << "]";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: HName.cc,v $
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_HName_H
|
||||
#define IVL_HName_H
|
||||
#ifndef __HName_H
|
||||
#define __HName_H
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001 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,92 +16,71 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: HName.h,v 1.1 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
# include <list>
|
||||
# include <vector>
|
||||
# include "StringHeap.h"
|
||||
|
||||
# include <cassert>
|
||||
#ifdef HAVE_IOSFWD
|
||||
# include <iosfwd>
|
||||
#else
|
||||
class ostream;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This class represents a component of a Verilog hierarchical name. A
|
||||
* hierarchical component contains a name string (represented here
|
||||
* with a perm_string) and an optional signed number. This signed
|
||||
* number is used if the scope is part of an array, for example an
|
||||
* array of module instances or a loop generated scope.
|
||||
* This class represents a Verilog hierarchical name. A hierarchical
|
||||
* name is an ordered list of simple names.
|
||||
*/
|
||||
|
||||
class hname_t {
|
||||
|
||||
friend ostream& operator<< (ostream&out, const hname_t&that);
|
||||
|
||||
public:
|
||||
hname_t ();
|
||||
explicit hname_t (perm_string text);
|
||||
explicit hname_t (perm_string text, int num);
|
||||
explicit hname_t (perm_string text, std::vector<int>&nums);
|
||||
explicit hname_t (const char*text);
|
||||
hname_t (const hname_t&that);
|
||||
~hname_t();
|
||||
|
||||
hname_t& operator= (const hname_t&);
|
||||
// This method adds a name to the end of the hierarchical
|
||||
// path. This becomes a new base name.
|
||||
void append(const char*text);
|
||||
|
||||
bool operator == (const hname_t&that) const;
|
||||
bool operator < (const hname_t&that) const;
|
||||
// This method adds a name to the *front* of the hierarchical
|
||||
// path. The base name remains the same, unless this is the
|
||||
// only component.
|
||||
void prepend(const char*text);
|
||||
|
||||
// Return the string part of the hname_t.
|
||||
perm_string peek_name(void) const;
|
||||
// This method removes the tail name from the hierarchy, and
|
||||
// returns a pointer to that tail name. That tail name now
|
||||
// must be removed by the caller.
|
||||
char* remove_tail_name();
|
||||
|
||||
size_t has_numbers() const;
|
||||
int peek_number(size_t idx) const;
|
||||
// Return the given component in the hierarchical name. If the
|
||||
// idx is too large, return 0.
|
||||
const char*peek_name(unsigned idx) const;
|
||||
const char*peek_tail_name() const;
|
||||
|
||||
friend ostream& operator<< (ostream&, const hname_t&);
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
// If the number is anything other than INT_MIN, then this is
|
||||
// the numeric part of the name. Otherwise, it is not part of
|
||||
// the name at all.
|
||||
std::vector<int> number_;
|
||||
union {
|
||||
char**array_;
|
||||
char* item_;
|
||||
};
|
||||
unsigned count_;
|
||||
|
||||
private: // not implemented
|
||||
hname_t& operator= (const hname_t&);
|
||||
};
|
||||
|
||||
inline hname_t::~hname_t()
|
||||
{
|
||||
}
|
||||
extern bool operator < (const hname_t&, const hname_t&);
|
||||
extern bool operator == (const hname_t&, const hname_t&);
|
||||
|
||||
inline perm_string hname_t::peek_name(void) const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
inline int hname_t::peek_number(size_t idx) const
|
||||
{
|
||||
assert(number_.size() > idx);
|
||||
return number_[idx];
|
||||
}
|
||||
|
||||
inline size_t hname_t::has_numbers() const
|
||||
{
|
||||
return number_.size();
|
||||
}
|
||||
|
||||
extern ostream& operator<< (ostream&, const hname_t&);
|
||||
|
||||
inline bool operator != (const hname_t&l, const hname_t&r)
|
||||
{ return ! (l == r); }
|
||||
|
||||
inline ostream& operator<< (ostream&out, const list<hname_t>&ll)
|
||||
{
|
||||
list<hname_t>::const_iterator cur = ll.begin();
|
||||
out << *cur;
|
||||
++ cur;
|
||||
while (cur != ll.end()) {
|
||||
out << "." << *cur;
|
||||
++ cur;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif /* IVL_HName_H */
|
||||
/*
|
||||
* $Log: HName.h,v $
|
||||
* 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
|
||||
|
||||
@@ -14,30 +14,26 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: LineInfo.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
LineInfo::LineInfo()
|
||||
: lineno_(0)
|
||||
{
|
||||
}
|
||||
# include <cstdio>
|
||||
|
||||
LineInfo::~LineInfo()
|
||||
{
|
||||
}
|
||||
|
||||
string LineInfo::get_fileline() const
|
||||
string LineInfo::get_line() const
|
||||
{
|
||||
ostringstream buf;
|
||||
buf << (file_.str()? file_.str() : "") << ":" << lineno_;
|
||||
|
||||
string res = buf.str();
|
||||
return res;
|
||||
char buf[8];
|
||||
sprintf(buf, "%u", lineno_);
|
||||
return string(file_? file_ : "") + ":" + buf;
|
||||
}
|
||||
|
||||
void LineInfo::set_line(const LineInfo&that)
|
||||
@@ -46,12 +42,14 @@ void LineInfo::set_line(const LineInfo&that)
|
||||
lineno_ = that.lineno_;
|
||||
}
|
||||
|
||||
void LineInfo::set_file(perm_string f)
|
||||
{
|
||||
file_ = f;
|
||||
}
|
||||
/*
|
||||
* $Log: LineInfo.cc,v $
|
||||
* 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/11/30 17:31:42 steve
|
||||
* Change LineInfo to store const C strings.
|
||||
*
|
||||
*/
|
||||
|
||||
void LineInfo::set_lineno(unsigned n)
|
||||
{
|
||||
lineno_ = n;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_LineInfo_H
|
||||
#define IVL_LineInfo_H
|
||||
#ifndef __LineInfo_H
|
||||
#define __LineInfo_H
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,14 +16,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: LineInfo.h,v 1.5 2000/11/30 17:31:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
* This class holds line information for an internal object.
|
||||
*
|
||||
@@ -35,23 +35,30 @@ using namespace std;
|
||||
|
||||
class LineInfo {
|
||||
public:
|
||||
LineInfo();
|
||||
virtual ~LineInfo();
|
||||
LineInfo() : file_(0), lineno_(0) { }
|
||||
~LineInfo();
|
||||
|
||||
string get_line() const;
|
||||
|
||||
// Get a fully formatted file/lineno
|
||||
string get_fileline() const;
|
||||
// Set the file/line from another LineInfo object.
|
||||
void set_line(const LineInfo&that);
|
||||
|
||||
// Access parts of LineInfo data
|
||||
void set_file(perm_string f);
|
||||
void set_lineno(unsigned n);
|
||||
void set_file(const char*f) { file_ = f; }
|
||||
void set_lineno(unsigned n) { lineno_ = n; }
|
||||
|
||||
perm_string get_file() const { return file_; }
|
||||
unsigned get_lineno() const { return lineno_; }
|
||||
private:
|
||||
perm_string file_;
|
||||
const char* file_;
|
||||
unsigned lineno_;
|
||||
};
|
||||
|
||||
#endif /* IVL_LineInfo_H */
|
||||
/*
|
||||
* $Log: LineInfo.h,v $
|
||||
* Revision 1.5 2000/11/30 17:31:42 steve
|
||||
* Change LineInfo to store const C strings.
|
||||
*
|
||||
* Revision 1.4 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.3 1999/02/15 02:06:15 steve
|
||||
* Elaborate gate ranges.
|
||||
*/
|
||||
#endif
|
||||
+154
-287
@@ -12,380 +12,247 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
# Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.115 2002/02/16 03:18:53 steve Exp $"
|
||||
#
|
||||
#
|
||||
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.6
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
SUBDIRS = ivlpp vhdlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
|
||||
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver
|
||||
# Only run distclean for these directories.
|
||||
NOTUSED = tgt-fpga tgt-pal tgt-verilog
|
||||
SUBDIRS = @subdirs@
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
else
|
||||
NOTUSED += driver-vpi
|
||||
endif
|
||||
|
||||
# To get the version headers to build correctly we only want to look
|
||||
# for C++ files in the source directory. All other files will require
|
||||
# an explicit $(srcdir). The one exception to this is if we need to
|
||||
# rebuild the lexor_keyword.cc file. If we do, then we want to use the
|
||||
# local version instead of the one is $(srcdir).
|
||||
vpath lexor_keyword.cc .
|
||||
vpath %.cc $(srcdir)/libmisc
|
||||
vpath %.cc $(srcdir)
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
# This is actually the directory where we install our own header files.
|
||||
# It is a little different from the generic includedir.
|
||||
includedir = @includedir@/iverilog$(suffix)
|
||||
mandir = @mandir@
|
||||
includedir = $(prefix)/include
|
||||
|
||||
dllib=@DLLIB@
|
||||
|
||||
# For a cross compile these defines will need to be set accordingly.
|
||||
HOSTCC = @CC@
|
||||
HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
rdynamic=@rdynamic@
|
||||
strip_dynamic=@strip_dynamic@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
STRIP = @STRIP@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
MAN = @MAN@
|
||||
PS2PDF = @PS2PDF@
|
||||
GIT = @GIT@
|
||||
|
||||
ifeq (@srcdir@,.)
|
||||
INCLUDE_PATH = -I. -Ilibmisc
|
||||
else
|
||||
INCLUDE_PATH = -I. -I$(srcdir) -I$(srcdir)/libmisc
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
# The TARGETS variable lists the target modules that can be build and
|
||||
# installed. Some of them depend on external things, so are only
|
||||
# compiled if the prerequisites are installed.
|
||||
TARGETS = tgt-null
|
||||
ifeq ('@HAVE_IPAL@','yes')
|
||||
TARGETS += tgt-pal
|
||||
endif
|
||||
|
||||
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
CTARGETFLAGS = @CTARGETFLAGS@
|
||||
ifeq (@ENABLE_VVM@,yes)
|
||||
SUB_VVM = vvm
|
||||
endif
|
||||
|
||||
# Source files in the libmisc directory
|
||||
M = LineInfo.o StringHeap.o
|
||||
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
|
||||
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
|
||||
|
||||
O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
||||
elab_expr.o elaborate_analog.o elab_lval.o elab_net.o \
|
||||
elab_scope.o elab_sig.o elab_sig_analog.o elab_type.o \
|
||||
emit.o eval.o eval_attrib.o \
|
||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
|
||||
net_design.o netclass.o netdarray.o \
|
||||
netenum.o netparray.o netqueue.o netscalar.o netstruct.o netvector.o \
|
||||
net_event.o net_expr.o net_func.o \
|
||||
net_func_eval.o net_link.o net_modulo.o \
|
||||
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
|
||||
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
|
||||
pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
|
||||
pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
|
||||
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PGate.o \
|
||||
PGenerate.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
|
||||
Statement.o AStatement.o $M $(FF) $(TT)
|
||||
|
||||
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
all: ivl@EXEEXT@ libvpi.a
|
||||
for dir in $(SUBDIRS) $(SUB_VVM); do (cd $$dir ; $(MAKE) all); done
|
||||
cd vpi ; $(MAKE) all
|
||||
cd ivlpp ; $(MAKE) all
|
||||
cd driver ; $(MAKE) VERSION=$(VERSION) all
|
||||
cd tgt-verilog ; $(MAKE) all
|
||||
cd tgt-stub ; $(MAKE) all
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) all); done
|
||||
|
||||
# In the windows world, the installer will need a dosify program to
|
||||
# dosify text files.
|
||||
ifeq (@MINGW32@,yes)
|
||||
ifeq (@WIN32@,yes)
|
||||
all: dosify.exe
|
||||
dosify.exe: $(srcdir)/dosify.c
|
||||
$(HOSTCC) $(HOSTCFLAGS) -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
|
||||
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
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
|
||||
driver/iverilog -Ccheck.conf -ocheck.vvp -tvvp-check -B./ivlpp $(srcdir)/examples/hello.vl
|
||||
vvp/vvp -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
|
||||
clean:
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
rm -f *.o parse.cc parse.h lexor.cc
|
||||
rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps
|
||||
rm -f parse.output syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
|
||||
rm -rf dep
|
||||
rm -f version.exe
|
||||
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a libvpi.a
|
||||
cd vpi ; $(MAKE) clean
|
||||
cd driver ; $(MAKE) clean
|
||||
cd ivlpp ; $(MAKE) clean
|
||||
cd tgt-verilog ; $(MAKE) clean
|
||||
cd tgt-stub ; $(MAKE) clean
|
||||
for dir in $(SUBDIRS) $(SUB_VVM); do (cd $$dir ; $(MAKE) clean); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) clean); done
|
||||
|
||||
distclean: clean
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) $@ && ) true
|
||||
rm -f Makefile config.status config.log config.cache
|
||||
rm -f stamp-config-h config.h
|
||||
rm -f stamp-_pli_types-h _pli_types.h
|
||||
ifneq (@srcdir@,.)
|
||||
rm -f version_tag.h check.conf
|
||||
rmdir $(SUBDIRS) $(NOTUSED)
|
||||
for dir in $(SUBDIRS) $(SUB_VVM); do (cd $$dir ; $(MAKE) distclean); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) distclean); done
|
||||
rm -f vvm/Makefile
|
||||
rm -f vpi/Makefile
|
||||
rm -f ivlpp/Makefile
|
||||
rm -f driver/Makefile
|
||||
rm -f config.status config.cache config.log
|
||||
rm -f Makefile
|
||||
|
||||
ifeq (@ENABLE_VVM@,yes)
|
||||
TT_VVM = t-vvm.o
|
||||
endif
|
||||
rm -rf autom4te.cache
|
||||
|
||||
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c
|
||||
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
|
||||
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
|
||||
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o $(TT_VVM) t-xnf.o
|
||||
FF = nodangle.o synth.o syn-rules.o xnfio.o
|
||||
|
||||
cppcheck-all:
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) cppcheck && ) true
|
||||
$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) cppcheck && ) true
|
||||
$(MAKE) cppcheck
|
||||
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
|
||||
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
|
||||
elab_sig.o emit.o eval.o eval_rconst.o \
|
||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||
load_module.o mangle.o netlist.o netmisc.o net_assign.o \
|
||||
net_design.o net_event.o net_expr.o net_force.o net_link.o net_modulo.o \
|
||||
net_proc.o net_scope.o net_udp.o pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_dump.o \
|
||||
set_width.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 \
|
||||
PTask.o PFunction.o PWire.o Statement.o \
|
||||
$(FF) $(TT)
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in config.status
|
||||
./config.status --file=$@
|
||||
|
||||
dep:
|
||||
mkdir dep
|
||||
|
||||
stamp-config-h: $(srcdir)/config.h.in config.status
|
||||
@rm -f $@
|
||||
./config.status config.h
|
||||
config.h: stamp-config-h
|
||||
|
||||
stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
|
||||
@rm -f $@
|
||||
./config.status _pli_types.h
|
||||
_pli_types.h: stamp-_pli_types-h
|
||||
|
||||
$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
|
||||
cd $(srcdir) && autoconf
|
||||
|
||||
config.status: $(srcdir)/configure
|
||||
./config.status --recheck
|
||||
Makefile: Makefile.in config.h.in config.status
|
||||
./config.status
|
||||
|
||||
|
||||
libvpi.a: vpithunk.o
|
||||
rm -f $@
|
||||
ar cvq $@ vpithunk.o
|
||||
ranlib $@
|
||||
|
||||
# The vpithunk.c file (that makes up the libvpi.a library) needs to
|
||||
# be make with PIC flags, because shared objects load it.
|
||||
vpithunk.o: vpithunk.c
|
||||
@[ -d dep ] || mkdir dep
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(PICFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
|
||||
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
|
||||
# export and import library, and the last link makes a, ivl.exe
|
||||
# that really exports the things that the import library imports.
|
||||
ivl@EXEEXT@: $O $(srcdir)/ivl.def
|
||||
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
|
||||
$(DLLTOOL) --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
|
||||
ivl@EXEEXT@: $O ivl.def
|
||||
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
|
||||
dlltool --dllname ivl@EXEEXT@ --def ivl.def \
|
||||
--output-lib libivl.a --output-exp ivl.exp
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||
else
|
||||
ivl@EXEEXT@: $O
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
$(CXX) $(CXXFLAGS) $(rdynamic) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,no)
|
||||
all: iverilog-vpi
|
||||
|
||||
iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
|
||||
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
||||
-e 's;@SUFFIX@;$(suffix);' \
|
||||
-e 's;@IVCC@;$(CC);' \
|
||||
-e 's;@IVCXX@;$(CXX);' \
|
||||
-e 's;@IVCFLAGS@;$(CFLAGS);' \
|
||||
-e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@IVCTARGETFLAGS@;$(CTARGETFLAGS);' \
|
||||
-e 's;@INCLUDEDIR@;$(includedir);' \
|
||||
-e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||
chmod +x $@
|
||||
endif
|
||||
|
||||
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
|
||||
|
||||
%.o: %.cc config.h
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
%.o: %.cc
|
||||
@[ -d dep ] || mkdir dep
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
# Here are some explicit dependencies needed to get things going.
|
||||
main.o: main.cc version_tag.h
|
||||
|
||||
lexor.o: lexor.cc parse.h
|
||||
|
||||
parse.o: parse.cc
|
||||
|
||||
# Build this in two steps to avoid parallel build issues (see pr3462585)
|
||||
parse.cc: $(srcdir)/parse.y
|
||||
$(YACC) --verbose -t -p VL -d -o $@ $<
|
||||
parse.h: parse.cc
|
||||
mv parse.cc.h $@ 2>/dev/null || mv parse.hh $@
|
||||
parse.h parse.cc: $(srcdir)/parse.y
|
||||
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
|
||||
mv parse.cc.h parse.h || mv parse.hh parse.h
|
||||
|
||||
syn-rules.cc: $(srcdir)/syn-rules.y
|
||||
$(YACC) --verbose -t -p syn_ -o $@ $<
|
||||
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
|
||||
|
||||
lexor.cc: $(srcdir)/lexor.lex
|
||||
$(LEX) -s -t $< > $@
|
||||
$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex
|
||||
|
||||
lexor_keyword.o: lexor_keyword.cc parse.h
|
||||
lexor_keyword.o: lexor_keyword.cc
|
||||
|
||||
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
|
||||
gperf -o -i 7 -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
|
||||
lexor_keyword.cc: lexor_keyword.gperf
|
||||
gperf -o -i 7 -C -k 1-3,$$ -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.pdf: iverilog-vpi.ps
|
||||
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
|
||||
|
||||
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
|
||||
# version_tag.h file in the source tree (included in snapshots and releases),
|
||||
# and finally use nothing.
|
||||
|
||||
# "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:
|
||||
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
|
||||
echo "Using git-describe for VERSION_TAG"; \
|
||||
tmp=`$(GIT) --git-dir $(srcdir)/.git describe --always --dirty \
|
||||
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
|
||||
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
|
||||
elif test -r $(srcdir)/version_tag.h; then \
|
||||
echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \
|
||||
diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \
|
||||
else \
|
||||
echo "Using empty VERSION_TAG"; \
|
||||
echo '#define VERSION_TAG ""' > version_tag.h; \
|
||||
fi
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
ifeq ($(MAN),none)
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||
else
|
||||
ifeq ($(PS2PDF),none)
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||
else
|
||||
INSTALL_DOC = $(prefix)/iverilog-vpi$(suffix).pdf $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||
all: dep iverilog-vpi.pdf
|
||||
endif
|
||||
endif
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
else
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi$(suffix).1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
ifeq (@WIN32@,yes)
|
||||
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/QUICK_START.txt
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
WIN32_INSTALL =
|
||||
else
|
||||
WIN32_INSTALL = $(bindir)/iverilog-vpi$(suffix)
|
||||
endif
|
||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h $(includedir)/vpi_user.h $(libdir)/libvpi.a $(WIN32_INSTALL)
|
||||
cd vpi ; $(MAKE) install
|
||||
cd ivlpp ; $(MAKE) install
|
||||
cd driver ; $(MAKE) install
|
||||
for tgt in $(SUBDIRS) $(SUB_VVM); do (cd $$tgt ; $(MAKE) install); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) install); done
|
||||
|
||||
install: all installdirs $(libdir)/ivl$(suffix)/ivl@EXEEXT@ $(libdir)/ivl$(suffix)/include/constants.vams $(libdir)/ivl$(suffix)/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/sv_vpi_user.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
$(libdir)/libvpi.a : ./libvpi.a
|
||||
$(INSTALL_DATA) libvpi.a $(libdir)/libvpi.a
|
||||
|
||||
$(bindir)/iverilog-vpi$(suffix): ./iverilog-vpi
|
||||
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
|
||||
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
|
||||
$(STRIP) $(strip_dynamic) $(libdir)/ivl/ivl@EXEEXT@
|
||||
|
||||
$(libdir)/ivl$(suffix)/ivl@EXEEXT@: ./ivl@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@"
|
||||
|
||||
$(libdir)/ivl$(suffix)/include/constants.vams: $(srcdir)/constants.vams
|
||||
$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
|
||||
|
||||
$(libdir)/ivl$(suffix)/include/disciplines.vams: $(srcdir)/disciplines.vams
|
||||
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"
|
||||
$(libdir)/ivl/iverilog.conf: $(srcdir)/iverilog.conf
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog.conf $(libdir)/ivl/iverilog.conf
|
||||
|
||||
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h"
|
||||
|
||||
$(includedir)/_pli_types.h: _pli_types.h
|
||||
$(INSTALL_DATA) $< "$(DESTDIR)$(includedir)/_pli_types.h"
|
||||
|
||||
$(includedir)/sv_vpi_user.h: $(srcdir)/sv_vpi_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(includedir)/sv_vpi_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(includedir)/ivl_target.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 $(includedir)/vpi_user.h
|
||||
|
||||
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h"
|
||||
# In windows installations, put a few examples and the quick_start
|
||||
# into the destination directory.
|
||||
ifeq (@WIN32@,yes)
|
||||
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
|
||||
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
|
||||
mv tmp.vl $(prefix)/hello.vl
|
||||
|
||||
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
|
||||
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
|
||||
$(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
|
||||
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
|
||||
mv tmp.vl $(prefix)/sqrt.vl
|
||||
|
||||
$(mandir)/man1/iverilog-vpi$(suffix).1: iverilog-vpi.man
|
||||
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
|
||||
$(prefix)/QUICK_START.txt: $(srcdir)/QUICK_START.txt
|
||||
./dosify.exe $(srcdir)/QUICK_START.txt tmp.txt
|
||||
mv tmp.txt $(prefix)/QUICK_START.txt
|
||||
endif
|
||||
|
||||
$(prefix)/iverilog-vpi$(suffix).pdf: iverilog-vpi.pdf
|
||||
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
|
||||
installdirs: mkinstalldirs
|
||||
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl
|
||||
|
||||
|
||||
installdirs: $(srcdir)/mkinstalldirs
|
||||
$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \
|
||||
"$(DESTDIR)$(includedir)" \
|
||||
"$(DESTDIR)$(libdir)/ivl$(suffix)" \
|
||||
"$(DESTDIR)$(libdir)/ivl$(suffix)/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 f in ivl_target.h vpi_user.h _pli_types.h sv_vpi_user.h acc_user.h veriuser.h; \
|
||||
do rm -f "$(DESTDIR)$(includedir)/$$f"; done
|
||||
-test X$(suffix) = X || rmdir "$(DESTDIR)$(includedir)"
|
||||
rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
|
||||
rm -f $(libdir)/ivl/ivl@EXEEXT@
|
||||
rm -f $(bindir)/verilog
|
||||
rm -f $(bindir)/gverilog@EXEEXT@
|
||||
rm -f $(includedir)/ivl_target.h
|
||||
rm -f $(includedir)/vpi_user.h
|
||||
cd driver ; $(MAKE) uninstall
|
||||
cd vpi ; $(MAKE) uninstall
|
||||
cd ivlpp ; $(MAKE) uninstall
|
||||
for tgt in $(SUBDIRS) $(SUB_VVM); do (cd $$tgt ; $(MAKE) uninstall); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) uninstall); done
|
||||
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
-include $(patsubst %.o, dep/%.d, vpithunk.o)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,34 +14,30 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.cc,v 1.17 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Module.h"
|
||||
# include "PGate.h"
|
||||
# include "PWire.h"
|
||||
# include <cassert>
|
||||
# include <assert.h>
|
||||
|
||||
list<Module::named_expr_t> Module::user_defparms;
|
||||
|
||||
/* n is a permallocated string. */
|
||||
Module::Module(LexicalScope*parent, perm_string n)
|
||||
: PScopeExtra(n, parent)
|
||||
Module::Module(const char*name, const svector<Module::port_t*>*pp)
|
||||
: name_(strdup(name))
|
||||
{
|
||||
library_flag = false;
|
||||
is_cell = false;
|
||||
program_block = false;
|
||||
uc_drive = UCD_NONE;
|
||||
timescale_warn_done = false;
|
||||
time_unit = 0;
|
||||
time_precision = 0;
|
||||
time_from_timescale = false;
|
||||
if (pp)
|
||||
ports_ = *pp;
|
||||
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
{
|
||||
free(name_);
|
||||
}
|
||||
|
||||
void Module::add_gate(PGate*gate)
|
||||
@@ -49,68 +45,77 @@ void Module::add_gate(PGate*gate)
|
||||
gates_.push_back(gate);
|
||||
}
|
||||
|
||||
void Module::add_task(const string&name, PTask*task)
|
||||
{
|
||||
tasks_[name] = task;
|
||||
}
|
||||
|
||||
void Module::add_function(const string &name, PFunction *func)
|
||||
{
|
||||
funcs_[name] = func;
|
||||
}
|
||||
|
||||
PWire* Module::add_wire(PWire*wire)
|
||||
{
|
||||
PWire*&ep = wires_[wire->path()];
|
||||
if (ep) return ep;
|
||||
|
||||
assert(ep == 0);
|
||||
ep = wire;
|
||||
return wire;
|
||||
}
|
||||
|
||||
void Module::add_behavior(PProcess*b)
|
||||
{
|
||||
behaviors_.push_back(b);
|
||||
}
|
||||
|
||||
unsigned Module::port_count() const
|
||||
{
|
||||
return ports.size();
|
||||
return ports_.count();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the array of PEIdent object that are at this port of the
|
||||
* module. If the port is internally unconnected, return an empty
|
||||
* array.
|
||||
* 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;
|
||||
if (ports_[idx])
|
||||
return ports_[idx]->expr;
|
||||
else
|
||||
return zero;
|
||||
}
|
||||
|
||||
unsigned Module::find_port(const char*name) const
|
||||
unsigned Module::find_port(const string&name) const
|
||||
{
|
||||
assert(name != 0);
|
||||
for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) {
|
||||
if (ports[idx] == 0) {
|
||||
/* It is possible to have undeclared ports. These
|
||||
are ports that are skipped in the declaration,
|
||||
for example like so: module foo(x ,, y); The
|
||||
port between x and y is unnamed and thus
|
||||
inaccessible to binding by name. */
|
||||
continue;
|
||||
}
|
||||
assert(ports[idx]);
|
||||
if (ports[idx]->name == name)
|
||||
assert(name != "");
|
||||
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1)
|
||||
if (ports_[idx]->name == name)
|
||||
return idx;
|
||||
}
|
||||
|
||||
return ports.size();
|
||||
return ports_.count();
|
||||
}
|
||||
|
||||
perm_string Module::get_port_name(unsigned idx) const
|
||||
|
||||
PWire* Module::get_wire(const hname_t&name) const
|
||||
{
|
||||
|
||||
assert(idx < ports.size());
|
||||
if (ports[idx] == 0) {
|
||||
/* It is possible to have undeclared ports. These
|
||||
are ports that are skipped in the declaration,
|
||||
for example like so: module foo(x ,, y); The
|
||||
port between x and y is unnamed and thus
|
||||
inaccessible to binding by name. */
|
||||
return perm_string::literal("");
|
||||
}
|
||||
return ports[idx]->name;
|
||||
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
|
||||
if (obj == wires_.end())
|
||||
return 0;
|
||||
else
|
||||
return (*obj).second;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PGate* Module::get_gate(perm_string name)
|
||||
PGate* Module::get_gate(const string&name)
|
||||
{
|
||||
for (list<PGate*>::iterator cur = gates_.begin()
|
||||
; cur != gates_.end() ; ++ cur ) {
|
||||
; cur != gates_.end()
|
||||
; cur ++ ) {
|
||||
|
||||
if ((*cur)->get_name() == name)
|
||||
return *cur;
|
||||
@@ -119,7 +124,81 @@ PGate* Module::get_gate(perm_string name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const map<hname_t,PWire*>& Module::get_wires() const
|
||||
{
|
||||
return wires_;
|
||||
}
|
||||
|
||||
const list<PGate*>& Module::get_gates() const
|
||||
{
|
||||
return gates_;
|
||||
}
|
||||
|
||||
const list<PProcess*>& Module::get_behaviors() const
|
||||
{
|
||||
return behaviors_;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: Module.cc,v $
|
||||
* Revision 1.17 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.16 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.15 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.14 2000/11/15 20:31:05 steve
|
||||
* Fix warning about temporaries.
|
||||
*
|
||||
* Revision 1.13 2000/11/05 06:05:59 steve
|
||||
* Handle connectsion to internally unconnected modules (PR#38)
|
||||
*
|
||||
* Revision 1.12 2000/05/16 04:05:15 steve
|
||||
* Module ports are really special PEIdent
|
||||
* expressions, because a name can be used
|
||||
* many places in the port list.
|
||||
*
|
||||
* Revision 1.11 2000/03/12 17:09:40 steve
|
||||
* Support localparam.
|
||||
*
|
||||
* Revision 1.10 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.9 2000/01/09 20:37:57 steve
|
||||
* Careful with wires connected to multiple ports.
|
||||
*
|
||||
* Revision 1.8 1999/12/11 05:45:41 steve
|
||||
* Fix support for attaching attributes to primitive gates.
|
||||
*
|
||||
* Revision 1.7 1999/09/17 02:06:25 steve
|
||||
* Handle unconnected module ports.
|
||||
*
|
||||
* Revision 1.6 1999/08/04 02:13:02 steve
|
||||
* Elaborate module ports that are concatenations of
|
||||
* module signals.
|
||||
*
|
||||
* Revision 1.5 1999/08/03 04:14:49 steve
|
||||
* Parse into pform arbitrarily complex module
|
||||
* port declarations.
|
||||
*
|
||||
* Revision 1.4 1999/07/31 19:14:47 steve
|
||||
* Add functions up to elaboration (Ed Carter)
|
||||
*
|
||||
* Revision 1.3 1999/07/03 02:12:51 steve
|
||||
* Elaborate user defined tasks.
|
||||
*
|
||||
* Revision 1.2 1999/06/17 05:34:42 steve
|
||||
* Clean up interface of the PWire class,
|
||||
* Properly match wire ranges.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:51 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_Module_H
|
||||
#define IVL_Module_H
|
||||
#ifndef __Module_H
|
||||
#define __Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-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,26 +16,23 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.h,v 1.24 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include <vector>
|
||||
# include <utility>
|
||||
# include "StringHeap.h"
|
||||
# include "svector.h"
|
||||
# include "HName.h"
|
||||
# include "named.h"
|
||||
# include "PScope.h"
|
||||
# include "LineInfo.h"
|
||||
# include "netlist.h"
|
||||
# include "pform_types.h"
|
||||
# include <string>
|
||||
class PEvent;
|
||||
class PExpr;
|
||||
class PEIdent;
|
||||
class PGate;
|
||||
class PGenerate;
|
||||
class PSpecPath;
|
||||
class PTask;
|
||||
class PFunction;
|
||||
class PWire;
|
||||
@@ -49,7 +46,7 @@ class NetScope;
|
||||
* therefore the handle for grasping the described circuit.
|
||||
*/
|
||||
|
||||
class Module : public PScopeExtra, public LineInfo {
|
||||
class Module : public LineInfo {
|
||||
|
||||
/* The module ports are in general a vector of port_t
|
||||
objects. Each port has a name and an ordered list of
|
||||
@@ -58,44 +55,26 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
the port. */
|
||||
public:
|
||||
struct port_t {
|
||||
perm_string name;
|
||||
vector<PEIdent*> expr;
|
||||
string name;
|
||||
svector<PEIdent*> expr;
|
||||
};
|
||||
|
||||
public:
|
||||
/* The name passed here is the module name, not the instance
|
||||
name. This make must be a permallocated string. */
|
||||
explicit Module(LexicalScope*parent, perm_string name);
|
||||
explicit Module(const char*name, const svector<port_t*>*);
|
||||
~Module();
|
||||
|
||||
/* Initially false. This is set to true if the module has been
|
||||
declared as a library module. This makes the module
|
||||
ineligible for being chosen as an implicit root. It has no
|
||||
other effect. */
|
||||
bool library_flag;
|
||||
|
||||
bool is_cell;
|
||||
|
||||
/* This is true if the module represents a program block
|
||||
instead of a module/cell. Program blocks have content
|
||||
restrictions and slightly modify scheduling semantics. */
|
||||
bool program_block;
|
||||
|
||||
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
|
||||
UCDriveType uc_drive;
|
||||
|
||||
/* specparams are simpler than other parameters, in that they
|
||||
can have a range, but not an explicit type. The restrictions
|
||||
are enforced by the parser. */
|
||||
map<perm_string,param_expr_t>specparams;
|
||||
/* The module has parameters that are evaluated when the
|
||||
module is elaborated. During parsing, I put the parameters
|
||||
into this map. */
|
||||
map<string,PExpr*>parameters;
|
||||
map<string,PExpr*>localparams;
|
||||
|
||||
/* The module also has defparam assignments which don't create
|
||||
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;
|
||||
static list<named_expr_t>user_defparms;
|
||||
map<hname_t,PExpr*>defparms;
|
||||
|
||||
/* Parameters may be overridden at instantiation time;
|
||||
the overrides do not contain explicit parameter names,
|
||||
@@ -103,61 +82,159 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
appear in the instantiated module. Therefore a
|
||||
list of names in module-order is needed to pass from
|
||||
a parameter-index to its name. */
|
||||
list<perm_string> param_names;
|
||||
list<string> param_names;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
vector<port_t*> ports;
|
||||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
/* Keep a table of named events declared in the module. */
|
||||
map<string,PEvent*>events;
|
||||
|
||||
/* These are the timescale for this module. The default is
|
||||
set by the `timescale directive. */
|
||||
int time_unit, time_precision;
|
||||
bool time_from_timescale;
|
||||
bool timescale_warn_done;
|
||||
|
||||
/* The module has a list of generate schemes that appear in
|
||||
the module definition. These are used at elaboration time. */
|
||||
list<PGenerate*> generate_schemes;
|
||||
|
||||
/* Nested modules are placed here, and are not elaborated
|
||||
unless they are instantiated, implicitly or explicitly. */
|
||||
std::map<perm_string,Module*> nested_modules;
|
||||
|
||||
list<PSpecPath*> specify_paths;
|
||||
|
||||
// The mod_name() is the name of the module type.
|
||||
perm_string mod_name() const { return pscope_name(); }
|
||||
const char*mod_name() const { return name_; }
|
||||
|
||||
void add_gate(PGate*gate);
|
||||
|
||||
// The add_wire method adds a wire by name, but only if the
|
||||
// wire name doesn't already exist. Either way, the result is
|
||||
// the existing wire or the pointer passed in.
|
||||
PWire* add_wire(PWire*wire);
|
||||
|
||||
void add_behavior(PProcess*behave);
|
||||
void add_task(const string&name, PTask*def);
|
||||
void add_function(const string&name, PFunction*def);
|
||||
|
||||
unsigned port_count() const;
|
||||
const vector<PEIdent*>& get_port(unsigned idx) const;
|
||||
unsigned find_port(const char*name) const;
|
||||
const svector<PEIdent*>& get_port(unsigned idx) const;
|
||||
unsigned find_port(const string&) const;
|
||||
|
||||
// Return port name ("" for undeclared port)
|
||||
perm_string get_port_name(unsigned idx) const;
|
||||
|
||||
PGate* get_gate(perm_string name);
|
||||
// Find a wire by name. This is used for connecting gates to
|
||||
// existing wires, etc.
|
||||
PWire* get_wire(const hname_t&name) const;
|
||||
PGate* get_gate(const string&name);
|
||||
|
||||
const map<hname_t,PWire*>& get_wires() const;
|
||||
const list<PGate*>& get_gates() const;
|
||||
const list<PProcess*>& get_behaviors() const;
|
||||
|
||||
void dump(ostream&out) const;
|
||||
bool elaborate(Design*, NetScope*scope) const;
|
||||
|
||||
typedef map<perm_string,PExpr*> replace_t;
|
||||
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep);
|
||||
bool elaborate_scope(Design*, NetScope*scope) const;
|
||||
|
||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
void dump_specparams_(ostream&out, unsigned indent) const;
|
||||
char* name_;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
svector<port_t*> ports_;
|
||||
|
||||
map<hname_t,PWire*> wires_;
|
||||
list<PGate*> gates_;
|
||||
list<PProcess*> behaviors_;
|
||||
map<string,PTask*> tasks_;
|
||||
map<string,PFunction*> funcs_;
|
||||
|
||||
private: // Not implemented
|
||||
Module(const Module&);
|
||||
Module& operator= (const Module&);
|
||||
};
|
||||
|
||||
#endif /* IVL_Module_H */
|
||||
|
||||
/*
|
||||
* $Log: Module.h,v $
|
||||
* Revision 1.24 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.23 2001/10/31 03:11:15 steve
|
||||
* detect module ports not declared within the module.
|
||||
*
|
||||
* Revision 1.22 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.21 2000/11/05 06:05:59 steve
|
||||
* Handle connectsion to internally unconnected modules (PR#38)
|
||||
*
|
||||
* Revision 1.20 2000/07/22 22:09:03 steve
|
||||
* Parse and elaborate timescale to scopes.
|
||||
*
|
||||
* Revision 1.19 2000/05/16 04:05:15 steve
|
||||
* Module ports are really special PEIdent
|
||||
* expressions, because a name can be used
|
||||
* many places in the port list.
|
||||
*
|
||||
* Revision 1.18 2000/05/02 16:27:38 steve
|
||||
* Move signal elaboration to a seperate pass.
|
||||
*
|
||||
* Revision 1.17 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
* Revision 1.16 2000/03/12 17:09:40 steve
|
||||
* Support localparam.
|
||||
*
|
||||
* Revision 1.15 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.14 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.13 2000/01/09 20:37:57 steve
|
||||
* Careful with wires connected to multiple ports.
|
||||
*
|
||||
* Revision 1.12 2000/01/09 05:50:48 steve
|
||||
* Support named parameter override lists.
|
||||
*
|
||||
* Revision 1.11 1999/12/11 05:45:41 steve
|
||||
* Fix support for attaching attributes to primitive gates.
|
||||
*
|
||||
* Revision 1.10 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
* Revision 1.9 1999/08/23 16:48:39 steve
|
||||
* Parameter overrides support from Peter Monta
|
||||
* AND and XOR support wide expressions.
|
||||
*
|
||||
* Revision 1.8 1999/08/04 02:13:02 steve
|
||||
* Elaborate module ports that are concatenations of
|
||||
* module signals.
|
||||
*
|
||||
* Revision 1.7 1999/08/03 04:14:49 steve
|
||||
* Parse into pform arbitrarily complex module
|
||||
* port declarations.
|
||||
*
|
||||
* Revision 1.6 1999/07/31 19:14:47 steve
|
||||
* Add functions up to elaboration (Ed Carter)
|
||||
*
|
||||
* Revision 1.5 1999/07/03 02:12:51 steve
|
||||
* Elaborate user defined tasks.
|
||||
*
|
||||
* Revision 1.4 1999/06/15 03:44:53 steve
|
||||
* Get rid of the STL vector template.
|
||||
*
|
||||
* Revision 1.3 1999/02/21 17:01:57 steve
|
||||
* Add support for module parameters.
|
||||
*
|
||||
* Revision 1.2 1999/01/25 05:45:56 steve
|
||||
* Add the LineInfo class to carry the source file
|
||||
* location of things. PGate, Statement and PProcess.
|
||||
*
|
||||
* elaborate handles module parameter mismatches,
|
||||
* missing or incorrect lvalues for procedural
|
||||
* assignment, and errors are propogated to the
|
||||
* top of the elaboration call tree.
|
||||
*
|
||||
* Attach line numbers to processes, gates and
|
||||
* assignment statements.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:52 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PClass.h"
|
||||
|
||||
PClass::PClass(perm_string name, LexicalScope*parent)
|
||||
: PScopeExtra(name, parent), type(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PClass::~PClass()
|
||||
{
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
#ifndef IVL_PClass_H
|
||||
#define IVL_PClass_H
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PScope.h"
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <iostream>
|
||||
|
||||
class PChainConstructor;
|
||||
|
||||
/*
|
||||
* SystemVerilog supports class declarations with their own lexical
|
||||
* scope, etc. The parser arranges for these to be created and
|
||||
* collected.
|
||||
*/
|
||||
|
||||
class PClass : public PScopeExtra, public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PClass (perm_string name, LexicalScope*parent);
|
||||
~PClass();
|
||||
|
||||
void dump(std::ostream&out, unsigned indent) const;
|
||||
|
||||
public:
|
||||
class_type_t*type;
|
||||
};
|
||||
|
||||
#endif /* IVL_PClass_H */
|
||||
+72
-109
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2011 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
|
||||
@@ -14,8 +14,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PDelays.cc,v 1.8 2001/12/29 20:19:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
@@ -24,12 +27,6 @@
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
# 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()
|
||||
{
|
||||
@@ -55,137 +52,70 @@ void PDelays::set_delay(PExpr*del)
|
||||
}
|
||||
|
||||
|
||||
void PDelays::set_delays(const list<PExpr*>*del, bool df)
|
||||
void PDelays::set_delays(const svector<PExpr*>*del, bool df)
|
||||
{
|
||||
assert(del);
|
||||
assert(del->size() <= 3);
|
||||
|
||||
list<PExpr*>::const_iterator cur = del->begin();
|
||||
for (unsigned idx = 0 ; cur != del->end() ; idx += 1, ++cur)
|
||||
delay_[idx] = *cur;
|
||||
assert(del->count() <= 3);
|
||||
for (unsigned idx = 0 ; idx < del->count() ; idx += 1)
|
||||
delay_[idx] = (*del)[idx];
|
||||
|
||||
delete_flag_ = df;
|
||||
}
|
||||
|
||||
unsigned PDelays::delay_count() const
|
||||
static unsigned long calculate_val(Design*des, const NetScope*scope,
|
||||
const PExpr*expr)
|
||||
{
|
||||
unsigned dly_cnt = 0;
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
if (delay_[idx]) dly_cnt += 1;
|
||||
assert(expr);
|
||||
unsigned long val;
|
||||
|
||||
return dly_cnt;
|
||||
}
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
|
||||
static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
|
||||
{
|
||||
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||
if (verireal*dr = expr->eval_rconst(des, scope)) {
|
||||
val = dr->as_long(shift);
|
||||
delete dr;
|
||||
|
||||
/* 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;
|
||||
} else {
|
||||
verinum*dv = expr->eval_const(des, scope);
|
||||
if (dv == 0) {
|
||||
cerr << expr->get_line() << ": sorry: non-constant "
|
||||
<< "delays not supported here: " << *expr << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
assert(dv);
|
||||
val = dv->as_ulong();
|
||||
val = des->scale_to_precision(val, scope);
|
||||
delete dv;
|
||||
}
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
units, and return an adjusted value. */
|
||||
|
||||
if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
|
||||
uint64_t delay = get_scaled_time_from_real(des, scope, tmp);
|
||||
|
||||
delete tmp;
|
||||
NetEConst*tmp2 = new NetEConst(verinum(delay, 64));
|
||||
tmp2->set_line(*expr);
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
|
||||
verinum fn = tmp->value();
|
||||
uint64_t delay = des->scale_to_precision(fn.as_ulong64(), scope);
|
||||
|
||||
delete tmp;
|
||||
NetEConst*tmp2 = new NetEConst(verinum(delay, 64));
|
||||
tmp2->set_line(*expr);
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
/* Oops, cannot evaluate down to a constant. */
|
||||
return dex;
|
||||
}
|
||||
|
||||
static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
|
||||
{
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
||||
if (dynamic_cast<NetESignal*> (expr))
|
||||
return expr;
|
||||
|
||||
if (dynamic_cast<NetEConst*> (expr))
|
||||
return expr;
|
||||
|
||||
NetNet*sig = expr->synthesize(des, scope, expr);
|
||||
if (sig == 0) {
|
||||
cerr << expr->get_fileline() << ": error: Expression " << *expr
|
||||
<< " is not suitable as a delay expression." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
expr = new NetESignal(sig);
|
||||
return expr;
|
||||
}
|
||||
|
||||
static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
|
||||
{
|
||||
NetEConst *c_rise = dynamic_cast<NetEConst*>(rise);
|
||||
NetEConst *c_fall = dynamic_cast<NetEConst*>(fall);
|
||||
if (c_rise && c_fall) {
|
||||
if (c_rise->value() < c_fall->value()) return rise;
|
||||
else return fall;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return val;
|
||||
}
|
||||
|
||||
void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
NetExpr*&decay_time,
|
||||
bool as_nets_flag) const
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
|
||||
|
||||
if (delay_[0]) {
|
||||
rise_time = calculate_val(des, scope, delay_[0]);
|
||||
if (as_nets_flag)
|
||||
rise_time = make_delay_nets(des, scope, 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);
|
||||
|
||||
if (delay_[2]) {
|
||||
decay_time = calculate_val(des, scope, delay_[2]);
|
||||
if (as_nets_flag)
|
||||
decay_time = make_delay_nets(des, scope,
|
||||
decay_time);
|
||||
|
||||
} else {
|
||||
// If this is zero then we need to do the min()
|
||||
// at run time.
|
||||
decay_time = calc_decay_time(rise_time, fall_time);
|
||||
if (rise_time < fall_time)
|
||||
decay_time = rise_time;
|
||||
else
|
||||
decay_time = fall_time;
|
||||
}
|
||||
} else {
|
||||
assert(delay_[2] == 0);
|
||||
@@ -198,3 +128,36 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
decay_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PDelays.cc,v $
|
||||
* Revision 1.8 2001/12/29 20:19:31 steve
|
||||
* Do not delete delay expressions of UDP instances.
|
||||
*
|
||||
* Revision 1.7 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.6 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2001/01/20 02:15:50 steve
|
||||
* apologize for not supporting non-constant delays.
|
||||
*
|
||||
* Revision 1.3 2001/01/14 23:04:55 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PDelays_H
|
||||
#define IVL_PDelays_H
|
||||
#ifndef __PDelays_H
|
||||
#define __PDelays_H
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999 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,23 +16,23 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PDelays.h,v 1.5 2001/12/29 20:19:31 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
# include <string>
|
||||
# include <list>
|
||||
# include <iostream>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 2
|
||||
using namespace std;
|
||||
#endif
|
||||
#ifdef HAVE_IOSFWD
|
||||
# include <iosfwd>
|
||||
#else
|
||||
class ostream;
|
||||
#endif
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class NetExpr;
|
||||
class PExpr;
|
||||
|
||||
/*
|
||||
@@ -49,15 +49,12 @@ class PDelays {
|
||||
this object takes ownership of the expressions, and will
|
||||
delete it in the destructor. */
|
||||
void set_delay(PExpr*);
|
||||
void set_delays(const list<PExpr*>*del, bool delete_flag=true);
|
||||
|
||||
unsigned delay_count() const;
|
||||
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
|
||||
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
NetExpr*&decay_time,
|
||||
bool as_nets_flag =false) const;
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const;
|
||||
|
||||
void dump_delays(ostream&out) const;
|
||||
|
||||
@@ -72,4 +69,22 @@ class PDelays {
|
||||
|
||||
ostream& operator << (ostream&o, const PDelays&);
|
||||
|
||||
#endif /* IVL_PDelays_H */
|
||||
/*
|
||||
* $Log: PDelays.h,v $
|
||||
* 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Stephen Williams ([email protected])
|
||||
* Copyright (c) 200Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,14 +14,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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PEvent.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PEvent.h"
|
||||
|
||||
PEvent::PEvent(perm_string n)
|
||||
PEvent::PEvent(const string&n)
|
||||
: name_(n)
|
||||
{
|
||||
}
|
||||
@@ -30,8 +33,19 @@ PEvent::~PEvent()
|
||||
{
|
||||
}
|
||||
|
||||
perm_string PEvent::name() const
|
||||
string PEvent::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PEvent.cc,v $
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PEvent_H
|
||||
#define IVL_PEvent_H
|
||||
#ifndef __PEvent_H
|
||||
#define __PEvent_H
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,11 +16,13 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PEvent.h,v 1.5 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
|
||||
class Design;
|
||||
@@ -29,26 +31,43 @@ class NetScope;
|
||||
/*
|
||||
* The PEvent class represents event objects. These are things that
|
||||
* are declared in Verilog as ``event foo;'' The name passed to the
|
||||
* constructor is the "foo" part of the declaration.
|
||||
* constructure is the "foo" part of the declaration.
|
||||
*/
|
||||
class PEvent : public LineInfo {
|
||||
|
||||
public:
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
// of the event, without any scope.
|
||||
explicit PEvent(perm_string name);
|
||||
explicit PEvent(const string&name);
|
||||
~PEvent();
|
||||
|
||||
perm_string name() const;
|
||||
string name() const;
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
string name_;
|
||||
|
||||
private: // not implemented
|
||||
PEvent(const PEvent&);
|
||||
PEvent& operator= (const PEvent&);
|
||||
};
|
||||
|
||||
#endif /* IVL_PEvent_H */
|
||||
/*
|
||||
* $Log: PEvent.h,v $
|
||||
* 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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2012 Stephen Williams <[email protected]>
|
||||
* Copyright CERN 2013 / 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
|
||||
@@ -15,104 +14,43 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.cc,v 1.29 2001/12/30 21:32:03 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "compiler.h"
|
||||
# include "PExpr.h"
|
||||
# include "PWire.h"
|
||||
# include "Module.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
# include <typeinfo>
|
||||
|
||||
PExpr::PExpr()
|
||||
{
|
||||
expr_type_ = IVL_VT_NO_TYPE;
|
||||
expr_width_ = 0;
|
||||
min_width_ = 0;
|
||||
signed_flag_ = false;
|
||||
}
|
||||
|
||||
PExpr::~PExpr()
|
||||
{
|
||||
}
|
||||
|
||||
void PExpr::declare_implicit_nets(LexicalScope*, NetNet::Type)
|
||||
{
|
||||
}
|
||||
|
||||
bool PExpr::has_aa_term(Design*, NetScope*) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PExpr::is_the_same(const PExpr*that) const
|
||||
{
|
||||
return typeid(this) == typeid(that);
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_lnet(Design*, NetScope*) const
|
||||
{
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "expression not valid in assign l-value: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_bi_net(Design*, NetScope*) const
|
||||
{
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "expression not valid as argument to inout port: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool PExpr::is_collapsible_net(Design*, NetScope*) const
|
||||
bool PExpr::is_constant(Module*) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const char* PExpr::width_mode_name(width_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case PExpr::SIZED:
|
||||
return "sized";
|
||||
case PExpr::UNSIZED:
|
||||
return "unsized";
|
||||
case PExpr::EXPAND:
|
||||
return "expand";
|
||||
case PExpr::LOSSLESS:
|
||||
return "lossless";
|
||||
case PExpr::UPSIZE:
|
||||
return "upsize";
|
||||
default:
|
||||
return "??";
|
||||
}
|
||||
}
|
||||
|
||||
PEAssignPattern::PEAssignPattern()
|
||||
{
|
||||
}
|
||||
|
||||
PEAssignPattern::PEAssignPattern(const list<PExpr*>&p)
|
||||
: parms_(p.size())
|
||||
{
|
||||
size_t idx = 0;
|
||||
for (list<PExpr*>::const_iterator cur = p.begin()
|
||||
; cur != p.end() ; ++cur) {
|
||||
parms_[idx] = *cur;
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
PEAssignPattern::~PEAssignPattern()
|
||||
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_line() << ": error: expression not valid in assign l-value: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
|
||||
@@ -124,175 +62,37 @@ PEBinary::~PEBinary()
|
||||
{
|
||||
}
|
||||
|
||||
void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
bool PEBinary::is_constant(Module*mod) const
|
||||
{
|
||||
assert(left_ && right_);
|
||||
left_->declare_implicit_nets(scope, type);
|
||||
right_->declare_implicit_nets(scope, type);
|
||||
return left_->is_constant(mod) && right_->is_constant(mod);
|
||||
}
|
||||
|
||||
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(left_ && right_);
|
||||
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
|
||||
}
|
||||
|
||||
PECastSize::PECastSize(unsigned si, PExpr*b)
|
||||
: size_(si), base_(b)
|
||||
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
|
||||
: path_(n), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECastSize::~PECastSize()
|
||||
PECallFunction::PECallFunction(const hname_t&n)
|
||||
: path_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PECastType::PECastType(data_type_t*t, PExpr*b)
|
||||
: target_(t), base_(b)
|
||||
{
|
||||
}
|
||||
|
||||
PECastType::~PECastType()
|
||||
{
|
||||
}
|
||||
|
||||
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
l_width_ = 0;
|
||||
r_width_ = 0;
|
||||
}
|
||||
|
||||
PEBComp::~PEBComp()
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
PEBShift::~PEBShift()
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
|
||||
: package_(0), path_(n), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector<PExpr *> &parms)
|
||||
: package_(pkg), path_(n), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
static pform_name_t pn_from_ps(perm_string n)
|
||||
{
|
||||
name_component_t tmp_name (n);
|
||||
pform_name_t tmp;
|
||||
tmp.push_back(tmp_name);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *> &parms)
|
||||
: package_(pkg), path_(pn_from_ps(n)), parms_(parms.size())
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
for (list<PExpr*>::const_iterator idx = parms.begin()
|
||||
; idx != parms.end() ; ++idx)
|
||||
parms_[tmp_idx++] = *idx;
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
|
||||
: package_(0), path_(pn_from_ps(n)), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n)
|
||||
: package_(0), path_(pn_from_ps(n))
|
||||
{
|
||||
}
|
||||
|
||||
// NOTE: Anachronism. Try to work all use of svector out.
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
|
||||
: package_(0), path_(n), parms_(parms.size())
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
for (list<PExpr*>::const_iterator idx = parms.begin()
|
||||
; idx != parms.end() ; ++idx)
|
||||
parms_[tmp_idx++] = *idx;
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms)
|
||||
: package_(0), path_(pn_from_ps(n)), parms_(parms.size())
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
for (list<PExpr*>::const_iterator idx = parms.begin()
|
||||
; idx != parms.end() ; ++idx)
|
||||
parms_[tmp_idx++] = *idx;
|
||||
}
|
||||
|
||||
PECallFunction::~PECallFunction()
|
||||
{
|
||||
}
|
||||
|
||||
void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
PEConcat::PEConcat(const svector<PExpr*>&p, PExpr*r)
|
||||
: parms_(p), repeat_(r)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
parms_[idx]->declare_implicit_nets(scope, type);
|
||||
}
|
||||
}
|
||||
|
||||
bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
|
||||
bool PEConcat::is_constant(Module *mod) const
|
||||
{
|
||||
bool flag = false;
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
flag = parms_[idx]->has_aa_term(des, scope) || flag;
|
||||
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 flag;
|
||||
}
|
||||
|
||||
PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r)
|
||||
: parms_(p.size()), width_modes_(SIZED, p.size()), repeat_(r)
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == p.size());
|
||||
for (list<PExpr*>::const_iterator idx = p.begin()
|
||||
; idx != p.end() ; ++idx)
|
||||
parms_[tmp_idx++] = *idx;
|
||||
|
||||
tested_scope_ = 0;
|
||||
repeat_count_ = 1;
|
||||
return constant;
|
||||
}
|
||||
|
||||
PEConcat::~PEConcat()
|
||||
@@ -300,25 +100,6 @@ PEConcat::~PEConcat()
|
||||
delete repeat_;
|
||||
}
|
||||
|
||||
void PEConcat::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
parms_[idx]->declare_implicit_nets(scope, type);
|
||||
}
|
||||
}
|
||||
|
||||
bool PEConcat::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool flag = false;
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
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)
|
||||
{
|
||||
@@ -333,25 +114,11 @@ 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_;
|
||||
}
|
||||
|
||||
PENull::PENull(void)
|
||||
{
|
||||
}
|
||||
|
||||
PENull::~PENull()
|
||||
{
|
||||
}
|
||||
|
||||
PEFNumber::PEFNumber(verireal*v)
|
||||
: value_(v)
|
||||
{
|
||||
@@ -367,19 +134,13 @@ const verireal& PEFNumber::value() const
|
||||
return *value_;
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(const pform_name_t&that)
|
||||
: package_(0), path_(that), no_implicit_sig_(false)
|
||||
bool PEFNumber::is_constant(Module*) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
|
||||
: package_(0), no_implicit_sig_(no_implicit_sig)
|
||||
{
|
||||
path_.push_back(name_component_t(s));
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
|
||||
: package_(pkg), path_(that), no_implicit_sig_(true)
|
||||
PEIdent::PEIdent(const hname_t&s)
|
||||
: path_(s), msb_(0), lsb_(0), idx_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -387,101 +148,30 @@ PEIdent::~PEIdent()
|
||||
{
|
||||
}
|
||||
|
||||
void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
const hname_t& PEIdent::path() const
|
||||
{
|
||||
/* We create an implicit wire if:
|
||||
- this is a simple identifier
|
||||
- an identifier of that name has not already been declared in
|
||||
any enclosing scope.
|
||||
- this is not an implicit named port connection */
|
||||
if (no_implicit_sig_)
|
||||
return;
|
||||
if ((path_.size() == 1) && (path_.front().index.size() == 0)) {
|
||||
perm_string name = path_.front().name;
|
||||
LexicalScope*ss = scope;
|
||||
while (ss) {
|
||||
if (ss->wires.find(name) != ss->wires.end())
|
||||
return;
|
||||
if (ss->localparams.find(name) != ss->localparams.end())
|
||||
return;
|
||||
if (ss->parameters.find(name) != ss->parameters.end())
|
||||
return;
|
||||
if (ss->genvars.find(name) != ss->genvars.end())
|
||||
return;
|
||||
if (ss->events.find(name) != ss->events.end())
|
||||
return;
|
||||
/* Strictly speaking, we should also check for name clashes
|
||||
with tasks, functions, named blocks, module instances,
|
||||
and generate blocks. However, this information is not
|
||||
readily available. As these names would not be legal in
|
||||
this context, we can declare implicit nets here and rely
|
||||
on later checks for name clashes to report the error. */
|
||||
return path_;
|
||||
}
|
||||
|
||||
ss = ss->parent_scope();
|
||||
}
|
||||
PWire*net = new PWire(name, type, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
|
||||
net->set_file(get_file());
|
||||
net->set_lineno(get_lineno());
|
||||
net->set_range_scalar(SR_NET);
|
||||
scope->wires[name] = net;
|
||||
if (warn_implicit) {
|
||||
cerr << get_fileline() << ": warning: implicit "
|
||||
"definition of wire '" << name << "'." << endl;
|
||||
}
|
||||
/*
|
||||
* An identifier can be in a constant expresion if (and only if) it is
|
||||
* a parameter.
|
||||
*/
|
||||
bool PEIdent::is_constant(Module*mod) const
|
||||
{
|
||||
if (mod == 0) return false;
|
||||
|
||||
{ map<string,PExpr*>::const_iterator cur;
|
||||
cur = mod->parameters.find(path_.peek_name(0));
|
||||
if (cur != mod->parameters.end()) return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet* net = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
const NetExpr*ex1, *ex2;
|
||||
|
||||
scope = symbol_search(this, des, scope, path_, net, par, eve, ex1, ex2);
|
||||
|
||||
if (scope)
|
||||
return scope->is_auto();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PENewArray::PENewArray(PExpr*size_expr, PExpr*init_expr)
|
||||
: size_(size_expr), init_(init_expr)
|
||||
{
|
||||
}
|
||||
|
||||
PENewArray::~PENewArray()
|
||||
{
|
||||
delete size_;
|
||||
}
|
||||
|
||||
PENewClass::PENewClass(void)
|
||||
{
|
||||
}
|
||||
|
||||
PENewClass::PENewClass(const list<PExpr*>&p)
|
||||
: parms_(p.size())
|
||||
{
|
||||
size_t tmp_idx = 0;
|
||||
for (list<PExpr*>::const_iterator cur = p.begin()
|
||||
; cur != p.end() ; ++ cur) {
|
||||
parms_[tmp_idx++] = *cur;
|
||||
{ map<string,PExpr*>::const_iterator cur;
|
||||
cur = mod->localparams.find(path_.peek_name(0));
|
||||
if (cur != mod->localparams.end()) return true;
|
||||
}
|
||||
}
|
||||
|
||||
PENewClass::~PENewClass()
|
||||
{
|
||||
}
|
||||
|
||||
PENewCopy::PENewCopy(PExpr*src)
|
||||
: src_(src)
|
||||
{
|
||||
}
|
||||
|
||||
PENewCopy::~PENewCopy()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PENumber::PENumber(verinum*vp)
|
||||
@@ -509,6 +199,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)
|
||||
{
|
||||
@@ -524,6 +219,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)
|
||||
{
|
||||
@@ -533,29 +233,11 @@ PETernary::~PETernary()
|
||||
{
|
||||
}
|
||||
|
||||
void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
{
|
||||
assert(expr_ && tru_ && fal_);
|
||||
expr_->declare_implicit_nets(scope, type);
|
||||
tru_->declare_implicit_nets(scope, type);
|
||||
fal_->declare_implicit_nets(scope, type);
|
||||
}
|
||||
|
||||
bool PETernary::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(expr_ && tru_ && fal_);
|
||||
return expr_->has_aa_term(des, scope)
|
||||
|| tru_->has_aa_term(des, scope)
|
||||
|| fal_->has_aa_term(des, scope);
|
||||
}
|
||||
|
||||
PETypename::PETypename(data_type_t*dt)
|
||||
: data_type_(dt)
|
||||
{
|
||||
}
|
||||
|
||||
PETypename::~PETypename()
|
||||
bool PETernary::is_constant(Module*m) const
|
||||
{
|
||||
return expr_->is_constant(m)
|
||||
&& tru_->is_constant(m)
|
||||
&& fal_->is_constant(m);
|
||||
}
|
||||
|
||||
PEUnary::PEUnary(char op, PExpr*ex)
|
||||
@@ -567,22 +249,129 @@ PEUnary::~PEUnary()
|
||||
{
|
||||
}
|
||||
|
||||
void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
bool PEUnary::is_constant(Module*m) const
|
||||
{
|
||||
assert(expr_);
|
||||
expr_->declare_implicit_nets(scope, type);
|
||||
return expr_->is_constant(m);
|
||||
}
|
||||
|
||||
bool PEUnary::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(expr_);
|
||||
return expr_->has_aa_term(des, scope);
|
||||
}
|
||||
/*
|
||||
* $Log: PExpr.cc,v $
|
||||
* Revision 1.29 2001/12/30 21:32:03 steve
|
||||
* Support elaborate_net for PEString objects.
|
||||
*
|
||||
* Revision 1.28 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.27 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Revision 1.26 2001/11/07 04:26:46 steve
|
||||
* elaborate_lnet uses scope instead of string path.
|
||||
*
|
||||
* Revision 1.25 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* Revision 1.24 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.23 2001/01/14 23:04:55 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
* Revision 1.22 2001/01/12 04:31:27 steve
|
||||
* Handle error idents in constants not in any scope (PR#97)
|
||||
*
|
||||
* Revision 1.21 2000/12/16 19:03:30 steve
|
||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||
*
|
||||
* Revision 1.20 2000/12/10 22:01:35 steve
|
||||
* Support decimal constants in behavioral delays.
|
||||
*
|
||||
* Revision 1.19 2000/06/30 15:50:20 steve
|
||||
* Allow unary operators in constant expressions.
|
||||
*
|
||||
* Revision 1.18 2000/05/07 04:37:55 steve
|
||||
* Carry strength values from Verilog source to the
|
||||
* pform and netlist for gates.
|
||||
*
|
||||
* Change vvm constants to use the driver_t to drive
|
||||
* a constant value. This works better if there are
|
||||
* multiple drivers on a signal.
|
||||
*
|
||||
* Revision 1.17 2000/05/04 03:37:58 steve
|
||||
* Add infrastructure for system functions, move
|
||||
* $time to that structure and add $random.
|
||||
*
|
||||
* Revision 1.16 2000/04/12 04:23:57 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
*
|
||||
* Handle named events within the mix of net events
|
||||
* and edges. As a unified lot they get caught together.
|
||||
* wait statements are broken into more complex statements
|
||||
* that include a conditional.
|
||||
*
|
||||
* Do not generate NetPEvent or NetNEvent objects in
|
||||
* elaboration. NetEvent, NetEvWait and NetEvProbe
|
||||
* take over those functions in the netlist.
|
||||
*
|
||||
* Revision 1.15 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
* Revision 1.14 2000/03/12 18:22:11 steve
|
||||
* Binary and unary operators in parameter expressions.
|
||||
*
|
||||
* Revision 1.13 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.12 1999/12/31 17:38:37 steve
|
||||
* Standardize some of the error messages.
|
||||
*
|
||||
* Revision 1.11 1999/10/31 04:11:27 steve
|
||||
* Add to netlist links pin name and instance number,
|
||||
* and arrange in vvm for pin connections by name
|
||||
* and instance number.
|
||||
*
|
||||
* Revision 1.10 1999/09/25 02:57:29 steve
|
||||
* Parse system function calls.
|
||||
*
|
||||
* Revision 1.9 1999/09/16 04:18:15 steve
|
||||
* elaborate concatenation repeats.
|
||||
*
|
||||
* Revision 1.8 1999/09/15 04:17:52 steve
|
||||
* separate assign lval elaboration for error checking.
|
||||
*
|
||||
* Revision 1.7 1999/07/22 02:05:20 steve
|
||||
* is_constant method for PEConcat.
|
||||
*
|
||||
* Revision 1.6 1999/07/17 19:50:59 steve
|
||||
* netlist support for ternary operator.
|
||||
*
|
||||
* Revision 1.5 1999/06/16 03:13:29 steve
|
||||
* More syntax parse with sorry stubs.
|
||||
*
|
||||
* Revision 1.4 1999/06/10 04:03:52 steve
|
||||
* Add support for the Ternary operator,
|
||||
* Add support for repeat concatenation,
|
||||
* Correct some seg faults cause by elaboration
|
||||
* errors,
|
||||
* Parse the casex anc casez statements.
|
||||
*
|
||||
* Revision 1.3 1999/05/16 05:08:42 steve
|
||||
* Redo constant expression detection to happen
|
||||
* after parsing.
|
||||
*
|
||||
* Parse more operators and expressions.
|
||||
*
|
||||
* Revision 1.2 1998/11/11 00:01:51 steve
|
||||
* Check net ranges in declarations.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:53 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
|
||||
PEVoid::PEVoid()
|
||||
{
|
||||
}
|
||||
|
||||
PEVoid::~PEVoid()
|
||||
{
|
||||
}
|
||||
|
||||
+34
-49
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2013 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
|
||||
@@ -14,26 +14,31 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PFunction.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "PTask.h"
|
||||
# include "Statement.h"
|
||||
# include <cassert>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
|
||||
: PTaskFunc(name, parent), statement_(0)
|
||||
#include "PTask.h"
|
||||
|
||||
PFunction::PFunction()
|
||||
: out_(0), ports_(0), statement_(0)
|
||||
{
|
||||
is_auto_ = is_auto__;
|
||||
return_type_ = 0;
|
||||
}
|
||||
|
||||
PFunction::~PFunction()
|
||||
{
|
||||
}
|
||||
|
||||
void PFunction::set_ports(svector<PWire *>*p)
|
||||
{
|
||||
assert(ports_ == 0);
|
||||
ports_ = p;
|
||||
}
|
||||
|
||||
void PFunction::set_statement(Statement*s)
|
||||
{
|
||||
assert(s != 0);
|
||||
@@ -41,45 +46,25 @@ void PFunction::set_statement(Statement*s)
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
void PFunction::push_statement_front(Statement*stmt)
|
||||
void PFunction::set_output(PWire*o)
|
||||
{
|
||||
// This can only happen after the statement is initially set.
|
||||
ivl_assert(*this, statement_);
|
||||
|
||||
// Get the PBlock of the statement. If it is not a PBlock,
|
||||
// then create one to wrap the existing statement and the new
|
||||
// statement that we're pushing.
|
||||
PBlock*blk = dynamic_cast<PBlock*> (statement_);
|
||||
if (blk == 0) {
|
||||
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
||||
tmp->set_line(*this);
|
||||
vector<Statement*>tmp_list(1);
|
||||
tmp_list[0] = statement_;
|
||||
tmp->set_statement(tmp_list);
|
||||
|
||||
statement_ = tmp;
|
||||
blk = tmp;
|
||||
}
|
||||
|
||||
// Now do the push.
|
||||
blk->push_statement_front(stmt);
|
||||
assert(out_ == 0);
|
||||
out_ = o;
|
||||
}
|
||||
|
||||
void PFunction::set_return(data_type_t*t)
|
||||
{
|
||||
return_type_ = t;
|
||||
}
|
||||
|
||||
PChainConstructor* PFunction::extract_chain_constructor()
|
||||
{
|
||||
PChainConstructor*res = 0;
|
||||
|
||||
if ((res = dynamic_cast<PChainConstructor*> (statement_))) {
|
||||
statement_ = 0;
|
||||
|
||||
} else if (PBlock*blk = dynamic_cast<PBlock*>(statement_)) {
|
||||
res = blk->extract_chain_constructor();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
/*
|
||||
* $Log: PFunction.cc,v $
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
* Revision 1.3 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.2 1999/08/25 22:22:41 steve
|
||||
* elaborate some aspects of functions.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2013 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,76 +14,66 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.cc,v 1.13 2001/11/22 06:20:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PGate.h"
|
||||
# include "PExpr.h"
|
||||
# include "verinum.h"
|
||||
# include <cassert>
|
||||
# include <assert.h>
|
||||
|
||||
void PGate::set_pins_(list<PExpr*>*pins)
|
||||
PGate::PGate(const string&name,
|
||||
svector<PExpr*>*pins,
|
||||
const svector<PExpr*>*del)
|
||||
: name_(name), pins_(pins)
|
||||
{
|
||||
assert(pins);
|
||||
assert(pins->size() == pins_.size());
|
||||
|
||||
for (size_t idx = 0 ; idx < pins_.size() ; idx += 1) {
|
||||
pins_[idx] = pins->front();
|
||||
pins->pop_front();
|
||||
}
|
||||
|
||||
assert(pins->empty());
|
||||
delete pins;
|
||||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
|
||||
: name_(name), pins_(pins? pins->size() : 0)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
if (del) delay_.set_delays(del);
|
||||
str0_ = IVL_DR_STRONG;
|
||||
str1_ = IVL_DR_STRONG;
|
||||
str0_ = STRONG;
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del)
|
||||
: name_(name), pins_(pins? pins->size() : 0)
|
||||
PGate::PGate(const string&name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: name_(name), pins_(pins)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
if (del) delay_.set_delay(del);
|
||||
str0_ = IVL_DR_STRONG;
|
||||
str1_ = IVL_DR_STRONG;
|
||||
str0_ = STRONG;
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins)
|
||||
: name_(name), pins_(pins? pins->size() : 0)
|
||||
PGate::PGate(const string&name, svector<PExpr*>*pins)
|
||||
: name_(name), pins_(pins)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
str0_ = IVL_DR_STRONG;
|
||||
str1_ = IVL_DR_STRONG;
|
||||
str0_ = STRONG;
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::~PGate()
|
||||
{
|
||||
}
|
||||
|
||||
ivl_drive_t PGate::strength0() const
|
||||
PGate::strength_t PGate::strength0() const
|
||||
{
|
||||
return str0_;
|
||||
}
|
||||
|
||||
void PGate::strength0(ivl_drive_t s)
|
||||
void PGate::strength0(PGate::strength_t s)
|
||||
{
|
||||
str0_ = s;
|
||||
}
|
||||
|
||||
ivl_drive_t PGate::strength1() const
|
||||
PGate::strength_t PGate::strength1() const
|
||||
{
|
||||
return str1_;
|
||||
}
|
||||
|
||||
void PGate::strength1(ivl_drive_t s)
|
||||
void PGate::strength1(PGate::strength_t s)
|
||||
{
|
||||
str1_ = s;
|
||||
}
|
||||
@@ -100,48 +90,39 @@ void PGate::elaborate_scope(Design*, NetScope*) const
|
||||
* parameters. This method understands how to handle the different
|
||||
* numbers of expressions.
|
||||
*/
|
||||
|
||||
void PGate::eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_expr,
|
||||
NetExpr*&fall_expr,
|
||||
NetExpr*&decay_expr,
|
||||
bool as_net_flag) const
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const
|
||||
{
|
||||
delay_.eval_delays(des, scope,
|
||||
rise_expr, fall_expr, decay_expr,
|
||||
as_net_flag);
|
||||
delay_.eval_delays(des, scope, rise_time, fall_time, decay_time);
|
||||
}
|
||||
|
||||
unsigned PGate::delay_count() const
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins)
|
||||
: PGate("", pins)
|
||||
{
|
||||
return delay_.delay_count();
|
||||
assert(pins->count() == 2);
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(list<PExpr*>*pins)
|
||||
: PGate(perm_string(), pins)
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels)
|
||||
: PGate("", pins, dels)
|
||||
{
|
||||
assert(pin_count() == 2);
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(list<PExpr*>*pins, list<PExpr*>*dels)
|
||||
: PGate(perm_string(), pins, dels)
|
||||
{
|
||||
assert(pin_count() == 2);
|
||||
assert(pins->count() == 2);
|
||||
}
|
||||
|
||||
PGAssign::~PGAssign()
|
||||
{
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
list<PExpr*>*pins,
|
||||
list<PExpr*>*del)
|
||||
PGBuiltin::PGBuiltin(Type t, const string&name,
|
||||
svector<PExpr*>*pins,
|
||||
svector<PExpr*>*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
list<PExpr*>*pins,
|
||||
PGBuiltin::PGBuiltin(Type t, const string&name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
{
|
||||
@@ -161,128 +142,27 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
const char* PGBuiltin::gate_name() const
|
||||
{
|
||||
switch(type_) {
|
||||
case AND:
|
||||
return "AND";
|
||||
break;
|
||||
case NAND:
|
||||
return "NAND";
|
||||
break;
|
||||
|
||||
case OR:
|
||||
return "OR";
|
||||
break;
|
||||
case NOR:
|
||||
return "NOR";
|
||||
break;
|
||||
|
||||
case XOR:
|
||||
return "XOR";
|
||||
break;
|
||||
case XNOR:
|
||||
return "XNOR";
|
||||
break;
|
||||
|
||||
case BUF:
|
||||
return "BUF";
|
||||
break;
|
||||
case NOT:
|
||||
return "NOT";
|
||||
break;
|
||||
|
||||
case BUFIF0:
|
||||
return "BUFIF0";
|
||||
break;
|
||||
case NOTIF0:
|
||||
return "NOTIF0";
|
||||
break;
|
||||
|
||||
case BUFIF1:
|
||||
return "BUFIF1";
|
||||
break;
|
||||
case NOTIF1:
|
||||
return "NOTIF1";
|
||||
break;
|
||||
|
||||
case NMOS:
|
||||
return "NMOS";
|
||||
break;
|
||||
case RNMOS:
|
||||
return "RNMOS";
|
||||
break;
|
||||
|
||||
case PMOS:
|
||||
return "PMOS";
|
||||
break;
|
||||
case RPMOS:
|
||||
return "RPMOS";
|
||||
break;
|
||||
|
||||
case TRAN:
|
||||
return "TRAN";
|
||||
break;
|
||||
case RTRAN:
|
||||
return "RTRAN";
|
||||
break;
|
||||
|
||||
case TRANIF0:
|
||||
return "TRANIF0";
|
||||
break;
|
||||
case RTRANIF0:
|
||||
return "RTRANIF0";
|
||||
break;
|
||||
|
||||
case TRANIF1:
|
||||
return "TRANIF1";
|
||||
break;
|
||||
case RTRANIF1:
|
||||
return "RTRANIF1";
|
||||
break;
|
||||
|
||||
case CMOS:
|
||||
return "CMOS";
|
||||
break;
|
||||
case RCMOS:
|
||||
return "RCMOS";
|
||||
break;
|
||||
|
||||
case PULLUP:
|
||||
return "PULLUP";
|
||||
break;
|
||||
case PULLDOWN:
|
||||
return "PULLDOWN";
|
||||
break;
|
||||
}
|
||||
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
|
||||
: PGate(name, pins), bound_type_(0), type_(type), overrides_(0), pins_(0),
|
||||
PGModule::PGModule(const char*type, const string&name, svector<PExpr*>*pins)
|
||||
: PGate(name, pins), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = strdup(type);
|
||||
}
|
||||
|
||||
PGModule::PGModule(perm_string type, perm_string name,
|
||||
PGModule::PGModule(const char*type, const string&name,
|
||||
named<PExpr*>*pins, unsigned npins)
|
||||
: PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins),
|
||||
: PGate(name, 0), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PGModule::PGModule(Module*type, perm_string name)
|
||||
: PGate(name, 0), bound_type_(type), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = strdup(type);
|
||||
}
|
||||
|
||||
PGModule::~PGModule()
|
||||
{
|
||||
free(type_);
|
||||
}
|
||||
|
||||
void PGModule::set_parameters(list<PExpr*>*o)
|
||||
void PGModule::set_parameters(svector<PExpr*>*o)
|
||||
{
|
||||
assert(overrides_ == 0);
|
||||
overrides_ = o;
|
||||
@@ -305,7 +185,58 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
perm_string PGModule::get_type() const
|
||||
const char* PGModule::get_type()
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PGate.cc,v $
|
||||
* Revision 1.13 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.12 2001/10/21 00:42:47 steve
|
||||
* Module types in pform are char* instead of string.
|
||||
*
|
||||
* Revision 1.11 2001/10/19 01:55:32 steve
|
||||
* Method to get the type_ member
|
||||
*
|
||||
* Revision 1.10 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.9 2000/05/06 15:41:56 steve
|
||||
* Carry assignment strength to pform.
|
||||
*
|
||||
* Revision 1.8 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.7 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.6 2000/02/18 05:15:02 steve
|
||||
* Catch module instantiation arrays.
|
||||
*
|
||||
* Revision 1.5 1999/09/14 01:50:35 steve
|
||||
* Handle gates without delays.
|
||||
*
|
||||
* Revision 1.4 1999/09/04 19:11:46 steve
|
||||
* Add support for delayed non-blocking assignments.
|
||||
*
|
||||
* Revision 1.3 1999/08/01 21:18:55 steve
|
||||
* elaborate rise/fall/decay for continuous assign.
|
||||
*
|
||||
* Revision 1.2 1999/08/01 16:34:50 steve
|
||||
* Parse and elaborate rise/fall/decay times
|
||||
* for gates, and handle the rules for partial
|
||||
* lists of times.
|
||||
*
|
||||
* Revision 1.1 1999/02/15 02:06:15 steve
|
||||
* Elaborate gate ranges.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PGate_H
|
||||
#define IVL_PGate_H
|
||||
#ifndef __PGate_H
|
||||
#define __PGate_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,21 +16,22 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.h,v 1.22 2001/11/22 06:20:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "named.h"
|
||||
# include "LineInfo.h"
|
||||
# include "PDelays.h"
|
||||
# include "netlist.h"
|
||||
# include <map>
|
||||
# include <list>
|
||||
# include <vector>
|
||||
# include <string>
|
||||
class PExpr;
|
||||
class PUdp;
|
||||
class Design;
|
||||
class NetScope;
|
||||
class Module;
|
||||
|
||||
/*
|
||||
@@ -48,60 +49,55 @@ class Module;
|
||||
* strength of the 1 drive.
|
||||
*/
|
||||
class PGate : public LineInfo {
|
||||
|
||||
|
||||
public:
|
||||
explicit PGate(perm_string name, list<PExpr*>*pins,
|
||||
const list<PExpr*>*del);
|
||||
enum strength_t { HIGHZ, WEAK, PULL, STRONG, SUPPLY };
|
||||
|
||||
explicit PGate(perm_string name, list<PExpr*>*pins,
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins,
|
||||
const svector<PExpr*>*del);
|
||||
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
|
||||
explicit PGate(perm_string name, list<PExpr*>*pins);
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins);
|
||||
|
||||
virtual ~PGate();
|
||||
|
||||
perm_string get_name() const { return name_; }
|
||||
const string& get_name() const { return name_; }
|
||||
|
||||
// This evaluates the delays as far as possible, but returns
|
||||
// an expression, and do not signal errors.
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
NetExpr*&decay_time,
|
||||
bool as_net_flag =false) const;
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const;
|
||||
|
||||
unsigned delay_count() const;
|
||||
unsigned pin_count() const { return pins_? pins_->count() : 0; }
|
||||
const PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
|
||||
|
||||
unsigned pin_count() const { return pins_.size(); }
|
||||
PExpr*pin(unsigned idx) const { return pins_[idx]; }
|
||||
strength_t strength0() const;
|
||||
strength_t strength1() const;
|
||||
|
||||
ivl_drive_t strength0() const;
|
||||
ivl_drive_t strength1() const;
|
||||
void strength0(strength_t);
|
||||
void strength1(strength_t);
|
||||
|
||||
void strength0(ivl_drive_t);
|
||||
void strength1(ivl_drive_t);
|
||||
map<string,string> attributes;
|
||||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
protected:
|
||||
const vector<PExpr*>& get_pins() const { return pins_; }
|
||||
const svector<PExpr*>* get_pins() const { return pins_; }
|
||||
|
||||
void dump_pins(ostream&out) const;
|
||||
void dump_delays(ostream&out) const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
const string name_;
|
||||
PDelays delay_;
|
||||
vector<PExpr*>pins_;
|
||||
svector<PExpr*>*pins_;
|
||||
|
||||
ivl_drive_t str0_, str1_;
|
||||
|
||||
void set_pins_(list<PExpr*>*pins);
|
||||
strength_t str0_, str1_;
|
||||
|
||||
private: // not implemented
|
||||
PGate(const PGate&);
|
||||
@@ -115,16 +111,14 @@ class PGate : public LineInfo {
|
||||
class PGAssign : public PGate {
|
||||
|
||||
public:
|
||||
explicit PGAssign(list<PExpr*>*pins);
|
||||
explicit PGAssign(list<PExpr*>*pins, list<PExpr*>*dels);
|
||||
explicit PGAssign(svector<PExpr*>*pins);
|
||||
explicit PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels);
|
||||
~PGAssign();
|
||||
|
||||
void dump(ostream&out, unsigned ind =4) const;
|
||||
void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -147,36 +141,23 @@ class PGBuiltin : public PGate {
|
||||
TRANIF1, RTRANIF0, RTRANIF1 };
|
||||
|
||||
public:
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
list<PExpr*>*pins,
|
||||
list<PExpr*>*del);
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
list<PExpr*>*pins,
|
||||
explicit PGBuiltin(Type t, const string&name,
|
||||
svector<PExpr*>*pins,
|
||||
svector<PExpr*>*del);
|
||||
explicit PGBuiltin(Type t, const string&name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
~PGBuiltin();
|
||||
|
||||
Type type() const { return type_; }
|
||||
const char * gate_name() const;
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
unsigned calculate_array_count_(Design*, NetScope*,
|
||||
long&high, long&low) const;
|
||||
|
||||
void calculate_gate_and_lval_count_(unsigned&gate_count,
|
||||
unsigned&lval_count) const;
|
||||
|
||||
NetNode* create_gate_for_output_(Design*, NetScope*,
|
||||
perm_string gate_name,
|
||||
unsigned instance_width) const;
|
||||
|
||||
bool check_delay_count(Design*des) const;
|
||||
|
||||
Type type_;
|
||||
|
||||
PExpr*msb_;
|
||||
PExpr*lsb_;
|
||||
};
|
||||
@@ -190,46 +171,38 @@ class PGBuiltin : public PGate {
|
||||
class PGModule : public PGate {
|
||||
|
||||
public:
|
||||
// The name is the *instance* name of the gate.
|
||||
|
||||
// If the binding of ports is by position, this constructor
|
||||
// builds everything all at once.
|
||||
explicit PGModule(perm_string type, perm_string name,
|
||||
list<PExpr*>*pins);
|
||||
explicit PGModule(const char*type, const string&name,
|
||||
svector<PExpr*>*pins);
|
||||
|
||||
// If the binding of ports is by name, this constructor takes
|
||||
// the bindings and stores them for later elaboration.
|
||||
explicit PGModule(perm_string type, perm_string name,
|
||||
explicit PGModule(const char*type, const string&name,
|
||||
named<PExpr*>*pins, unsigned npins);
|
||||
|
||||
// If the module type is known by design, then use this
|
||||
// constructor.
|
||||
explicit PGModule(Module*type, perm_string name);
|
||||
|
||||
~PGModule();
|
||||
|
||||
// Parameter overrides can come as an ordered list, or a set
|
||||
// of named expressions.
|
||||
void set_parameters(list<PExpr*>*o);
|
||||
void set_parameters(svector<PExpr*>*o);
|
||||
void set_parameters(named<PExpr*>*pa, unsigned npa);
|
||||
|
||||
// Modules can be instantiated in ranges. The parser uses this
|
||||
// method to pass the range to the pform.
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
// This returns the module name of this module. It is a
|
||||
// permallocated string.
|
||||
perm_string get_type() const;
|
||||
const char* get_type();
|
||||
|
||||
private:
|
||||
Module*bound_type_;
|
||||
perm_string type_;
|
||||
list<PExpr*>*overrides_;
|
||||
char* type_;
|
||||
svector<PExpr*>*overrides_;
|
||||
named<PExpr*>*pins_;
|
||||
unsigned npins_;
|
||||
|
||||
@@ -241,23 +214,106 @@ 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;
|
||||
unsigned calculate_instance_count_(Design*, NetScope*,
|
||||
long&high, long&low,
|
||||
perm_string name) const;
|
||||
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
|
||||
void elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const;
|
||||
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
|
||||
// Not currently used.
|
||||
#if 0
|
||||
bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const;
|
||||
#endif
|
||||
|
||||
NetNet*resize_net_to_port_(Design*des, NetScope*scope,
|
||||
NetNet*sig, unsigned port_wid,
|
||||
NetNet::PortType dir, bool as_signed) const;
|
||||
};
|
||||
|
||||
#endif /* IVL_PGate_H */
|
||||
/*
|
||||
* $Log: PGate.h,v $
|
||||
* Revision 1.22 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.21 2001/10/21 00:42:47 steve
|
||||
* Module types in pform are char* instead of string.
|
||||
*
|
||||
* Revision 1.20 2001/10/19 01:55:32 steve
|
||||
* Method to get the type_ member
|
||||
*
|
||||
* Revision 1.19 2001/04/22 23:09:45 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.18 2000/05/06 15:41:56 steve
|
||||
* Carry assignment strength to pform.
|
||||
*
|
||||
* Revision 1.17 2000/05/02 16:27:38 steve
|
||||
* Move signal elaboration to a seperate pass.
|
||||
*
|
||||
* Revision 1.16 2000/03/29 04:37:10 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.15 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.14 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.13 2000/02/18 05:15:02 steve
|
||||
* Catch module instantiation arrays.
|
||||
*
|
||||
* Revision 1.12 2000/01/09 05:50:48 steve
|
||||
* Support named parameter override lists.
|
||||
*
|
||||
* Revision 1.11 1999/12/11 05:45:41 steve
|
||||
* Fix support for attaching attributes to primitive gates.
|
||||
*
|
||||
* Revision 1.10 1999/09/04 19:11:46 steve
|
||||
* Add support for delayed non-blocking assignments.
|
||||
*
|
||||
* Revision 1.9 1999/08/23 16:48:39 steve
|
||||
* Parameter overrides support from Peter Monta
|
||||
* AND and XOR support wide expressions.
|
||||
*
|
||||
* Revision 1.8 1999/08/01 21:18:55 steve
|
||||
* elaborate rise/fall/decay for continuous assign.
|
||||
*
|
||||
* Revision 1.7 1999/08/01 16:34:50 steve
|
||||
* Parse and elaborate rise/fall/decay times
|
||||
* for gates, and handle the rules for partial
|
||||
* lists of times.
|
||||
*
|
||||
* Revision 1.6 1999/05/29 02:36:17 steve
|
||||
* module parameter bind by name.
|
||||
*
|
||||
* Revision 1.5 1999/05/10 00:16:58 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*
|
||||
* Revision 1.4 1999/02/15 02:06:15 steve
|
||||
* Elaborate gate ranges.
|
||||
*
|
||||
* Revision 1.3 1999/01/25 05:45:56 steve
|
||||
* Add the LineInfo class to carry the source file
|
||||
* location of things. PGate, Statement and PProcess.
|
||||
*
|
||||
* elaborate handles module parameter mismatches,
|
||||
* missing or incorrect lvalues for procedural
|
||||
* assignment, and errors are propogated to the
|
||||
* top of the elaboration call tree.
|
||||
*
|
||||
* Attach line numbers to processes, gates and
|
||||
* assignment statements.
|
||||
*
|
||||
* 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/03 23:28:54 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
-114
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2011 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PGenerate.h"
|
||||
# include "PWire.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
PGenerate::PGenerate(LexicalScope*parent, unsigned id)
|
||||
: LexicalScope(parent), id_number(id)
|
||||
{
|
||||
direct_nested_ = false;
|
||||
scheme_type = GS_NONE;
|
||||
loop_init = 0;
|
||||
loop_test = 0;
|
||||
loop_step = 0;
|
||||
}
|
||||
|
||||
PGenerate::~PGenerate()
|
||||
{
|
||||
}
|
||||
|
||||
void PGenerate::add_gate(PGate*gate)
|
||||
{
|
||||
gates.push_back(gate);
|
||||
}
|
||||
|
||||
void PGenerate::probe_for_direct_nesting_(void)
|
||||
{
|
||||
direct_nested_ = false;
|
||||
|
||||
ivl_assert(*this, scheme_type==GS_CASE_ITEM || scheme_type==GS_CONDIT || scheme_type==GS_ELSE);
|
||||
|
||||
// If this scheme has received an explicit name, then it
|
||||
// cannot be direct nested.
|
||||
if (scope_name[0] != '$') return;
|
||||
|
||||
if (! tasks.empty()) return;
|
||||
if (! funcs.empty()) return;
|
||||
if (! gates.empty()) return;
|
||||
if (! parameters.empty()) return;
|
||||
if (! localparams.empty()) return;
|
||||
if (! events.empty()) return;
|
||||
if (! wires.empty()) return;
|
||||
if (! genvars.empty()) return;
|
||||
if (! behaviors.empty()) return;
|
||||
if (! analog_behaviors.empty()) return;
|
||||
|
||||
if (generate_schemes.empty()) return;
|
||||
|
||||
switch (generate_schemes.size()) {
|
||||
case 1: {
|
||||
PGenerate*child = generate_schemes.front();
|
||||
if (child->scheme_type == GS_CONDIT)
|
||||
direct_nested_ = true;
|
||||
if (child->scheme_type == GS_CASE)
|
||||
direct_nested_ = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
PGenerate*child1 = generate_schemes.front();
|
||||
PGenerate*child2 = generate_schemes.back();
|
||||
if (child1->scheme_type==GS_CONDIT && child2->scheme_type==GS_ELSE)
|
||||
direct_nested_ = true;
|
||||
if (child2->scheme_type==GS_CONDIT && child1->scheme_type==GS_ELSE)
|
||||
direct_nested_ = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ostream& operator << (ostream&out, PGenerate::scheme_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case PGenerate::GS_NONE:
|
||||
out << "GS_NONE";
|
||||
break;
|
||||
case PGenerate::GS_LOOP:
|
||||
out << "GS_LOOP";
|
||||
break;
|
||||
case PGenerate::GS_CONDIT:
|
||||
out << "GS_CONDIT";
|
||||
break;
|
||||
case PGenerate::GS_ELSE:
|
||||
out << "GS_ELSE";
|
||||
break;
|
||||
case PGenerate::GS_CASE:
|
||||
out << "GS_CASE";
|
||||
break;
|
||||
case PGenerate::GS_CASE_ITEM:
|
||||
out << "GS_CASE_ITEM";
|
||||
break;
|
||||
case PGenerate::GS_NBLOCK:
|
||||
out << "GS_NBLOCK";
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
-142
@@ -1,142 +0,0 @@
|
||||
#ifndef IVL_PGenerate_H
|
||||
#define IVL_PGenerate_H
|
||||
/*
|
||||
* Copyright (c) 2006-2014 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "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;
|
||||
|
||||
/*
|
||||
* This represents a generate scheme. The interpretation of the
|
||||
* members depends on the scheme_type.
|
||||
*
|
||||
* GS_LOOP
|
||||
*
|
||||
* GS_CASE
|
||||
* loop_test is the expression to be compared.
|
||||
* generates contains only GS_CASE_ITEM schemes.
|
||||
* GS_CASE_ITEM
|
||||
* 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 {
|
||||
|
||||
public:
|
||||
explicit PGenerate(LexicalScope*parent, unsigned id_number);
|
||||
~PGenerate();
|
||||
|
||||
// Generate schemes have an ID number, for when the scope is
|
||||
// implicit.
|
||||
const unsigned id_number;
|
||||
perm_string scope_name;
|
||||
|
||||
// This is used during parsing to stack lexical scopes within
|
||||
// this generate scheme.
|
||||
// LexicalScope*lexical_scope;
|
||||
|
||||
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE,
|
||||
GS_CASE, GS_CASE_ITEM, GS_NBLOCK};
|
||||
scheme_t scheme_type;
|
||||
|
||||
// generate loops have an index variable and three
|
||||
// expressions: for (index = <init>; <test>; index=<step>)
|
||||
perm_string loop_index;
|
||||
PExpr*loop_init;
|
||||
PExpr*loop_test;
|
||||
PExpr*loop_step;
|
||||
// Case items may have multiple guard expression values. It is
|
||||
// enough for any on of the guards to match the case statement
|
||||
// test value.
|
||||
std::valarray<PExpr*> item_test;
|
||||
|
||||
// defparam assignments found in this scope.
|
||||
typedef pair<pform_name_t,PExpr*> named_expr_t;
|
||||
list<named_expr_t>defparms;
|
||||
|
||||
list<PGate*> gates;
|
||||
void add_gate(PGate*);
|
||||
|
||||
// Tasks instantiated within this scheme.
|
||||
map<perm_string,PTask*> tasks;
|
||||
map<perm_string,PFunction*>funcs;
|
||||
|
||||
// Generate schemes can contain further generate schemes.
|
||||
list<PGenerate*> generate_schemes;
|
||||
// PGenerate*parent;
|
||||
|
||||
// This method is called by the elaboration of a module to
|
||||
// generate scopes. the container is the scope that is to
|
||||
// contain the generated scope.
|
||||
bool generate_scope(Design*des, NetScope*container);
|
||||
|
||||
// Elaborate signals within any of the generated scopes that
|
||||
// were made by this generate block within the given container scope.
|
||||
bool elaborate_sig(Design*des, NetScope*container) const;
|
||||
bool elaborate(Design*des, NetScope*container) const;
|
||||
|
||||
void dump(ostream&out, unsigned indent) const;
|
||||
|
||||
private:
|
||||
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 /* IVL_PGenerate_H */
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Stephen Williams ([email protected])
|
||||
* Copyright CERN 2013 / Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PPackage.h"
|
||||
|
||||
PPackage::PPackage(perm_string name, LexicalScope*parent)
|
||||
: PScopeExtra(name, parent)
|
||||
{
|
||||
}
|
||||
|
||||
PPackage::~PPackage()
|
||||
{
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
#ifndef IVL_PPackage_H
|
||||
#define IVL_PPackage_H
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Stephen Williams ([email protected])
|
||||
* Copyright CERN 2013 / Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PScope.h"
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* SystemVerilog supports class declarations with their own lexical
|
||||
* scope, etc. The parser arranges for these to be created and
|
||||
* collected.
|
||||
*/
|
||||
|
||||
class PPackage : public PScopeExtra, public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PPackage (perm_string name, LexicalScope*parent);
|
||||
~PPackage();
|
||||
|
||||
bool elaborate_scope(Design*des, NetScope*scope);
|
||||
bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
bool elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
void pform_dump(std::ostream&out) const;
|
||||
};
|
||||
|
||||
#endif /* IVL_PPackage_H */
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008,2010 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PScope.h"
|
||||
|
||||
PScope::PScope(perm_string n, LexicalScope*parent)
|
||||
: LexicalScope(parent), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PScope::PScope(perm_string n)
|
||||
: LexicalScope(0), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PScope::~PScope()
|
||||
{
|
||||
for(map<perm_string, data_type_t*>::iterator it = typedefs.begin();
|
||||
it != typedefs.end(); ++it)
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
PWire* LexicalScope::wires_find(perm_string name)
|
||||
{
|
||||
map<perm_string,PWire*>::const_iterator cur = wires.find(name);
|
||||
if (cur == wires.end())
|
||||
return 0;
|
||||
else
|
||||
return (*cur).second;
|
||||
}
|
||||
|
||||
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
|
||||
: PScope(n, parent)
|
||||
{
|
||||
}
|
||||
|
||||
PScopeExtra::PScopeExtra(perm_string n)
|
||||
: PScope(n)
|
||||
{
|
||||
}
|
||||
|
||||
PScopeExtra::~PScopeExtra()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
#ifndef IVL_PScope_H
|
||||
#define IVL_PScope_H
|
||||
/*
|
||||
* Copyright (c) 2008-2014 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include "pform_types.h"
|
||||
# include "ivl_target.h"
|
||||
# include <map>
|
||||
# include <set>
|
||||
# include <vector>
|
||||
|
||||
class PEvent;
|
||||
class PExpr;
|
||||
class PFunction;
|
||||
class PPackage;
|
||||
class AProcess;
|
||||
class PProcess;
|
||||
class PClass;
|
||||
class PTask;
|
||||
class PWire;
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
|
||||
/*
|
||||
* The PScope class is a base representation of an object that
|
||||
* represents lexical scope. For example, a module, a function/task, a
|
||||
* named block is derived from a PScope.
|
||||
*
|
||||
* NOTE: This is not the same concept as the "scope" of an elaborated
|
||||
* hierarchy. That is represented by NetScope objects after elaboration.
|
||||
*/
|
||||
|
||||
class LexicalScope {
|
||||
|
||||
public:
|
||||
explicit LexicalScope(LexicalScope*parent) : parent_(parent) { }
|
||||
// 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;
|
||||
|
||||
// Defined types in the scope.
|
||||
map<perm_string,data_type_t*>typedefs;
|
||||
|
||||
// Named events in the scope.
|
||||
map<perm_string,PEvent*>events;
|
||||
|
||||
// Symbols that are imported. Bind the imported name to the
|
||||
// package from which the name is imported.
|
||||
std::map<perm_string,PPackage*>imports;
|
||||
|
||||
// Nets and variables (wires) in the scope
|
||||
map<perm_string,PWire*>wires;
|
||||
PWire* wires_find(perm_string name);
|
||||
|
||||
// Genvars in the scope. These will only be present in module
|
||||
// scopes, but are listed here to allow them to be found when
|
||||
// creating implicit nets.
|
||||
map<perm_string,LineInfo*> genvars;
|
||||
|
||||
// Behaviors (processes) in this scope
|
||||
list<PProcess*> behaviors;
|
||||
list<AProcess*> analog_behaviors;
|
||||
|
||||
// Enumeration sets.
|
||||
std::set<enum_type_t*> enum_sets;
|
||||
|
||||
LexicalScope* parent_scope() const { return parent_; }
|
||||
|
||||
protected:
|
||||
void dump_typedefs_(ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_parameters_(ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_localparams_(ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_enumerations_(ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_events_(ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_wires_(ostream&out, unsigned indent) const;
|
||||
|
||||
private:
|
||||
LexicalScope*parent_;
|
||||
};
|
||||
|
||||
class PScope : public LexicalScope {
|
||||
|
||||
public:
|
||||
// When created, a scope has a name and a parent. The name is
|
||||
// the name of the definition. For example, if this is a
|
||||
// module declaration, the name is the name after the "module"
|
||||
// keyword, and if this is a task scope, the name is the task
|
||||
// name. The parent is the lexical parent of this scope. Since
|
||||
// modules do not nest in Verilog, the parent must be nil for
|
||||
// modules. Scopes for tasks and functions point to their
|
||||
// containing module.
|
||||
PScope(perm_string name, LexicalScope*parent);
|
||||
PScope(perm_string name);
|
||||
virtual ~PScope();
|
||||
|
||||
perm_string pscope_name() const { return name_; }
|
||||
|
||||
protected:
|
||||
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
|
||||
|
||||
bool elaborate_behaviors_(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
};
|
||||
|
||||
/*
|
||||
* Some scopes can carry definitions. These include Modules and PClass
|
||||
* scopes. These derive from PScopeExtra so that they hold the maps of
|
||||
* extra definitions.
|
||||
*/
|
||||
class PScopeExtra : public PScope {
|
||||
|
||||
public:
|
||||
PScopeExtra(perm_string, LexicalScope*parent);
|
||||
PScopeExtra(perm_string);
|
||||
~PScopeExtra();
|
||||
|
||||
/* Task definitions within this module */
|
||||
std::map<perm_string,PTask*> tasks;
|
||||
std::map<perm_string,PFunction*> funcs;
|
||||
/* class definitions within this module. */
|
||||
std::map<perm_string,PClass*> classes;
|
||||
/* This is the lexical order of the classes, and is used by
|
||||
elaboration to choose an elaboration order. */
|
||||
std::vector<PClass*> classes_lexical;
|
||||
|
||||
protected:
|
||||
void dump_classes_(ostream&out, unsigned indent) const;
|
||||
void dump_tasks_(ostream&out, unsigned indent) const;
|
||||
void dump_funcs_(ostream&out, unsigned indent) const;
|
||||
};
|
||||
|
||||
#endif /* IVL_PScope_H */
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2011 Stephen Williams <[email protected]>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PSpec.h"
|
||||
|
||||
PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity,
|
||||
bool full_flag)
|
||||
: conditional(false), condition(0), edge(0),
|
||||
src(src_cnt), dst(dst_cnt),
|
||||
data_source_expression(0)
|
||||
{
|
||||
full_flag_ = full_flag;
|
||||
polarity_ = polarity;
|
||||
}
|
||||
|
||||
PSpecPath::~PSpecPath()
|
||||
{
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
#ifndef IVL_PSpec_H
|
||||
#define IVL_PSpec_H
|
||||
/*
|
||||
* Copyright (c) 2006-2014 Stephen Williams <[email protected]>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <vector>
|
||||
|
||||
class PExpr;
|
||||
|
||||
/*
|
||||
* The PSpecPath is the parse of a specify path, which is in its most
|
||||
* general form <path> = <delays>. The <delays> are collected into the
|
||||
* "delays" vector in all cases, and the variety is in the other
|
||||
* members.
|
||||
*
|
||||
* All paths also have a list of source names in the src vector, and a
|
||||
* list of destination names in the dst vector. These pairs are the
|
||||
* actual paths.
|
||||
*
|
||||
* If the path is a simple path, then:
|
||||
* condition == nil
|
||||
* edge == 0
|
||||
* data_source_expression == nil
|
||||
*
|
||||
* If the path is conditional, then conditional == true and condition
|
||||
* is the condition expression. If the condition expression is nil,
|
||||
* then this is an ifnone conditional path.
|
||||
*
|
||||
* If data_source_expression != nil, then the path is edge sensitive
|
||||
* and the edge might not be 0.
|
||||
*
|
||||
* The full flag is used to verify that only vectors of the same size
|
||||
* are used in a parallel connection. Icarus always creates a full
|
||||
* connection between the source and destination. The polarity is for
|
||||
* informational (display) purposes only. The polarity is either '+',
|
||||
* '-' or 0.
|
||||
*/
|
||||
class PSpecPath : public LineInfo {
|
||||
|
||||
public:
|
||||
PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity,
|
||||
bool full_flag);
|
||||
~PSpecPath();
|
||||
|
||||
void elaborate(class Design*des, class NetScope*scope) const;
|
||||
|
||||
void dump(std::ostream&out, unsigned ind) const;
|
||||
|
||||
public:
|
||||
// Condition expression, if present.
|
||||
bool conditional;
|
||||
class PExpr* condition;
|
||||
// Edge specification (-1==negedge, 0 = no edge, 1==posedge)
|
||||
int edge;
|
||||
// Is this a full connection.
|
||||
bool full_flag_;
|
||||
// What is the polarity of the connection.
|
||||
char polarity_;
|
||||
// Ordered set of source nodes of a path
|
||||
std::vector<perm_string> src;
|
||||
// Ordered set of destination nodes of a path
|
||||
std::vector<perm_string> dst;
|
||||
// Data source expression
|
||||
class PExpr* data_source_expression;
|
||||
|
||||
std::vector<class PExpr*>delays;
|
||||
};
|
||||
|
||||
#endif /* IVL_PSpec_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2008,2010 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
|
||||
@@ -14,57 +14,58 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PTask.cc,v 1.6 2001/07/25 03:10:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PTask.h"
|
||||
# include <cassert>
|
||||
|
||||
PTaskFunc::PTaskFunc(perm_string n, LexicalScope*p)
|
||||
: PScope(n,p), this_type_(0), ports_(0)
|
||||
PTask::PTask()
|
||||
: ports_(0), statement_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PTaskFunc::~PTaskFunc()
|
||||
{
|
||||
}
|
||||
|
||||
void PTaskFunc::set_ports(vector<pform_tf_port_t>*p)
|
||||
{
|
||||
assert(ports_ == 0);
|
||||
ports_ = p;
|
||||
}
|
||||
|
||||
void PTaskFunc::set_this(class_type_t*type, PWire*this_wire)
|
||||
{
|
||||
assert(this_type_ == 0);
|
||||
this_type_ = type;
|
||||
|
||||
// Push a synthethis argument that is the "this" value.
|
||||
if (ports_==0)
|
||||
ports_ = new vector<pform_tf_port_t>;
|
||||
|
||||
size_t use_size = ports_->size();
|
||||
ports_->resize(use_size + 1);
|
||||
for (size_t idx = use_size ; idx > 0 ; idx -= 1)
|
||||
ports_->at(idx) = ports_->at(idx-1);
|
||||
|
||||
ports_->at(0) = pform_tf_port_t(this_wire);
|
||||
}
|
||||
|
||||
PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__)
|
||||
: PTaskFunc(name, parent), statement_(0)
|
||||
{
|
||||
is_auto_ = is_auto__;
|
||||
}
|
||||
|
||||
PTask::~PTask()
|
||||
{
|
||||
}
|
||||
|
||||
void PTask::set_ports(svector<PWire*>*p)
|
||||
{
|
||||
assert(ports_ == 0);
|
||||
ports_ = p;
|
||||
}
|
||||
|
||||
void PTask::set_statement(Statement*s)
|
||||
{
|
||||
assert(statement_ == 0);
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: PTask.cc,v $
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PTask_H
|
||||
#define IVL_PTask_H
|
||||
#ifndef __PTask_H
|
||||
#define __PTask_H
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-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,69 +16,30 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PTask.h,v 1.11 2001/11/22 06:20:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "PScope.h"
|
||||
# include "StringHeap.h"
|
||||
# include "svector.h"
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include <list>
|
||||
class Design;
|
||||
class NetExpr;
|
||||
class NetNet;
|
||||
class NetScope;
|
||||
class PChainConstructor;
|
||||
class PWire;
|
||||
class Statement;
|
||||
class PExpr;
|
||||
|
||||
|
||||
class PTaskFunc : public PScope, public LineInfo {
|
||||
|
||||
public:
|
||||
PTaskFunc(perm_string name, LexicalScope*parent);
|
||||
~PTaskFunc();
|
||||
|
||||
void set_ports(std::vector<pform_tf_port_t>*p);
|
||||
|
||||
void set_this(class_type_t*use_type, PWire*this_wire);
|
||||
|
||||
// If this task is a method of a class, this returns a pointer
|
||||
// to the class type.
|
||||
inline class_type_t* method_of() const { return this_type_; }
|
||||
|
||||
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const =0;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const =0;
|
||||
|
||||
virtual void dump(std::ostream&, unsigned) const =0;
|
||||
|
||||
protected:
|
||||
// Elaborate the ports list. Write into the ports vector the
|
||||
// NetNet pointers for the ports, and write into the pdefs the
|
||||
// default value expressions, if any.
|
||||
void elaborate_sig_ports_(Design*des, NetScope*scope,
|
||||
std::vector<NetNet*>&ports,
|
||||
std::vector<NetExpr*>&pdefs) const;
|
||||
|
||||
void dump_ports_(std::ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
class_type_t*this_type_;
|
||||
std::vector<pform_tf_port_t>*ports_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The PTask holds the parsed definitions of a task.
|
||||
*/
|
||||
class PTask : public PTaskFunc {
|
||||
class PTask : public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
|
||||
explicit PTask();
|
||||
~PTask();
|
||||
|
||||
void set_ports(svector<PWire *>*p);
|
||||
void set_statement(Statement *s);
|
||||
|
||||
// Tasks introduce scope, to need to be handled during the
|
||||
@@ -93,13 +54,11 @@ class PTask : public PTaskFunc {
|
||||
// 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&);
|
||||
@@ -110,29 +69,16 @@ class PTask : public PTaskFunc {
|
||||
* The function is similar to a task (in this context) but there is a
|
||||
* single output port and a set of input ports. The output port is the
|
||||
* function return value.
|
||||
*
|
||||
* The output value is not elaborated until elaborate_sig.
|
||||
*/
|
||||
class PFunction : public PTaskFunc {
|
||||
class PFunction : public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
|
||||
explicit PFunction();
|
||||
~PFunction();
|
||||
|
||||
void set_ports(svector<PWire *>*p);
|
||||
void set_statement(Statement *s);
|
||||
void set_return(data_type_t*t);
|
||||
|
||||
inline Statement* get_statement() { return statement_; }
|
||||
|
||||
// Push this statement to the front of the existing
|
||||
// definition. If the statement is a simple statement, make a
|
||||
// block to contain the statements.
|
||||
void push_statement_front(Statement*stmt);
|
||||
|
||||
// This is only used if this function is a constructor. In
|
||||
// that case, this method looks for a PChainConstructor in the
|
||||
// statement and extracts it if found.
|
||||
PChainConstructor*extract_chain_constructor();
|
||||
void set_output(PWire*);
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -142,14 +88,59 @@ class PFunction : public PTaskFunc {
|
||||
/* Elaborate the behavioral statement. */
|
||||
void elaborate(Design *des, NetScope*) const;
|
||||
|
||||
bool is_auto() const { return is_auto_; };
|
||||
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
data_type_t* return_type_;
|
||||
PWire*out_;
|
||||
svector<PWire *> *ports_;
|
||||
Statement *statement_;
|
||||
bool is_auto_;
|
||||
};
|
||||
|
||||
#endif /* IVL_PTask_H */
|
||||
/*
|
||||
* $Log: PTask.h,v $
|
||||
* Revision 1.11 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.10 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
* Revision 1.9 2000/07/30 18:25:43 steve
|
||||
* Rearrange task and function elaboration so that the
|
||||
* NetTaskDef and NetFuncDef functions are created during
|
||||
* signal enaboration, and carry these objects in the
|
||||
* NetScope class instead of the extra, useless map in
|
||||
* the Design class.
|
||||
*
|
||||
* Revision 1.8 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.7 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.6 1999/09/30 21:28:34 steve
|
||||
* Handle mutual reference of tasks by elaborating
|
||||
* task definitions in two passes, like functions.
|
||||
*
|
||||
* Revision 1.5 1999/09/01 20:46:19 steve
|
||||
* Handle recursive functions and arbitrary function
|
||||
* references to other functions, properly pass
|
||||
* function parameters and save function results.
|
||||
*
|
||||
* Revision 1.4 1999/08/25 22:22:41 steve
|
||||
* elaborate some aspects of functions.
|
||||
*
|
||||
* Revision 1.3 1999/07/31 19:14:47 steve
|
||||
* Add functions up to elaboration (Ed Carter)
|
||||
*
|
||||
* Revision 1.2 1999/07/24 02:11:19 steve
|
||||
* Elaborate task input ports.
|
||||
*
|
||||
* Revision 1.1 1999/07/03 02:12:51 steve
|
||||
* Elaborate user defined tasks.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-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
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PUdp.h"
|
||||
|
||||
PUdp::PUdp(perm_string n, unsigned nports)
|
||||
: ports(nports), sequential(false), initial(verinum::Vx), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned PUdp::find_port(const char*name)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
|
||||
if (ports[idx] == name)
|
||||
return idx;
|
||||
}
|
||||
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PUdp_H
|
||||
#define IVL_PUdp_H
|
||||
#ifndef __PUdp_H
|
||||
#define __PUdp_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-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,22 +16,27 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PUdp.h,v 1.5 2001/04/22 23:09:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <map>
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include "svector.h"
|
||||
# include <string>
|
||||
# include "verinum.h"
|
||||
|
||||
class PExpr;
|
||||
svector<string>::svector<string>(unsigned size)
|
||||
: nitems_(size), items_(new string[size])
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* This class represents a parsed UDP. This is a much simpler object
|
||||
* than a module or macromodule.
|
||||
* then a module or macromodule.
|
||||
*
|
||||
* - all ports are scalar,
|
||||
* - all ports are scaler,
|
||||
* - pin 0 (the first port) is always output,
|
||||
* and the remaining pins are input.
|
||||
*
|
||||
@@ -46,16 +51,15 @@ class PExpr;
|
||||
* the current output.
|
||||
*
|
||||
* If the UDP is sequential, the "initial" member is taken to be the
|
||||
* initial value assigned in the source, or 'x' if none is given.
|
||||
* intial value assigned in the source, or 'x' if none is given.
|
||||
*/
|
||||
class PUdp : public LineInfo {
|
||||
class PUdp {
|
||||
|
||||
public:
|
||||
explicit PUdp(perm_string n, unsigned nports);
|
||||
explicit PUdp(const string&n, unsigned nports)
|
||||
: ports(nports), sequential(false), initial(verinum::Vx), name_(n) { }
|
||||
|
||||
svector<string>ports;
|
||||
unsigned find_port(const char*name);
|
||||
|
||||
bool sequential;
|
||||
|
||||
svector<string>tinput;
|
||||
@@ -64,11 +68,11 @@ class PUdp : public LineInfo {
|
||||
|
||||
verinum::V initial;
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
map<string,string> attributes;
|
||||
|
||||
void dump(ostream&out) const;
|
||||
|
||||
perm_string name_;
|
||||
const string name_;
|
||||
private:
|
||||
|
||||
private: // Not implemented
|
||||
@@ -76,4 +80,27 @@ class PUdp : public LineInfo {
|
||||
PUdp& operator= (const PUdp&);
|
||||
};
|
||||
|
||||
#endif /* IVL_PUdp_H */
|
||||
/*
|
||||
* $Log: PUdp.h,v $
|
||||
* 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2012 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
|
||||
@@ -14,29 +14,25 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PWire.cc,v 1.8 2002/01/26 05:28:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "PWire.h"
|
||||
# include "PExpr.h"
|
||||
# include <cassert>
|
||||
|
||||
PWire::PWire(perm_string n,
|
||||
NetNet::Type t,
|
||||
NetNet::PortType pt,
|
||||
ivl_variable_type_t dt)
|
||||
: name_(n), type_(t), port_type_(pt), data_type_(dt),
|
||||
signed_(false), isint_(false),
|
||||
port_set_(false), net_set_(false), is_scalar_(false),
|
||||
error_cnt_(0), set_data_type_(0),
|
||||
discipline_(0)
|
||||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
|
||||
: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt)
|
||||
: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
|
||||
{
|
||||
if (t == NetNet::INTEGER) {
|
||||
type_ = NetNet::REG;
|
||||
signed_ = true;
|
||||
isint_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
NetNet::Type PWire::get_wire_type() const
|
||||
@@ -44,9 +40,9 @@ NetNet::Type PWire::get_wire_type() const
|
||||
return type_;
|
||||
}
|
||||
|
||||
perm_string PWire::basename() const
|
||||
const hname_t& PWire::path() const
|
||||
{
|
||||
return name_;
|
||||
return hname_;
|
||||
}
|
||||
|
||||
bool PWire::set_wire_type(NetNet::Type t)
|
||||
@@ -58,21 +54,9 @@ bool PWire::set_wire_type(NetNet::Type t)
|
||||
type_ = t;
|
||||
return true;
|
||||
case NetNet::IMPLICIT_REG:
|
||||
if (t == NetNet::REG) {
|
||||
type_ = t;
|
||||
return true;
|
||||
}
|
||||
if (t == NetNet::INTEGER) {
|
||||
type_ = NetNet::REG;
|
||||
isint_ = true;
|
||||
return true;
|
||||
}
|
||||
if (t == NetNet::REG) { type_ = t; return true; }
|
||||
return false;
|
||||
case NetNet::REG:
|
||||
if (t == NetNet::INTEGER) {
|
||||
isint_ = true;
|
||||
return true;
|
||||
}
|
||||
if (t == NetNet::REG) return true;
|
||||
return false;
|
||||
default:
|
||||
@@ -109,26 +93,6 @@ bool PWire::set_port_type(NetNet::PortType pt)
|
||||
}
|
||||
}
|
||||
|
||||
bool PWire::set_data_type(ivl_variable_type_t dt)
|
||||
{
|
||||
if (data_type_ != IVL_VT_NO_TYPE) {
|
||||
if (data_type_ != dt)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
assert(data_type_ == IVL_VT_NO_TYPE);
|
||||
data_type_ = dt;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ivl_variable_type_t PWire::get_data_type() const
|
||||
{
|
||||
return data_type_;
|
||||
}
|
||||
|
||||
void PWire::set_signed(bool flag)
|
||||
{
|
||||
signed_ = flag;
|
||||
@@ -139,146 +103,50 @@ bool PWire::get_signed() const
|
||||
return signed_;
|
||||
}
|
||||
|
||||
bool PWire::get_isint() const
|
||||
void PWire::set_range(PExpr*m, PExpr*l)
|
||||
{
|
||||
if (isint_)
|
||||
return true;
|
||||
|
||||
if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(set_data_type_)) {
|
||||
return tmp->integer_flag;
|
||||
}
|
||||
|
||||
return false;
|
||||
msb_ = svector<PExpr*>(msb_,m);
|
||||
lsb_ = svector<PExpr*>(lsb_,l);
|
||||
}
|
||||
|
||||
bool PWire::get_scalar() const
|
||||
void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||
{
|
||||
return is_scalar_;
|
||||
assert(lidx_ == 0);
|
||||
assert(ridx_ == 0);
|
||||
assert(type_ == NetNet::REG);
|
||||
lidx_ = ldx;
|
||||
ridx_ = rdx;
|
||||
}
|
||||
|
||||
void PWire::set_range_scalar(PWSRType type)
|
||||
{
|
||||
is_scalar_ = true;
|
||||
switch (type) {
|
||||
case SR_PORT:
|
||||
if (port_set_) {
|
||||
cerr << get_fileline() << ": error: Port ``" << name_
|
||||
<< "'' has already been declared a port." << endl;
|
||||
error_cnt_ += 1;
|
||||
} else {
|
||||
port_set_ = true;
|
||||
}
|
||||
return;
|
||||
/*
|
||||
* $Log: PWire.cc,v $
|
||||
* Revision 1.8 2002/01/26 05:28:28 steve
|
||||
* Detect scalar/vector declarion mismatch.
|
||||
*
|
||||
* Revision 1.7 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* 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/01/06 02:29:35 steve
|
||||
* Support arrays of integers.
|
||||
*
|
||||
* Revision 1.4 2000/12/11 00:31:43 steve
|
||||
* Add support for signed reg variables,
|
||||
* simulate in t-vvm signed comparisons.
|
||||
*
|
||||
* Revision 1.3 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.2 1999/09/10 05:02:09 steve
|
||||
* Handle integers at task parameters.
|
||||
*
|
||||
* Revision 1.1 1999/06/17 05:34:42 steve
|
||||
* Clean up interface of the PWire class,
|
||||
* Properly match wire ranges.
|
||||
*
|
||||
*/
|
||||
|
||||
case SR_NET:
|
||||
if (net_set_) {
|
||||
cerr << get_fileline() << ": error: Net ``" << name_
|
||||
<< "'' has already been declared." << endl;
|
||||
error_cnt_ += 1;
|
||||
} else {
|
||||
net_set_ = true;
|
||||
}
|
||||
return;
|
||||
|
||||
case SR_BOTH:
|
||||
if (port_set_ || net_set_) {
|
||||
if (port_set_) {
|
||||
cerr << get_fileline() << ": error: Port ``" << name_
|
||||
<< "'' has already been declared a port." << endl;
|
||||
error_cnt_ += 1;
|
||||
}
|
||||
if (net_set_) {
|
||||
cerr << get_fileline() << ": error: Net ``" << name_
|
||||
<< "'' has already been declared." << endl;
|
||||
error_cnt_ += 1;
|
||||
}
|
||||
} else {
|
||||
port_set_ = true;
|
||||
net_set_ = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PWire::set_range(const list<pform_range_t>&rlist, PWSRType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SR_PORT:
|
||||
if (port_set_) {
|
||||
cerr << get_fileline() << ": error: Port ``" << name_
|
||||
<< "'' has already been declared a port." << endl;
|
||||
error_cnt_ += 1;
|
||||
} else {
|
||||
port_ = rlist;
|
||||
port_set_ = true;
|
||||
is_scalar_ = false;
|
||||
}
|
||||
return;
|
||||
|
||||
case SR_NET:
|
||||
if (net_set_) {
|
||||
cerr << get_fileline() << ": error: Net ``" << name_
|
||||
<< "'' has already been declared." << endl;
|
||||
error_cnt_ += 1;
|
||||
} else {
|
||||
net_ = rlist;
|
||||
net_set_ = true;
|
||||
is_scalar_ = false;
|
||||
}
|
||||
return;
|
||||
|
||||
case SR_BOTH:
|
||||
if (port_set_ || net_set_) {
|
||||
if (port_set_) {
|
||||
cerr << get_fileline() << ": error: Port ``" << name_
|
||||
<< "'' has already been declared a port." << endl;
|
||||
error_cnt_ += 1;
|
||||
}
|
||||
if (net_set_) {
|
||||
cerr << get_fileline() << ": error: Net ``" << name_
|
||||
<< "'' has already been declared." << endl;
|
||||
error_cnt_ += 1;
|
||||
}
|
||||
} else {
|
||||
port_ = rlist;
|
||||
port_set_ = true;
|
||||
net_ = rlist;
|
||||
net_set_ = true;
|
||||
is_scalar_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PWire::set_unpacked_idx(const list<pform_range_t>&ranges)
|
||||
{
|
||||
if (! unpacked_.empty()) {
|
||||
cerr << get_fileline() << ": error: Array ``" << name_
|
||||
<< "'' has already been declared." << endl;
|
||||
error_cnt_ += 1;
|
||||
} else {
|
||||
unpacked_ = ranges;
|
||||
}
|
||||
}
|
||||
|
||||
void PWire::set_data_type(data_type_t*type)
|
||||
{
|
||||
assert(set_data_type_ == 0);
|
||||
set_data_type_ = type;
|
||||
|
||||
if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(type)) {
|
||||
if (tmp->integer_flag)
|
||||
isint_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PWire::set_discipline(ivl_discipline_t d)
|
||||
{
|
||||
assert(discipline_ == 0);
|
||||
discipline_ = d;
|
||||
}
|
||||
|
||||
ivl_discipline_t PWire::get_discipline(void) const
|
||||
{
|
||||
return discipline_;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PWire_H
|
||||
#define IVL_PWire_H
|
||||
#ifndef __PWire_H
|
||||
#define __PWire_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-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,14 +16,16 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PWire.h,v 1.11 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
# include "LineInfo.h"
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "StringHeap.h"
|
||||
# include "svector.h"
|
||||
|
||||
#ifdef HAVE_IOSFWD
|
||||
# include <iosfwd>
|
||||
@@ -33,34 +35,26 @@ class ostream;
|
||||
|
||||
class PExpr;
|
||||
class Design;
|
||||
class netdarray_t;
|
||||
|
||||
/*
|
||||
* The different type of PWire::set_range() calls.
|
||||
*/
|
||||
enum PWSRType {SR_PORT, SR_NET, SR_BOTH};
|
||||
|
||||
/*
|
||||
* Wires include nets, registers and ports. A net or register becomes
|
||||
* a port by declaration, so ports are not separate. The module
|
||||
* a port by declaration, so ports are not seperate. The module
|
||||
* identifies a port by keeping it in its port list.
|
||||
*
|
||||
* The hname parameter to the constructor is a hierarchical name. It
|
||||
* is the name of the wire within a module, so does not include the
|
||||
* current scope or any instances. Modules contain all the wires, so
|
||||
* from that perspective, sub-scopes within the module are a part of
|
||||
* the wire name.
|
||||
* is an array of strings starting with the root, running towards
|
||||
* the base name, and terminated by a null pointer. The environment
|
||||
* allocates the memory for me.
|
||||
*/
|
||||
class PWire : public LineInfo {
|
||||
|
||||
public:
|
||||
PWire(perm_string name,
|
||||
NetNet::Type t,
|
||||
NetNet::PortType pt,
|
||||
ivl_variable_type_t dt);
|
||||
PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt);
|
||||
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
|
||||
|
||||
// Return a hierarchical name.
|
||||
perm_string basename() const;
|
||||
//const string name() const;
|
||||
const hname_t&path() const;
|
||||
|
||||
NetNet::Type get_wire_type() const;
|
||||
bool set_wire_type(NetNet::Type);
|
||||
@@ -70,63 +64,81 @@ 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);
|
||||
|
||||
void set_range_scalar(PWSRType type);
|
||||
void set_range(const std::list<pform_range_t>&ranges, PWSRType type);
|
||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||
|
||||
void set_unpacked_idx(const std::list<pform_range_t>&ranges);
|
||||
|
||||
void set_data_type(data_type_t*type);
|
||||
|
||||
void set_discipline(ivl_discipline_t);
|
||||
ivl_discipline_t get_discipline(void) const;
|
||||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
map<string,string> attributes;
|
||||
|
||||
// Write myself to the specified stream.
|
||||
void dump(ostream&out, unsigned ind=4) const;
|
||||
void dump(ostream&out) const;
|
||||
|
||||
NetNet* elaborate_sig(Design*, NetScope*scope) const;
|
||||
void elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
hname_t hname_;
|
||||
NetNet::Type type_;
|
||||
NetNet::PortType port_type_;
|
||||
ivl_variable_type_t data_type_;
|
||||
bool signed_;
|
||||
bool isint_; // original type of integer
|
||||
|
||||
// These members hold expressions for the bit width of the
|
||||
// wire. If they do not exist, the wire is 1 bit wide. If they
|
||||
// do exist, they represent the packed dimensions of the
|
||||
// bit. The first item in the list is the first range, and so
|
||||
// on. For example "reg [3:0][7:0] ..." will contains the
|
||||
// range_t object for [3:0] first and [7:0] last.
|
||||
std::list<pform_range_t>port_;
|
||||
bool port_set_;
|
||||
std::list<pform_range_t>net_;
|
||||
bool net_set_;
|
||||
bool is_scalar_;
|
||||
unsigned error_cnt_;
|
||||
// wire. If they do not exist, the wire is 1 bit wide.
|
||||
svector<PExpr*>msb_;
|
||||
svector<PExpr*>lsb_;
|
||||
|
||||
// If this wire is actually a memory, these indices will give
|
||||
// me the size and address ranges of the memory.
|
||||
std::list<pform_range_t>unpacked_;
|
||||
|
||||
// This is the complex type of the wire. the data_type_ may
|
||||
// modify how this is interpreted.
|
||||
data_type_t*set_data_type_;
|
||||
|
||||
ivl_discipline_t discipline_;
|
||||
// me the size and address range of the memory.
|
||||
PExpr*lidx_;
|
||||
PExpr*ridx_;
|
||||
|
||||
private: // not implemented
|
||||
PWire(const PWire&);
|
||||
PWire& operator= (const PWire&);
|
||||
};
|
||||
|
||||
#endif /* IVL_PWire_H */
|
||||
/*
|
||||
* $Log: PWire.h,v $
|
||||
* Revision 1.11 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.10 2001/01/16 02:44:18 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
* Revision 1.9 2000/12/11 00:31:43 steve
|
||||
* Add support for signed reg variables,
|
||||
* simulate in t-vvm signed comparisons.
|
||||
*
|
||||
* Revision 1.8 2000/05/02 16:27:38 steve
|
||||
* Move signal elaboration to a seperate pass.
|
||||
*
|
||||
* Revision 1.7 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.6 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
* Revision 1.5 1999/06/17 05:34:42 steve
|
||||
* Clean up interface of the PWire class,
|
||||
* Properly match wire ranges.
|
||||
*
|
||||
* Revision 1.4 1999/06/02 15:38:46 steve
|
||||
* Line information with nets.
|
||||
*
|
||||
* Revision 1.3 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.2 1998/11/23 00:20:22 steve
|
||||
* NetAssign handles lvalues as pin links
|
||||
* instead of a signal pointer,
|
||||
* Wire attributes added,
|
||||
* Ability to parse UDP descriptions added,
|
||||
* XNF generates EXT records for signals with
|
||||
* the PAD attribute.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:55 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
+3
-3
@@ -16,8 +16,8 @@ execute even the most trivial design. For the purposes of simulation,
|
||||
we use as our example *the* most trivial simulation:
|
||||
|
||||
module main;
|
||||
|
||||
initial
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hello, World");
|
||||
$finish ;
|
||||
@@ -79,5 +79,5 @@ Verilog packages from the main Debian software site.
|
||||
|
||||
* Install From Source
|
||||
|
||||
In this case, see README.txt and other documentation that comes with
|
||||
In this case, see the readme and other documentation that comes with
|
||||
the source.
|
||||
|
||||
+222
-207
@@ -1,5 +1,5 @@
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
Copyright 2000-2004 Stephen Williams
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
September 17, 2000
|
||||
|
||||
|
||||
1.0 What is ICARUS Verilog?
|
||||
@@ -8,11 +8,15 @@ Icarus Verilog is intended to compile ALL of the Verilog HDL as
|
||||
described in the IEEE-1364 standard. Of course, it's not quite there
|
||||
yet. It does currently handle a mix of structural and behavioral
|
||||
constructs. For a view of the current state of Icarus Verilog, see its
|
||||
home page at <http://iverilog.icarus.com/>.
|
||||
|
||||
home page at <http://www.icarus.com/eda/verilog>.
|
||||
|
||||
Icarus Verilog is not aimed at being a simulator in the traditional
|
||||
sense, but a compiler that generates code employed by back-end
|
||||
tools.
|
||||
tools. These back-end tools currently include a simulator written in
|
||||
C++ called VVM, another faster simulator 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.
|
||||
@@ -36,7 +40,7 @@ on a UNIX-like system:
|
||||
- GNU Make
|
||||
The Makefiles use some GNU extensions, so a basic POSIX
|
||||
make will not work. Linux systems typically come with a
|
||||
satisfactory make. BSD based systems (i.e., NetBSD, FreeBSD)
|
||||
satisfactory make. BSD based systems (i.e. NetBSD, FreeBSD)
|
||||
typically have GNU make as the gmake program.
|
||||
|
||||
- ISO C++ Compiler
|
||||
@@ -56,22 +60,6 @@ on a UNIX-like system:
|
||||
A version problem with this program is the most common cause
|
||||
of difficulty. See the Icarus Verilog FAQ.
|
||||
|
||||
- readline 4.2
|
||||
On Linux systems, this usually means the readline-devel
|
||||
rpm. In any case, it is the development headers of readline
|
||||
that are needed.
|
||||
|
||||
- termcap
|
||||
The readline library in turn uses termcap.
|
||||
|
||||
If you are building from git, you will also need software to generate
|
||||
the configure scripts.
|
||||
|
||||
- autoconf 2.53
|
||||
This generates configure scripts from configure.in. The 2.53
|
||||
or later versions are known to work, autoconf 2.13 is
|
||||
reported to *not* work.
|
||||
|
||||
2.2 Compilation
|
||||
|
||||
Unpack the tar-ball and cd into the verilog-######### directory
|
||||
@@ -81,10 +69,14 @@ with the commands:
|
||||
./configure
|
||||
make
|
||||
|
||||
Normally, this command automatically figures out everything it needs
|
||||
Normally, this command automatically figures out every thing 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,17 +87,6 @@ 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.
|
||||
|
||||
2.3 (Optional) Testing
|
||||
|
||||
To run a simple test before installation, execute
|
||||
@@ -150,15 +131,14 @@ only sees a single input file. See ivlpp/ivlpp.txt for details.
|
||||
3.2 Parse
|
||||
|
||||
The Verilog compiler starts by parsing the Verilog source file. The
|
||||
output of the parse is a list of Module objects in "pform". The pform
|
||||
output of the parse in a list of Module objects in PFORM. The pform
|
||||
(see pform.h) is mostly a direct reflection of the compilation
|
||||
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.)
|
||||
One can see a human readable version of the final PFORM by using the
|
||||
``-P <path>'' flag to the compiler. This will cause iverilog to dump
|
||||
the PFORM into the file named <path>.
|
||||
|
||||
3.3 Elaboration
|
||||
|
||||
@@ -173,10 +153,10 @@ The elaborate() function performs the elaboration.
|
||||
|
||||
One can see a human readable version of the final, elaborated and
|
||||
optimized netlist by using the ``-N <path>'' flag to the compiler. If
|
||||
elaboration succeeds, the final netlist (i.e., after optimizations but
|
||||
elaboration succeeds, the final netlist (i.e. after optimizations but
|
||||
before code generation) will be dumped into the file named <path>.
|
||||
|
||||
Elaboration is actually performed in two steps: scopes and parameters
|
||||
Elaboration is actually performed it two steps: scopes and parameters
|
||||
first, followed by the structural and behavioral elaboration.
|
||||
|
||||
3.3.1 Scope Elaboration
|
||||
@@ -184,7 +164,8 @@ first, followed by the structural and behavioral elaboration.
|
||||
This pass scans through the pform looking for scopes and parameters. A
|
||||
tree of NetScope objects is built up and placed in the Design object,
|
||||
with the root module represented by the root NetScope object. The
|
||||
elab_scope.cc file contains most of the code for handling this phase.
|
||||
elab_scope.cc and elab_pexpr.cc files contain most of the code for
|
||||
handling this phase.
|
||||
|
||||
The tail of the elaborate_scope behavior (after the pform is
|
||||
traversed) includes a scan of the NetScope tree to locate defparam
|
||||
@@ -204,19 +185,19 @@ simply passing through the pform.
|
||||
|
||||
This is actually a collection of processing steps that perform
|
||||
optimizations that do not depend on the target technology. Examples of
|
||||
some useful transformations are
|
||||
some useful transformations would be,
|
||||
|
||||
- eliminate null effect circuitry
|
||||
- eliminate null effect circuitry,
|
||||
- combinational reduction
|
||||
- constant propagation
|
||||
|
||||
The actual functions performed are specified on the ivl command line by
|
||||
the -F flags (see below).
|
||||
the -F flags (See below).
|
||||
|
||||
3.5 Code Generation
|
||||
|
||||
This step takes the design netlist and uses it to drive the code
|
||||
generator (see target.h). This may require transforming the
|
||||
generator. (See target.h.) This may require transforming the
|
||||
design to suit the technology.
|
||||
|
||||
The emit() method of the Design class performs this step. It runs
|
||||
@@ -228,16 +209,13 @@ command line.
|
||||
|
||||
3.6 ATTRIBUTES
|
||||
|
||||
NOTE: The $attribute syntax will soon be deprecated in favor of the
|
||||
Verilog-2001 attribute syntax, which is cleaner and standardized.
|
||||
|
||||
The parser accepts, as an extension to Verilog, the $attribute module
|
||||
item. The syntax of the $attribute item is:
|
||||
|
||||
$attribute (<identifier>, <key>, <value>);
|
||||
|
||||
The $attribute keyword looks like a system task invocation. The
|
||||
difference here is that the parameters are more restricted than those
|
||||
difference here is that the parameters are more restricted then those
|
||||
of a system task. The <identifier> must be an identifier. This will be
|
||||
the item to get an attribute. The <key> and <value> are strings, not
|
||||
expressions, that give the key and the value of the attribute to be
|
||||
@@ -259,11 +237,6 @@ between processing steps. Processing steps that are aware of others
|
||||
may place attributes on netlist objects to communicate information to
|
||||
later steps.
|
||||
|
||||
Icarus Verilog also accepts the Verilog 2001 syntax for
|
||||
attributes. They have the same general meaning as with the $attribute
|
||||
syntax, but they are attached to objects by position instead of by
|
||||
name. Also, the key is a Verilog identifier instead of a string.
|
||||
|
||||
4.0 Running iverilog
|
||||
|
||||
The preferred way to invoke the compiler is with the iverilog(1)
|
||||
@@ -271,15 +244,109 @@ command. This program invokes the preprocessor (ivlpp) and the
|
||||
compiler (ivl) with the proper command line options to get the job
|
||||
done in a friendly way. See the iverilog(1) man page for usage details.
|
||||
|
||||
4.1 Running IVL Directly (not recommended)
|
||||
|
||||
4.1 EXAMPLES
|
||||
NOTE: The preferred method of running Icarus Verilog is the
|
||||
iverilog command described above. The instructions below may
|
||||
change at any time without notice.
|
||||
|
||||
The ivl command is the compiler driver, that invokes the parser,
|
||||
optimization functions and the code generator, but not the preprocessor.
|
||||
|
||||
Usage: ivl <options>... file
|
||||
ivl -h
|
||||
ivl -V
|
||||
|
||||
-F <name>
|
||||
Use this flag to request an optimization function be applied
|
||||
to the netlist before it is sent to the target output
|
||||
stage. Any number of -F options may be given, to specify a
|
||||
variety of processing steps. The steps will be applied in
|
||||
order, with the output of one uses as the input to the next.
|
||||
|
||||
The function is specified by name. Use the "ivl -h" command to
|
||||
get a list of configured function names.
|
||||
|
||||
-h
|
||||
Print usage information, and exit.
|
||||
|
||||
-m <module>
|
||||
Cause a named VPI module to be included in the module
|
||||
list. This parameter appends the named module to the end of
|
||||
the VPI_MODULE_LIST. This is an ordered list of modules to be
|
||||
loaded into the simulation at runtime.
|
||||
|
||||
This list can also be set with -fVPI_MODULE_LIST=<list> which
|
||||
sets the list completely. Then, -m after this will append
|
||||
module names to the list specified. The default list
|
||||
includes "system".
|
||||
|
||||
-N <file>
|
||||
Dump the elaborated netlist to the named file. The netlist is
|
||||
the folly elaborated netlist, after all the function modules
|
||||
are applied and right before the output generator is
|
||||
called. This is an aid for debugging the compiler, and the
|
||||
output generator in particular.
|
||||
|
||||
-o <file>
|
||||
Normally, the generated result is sent to standard
|
||||
output. Use the -o flag to specify an output file for the
|
||||
generated result.
|
||||
|
||||
-P <file>
|
||||
Write the PForm of the parsed input to the specified file.
|
||||
The pform is the compiler's understanding of the input after
|
||||
parsing and before elaboration. This is an aid for debugging
|
||||
the compiler.
|
||||
|
||||
-p <assign>
|
||||
Use this flag to set a parameter value. The format of the
|
||||
assignment is <key>=<value> where key is any string up to the
|
||||
first '=', and <value> is the rest of the option. If the '='
|
||||
is omitted, then the key is assigned the empty string.
|
||||
|
||||
The useful keys are defined by the functions and the target in
|
||||
use. These assignments are specifically useful for passing
|
||||
target specific information to the target back-end, or
|
||||
options/parameters to optimization functions, if any are defined.
|
||||
|
||||
-s <module>
|
||||
Normally, ivl will locate all the modules that are defined but
|
||||
never instantiated, and use these as the design roots for
|
||||
elaboration. This flag allows the choice of root module(s) to
|
||||
be manually overridden. It can be used more than once on the
|
||||
command line if multiple root modules are needed.
|
||||
|
||||
-T [min|typ|max]
|
||||
Normally, ivl will select typ values from min:type:max
|
||||
expressions and print a warning. This flag tells the compiler
|
||||
exactly which value to choose, and suppresses the warning.
|
||||
|
||||
-t <name>
|
||||
Select the output format for the compiled result. Use the
|
||||
"ivl -h" command to get a list of configured targets.
|
||||
|
||||
-v Print progress indications, and (if supported by the system)
|
||||
executions times in ivl precessing steps.
|
||||
|
||||
-V
|
||||
Print version and copyright information for ivl, and exit.
|
||||
|
||||
-y <dir>
|
||||
Add the specified directory to the library search path. If
|
||||
missing modules are discovered during elaboration, ivl will
|
||||
attempt to locate an implementation by searching the library
|
||||
directories for a Verilog source file with the same name as
|
||||
the module.
|
||||
|
||||
4.2 EXAMPLES
|
||||
|
||||
Example: Compiling "hello.vl"
|
||||
|
||||
------------------------ hello.vl ----------------------------
|
||||
module main();
|
||||
|
||||
initial
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hi there");
|
||||
$finish ;
|
||||
@@ -289,7 +356,7 @@ endmodule
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
Ensure that "iverilog" is on your search path, and the vpi library
|
||||
Insure that "iverilog" is on your search path, and the vpi library
|
||||
is available.
|
||||
|
||||
To compile the program:
|
||||
@@ -316,162 +383,110 @@ Verilog web page for the current state of support for Verilog, and in
|
||||
particular, browse the bug report database for reported unsupported
|
||||
constructs.
|
||||
|
||||
- System functions are supported, but the return value is a little
|
||||
tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page.
|
||||
- block disable not supported, i.e.:
|
||||
|
||||
begin : foo
|
||||
[...]
|
||||
disable foo; // sorry
|
||||
[...]
|
||||
end
|
||||
|
||||
- Functions in structural contexts are not supported.
|
||||
|
||||
assign foo = user_function(a,b); // sorry
|
||||
always @(a or b) foo = user_function(a,b); // OK
|
||||
|
||||
- real data types not supported. This includes real and
|
||||
realtime. However, floating point constants in delay expressions
|
||||
are supported so that `timescale works properly.
|
||||
|
||||
- System functions are supported, but the compiler presumes that
|
||||
they return 32 bits. This is the typical case.
|
||||
|
||||
- Specify blocks are parsed but ignored in general.
|
||||
|
||||
- trireg is not supported. tri0 and tri1 are supported.
|
||||
|
||||
- tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1
|
||||
and rtranif0 are not supported.
|
||||
|
||||
- Net delays, of the form "wire #N foo;" do not work. Delays in
|
||||
every other context do work properly, including the V2001 form
|
||||
"wire #5 foo = bar;"
|
||||
|
||||
- Event controls inside non-blocking assignments are not supported.
|
||||
i.e.: a <= @(posedge clk) b;
|
||||
|
||||
- Macro arguments are not supported. `define macros are supported,
|
||||
but they cannot take arguments.
|
||||
|
||||
5.1 Nonstandard Constructs or Behaviors
|
||||
|
||||
Icarus Verilog includes some features that are not part of the
|
||||
IEEE1364 standard, but have well defined meaning, and also sometimes
|
||||
gives nonstandard (but extended) meanings to some features of the
|
||||
language that are defined. See the "extensions.txt" documentation for
|
||||
more details.
|
||||
|
||||
$is_signed(<expr>)
|
||||
This system function returns 1 if the expression contained is
|
||||
signed, or 0 otherwise. This is mostly of use for compiler
|
||||
regression tests.
|
||||
|
||||
$sizeof(<expr>)
|
||||
$bits(<expr>)
|
||||
The $bits system function returns the size in bits of the
|
||||
expression that is its argument. The result of this
|
||||
function is undefined if the argument doesn't have a
|
||||
self-determined size.
|
||||
|
||||
The $sizeof function is deprecated in favor of $bits, which is
|
||||
the same thing, but included in the SystemVerilog definition.
|
||||
|
||||
$simtime
|
||||
The $simtime system function returns as a 64bit value the
|
||||
simulation time, unscaled by the time units of local
|
||||
scope. This is different from the $time and $stime functions
|
||||
which return the scaled times. This function is added for
|
||||
regression testing of the compiler and run time, but can be
|
||||
used by applications who really want the simulation time.
|
||||
|
||||
Note that the simulation time can be confusing if there are
|
||||
lots of different `timescales within a design. It is not in
|
||||
general possible to predict what the simulation precision will
|
||||
turn out to be.
|
||||
|
||||
$mti_random()
|
||||
$mti_dist_uniform
|
||||
These functions are similar to the IEEE1364 standard $random
|
||||
functions, but they use the Mersenne Twister (MT19937)
|
||||
algorithm. This is considered an excellent random number
|
||||
generator, but does not generate the same sequence as the
|
||||
standardized $random.
|
||||
|
||||
Builtin system functions
|
||||
|
||||
Certain of the system functions have well defined meanings, so
|
||||
can theoretically be evaluated at compile time, instead of
|
||||
using runtime VPI code. Doing so means that VPI cannot
|
||||
override the definitions of functions handled in this
|
||||
manner. On the other hand, this makes them synthesizable, and
|
||||
also allows for more aggressive constant propagation. The
|
||||
functions handled in this manner are:
|
||||
|
||||
$bits
|
||||
$signed
|
||||
$sizeof
|
||||
$unsigned
|
||||
|
||||
Implementations of these system functions in VPI modules will
|
||||
be ignored.
|
||||
|
||||
Preprocessing Library Modules
|
||||
|
||||
Icarus Verilog does preprocess modules that are loaded from
|
||||
libraries via the -y mechanism. However, the only macros
|
||||
defined during compilation of that file are those that it
|
||||
defines itself (or includes) or that are defined on the
|
||||
command line or command file.
|
||||
|
||||
Specifically, macros defined in the non-library source files
|
||||
are not remembered when the library module is loaded. This is
|
||||
intentional. If it were otherwise, then compilation results
|
||||
might vary depending on the order that libraries are loaded,
|
||||
and that is too unpredictable.
|
||||
|
||||
It is said that some commercial compilers do allow macro
|
||||
definitions to span library modules. That's just plain weird.
|
||||
|
||||
Width in %t Time Formats
|
||||
|
||||
Standard Verilog does not allow width fields in the %t formats
|
||||
of display strings. For example, this is illegal:
|
||||
|
||||
$display("Time is %0t", %time);
|
||||
|
||||
Standard Verilog instead relies on the $timeformat to
|
||||
completely specify the format.
|
||||
|
||||
Icarus Verilog allows the programmer to specify the field
|
||||
width. The "%t" format in Icarus Verilog works exactly as it
|
||||
does in standard Verilog. However, if the programmer chooses
|
||||
to specify a minimum width (i.e., "%5t"), then for that display
|
||||
Icarus Verilog will override the $timeformat minimum width and
|
||||
use the explicit minimum width.
|
||||
|
||||
vpiScope iterator on vpiScope objects.
|
||||
|
||||
In the VPI, the normal way to iterate over vpiScope objects
|
||||
contained within a vpiScope object, is the vpiInternalScope
|
||||
iterator. Icarus Verilog adds support for the vpiScope
|
||||
iterator of a vpiScope object, that iterates over *everything*
|
||||
the is contained in the current scope. This is useful in cases
|
||||
where one wants to iterate over all the objects in a scope
|
||||
without iterating over all the contained types explicitly.
|
||||
|
||||
time 0 race resolution.
|
||||
|
||||
Combinational logic is routinely modeled using always
|
||||
blocks. However, this can lead to race conditions if the
|
||||
inputs to the combinational block are initialized in initial
|
||||
statements. Icarus Verilog slightly modifies time 0 scheduling
|
||||
by arranging for always statements with ANYEDGE sensitivity
|
||||
lists to be scheduled before any other threads. This causes
|
||||
combinational always blocks to be triggered when the values in
|
||||
the sensitivity list are initialized by initial threads.
|
||||
|
||||
Nets with Types
|
||||
|
||||
Icarus Verilog support an extension syntax that allows nets
|
||||
and regs to be explicitly typed. The currently supported types
|
||||
are logic, bool and real. This implies that "logic" and "bool"
|
||||
are new keywords. Typical syntax is:
|
||||
|
||||
wire real foo = 1.0;
|
||||
reg logic bar, bat;
|
||||
|
||||
... and so forth. The syntax can be turned off by using the
|
||||
-g2 flag to iverilog, and turned on explicitly with the -g2x
|
||||
flag to iverilog.
|
||||
- force to nets are not supported. Force to variables, and
|
||||
assign/deassign, are supported.
|
||||
|
||||
6.0 CREDITS
|
||||
|
||||
Except where otherwise noted, Icarus Verilog, ivl and ivlpp are
|
||||
Copyright Stephen Williams. The proper notices are in the head of each
|
||||
file. However, I have early on received aid in the form of fixes,
|
||||
Verilog guidance, and especially testing from many people. Testers in
|
||||
particular include a larger community of people interested in a GPL
|
||||
Verilog for Linux.
|
||||
Verilog guidance, and especially testing from many people, including
|
||||
(in alphabetical order):
|
||||
|
||||
Eric Aardoom <[email protected]>
|
||||
Stephan I. Boettcher <[email protected]>
|
||||
Ed Carter <[email protected]>
|
||||
Larry Doolittle <[email protected]>
|
||||
Guy Hutchison <[email protected]>
|
||||
Ales Hvezda <[email protected]>
|
||||
Venkat Iyer <[email protected]>
|
||||
Yasuhisa Kato <[email protected]>
|
||||
James Lee <[email protected]>
|
||||
Peter Monta <[email protected]>
|
||||
Daniel H. Nelsen <[email protected]>
|
||||
Stefan Petersen <[email protected]>
|
||||
Jason Schonberg <[email protected]>
|
||||
Stuart Sutherland <[email protected]>
|
||||
Stephen Tell <[email protected]>
|
||||
Stefan Theide <[email protected]>
|
||||
Tom Verbeure
|
||||
Steve Wilson <[email protected]>
|
||||
|
||||
and others. Testers in particular include a larger community of people
|
||||
interested in a GPL Verilog for Linux. Special thanks to Steve Wilson
|
||||
for collecting and organizing the test suite code for all those testers.
|
||||
|
||||
|
||||
6.1 PORT MAINTAINERS
|
||||
|
||||
This is a list of people who have created ports and precompiled
|
||||
packages for various operating systems. These folks have graciously
|
||||
taken on the task of building Icarus Verilog on their systems and
|
||||
bundled it into neat packages.(+) If you want to be added to the list (or
|
||||
removed from the list) send e-mail to me.
|
||||
|
||||
FreeBSD/{Intel,alpha}
|
||||
Ying-Chieh Liao <[email protected]>
|
||||
|
||||
Linux/{alpha,Intel} (RPMS)
|
||||
Stephen Williams <[email protected]>
|
||||
|
||||
Linux/* (.debs)
|
||||
Hamish Moffatt <[email protected]>
|
||||
|
||||
Macintosh -- MacO/S
|
||||
Yasuhisa Kato <[email protected]>
|
||||
|
||||
Mac O/S X
|
||||
Timothy J. Wood <[email protected]>
|
||||
|
||||
NetBSD/*
|
||||
Dan McMahill <[email protected]>
|
||||
|
||||
Solaris/SPARC packages (.pkg)
|
||||
Dan McMahill <[email protected]>
|
||||
|
||||
Cygwin32/*
|
||||
Venkat Iyer <[email protected]>
|
||||
|
||||
Mingw32
|
||||
Venkat Iyer <[email protected]>
|
||||
|
||||
(+) These are not the only systems where Icarus Verilog has been run,
|
||||
just the systems where precompiled binaries are publicly available.
|
||||
|
||||
|
||||
6.2 TEST SUITE MANAGER
|
||||
|
||||
Steve Wilson <[email protected]> or <[email protected]> has taken on
|
||||
the large task of managing the test suite. He has maintained the
|
||||
regression test scripts, the driver list, received submissions from
|
||||
myself and others, and has written a great many tests on his own. Any
|
||||
compiler writer, for any language, will tell you that the test suite
|
||||
is at least as important as the compiler code itself.
|
||||
|
||||
|
||||
+56
-182
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2013 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
|
||||
@@ -14,35 +14,35 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Statement.cc,v 1.25 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Statement.h"
|
||||
# include "PExpr.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
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;
|
||||
if (de) delay_.set_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;
|
||||
}
|
||||
|
||||
PAssign_::~PAssign_()
|
||||
@@ -51,28 +51,18 @@ PAssign_::~PAssign_()
|
||||
delete rval_;
|
||||
}
|
||||
|
||||
PAssign::PAssign(PExpr*lval__, PExpr*ex)
|
||||
: PAssign_(lval__, ex, false), op_(0)
|
||||
PAssign::PAssign(PExpr*lval, PExpr*ex)
|
||||
: PAssign_(lval, ex)
|
||||
{
|
||||
}
|
||||
|
||||
PAssign::PAssign(PExpr*lval__, char op, PExpr*ex)
|
||||
: PAssign_(lval__, ex, false), op_(op)
|
||||
PAssign::PAssign(PExpr*lval, PExpr*d, PExpr*ex)
|
||||
: PAssign_(lval, d, ex)
|
||||
{
|
||||
}
|
||||
|
||||
PAssign::PAssign(PExpr*lval__, PExpr*d, PExpr*ex)
|
||||
: PAssign_(lval__, d, ex), op_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PAssign::PAssign(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
|
||||
: PAssign_(lval__, cnt, d, ex), op_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant)
|
||||
: PAssign_(lval__, ex, is_constant), op_(0)
|
||||
PAssign::PAssign(PExpr*lval, PEventStatement*d, PExpr*ex)
|
||||
: PAssign_(lval, d, ex)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -80,18 +70,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,99 +84,37 @@ PAssignNB::~PAssignNB()
|
||||
{
|
||||
}
|
||||
|
||||
PBlock::PBlock(perm_string n, LexicalScope*parent, BL_TYPE t)
|
||||
: PScope(n, parent), bl_type_(t)
|
||||
PBlock::PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st)
|
||||
: name_(n), bl_type_(t), list_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PBlock::PBlock(BL_TYPE t, const svector<Statement*>&st)
|
||||
: bl_type_(t), list_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PBlock::PBlock(BL_TYPE t)
|
||||
: PScope(perm_string()), bl_type_(t)
|
||||
: bl_type_(t)
|
||||
{
|
||||
}
|
||||
|
||||
PBlock::~PBlock()
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < list_.size() ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < list_.count() ; idx += 1)
|
||||
delete list_[idx];
|
||||
}
|
||||
|
||||
PChainConstructor* PBlock::extract_chain_constructor()
|
||||
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
|
||||
: path_(n), parms_(p)
|
||||
{
|
||||
if (list_.empty())
|
||||
return 0;
|
||||
|
||||
if (PChainConstructor*res = dynamic_cast<PChainConstructor*> (list_[0])) {
|
||||
for (size_t idx = 0 ; idx < list_.size()-1 ; idx += 1)
|
||||
list_[idx] = list_[idx+1];
|
||||
list_.resize(list_.size()-1);
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PBlock::set_join_type(PBlock::BL_TYPE type)
|
||||
{
|
||||
assert(bl_type_ == BL_PAR);
|
||||
assert(type==BL_PAR || type==BL_JOIN_NONE || type==BL_JOIN_ANY);
|
||||
bl_type_ = type;
|
||||
}
|
||||
|
||||
void PBlock::set_statement(const vector<Statement*>&st)
|
||||
{
|
||||
list_ = st;
|
||||
}
|
||||
|
||||
void PBlock::push_statement_front(Statement*that)
|
||||
{
|
||||
ivl_assert(*this, bl_type_==BL_SEQ);
|
||||
|
||||
list_.resize(list_.size()+1);
|
||||
for (size_t idx = list_.size()-1 ; idx > 0 ; idx -= 1)
|
||||
list_[idx] = list_[idx-1];
|
||||
|
||||
list_[0] = that;
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
|
||||
: package_(0), path_(n), parms_(p.size())
|
||||
{
|
||||
list<PExpr*>::const_iterator cur = p.begin();
|
||||
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
parms_[idx] = *cur;
|
||||
++cur;
|
||||
}
|
||||
assert(cur == p.end());
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&p)
|
||||
: package_(pkg), path_(n), parms_(p.size())
|
||||
{
|
||||
list<PExpr*>::const_iterator cur = p.begin();
|
||||
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
parms_[idx] = *cur;
|
||||
++cur;
|
||||
}
|
||||
assert(cur == p.end());
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(perm_string n, const list<PExpr*>&p)
|
||||
: package_(0), parms_(p.size())
|
||||
{
|
||||
list<PExpr*>::const_iterator cur = p.begin();
|
||||
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
parms_[idx] = *cur;
|
||||
++cur;
|
||||
}
|
||||
assert(cur == p.end());
|
||||
path_.push_back(name_component_t(n));
|
||||
}
|
||||
|
||||
PCallTask::~PCallTask()
|
||||
{
|
||||
}
|
||||
|
||||
const pform_name_t& PCallTask::path() const
|
||||
const hname_t& PCallTask::path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
@@ -221,21 +144,6 @@ PCAssign::~PCAssign()
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
PChainConstructor::PChainConstructor(const list<PExpr*>&parms)
|
||||
: parms_(parms.size())
|
||||
{
|
||||
list<PExpr*>::const_iterator cur = parms.begin();
|
||||
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
parms_[idx] = *cur;
|
||||
++cur;
|
||||
}
|
||||
assert(cur == parms.end());
|
||||
}
|
||||
|
||||
PChainConstructor::~PChainConstructor()
|
||||
{
|
||||
}
|
||||
|
||||
PCondit::PCondit(PExpr*ex, Statement*i, Statement*e)
|
||||
: expr_(ex), if_(i), else_(e)
|
||||
{
|
||||
@@ -268,7 +176,7 @@ PDelayStatement::~PDelayStatement()
|
||||
{
|
||||
}
|
||||
|
||||
PDisable::PDisable(const pform_name_t&sc)
|
||||
PDisable::PDisable(const hname_t&sc)
|
||||
: scope_(sc)
|
||||
{
|
||||
}
|
||||
@@ -277,21 +185,9 @@ PDisable::~PDisable()
|
||||
{
|
||||
}
|
||||
|
||||
PDoWhile::PDoWhile(PExpr*ex, Statement*st)
|
||||
: cond_(ex), statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PDoWhile::~PDoWhile()
|
||||
{
|
||||
delete cond_;
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
||||
: expr_(ee), statement_(0)
|
||||
{
|
||||
assert(expr_.count() > 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -301,11 +197,6 @@ PEventStatement::PEventStatement(PEEvent*ee)
|
||||
expr_[0] = ee;
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(void)
|
||||
: statement_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PEventStatement::~PEventStatement()
|
||||
{
|
||||
// delete the events and the statement?
|
||||
@@ -316,15 +207,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)
|
||||
{
|
||||
@@ -336,20 +218,6 @@ PForce::~PForce()
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
PForeach::PForeach(perm_string av, const list<perm_string>&ix, Statement*s)
|
||||
: array_var_(av), index_vars_(ix.size()), statement_(s)
|
||||
{
|
||||
size_t idx = 0;
|
||||
for (list<perm_string>::const_iterator cur = ix.begin()
|
||||
; cur != ix.end() ; ++cur)
|
||||
index_vars_[idx++] = *cur;
|
||||
}
|
||||
|
||||
PForeach::~PForeach()
|
||||
{
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PForever::PForever(Statement*s)
|
||||
: statement_(s)
|
||||
{
|
||||
@@ -361,8 +229,9 @@ PForever::~PForever()
|
||||
}
|
||||
|
||||
PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||
Statement*step, Statement*st)
|
||||
: name1_(n1), expr1_(e1), cond_(cond), step_(step), statement_(st)
|
||||
PExpr*n2, PExpr*e2, Statement*st)
|
||||
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
|
||||
statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -396,17 +265,7 @@ PRepeat::~PRepeat()
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PReturn::PReturn(PExpr*e)
|
||||
: expr_(e)
|
||||
{
|
||||
}
|
||||
|
||||
PReturn::~PReturn()
|
||||
{
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
PTrigger::PTrigger(const pform_name_t&e)
|
||||
PTrigger::PTrigger(const hname_t&e)
|
||||
: event_(e)
|
||||
{
|
||||
}
|
||||
@@ -415,8 +274,8 @@ PTrigger::~PTrigger()
|
||||
{
|
||||
}
|
||||
|
||||
PWhile::PWhile(PExpr*ex, Statement*st)
|
||||
: cond_(ex), statement_(st)
|
||||
PWhile::PWhile(PExpr*e1, Statement*st)
|
||||
: cond_(e1), statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -425,3 +284,18 @@ PWhile::~PWhile()
|
||||
delete cond_;
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: Statement.cc,v $
|
||||
* 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)
|
||||
*/
|
||||
|
||||
|
||||
+94
-191
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_Statement_H
|
||||
#define IVL_Statement_H
|
||||
#ifndef __Statement_H
|
||||
#define __Statement_H
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-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,57 +16,50 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Statement.h,v 1.31 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include <list>
|
||||
# include "ivl_target.h"
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
# include "PScope.h"
|
||||
# include "HName.h"
|
||||
# include "LineInfo.h"
|
||||
class PExpr;
|
||||
class PChainConstructor;
|
||||
class PPackage;
|
||||
class Statement;
|
||||
class PEventStatement;
|
||||
class Design;
|
||||
class NetAssign_;
|
||||
class NetCAssign;
|
||||
class NetDeassign;
|
||||
class NetForce;
|
||||
class NetScope;
|
||||
|
||||
/*
|
||||
* The PProcess is the root of a behavioral process. Each process gets
|
||||
* one of these, which contains its type (initial, always, or final)
|
||||
* and a pointer to the single statement that is the process. A module
|
||||
* may have several concurrent processes.
|
||||
* one of these, which contains its type (initial or always) and a
|
||||
* pointer to the single statement that is the process. A module may
|
||||
* have several concurrent processes.
|
||||
*/
|
||||
class PProcess : public LineInfo {
|
||||
|
||||
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;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
ivl_process_type_t type_;
|
||||
Type type_;
|
||||
Statement*statement_;
|
||||
};
|
||||
|
||||
@@ -84,9 +77,6 @@ class Statement : public LineInfo {
|
||||
virtual void dump(ostream&out, unsigned ind) 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;
|
||||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -96,54 +86,39 @@ 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*, ivl_type_t lv_net_type,
|
||||
ivl_variable_type_t lv_type,
|
||||
unsigned lv_width) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const;
|
||||
|
||||
NetExpr* elaborate_rval_obj_(Design*, NetScope*,
|
||||
ivl_variable_type_t type) const;
|
||||
|
||||
PExpr* delay_;
|
||||
PDelays delay_;
|
||||
PEventStatement*event_;
|
||||
PExpr* count_;
|
||||
|
||||
private:
|
||||
PExpr* lval_;
|
||||
PExpr* rval_;
|
||||
bool is_constant_;
|
||||
};
|
||||
|
||||
class PAssign : public PAssign_ {
|
||||
|
||||
public:
|
||||
// lval - assignment l-value
|
||||
// ex - assignment r-value
|
||||
// op - compressed assignment operator (i.e. '+', '-', ...)
|
||||
// de - delayed assignment delay expression
|
||||
explicit PAssign(PExpr*lval, PExpr*ex);
|
||||
explicit PAssign(PExpr*lval, char op, PExpr*ex);
|
||||
explicit PAssign(PExpr*lval, PExpr*de, PExpr*ex);
|
||||
explicit PAssign(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex);
|
||||
explicit PAssign(PExpr*lval, PExpr*ex, bool is_constant);
|
||||
explicit PAssign(PExpr*lval, PEventStatement*de, PExpr*ex);
|
||||
~PAssign();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetProc* elaborate_compressed_(Design*des, NetScope*scope) const;
|
||||
char op_;
|
||||
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
|
||||
Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
class PAssignNB : public PAssign_ {
|
||||
@@ -151,7 +126,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;
|
||||
@@ -169,53 +143,48 @@ class PAssignNB : public PAssign_ {
|
||||
* statements before constructing this object, so it knows a priori
|
||||
* what is contained.
|
||||
*/
|
||||
class PBlock : public PScope, public Statement {
|
||||
class PBlock : public Statement {
|
||||
|
||||
public:
|
||||
enum BL_TYPE { BL_SEQ, BL_PAR, BL_JOIN_NONE, BL_JOIN_ANY };
|
||||
enum BL_TYPE { BL_SEQ, BL_PAR };
|
||||
|
||||
// If the block has a name, it is a scope and also has a parent.
|
||||
explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t);
|
||||
// If it doesn't have a name, it's not a scope
|
||||
explicit PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(BL_TYPE t);
|
||||
~PBlock();
|
||||
|
||||
BL_TYPE bl_type() const { return bl_type_; }
|
||||
|
||||
// This is only used if this block is the statement list for a
|
||||
// constructor. We look for a PChainConstructor as the first
|
||||
// statement, and if it is there, extract it.
|
||||
PChainConstructor*extract_chain_constructor();
|
||||
|
||||
// If the bl_type() is BL_PAR, it is possible to replace it
|
||||
// with JOIN_NONE or JOIN_ANY. This is to help the parser.
|
||||
void set_join_type(BL_TYPE);
|
||||
|
||||
void set_statement(const std::vector<Statement*>&st);
|
||||
|
||||
// Copy the statement from that block to the front of this
|
||||
// block.
|
||||
void push_statement_front(Statement*that);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) 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;
|
||||
|
||||
private:
|
||||
BL_TYPE bl_type_;
|
||||
std::vector<Statement*>list_;
|
||||
string name_;
|
||||
const BL_TYPE bl_type_;
|
||||
svector<Statement*>list_;
|
||||
};
|
||||
|
||||
class PCallTask : public Statement {
|
||||
|
||||
public:
|
||||
explicit PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&parms);
|
||||
explicit PCallTask(const pform_name_t&n, const list<PExpr*>&parms);
|
||||
explicit PCallTask(perm_string n, const list<PExpr*>&parms);
|
||||
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
|
||||
~PCallTask();
|
||||
|
||||
const pform_name_t& path() const;
|
||||
const hname_t& path() const;
|
||||
|
||||
unsigned nparms() const { return parms_.count(); }
|
||||
|
||||
PExpr*&parm(unsigned idx)
|
||||
{ assert(idx < parms_.count());
|
||||
return parms_[idx];
|
||||
}
|
||||
|
||||
PExpr* parm(unsigned idx) const
|
||||
{ assert(idx < parms_.count());
|
||||
return parms_[idx];
|
||||
}
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
@@ -224,28 +193,15 @@ class PCallTask : public Statement {
|
||||
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
||||
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
|
||||
|
||||
NetProc*elaborate_method_(Design*des, NetScope*scope,
|
||||
bool add_this_flag = false) const;
|
||||
NetProc*elaborate_function_(Design*des, NetScope*scope) const;
|
||||
|
||||
NetProc*elaborate_build_call_(Design*des, NetScope*scope,
|
||||
NetScope*task, NetExpr*use_this) const;
|
||||
NetProc*elaborate_sys_task_method_(Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
bool test_task_calls_ok_(Design*des, NetScope*scope) const;
|
||||
|
||||
PPackage*package_;
|
||||
pform_name_t path_;
|
||||
vector<PExpr*> parms_;
|
||||
hname_t path_;
|
||||
svector<PExpr*> parms_;
|
||||
};
|
||||
|
||||
class PCase : public Statement {
|
||||
|
||||
public:
|
||||
struct Item {
|
||||
list<PExpr*>expr;
|
||||
svector<PExpr*>expr;
|
||||
Statement*stat;
|
||||
};
|
||||
|
||||
@@ -254,7 +210,6 @@ class PCase : public Statement {
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -282,26 +237,6 @@ class PCAssign : public Statement {
|
||||
PExpr*expr_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This represents the syntax "super.new(...)". This is not really an
|
||||
* executable statement, but the elaborator will handle these
|
||||
* specially and will remove them from the statement stream. If any
|
||||
*/
|
||||
class PChainConstructor : public Statement {
|
||||
public:
|
||||
PChainConstructor(const list<PExpr*>&parms);
|
||||
~PChainConstructor();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
inline const std::vector<PExpr*>& chain_args(void) const
|
||||
{ return parms_; }
|
||||
|
||||
private:
|
||||
std::vector<PExpr*> parms_;
|
||||
};
|
||||
|
||||
class PCondit : public Statement {
|
||||
|
||||
public:
|
||||
@@ -310,7 +245,6 @@ class PCondit : public Statement {
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -345,7 +279,6 @@ class PDelayStatement : public Statement {
|
||||
virtual void dump(ostream&out, unsigned ind) 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;
|
||||
|
||||
private:
|
||||
PExpr*delay_;
|
||||
@@ -354,35 +287,19 @@ class PDelayStatement : public Statement {
|
||||
|
||||
|
||||
/*
|
||||
* This represents the parsing of a disable <scope> statement.
|
||||
* This represends the parsing of a disable <scope> statement.
|
||||
*/
|
||||
class PDisable : public Statement {
|
||||
|
||||
public:
|
||||
explicit PDisable(const pform_name_t&sc);
|
||||
explicit PDisable(const hname_t&sc);
|
||||
~PDisable();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
pform_name_t scope_;
|
||||
};
|
||||
|
||||
class PDoWhile : public Statement {
|
||||
|
||||
public:
|
||||
PDoWhile(PExpr*ex, Statement*st);
|
||||
~PDoWhile();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*cond_;
|
||||
Statement*statement_;
|
||||
hname_t scope_;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -391,7 +308,6 @@ class PDoWhile : public Statement {
|
||||
*
|
||||
* @name <statement>;
|
||||
* @(expr) <statement>;
|
||||
* @* <statement>;
|
||||
*/
|
||||
class PEventStatement : public Statement {
|
||||
|
||||
@@ -399,44 +315,31 @@ class PEventStatement : public Statement {
|
||||
|
||||
explicit PEventStatement(const svector<PEEvent*>&ee);
|
||||
explicit PEventStatement(PEEvent*ee);
|
||||
// Make an @* statement.
|
||||
explicit PEventStatement(void);
|
||||
|
||||
~PEventStatement();
|
||||
|
||||
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;
|
||||
|
||||
NetProc* elaborate_wait(Design*des, NetScope*scope, NetProc*st) const;
|
||||
NetProc* elaborate_wait_fork(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
svector<PEEvent*>expr_;
|
||||
Statement*statement_;
|
||||
};
|
||||
|
||||
ostream& operator << (ostream&o, const PEventStatement&obj);
|
||||
|
||||
class PForce : public Statement {
|
||||
|
||||
public:
|
||||
explicit PForce(PExpr*l, PExpr*r);
|
||||
~PForce();
|
||||
|
||||
virtual NetForce* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -444,26 +347,6 @@ class PForce : public Statement {
|
||||
PExpr*expr_;
|
||||
};
|
||||
|
||||
class PForeach : public Statement {
|
||||
public:
|
||||
explicit PForeach(perm_string var, const std::list<perm_string>&ix, Statement*stmt);
|
||||
~PForeach();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
NetProc* elaborate_static_array_(Design*des, NetScope*scope,
|
||||
const std::vector<netrange_t>&dims) const;
|
||||
|
||||
private:
|
||||
perm_string array_var_;
|
||||
std::vector<perm_string> index_vars_;
|
||||
Statement*statement_;
|
||||
};
|
||||
|
||||
class PForever : public Statement {
|
||||
public:
|
||||
explicit PForever(Statement*s);
|
||||
@@ -471,7 +354,6 @@ class PForever : public Statement {
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -482,12 +364,11 @@ class PForStatement : public Statement {
|
||||
|
||||
public:
|
||||
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||
Statement*step, Statement*body);
|
||||
PExpr*n2, PExpr*e2, Statement*st);
|
||||
~PForStatement();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -496,7 +377,8 @@ class PForStatement : public Statement {
|
||||
|
||||
PExpr*cond_;
|
||||
|
||||
Statement*step_;
|
||||
PExpr* name2_;
|
||||
PExpr* expr2_;
|
||||
|
||||
Statement*statement_;
|
||||
};
|
||||
@@ -505,7 +387,6 @@ class PNoop : public Statement {
|
||||
|
||||
public:
|
||||
PNoop() { }
|
||||
~PNoop() { }
|
||||
};
|
||||
|
||||
class PRepeat : public Statement {
|
||||
@@ -515,7 +396,6 @@ class PRepeat : public Statement {
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -536,19 +416,6 @@ class PRelease : public Statement {
|
||||
PExpr*lval_;
|
||||
};
|
||||
|
||||
class PReturn : public Statement {
|
||||
|
||||
public:
|
||||
explicit PReturn(PExpr*e);
|
||||
~PReturn();
|
||||
|
||||
NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The PTrigger statement sends a trigger to a named event. Take the
|
||||
* name here.
|
||||
@@ -556,25 +423,24 @@ class PReturn : public Statement {
|
||||
class PTrigger : public Statement {
|
||||
|
||||
public:
|
||||
explicit PTrigger(const pform_name_t&ev);
|
||||
explicit PTrigger(const hname_t&ev);
|
||||
~PTrigger();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
pform_name_t event_;
|
||||
hname_t event_;
|
||||
};
|
||||
|
||||
class PWhile : public Statement {
|
||||
|
||||
public:
|
||||
PWhile(PExpr*ex, Statement*st);
|
||||
PWhile(PExpr*e1, Statement*st);
|
||||
~PWhile();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -582,4 +448,41 @@ class PWhile : public Statement {
|
||||
Statement*statement_;
|
||||
};
|
||||
|
||||
#endif /* IVL_Statement_H */
|
||||
/*
|
||||
* $Log: Statement.h,v $
|
||||
* Revision 1.31 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.30 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.29 2000/09/09 15:21:26 steve
|
||||
* move lval elaboration to PExpr virtual methods.
|
||||
*
|
||||
* Revision 1.28 2000/09/03 17:58:35 steve
|
||||
* Change elaborate_lval to return NetAssign_ objects.
|
||||
*
|
||||
* Revision 1.27 2000/07/26 05:08:07 steve
|
||||
* Parse disable statements to pform.
|
||||
*
|
||||
* Revision 1.26 2000/05/11 23:37:26 steve
|
||||
* Add support for procedural continuous assignment.
|
||||
*
|
||||
* Revision 1.25 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.24 2000/04/12 04:23:57 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
*
|
||||
* Handle named events within the mix of net events
|
||||
* and edges. As a unified lot they get caught together.
|
||||
* wait statements are broken into more complex statements
|
||||
* that include a conditional.
|
||||
*
|
||||
* Do not generate NetPEvent or NetNEvent objects in
|
||||
* elaboration. NetEvent, NetEvWait and NetEvProbe
|
||||
* take over those functions in the netlist.
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
#ifndef PLI_TYPES_H
|
||||
#define PLI_TYPES_H
|
||||
/*
|
||||
* Copyright (c) 2003-2014 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# undef HAVE_INTTYPES_H
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
|
||||
/*
|
||||
* If the host environment has the stdint.h header file,
|
||||
* then use that to size our PLI types.
|
||||
*/
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
# define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
|
||||
# include <inttypes.h>
|
||||
typedef uint64_t PLI_UINT64;
|
||||
typedef int64_t PLI_INT64;
|
||||
typedef uint32_t PLI_UINT32;
|
||||
typedef int32_t PLI_INT32;
|
||||
|
||||
typedef signed short PLI_INT16;
|
||||
typedef unsigned short PLI_UINT16;
|
||||
typedef char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
|
||||
# define PLI_UINT64_FMT PRIu64
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* If we do not have the c99 stdint.h header file, then use
|
||||
* configure detection to guess the pli types ourselves.
|
||||
*/
|
||||
|
||||
# define SIZEOF_UNSIGNED_LONG_LONG 8
|
||||
# define SIZEOF_UNSIGNED_LONG 8
|
||||
# define SIZEOF_UNSIGNED 4
|
||||
|
||||
#if SIZEOF_UNSIGNED >= 8
|
||||
typedef unsigned PLI_UINT64;
|
||||
typedef int PLI_INT64;
|
||||
# define PLI_UINT64_FMT "u"
|
||||
#else
|
||||
# if SIZEOF_UNSIGNED_LONG >= 8
|
||||
typedef unsigned long PLI_UINT64;
|
||||
typedef long PLI_INT64;
|
||||
# define PLI_UINT64_FMT "lu"
|
||||
# else
|
||||
# if SIZEOF_UNSIGNED_LONG_LONG > SIZEOF_UNSIGNED_LONG
|
||||
typedef unsigned long long PLI_UINT64;
|
||||
typedef long long PLI_INT64;
|
||||
# define PLI_UINT64_FMT "llu"
|
||||
# else
|
||||
typedef unsigned long PLI_UINT64;
|
||||
typedef long PLI_INT64;
|
||||
# define PLI_UINT64_FMT "lu"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef signed int PLI_INT32;
|
||||
typedef unsigned int PLI_UINT32;
|
||||
typedef signed short PLI_INT16;
|
||||
typedef unsigned short PLI_UINT16;
|
||||
typedef char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
#endif
|
||||
|
||||
#endif /* PLI_TYPES_H */
|
||||
-274
@@ -1,274 +0,0 @@
|
||||
#ifndef ACC_USER_H
|
||||
#define ACC_USER_H
|
||||
/*
|
||||
* Copyright (c) 2002-2014 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This header file contains the definitions and declarations needed
|
||||
* by an Icarus Verilog user using acc_ routines.
|
||||
*
|
||||
* NOTE: Icarus Verilog does not support acc_ routines. This is just a
|
||||
* stub. The functions that are implemented here are actually
|
||||
* implemented using VPI routines.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define EXTERN_C_START extern "C" {
|
||||
# define EXTERN_C_END }
|
||||
#else
|
||||
# define EXTERN_C_START
|
||||
# define EXTERN_C_END
|
||||
# define bool int
|
||||
#endif
|
||||
|
||||
EXTERN_C_START
|
||||
|
||||
# include "_pli_types.h"
|
||||
|
||||
/*
|
||||
* This is a declaration of the "handle" type that is compatible with
|
||||
* the vpiHandle from vpi_user.h. The libveriuser library implements
|
||||
* the acc handle type as a vpiHandle, to prevent useless indirection.
|
||||
*/
|
||||
typedef struct __vpiHandle *handle;
|
||||
|
||||
/* OBJECT TYPES */
|
||||
#define accModule 20
|
||||
#define accScope 21
|
||||
#define accNet 25
|
||||
#define accReg 30
|
||||
#define accIntegerParam 200
|
||||
#define accRealParam 202
|
||||
#define accStringParam 204
|
||||
#define accParameter 220
|
||||
#define accTopModule 224
|
||||
#define accModuleInstance 226
|
||||
#define accWire 260
|
||||
#define accNamedEvent 280
|
||||
#define accIntegerVar 281
|
||||
#define accRealVar 282
|
||||
#define accTimeVar 283
|
||||
#define accIntVar accIntegerVar
|
||||
#define accScalar 300
|
||||
#define accVector 302
|
||||
#define accUnknown 412
|
||||
#define accConstant 600
|
||||
|
||||
/* type VALUES FOR t_setval_delay STRUCTURE */
|
||||
#define accNoDelay 0
|
||||
#define accInertialDelay 1
|
||||
#define accTransportDelay 2
|
||||
#define accPureTransportDelay 3
|
||||
#define accForceFlag 4
|
||||
#define accReleaseFlag 5
|
||||
|
||||
/* type VALUES FOR t_setval_value STRUCTURE */
|
||||
#define accBinStrVal 1
|
||||
#define accOctStrVal 2
|
||||
#define accDecStrVal 3
|
||||
#define accHexStrVal 4
|
||||
#define accScalarVal 5
|
||||
#define accIntVal 6
|
||||
#define accRealVal 7
|
||||
#define accStringVal 8
|
||||
#define accVectorVal 9
|
||||
|
||||
/* Scalar values */
|
||||
#define acc0 0
|
||||
#define acc1 1
|
||||
#define accX 2
|
||||
#define accZ 3
|
||||
|
||||
/* type VALUES FOR t_acc_time STRUCTURE */
|
||||
#define accTime 1
|
||||
#define accSimTime 2
|
||||
#define accRealTime 3
|
||||
|
||||
/* reason codes */
|
||||
#define logic_value_change 1
|
||||
#define strength_value_change 2
|
||||
#define real_value_change 3
|
||||
#define vector_value_change 4
|
||||
#define event_value_change 5
|
||||
#define integer_value_change 6
|
||||
#define time_value_change 7
|
||||
#define sregister_value_change 8
|
||||
#define vregister_value_change 9
|
||||
#define realtime_value_change 10
|
||||
|
||||
/* VCL strength values */
|
||||
#define vclSupply 7
|
||||
#define vclStrong 6
|
||||
#define vclPull 5
|
||||
#define vclLarge 4
|
||||
#define vclWeak 3
|
||||
#define vclMedium 2
|
||||
#define vclSmall 1
|
||||
#define vclHighZ 0
|
||||
|
||||
/* Constants used by acc_vcl_add */
|
||||
#define vcl_verilog_logic 2
|
||||
#define VCL_VERILOG_LOGIC vcl_verilog_logic
|
||||
#define vcl_verilog_strength 3
|
||||
#define VCL_VERILOG_STRENGTH vcl_verilog_strength
|
||||
|
||||
typedef struct t_acc_time {
|
||||
int type;
|
||||
int low, high;
|
||||
double real;
|
||||
} s_acc_time, *p_acc_time;
|
||||
|
||||
typedef struct t_setval_delay {
|
||||
s_acc_time time;
|
||||
int model;
|
||||
} s_setval_delay, *p_setval_delay;
|
||||
|
||||
typedef struct t_acc_vecval {
|
||||
int aval;
|
||||
int bval;
|
||||
} s_acc_vecval, *p_acc_vecval;
|
||||
|
||||
typedef struct t_setval_value {
|
||||
int format;
|
||||
union {
|
||||
char*str;
|
||||
int scalar;
|
||||
int integer;
|
||||
double real;
|
||||
p_acc_vecval vector;
|
||||
} value;
|
||||
} s_setval_value, *p_setval_value, s_acc_value, *p_acc_value;
|
||||
|
||||
typedef struct t_strengths {
|
||||
PLI_UBYTE8 logic_value;
|
||||
PLI_UBYTE8 strength1;
|
||||
PLI_UBYTE8 strength2;
|
||||
} s_strengths, *p_strengths;
|
||||
|
||||
typedef struct t_vc_record {
|
||||
PLI_INT32 vc_reason;
|
||||
PLI_INT32 vc_hightime;
|
||||
PLI_INT32 vc_lowtime;
|
||||
void* user_data;
|
||||
union {
|
||||
PLI_UBYTE8 logic_value;
|
||||
double real_value;
|
||||
handle vector_handle;
|
||||
s_strengths strengths_s;
|
||||
} out_value;
|
||||
} s_vc_record, *p_vc_record;
|
||||
|
||||
|
||||
typedef struct t_location {
|
||||
PLI_INT32 line_no;
|
||||
const char*filename;
|
||||
} s_location, *p_location;
|
||||
|
||||
extern int acc_error_flag;
|
||||
|
||||
extern int acc_initialize(void);
|
||||
|
||||
extern void acc_close(void);
|
||||
|
||||
/*
|
||||
* This is the acc_configure command, and the config_param
|
||||
* codes that are accepted.
|
||||
*/
|
||||
extern int acc_configure(PLI_INT32 config_param, const char*value);
|
||||
#define accEnableArgs 6
|
||||
#define accDevelopmentVersion 11
|
||||
|
||||
extern int acc_fetch_argc(void);
|
||||
extern char**acc_fetch_argv(void);
|
||||
|
||||
extern PLI_INT32 acc_fetch_direction(handle obj);
|
||||
/* XXXX FIXME: Values returned by acc_fetch_direction */
|
||||
# define accInout 2
|
||||
|
||||
extern char* acc_fetch_fullname(handle obj);
|
||||
|
||||
extern int acc_fetch_location(p_location loc, handle obj);
|
||||
|
||||
extern char* acc_fetch_name(handle obj);
|
||||
extern char* acc_fetch_defname(handle obj);
|
||||
|
||||
extern double acc_fetch_paramval(handle obj);
|
||||
|
||||
extern double acc_fetch_tfarg(PLI_INT32);
|
||||
extern double acc_fetch_itfarg(PLI_INT32, handle);
|
||||
extern PLI_INT32 acc_fetch_tfarg_int(PLI_INT32);
|
||||
extern PLI_INT32 acc_fetch_itfarg_int(PLI_INT32, handle);
|
||||
extern char* acc_fetch_tfarg_str(PLI_INT32);
|
||||
extern char* acc_fetch_itfarg_str(PLI_INT32, handle);
|
||||
|
||||
typedef struct t_timescale_info {
|
||||
PLI_INT16 unit;
|
||||
PLI_INT16 precision;
|
||||
} s_timescale_info, *p_timescale_info;
|
||||
extern void acc_fetch_timescale_info(handle obj, p_timescale_info info);
|
||||
|
||||
extern PLI_INT32 acc_fetch_size(handle obj);
|
||||
|
||||
extern PLI_INT32 acc_fetch_type(handle obj);
|
||||
extern PLI_INT32 acc_fetch_fulltype(handle obj);
|
||||
extern PLI_INT32 acc_fetch_paramtype(handle obj);
|
||||
extern PLI_INT32 acc_fetch_range(handle object, int *msb, int *lsb);
|
||||
extern const char* acc_fetch_type_str(PLI_INT32 type);
|
||||
|
||||
extern char* acc_fetch_value(handle obj, const char*fmt, s_acc_value*value);
|
||||
|
||||
extern handle acc_handle_by_name(const char*name, handle scope);
|
||||
extern handle acc_handle_hiconn(handle port_ref_handle);
|
||||
extern handle acc_handle_object(const char*name);
|
||||
extern handle acc_handle_parent(handle obj);
|
||||
extern handle acc_handle_scope(handle obj);
|
||||
extern handle acc_handle_simulated_net(handle net);
|
||||
|
||||
extern handle acc_handle_tfarg(int n);
|
||||
extern handle acc_handle_tfinst(void);
|
||||
|
||||
extern PLI_INT32 acc_compare_handles(handle, handle);
|
||||
|
||||
extern handle acc_next(PLI_INT32 *, handle, handle);
|
||||
extern handle acc_next_bit(handle ref, handle bit);
|
||||
extern handle acc_next_port(handle ref, handle bit);
|
||||
extern handle acc_next_scope(handle, handle);
|
||||
extern handle acc_next_topmod(handle prev_topmod);
|
||||
|
||||
extern int acc_object_in_typelist(handle object, PLI_INT32*typelist);
|
||||
extern int acc_object_of_type(handle object, PLI_INT32 type);
|
||||
|
||||
extern char*acc_product_version(void);
|
||||
|
||||
extern char*acc_set_scope(handle ref, ...);
|
||||
|
||||
extern int acc_set_value(handle obj, p_setval_value value,
|
||||
p_setval_delay delay);
|
||||
|
||||
extern void acc_vcl_add(handle obj, PLI_INT32(*consumer)(p_vc_record),
|
||||
void*data, PLI_INT32 vcl_flag);
|
||||
extern void acc_vcl_delete(handle obj, PLI_INT32(*consumer)(p_vc_record),
|
||||
void*data, PLI_INT32 vcl_flag);
|
||||
|
||||
extern char* acc_version(void);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif /* ACC_USER_H */
|
||||
Vendored
-245
@@ -1,245 +0,0 @@
|
||||
|
||||
# AX_ENABLE_SUFFIX
|
||||
# ----------------
|
||||
# Create the configure option --enable-suffix[=suffix] to generate suffix
|
||||
# strings for the installed commands. This allows for shared installs of
|
||||
# different builds. Remember to change the default suffix string to some
|
||||
# value appropriate for the current version.
|
||||
AC_DEFUN([AX_ENABLE_SUFFIX],
|
||||
[AC_ARG_ENABLE([suffix],[AC_HELP_STRING([--enable-suffix],
|
||||
[Use/set the installation command suffix])],
|
||||
[true],[enable_suffix=no])
|
||||
if test X$enable_suffix = Xyes; then
|
||||
install_suffix='-0.10'
|
||||
elif test X$enable_suffix = Xno; then
|
||||
install_suffix=''
|
||||
else
|
||||
install_suffix="$enable_suffix"
|
||||
fi
|
||||
AC_SUBST(install_suffix)
|
||||
])# AX_ENABLE_SUFFIX
|
||||
|
||||
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
|
||||
# ------------------------------
|
||||
# Sub-macro for AX_C_UNDERSCORES_LEADING and AX_C_UNDERSCORES_TRAILING.
|
||||
# Unwarranted assumptions:
|
||||
# - the object file produced by AC_COMPILE_IFELSE is called "conftest.$ac_objext"
|
||||
# - the nm(1) utility is available, and its name is "nm".
|
||||
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF],
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([void underscore(void){}])],
|
||||
[AS_IF([nm conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
|
||||
[AC_MSG_ERROR([underscore test crashed])]
|
||||
)])
|
||||
|
||||
|
||||
# AX_C_UNDERSCORES_LEADING
|
||||
# ---------------------------------
|
||||
# Check if symbol names in object files produced by C compiler have
|
||||
# leading underscores. Define NEED_LU if so.
|
||||
AC_DEFUN([AX_C_UNDERSCORES_LEADING],
|
||||
[AC_CACHE_CHECK([for leading underscores], ax_cv_c_underscores_leading,
|
||||
[_AX_C_UNDERSCORES_MATCH_IF([_underscore],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
|
||||
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
|
||||
AC_DEFINE([NEED_LU], [1], [Symbol names in object files produced by C compiler have leading underscores.])
|
||||
fi
|
||||
])# AX_C_UNDERSCORES_LEADING
|
||||
|
||||
|
||||
# AX_C_UNDERSCORES_TRAILING
|
||||
# ---------------------------------
|
||||
# Check if symbol names in object files produced by C compiler have
|
||||
# trailing underscores. Define NEED_TU if so.
|
||||
AC_DEFUN([AX_C_UNDERSCORES_TRAILING],
|
||||
[AC_CACHE_CHECK([for trailing underscores], ax_cv_c_underscores_trailing,
|
||||
[_AX_C_UNDERSCORES_MATCH_IF([underscore_],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_trailing, yes)],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_trailing, no)])])
|
||||
if test $ax_cv_c_underscores_trailing = yes; then
|
||||
AC_DEFINE([NEED_TU], [1], [Symbol names in object files produced by C compiler have trailing underscores.])
|
||||
fi
|
||||
])# AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
# AX_WIN32
|
||||
# --------
|
||||
# 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_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
|
||||
# ---------------
|
||||
# mingw needs to link with libiberty.a, but cygwin alone can't tolerate it
|
||||
AC_DEFUN([AX_LD_EXTRALIBS],
|
||||
[AC_MSG_CHECKING([for extra libs needed])
|
||||
EXTRALIBS=
|
||||
case "${host}" in
|
||||
*-*-cygwin* )
|
||||
if test "$MINGW32" = "yes"; then
|
||||
EXTRALIBS="-liberty"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXTRALIBS)
|
||||
AC_MSG_RESULT($EXTRALIBS)
|
||||
])# AX_LD_EXTRALIBS
|
||||
|
||||
# AX_LD_SHAREDLIB_OPTS
|
||||
# --------------------
|
||||
# linker options when building a shared library
|
||||
AC_DEFUN([AX_LD_SHAREDLIB_OPTS],
|
||||
[AC_MSG_CHECKING([for shared library link flag])
|
||||
shared=-shared
|
||||
case "${host}" in
|
||||
*-*-cygwin*)
|
||||
shared="-shared -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-mingw*)
|
||||
shared="-shared -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
shared="-b"
|
||||
;;
|
||||
|
||||
*-*-darwin1.[0123])
|
||||
shared="-bundle -undefined suppress"
|
||||
;;
|
||||
|
||||
*-*-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)
|
||||
])# AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
# AX_C_PICFLAG
|
||||
# ------------
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
AC_DEFUN([AX_C_PICFLAG],
|
||||
[AC_MSG_CHECKING([for flag to make position independent code])
|
||||
PICFLAG=-fPIC
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
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)
|
||||
])# AX_C_PICFLAG
|
||||
|
||||
# AX_LD_RDYNAMIC
|
||||
# --------------
|
||||
# The -rdynamic flag is used by iverilog when compiling the target,
|
||||
# to know how to export symbols of the main program to loadable modules
|
||||
# that are brought in by -ldl
|
||||
AC_DEFUN([AX_LD_RDYNAMIC],
|
||||
[AC_MSG_CHECKING([for -rdynamic compiler flag])
|
||||
rdynamic=-rdynamic
|
||||
case "${host}" in
|
||||
|
||||
*-*-netbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-openbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-cygwin*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-mingw*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
rdynamic="-Wl,-all_load"
|
||||
strip_dynamic="-SX"
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(rdynamic)
|
||||
AC_MSG_RESULT($rdynamic)
|
||||
AC_SUBST(strip_dynamic)
|
||||
# since we didn't tell them we're "checking", no good place to tell the answer
|
||||
# AC_MSG_RESULT($strip_dynamic)
|
||||
])# AX_LD_RDYNAMIC
|
||||
|
||||
|
||||
# AX_C99_STRTOD
|
||||
# -------------
|
||||
AC_DEFUN([AX_C99_STRTOD],
|
||||
[# On MinGW we need to jump through hoops to get a C99 compliant strtod().
|
||||
case "${host}" in
|
||||
*-*-mingw*)
|
||||
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
|
||||
;;
|
||||
esac
|
||||
])# AX_C99_STRTOD
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp file name are based on the header name.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[
|
||||
_config_header=$1
|
||||
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
|
||||
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
|
||||
]) #_AC_AM_CONFIG_HEADER_HOOK
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2010 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
# include <cassert>
|
||||
|
||||
bool NetAssign::is_asynchronous()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCondit::is_asynchronous()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* NetEvWait statements come from statements of the form @(...) in the
|
||||
* Verilog source. These event waits are considered asynchronous if
|
||||
* all of the events in the list are ANYEDGE, and all the inputs to
|
||||
* the statement are included in the sensitivity list. If any of the
|
||||
* events are posedge or negedge, the statement is synchronous
|
||||
* (i.e. an edge-triggered flip-flop) and if any of the inputs are
|
||||
* unaccounted for in the sensitivity list then the statement is a
|
||||
* latch.
|
||||
*/
|
||||
bool NetEvWait::is_asynchronous()
|
||||
{
|
||||
/* The "sense" set contains the set of Nexa that are in the
|
||||
sensitivity list. We also require that the events are all
|
||||
level sensitive, but the nex_async_ method takes care of
|
||||
that test. */
|
||||
NexusSet*sense = new NexusSet;
|
||||
for (unsigned idx = 0 ; idx < events_.size() ; idx += 1) {
|
||||
NexusSet*tmp = events_[idx]->nex_async_();
|
||||
if (tmp == 0) {
|
||||
delete sense;
|
||||
return false;
|
||||
}
|
||||
|
||||
sense->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
NexusSet*inputs = statement_->nex_input();
|
||||
|
||||
if (! sense->contains(*inputs)) {
|
||||
delete sense;
|
||||
delete inputs;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete sense;
|
||||
delete inputs;
|
||||
|
||||
/* If it passes all the other tests, then this statement is
|
||||
asynchronous. */
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetProc::is_asynchronous()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetProcTop::is_asynchronous() const
|
||||
{
|
||||
if (type_ == IVL_PR_INITIAL)
|
||||
return false;
|
||||
|
||||
return statement_->is_asynchronous();
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
|
||||
ATTRIBUTE NAMING CONVENTIONS
|
||||
|
||||
Attributes that are specific to Icarus Verilog, and are intended to be
|
||||
of use to programmers, start with the prefix "ivl_".
|
||||
|
||||
Attributes with the "_ivl_" prefix are set aside for internal
|
||||
use. They may be generated internally by the compiler. They need not
|
||||
be documented here.
|
||||
|
||||
ATTRIBUTES TO CONTROL SYNTHESIS
|
||||
|
||||
The following is a summary of Verilog attributes that Icarus Verilog
|
||||
understands within Verilog source files to control synthesis
|
||||
behavior. This section documents generic synthesis attributes. For
|
||||
target specific attributes, see target specific documentation.
|
||||
|
||||
These attributes only effect the behavior of the synthesizer. For
|
||||
example, the ivl_combinational will not generate an error message
|
||||
if the Verilog is being compiled for simulation. (It may generate a
|
||||
warning.)
|
||||
|
||||
|
||||
* Attributes for "always" and "initial" statements
|
||||
|
||||
(* ivl_combinational *)
|
||||
|
||||
This attribute tells the compiler that the statement models
|
||||
combinational logic. If the compiler finds that it cannot make
|
||||
combinational logic out of a marked always statement, it will
|
||||
report an error.
|
||||
|
||||
This attribute can be used to prevent accidentally inferring
|
||||
latches or flip-flops where the user intended combinational
|
||||
logic.
|
||||
|
||||
(* ivl_synthesis_on *)
|
||||
|
||||
This attribute tells the compiler that the marked always statement
|
||||
is synthesizable. The compiler will attempt to synthesize the
|
||||
code in the marked "always" statement. If it cannot in any way
|
||||
synthesize it, then it will report an error.
|
||||
|
||||
(* ivl_synthesis_off *)
|
||||
|
||||
If this value is attached to an "always" statement, then the
|
||||
compiler will *not* synthesize the "always" statement. This can be
|
||||
used, for example, to mark embedded test bench code.
|
||||
|
||||
|
||||
* Attributes for modules
|
||||
|
||||
(* ivl_synthesis_cell *)
|
||||
|
||||
If this value is attached to a module during synthesis, that
|
||||
module will be considered a target architecture primitive, and
|
||||
its interior will not be synthesized further. The module can
|
||||
therefore hold a model for simulation purposes.
|
||||
|
||||
|
||||
* Attributes for signals (wire/reg/integer/tri/etc.)
|
||||
|
||||
(* PAD = "<pad assignment list>" *)
|
||||
|
||||
If this attribute is attached to a signal that happens to be a
|
||||
root module port, then targets that support it will use the string
|
||||
value as a list of pin assignments for the port/signal. The format
|
||||
is a comma separated list of location tokens, with the format of
|
||||
the token itself defined by the back-end tools in use.
|
||||
|
||||
* Other Attributes
|
||||
|
||||
[ none defined yet ]
|
||||
|
||||
|
||||
MISC
|
||||
|
||||
(* _ivl_schedule_push *)
|
||||
|
||||
If this attribute is attached to a thread object (always or
|
||||
initial statement) then the vvp code generator will generate code
|
||||
that causes the scheduler to push this thread at compile time. The
|
||||
compiler may internally add this attribute to always statements if
|
||||
it detects that it is combinational. This helps resolve time-0
|
||||
races.
|
||||
+11
-8
@@ -2,15 +2,18 @@
|
||||
|
||||
#
|
||||
# This shell script exists to run autoconf on source distributions
|
||||
# that are pulled from git The configure script is not included
|
||||
# in git, so it is easiest to just run this script whenever needed
|
||||
# to generate the configure script.
|
||||
# that are pulled from CVS. The configure scripts are not included
|
||||
# in CVS, and there are several configure.in files, so it is easiest
|
||||
# to just run this script to autoconf wherever needed.
|
||||
#
|
||||
echo "Autoconf in root..."
|
||||
autoconf -f
|
||||
autoconf
|
||||
|
||||
for dir in vpip vvp tgt-vvp tgt-fpga
|
||||
do
|
||||
echo "Autoconf in $dir..."
|
||||
( cd $dir ; autoconf )
|
||||
done
|
||||
|
||||
echo "Precompiling lexor_keyword.gperf"
|
||||
gperf -o -i 7 -C -k 1-4,6,9,\$ -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
|
||||
|
||||
echo "Precompiling vhdlpp/lexor_keyword.gperf"
|
||||
(cd vhdlpp ; gperf -o -i 7 --ignore-case -C -k 1-4,6,9,\$ -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc )
|
||||
gperf -o -i 7 -C -k 1-3,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
#
|
||||
# This source code is free software; you can redistribute it
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library 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 Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
suffix = @install_suffix@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = $(prefix)/include
|
||||
|
||||
vpidir = @libdir@/ivl$(suffix)
|
||||
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
ifeq (@srcdir@,.)
|
||||
INCLUDE_PATH = -I. -I..
|
||||
else
|
||||
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = cadpli.o
|
||||
|
||||
all: dep cadpli.vpl $(ALL32)
|
||||
|
||||
check: all
|
||||
|
||||
clean:
|
||||
rm -rf *.o dep cadpli.vpl
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all -f $(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=cadpli/$@
|
||||
|
||||
dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $<
|
||||
mv $*.d dep
|
||||
|
||||
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
|
||||
ifeq (@MINGW32@,yes)
|
||||
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
|
||||
endif
|
||||
|
||||
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
|
||||
$(CC) @shared@ $(LDFLAGS) -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
install: all installdirs $(vpidir)/cadpli.vpl
|
||||
|
||||
$(vpidir)/cadpli.vpl: ./cadpli.vpl
|
||||
$(INSTALL_PROGRAM) ./cadpli.vpl "$(DESTDIR)$(vpidir)/cadpli.vpl"
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(vpidir)"
|
||||
|
||||
uninstall: $(UNINSTALL32)
|
||||
rm -f "$(DESTDIR)$(vpidir)/cadpli.vpl"
|
||||
|
||||
uninstall32:
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2010 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <vpi_user.h>
|
||||
# include <veriuser.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
# include "config.h"
|
||||
# include "ivl_dlfcn.h"
|
||||
# include "ivl_alloc.h"
|
||||
|
||||
typedef void* (*funcvp)(void);
|
||||
|
||||
static void thunker_register(void)
|
||||
{
|
||||
struct t_vpi_vlog_info vlog_info;
|
||||
void*mod;
|
||||
void*boot;
|
||||
struct t_tfcell*tf;
|
||||
int idx;
|
||||
|
||||
vpi_get_vlog_info(&vlog_info);
|
||||
|
||||
for (idx = 0 ; idx < vlog_info.argc ; idx += 1) {
|
||||
char*module, *cp, *bp;
|
||||
if (strncmp("-cadpli=", vlog_info.argv[idx], 8) != 0)
|
||||
continue;
|
||||
|
||||
cp = vlog_info.argv[idx] + 8;
|
||||
assert(cp);
|
||||
|
||||
bp = strchr(cp, ':');
|
||||
assert(bp);
|
||||
|
||||
module = malloc(bp-cp+1);
|
||||
strncpy(module, cp, bp-cp);
|
||||
module[bp-cp] = 0;
|
||||
|
||||
mod = ivl_dlopen(module);
|
||||
if (mod == 0) {
|
||||
vpi_printf("%s link: %s\n", vlog_info.argv[idx], dlerror());
|
||||
free(module);
|
||||
continue;
|
||||
}
|
||||
|
||||
bp += 1;
|
||||
boot = ivl_dlsym(mod, bp);
|
||||
if (boot == 0) {
|
||||
vpi_printf("%s: Symbol %s not found.\n",
|
||||
vlog_info.argv[idx], bp);
|
||||
free(module);
|
||||
continue;
|
||||
}
|
||||
|
||||
free(module);
|
||||
assert(boot);
|
||||
|
||||
tf = (*((funcvp)boot))();
|
||||
assert(tf);
|
||||
|
||||
veriusertfs_register_table(tf);
|
||||
}
|
||||
}
|
||||
|
||||
void (*vlog_startup_routines[])(void) = {
|
||||
thunker_register,
|
||||
0
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
|
||||
CADENCE PLI1 MODULES
|
||||
|
||||
Copyright 2003 Stephen Williams
|
||||
|
||||
With the cadpli module, Icarus Verilog is able to load PLI1
|
||||
applications that were compiled and linked to be dynamic loaded by
|
||||
Verilog-XL or NC-Verilog. This allows Icarus Verilog users to run
|
||||
third-party modules that were compiled to interface with XL or
|
||||
NC. Obviously, this only works on the operating system that the PLI
|
||||
application was compiled to run on. For example, a Linux module can
|
||||
only be loaded and run under Linux.
|
||||
|
||||
Icarus Verilog uses an interface module, the "cadpli" module, to
|
||||
connect the worlds. This module is installed with Icarus Verilog, and
|
||||
is invoked by the usual -m flag to iverilog or vvp. This module in
|
||||
turn scans the extended arguments, looking for +cadpli= arguments. The
|
||||
latter specify the share object and bootstrap function for running the
|
||||
module. For example, to run the module product.so, that has the
|
||||
bootstrap function "my_boot":
|
||||
|
||||
vvp -mcadpli a.out -cadpli=./product.so:my_boot
|
||||
|
||||
The "-mcadpli" argument causes vvp to load the cadpli.vpl library
|
||||
module. This activates the -cadpli= argument interpreter. The
|
||||
-cadpli=<module>:<boot_func> argument, then, causes vvp, through the
|
||||
cadpli module, to load the loadable PLI application, invoke the
|
||||
my_boot function to get a veriusertfs table, and scan that table to
|
||||
register the system tasks and functions exported by that object. The
|
||||
format of the -cadpli= extended argument is essentially the same as
|
||||
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.
|
||||
+9
-4
@@ -1,4 +1,9 @@
|
||||
functor:cprop
|
||||
functor:nodangle
|
||||
-t:dll
|
||||
flag:DLL=tgt-vvp/vvp.tgt
|
||||
|
||||
# The make check target uses this to check the compilation of the
|
||||
# compiler.
|
||||
|
||||
[-tvvm-check]
|
||||
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o.cc -- -
|
||||
|
||||
[-tvvp-check]
|
||||
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=./tgt-vvp/vvp.tgt -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o -- -
|
||||
|
||||
+40
-223
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_compiler_H
|
||||
#define IVL_compiler_H
|
||||
#ifndef __compiler_H
|
||||
#define __compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-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,36 +16,24 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: compiler.h,v 1.7 2001/11/16 05:07:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "netlist.h"
|
||||
# include "StringHeap.h"
|
||||
|
||||
/*
|
||||
* This defines constants and defaults for the compiler in general.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* The integer_width is the width of integer variables. This is also
|
||||
* the minimum width of unsized integers when they are found in
|
||||
* self-determined contexts.
|
||||
*/
|
||||
extern unsigned integer_width;
|
||||
|
||||
/*
|
||||
* The width_cap is the width limit for unsized expressions.
|
||||
*/
|
||||
extern unsigned width_cap;
|
||||
|
||||
/*
|
||||
* This is the maximum number of recursive module loops allowed within
|
||||
* a generate block.
|
||||
*/
|
||||
extern unsigned recursive_mod_limit;
|
||||
/* The INTEGER_WIDTH is the default width of integer variables, and
|
||||
the presumed width of unsigned literal numbers. */
|
||||
#ifndef INTEGER_WIDTH
|
||||
# define INTEGER_WIDTH 32
|
||||
#endif
|
||||
|
||||
/* The TIME_WIDTH is the width of time variables. */
|
||||
#ifndef TIME_WIDTH
|
||||
@@ -73,214 +61,43 @@ extern unsigned recursive_mod_limit;
|
||||
|
||||
/*
|
||||
* These are flags to enable various sorts of warnings. By default all
|
||||
* the warnings are off, the -W<list> parameter arranges for each to be
|
||||
* enabled.
|
||||
* the warnings are of, the -W<list> parameter arranges for each to be
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
/* Implicit definitions of wires. */
|
||||
extern bool warn_implicit;
|
||||
|
||||
/* inherit timescales across files. */
|
||||
extern bool warn_timescale;
|
||||
|
||||
/* Warn about legal but questionable module port bindings. */
|
||||
extern bool warn_portbinding;
|
||||
|
||||
/* Warn about constant out of bound selects. */
|
||||
extern bool warn_ob_select;
|
||||
|
||||
/* Warn about structures that may have infinite loops. */
|
||||
extern bool warn_inf_loop;
|
||||
|
||||
/* Warn about always @* statements where a part or word select causes
|
||||
sensitivity to an entire vector or array. */
|
||||
extern bool warn_sens_entire_vec;
|
||||
extern bool warn_sens_entire_arr;
|
||||
|
||||
/* Warn about level-appropriate anachronisms. */
|
||||
extern bool warn_anachronisms;
|
||||
|
||||
/* This is true if verbose output is requested. */
|
||||
extern bool verbose_flag;
|
||||
|
||||
extern bool debug_scopes;
|
||||
extern bool debug_eval_tree;
|
||||
extern bool debug_elaborate;
|
||||
extern bool debug_emit;
|
||||
extern bool debug_synth2;
|
||||
extern bool debug_optimizer;
|
||||
|
||||
/* Control evaluation of functions at compile time:
|
||||
* 0 = only for functions in constant expressions
|
||||
* 1 = only for automatic functions
|
||||
* 2 = for all functions
|
||||
* Level 2 should only be used if the user can guarantee that a
|
||||
* function's local variables are never accessed from outside the
|
||||
* function. */
|
||||
extern unsigned opt_const_func;
|
||||
|
||||
/* Possibly temporary flag to control virtualization of pin arrays */
|
||||
extern bool disable_virtual_pins;
|
||||
|
||||
/* The vlog95 code generator does not want the compiler to generate concat-Z
|
||||
* LPM objects so this flag is used to block them from being generated. */
|
||||
extern bool disable_concatz_generation;
|
||||
|
||||
/* Limit to size of devirtualized arrays */
|
||||
extern unsigned long array_size_limit;
|
||||
|
||||
/* Path to a directory useful for finding subcomponents. */
|
||||
extern const char*basedir;
|
||||
|
||||
/* This is an ordered list of library suffixes to search. */
|
||||
/* This is an ordered list of libraries to search. */
|
||||
extern list<const char*>library_dirs;
|
||||
extern list<const char*>library_suff;
|
||||
extern int build_library_index(const char*path, bool key_case_sensitive);
|
||||
|
||||
/* This is the generation of Verilog that the compiler is asked to
|
||||
support. Then there are also more detailed controls for more
|
||||
specific language features. */
|
||||
enum generation_t {
|
||||
GN_VER1995 = 1,
|
||||
GN_VER2001_NOCONFIG = 2,
|
||||
GN_VER2001 = 3,
|
||||
GN_VER2005 = 4,
|
||||
GN_VER2005_SV = 5,
|
||||
GN_VER2009 = 6,
|
||||
GN_VER2012 = 7,
|
||||
GN_DEFAULT = 4
|
||||
};
|
||||
|
||||
extern generation_t generation_flag;
|
||||
|
||||
/* If this flag is true, enable extended types support. */
|
||||
extern bool gn_cadence_types_flag;
|
||||
|
||||
/* If this flag is true, enable miscellaneous extensions. */
|
||||
extern bool gn_icarus_misc_flag;
|
||||
|
||||
/* If this flag is true, then elaborate specify blocks. If this flag
|
||||
is false, then skip elaboration of specify behavior. */
|
||||
extern bool gn_specify_blocks_flag;
|
||||
|
||||
/* If this flag is true, then elaborate assertions. If this flag is
|
||||
false, then stub out assertion statements. */
|
||||
extern bool gn_assertions_flag;
|
||||
|
||||
/* If this flag is true, then support/elaborate Verilog-AMS. */
|
||||
extern bool gn_verilog_ams_flag;
|
||||
|
||||
/* If this flag is false a warning is printed when the port declaration
|
||||
is scalar and the net/register definition is vectored. */
|
||||
extern bool gn_io_range_error_flag;
|
||||
|
||||
/* If this flag is true, then force re-evaluation of user functions
|
||||
in a continuous assignment when any part of the expression is
|
||||
re-evaluated. */
|
||||
extern bool gn_strict_ca_eval_flag;
|
||||
|
||||
/* If this flag is true, then force strict conformance to the IEEE
|
||||
standard expression width rules. */
|
||||
extern bool gn_strict_expr_width_flag;
|
||||
|
||||
/* If variables can be converted to uwires by a continuous assignment
|
||||
(assuming no procedural assign, then return true. This will be true
|
||||
for SystemVerilog */
|
||||
static inline bool gn_var_can_be_uwire(void)
|
||||
{
|
||||
if (generation_flag == GN_VER2005_SV ||
|
||||
generation_flag == GN_VER2009 ||
|
||||
generation_flag == GN_VER2012)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool gn_system_verilog(void)
|
||||
{
|
||||
if (generation_flag == GN_VER2005_SV ||
|
||||
generation_flag == GN_VER2009 ||
|
||||
generation_flag == GN_VER2012)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool gn_modules_nest(void)
|
||||
{
|
||||
return gn_system_verilog();
|
||||
}
|
||||
|
||||
/* The bits of these GN_KEYWORDS_* constants define non-intersecting
|
||||
sets of keywords. The compiler enables groups of keywords by setting
|
||||
lexor_keyword_mask with the OR of the bits for the keywords to be
|
||||
enabled. */
|
||||
enum { GN_KEYWORDS_1364_1995 = 0x0001,
|
||||
GN_KEYWORDS_1364_2001 = 0x0002,
|
||||
GN_KEYWORDS_1364_2001_CONFIG = 0x0004,
|
||||
GN_KEYWORDS_1364_2005 = 0x0008,
|
||||
GN_KEYWORDS_VAMS_2_3 = 0x0010,
|
||||
GN_KEYWORDS_1800_2005 = 0x0020,
|
||||
GN_KEYWORDS_1800_2009 = 0x0040,
|
||||
GN_KEYWORDS_1800_2012 = 0x0080,
|
||||
GN_KEYWORDS_ICARUS = 0x8000
|
||||
};
|
||||
extern int lexor_keyword_mask;
|
||||
|
||||
/* This is the string to use to invoke the preprocessor. */
|
||||
extern char*ivlpp_string;
|
||||
|
||||
extern map<perm_string,unsigned> missing_modules;
|
||||
|
||||
/* Files that are library files are in this map. The lexor compares
|
||||
file names as it processes `line directives, and if the file name
|
||||
matches an entry in this table, it will turn on the
|
||||
library_active_flag so that modules know that they are in a
|
||||
library. */
|
||||
extern map<perm_string,bool> library_file_map;
|
||||
|
||||
/*
|
||||
* the lex_strings are perm_strings made up of tokens from the source
|
||||
* file. Identifiers are so likely to be used many times that it makes
|
||||
* much sense to use a StringHeapLex to hold them.
|
||||
* $Log: compiler.h,v $
|
||||
* Revision 1.7 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
*
|
||||
* Revision 1.6 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
* Revision 1.5 2000/10/31 17:49:02 steve
|
||||
* Support time variables.
|
||||
*
|
||||
* Revision 1.4 2000/08/20 04:13:56 steve
|
||||
* Add ivl_target support for logic gates, and
|
||||
* make the interface more accessible.
|
||||
*
|
||||
* Revision 1.3 2000/03/17 21:50:25 steve
|
||||
* Switch to control warnings.
|
||||
*
|
||||
* Revision 1.2 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.1 1999/06/06 20:42:48 steve
|
||||
* Make compiler width a compile time constant.
|
||||
*
|
||||
*/
|
||||
extern StringHeapLex lex_strings;
|
||||
|
||||
/*
|
||||
* The ivl_target.h API in a variety of places keeps strings of
|
||||
* bits. Manage these as perm_string in a StringHeap.
|
||||
*/
|
||||
extern StringHeapLex bits_strings;
|
||||
|
||||
/*
|
||||
* The filename_strings are perm_strings for file names. They are put
|
||||
* into their own StringHeapLex because these paths are used a *lot*
|
||||
* and this makes them more sure to hash together.
|
||||
*/
|
||||
extern StringHeapLex filename_strings;
|
||||
|
||||
|
||||
/*
|
||||
* system task/function listings.
|
||||
*/
|
||||
/*
|
||||
* This table describes all the return values of various system
|
||||
* functions. This table is used to elaborate expressions that are
|
||||
* system function calls.
|
||||
*/
|
||||
struct sfunc_return_type {
|
||||
const char* name;
|
||||
ivl_variable_type_t type;
|
||||
unsigned wid;
|
||||
int signed_flag;
|
||||
};
|
||||
|
||||
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
|
||||
extern int load_sys_func_table(const char*path);
|
||||
extern void cleanup_sys_func_table();
|
||||
|
||||
/*
|
||||
* In system Verilog it is allowed with a warning to call a function
|
||||
* as a task. You can even cast the return value away and have no
|
||||
* warning message.
|
||||
*/
|
||||
extern ivl_sfunc_as_task_t def_sfunc_as_task;
|
||||
|
||||
#endif /* IVL_compiler_H */
|
||||
#endif
|
||||
|
||||
Vendored
+565
-943
File diff suppressed because it is too large
Load Diff
+25
-25
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_config_H /* -*- c++ -*- */
|
||||
#define IVL_config_H
|
||||
#ifndef __config_H /* -*- c++ -*- */
|
||||
#define __config_H
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,8 +16,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: config.h.in,v 1.4 2002/02/16 03:18:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# if !defined(__GNUC__)
|
||||
@@ -28,38 +31,35 @@
|
||||
#endif
|
||||
|
||||
# undef NEED_LU
|
||||
# undef NEED_TU
|
||||
# undef NEED_TU
|
||||
# undef WLU
|
||||
# undef WTU
|
||||
# undef HAVE_TIMES
|
||||
# undef HAVE_IOSFWD
|
||||
# undef HAVE_GETOPT_H
|
||||
# undef HAVE_INTTYPES_H
|
||||
# undef HAVE_LIBIBERTY_H
|
||||
# undef HAVE_MALLOC_H
|
||||
# undef HAVE_DLFCN_H
|
||||
# undef HAVE_DL_H
|
||||
# undef HAVE_FCHMOD
|
||||
# undef HAVE_LIBREADLINE
|
||||
# undef HAVE_LIBZ
|
||||
# undef HAVE_LIBBZ2
|
||||
# undef HAVE_LROUND
|
||||
# undef HAVE_SYS_WAIT_H
|
||||
# undef WORDS_BIGENDIAN
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/* These two are needed by the lxt and lxt2 files (copied from GTKWave). */
|
||||
# undef HAVE_ALLOCA_H
|
||||
# undef HAVE_FSEEKO
|
||||
/* And this is needed by the fst files (copied from GTKWave). */
|
||||
# undef HAVE_LIBPTHREAD
|
||||
# undef ENABLE_VVM
|
||||
|
||||
/*
|
||||
* 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.4 2002/02/16 03:18:53 steve
|
||||
* Make vvm optional, normally off.
|
||||
*
|
||||
* Revision 1.3 2001/10/18 16:16:23 steve
|
||||
* Include HAVE_SYS_WAIT in config.h (PR#306)
|
||||
*
|
||||
* Revision 1.2 2001/09/15 18:27:04 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
* Revision 1.1 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
*/
|
||||
# undef CHECK_WITH_VALGRIND
|
||||
|
||||
#endif /* IVL_config_H */
|
||||
#endif // __config_H
|
||||
|
||||
Vendored
+153
-571
File diff suppressed because it is too large
Load Diff
+177
-249
@@ -1,41 +1,27 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(netlist.h)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADER(_pli_types.h)
|
||||
AC_CONFIG_HEADER(vhdlpp/vhdlpp_config.h)
|
||||
AC_CONFIG_HEADER(vvp/config.h)
|
||||
AC_CONFIG_HEADER(vpi/vpi_config.h)
|
||||
AC_CONFIG_HEADER(libveriuser/config.h)
|
||||
AC_CONFIG_HEADER(tgt-vvp/vvp_config.h)
|
||||
AC_CONFIG_HEADER(tgt-vhdl/vhdl_config.h)
|
||||
AC_CONFIG_HEADER(tgt-pcb/pcb_config.h)
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AC_ARG_ENABLE(vvm, vvm target -- the obsolete vvm code generator,
|
||||
AC_DEFINE(ENABLE_VVM))
|
||||
if test "${enable_vvm+set}" = set
|
||||
then
|
||||
ENABLE_VVM=yes
|
||||
else
|
||||
ENABLE_VVM=no
|
||||
fi
|
||||
AC_SUBST(ENABLE_VVM)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
# AC_PROG_CC_C99 is only available in autoconf version 2.60 and later.
|
||||
AC_PREREQ([2.60])
|
||||
AC_PROG_CC_C99
|
||||
AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
AC_CHECK_TOOL(LD, ld, false)
|
||||
AC_CHECK_TOOL(AR, ar, false)
|
||||
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
AC_CHECK_TOOL(WINDRES,windres,false)
|
||||
AC_CHECK_PROGS(XGPERF,gperf,none)
|
||||
AC_CHECK_PROGS(MAN,man,none)
|
||||
AC_CHECK_PROGS(PS2PDF,ps2pdf,none)
|
||||
AC_CHECK_PROGS(GIT,git,none)
|
||||
if test "$XGPERF" = "none"
|
||||
then
|
||||
echo ""
|
||||
echo "*** Warning: No suitable gperf found. ***"
|
||||
echo " The gperf package is essential for building ivl from"
|
||||
echo " git sources, or modifying the parse engine of ivl itself."
|
||||
echo " You can get away without it when simply building from"
|
||||
echo " snapshots or major releases."
|
||||
echo ""
|
||||
echo "*** Error: No suitable gperf found. ***"
|
||||
echo " Please install the 'gperf' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(LEX,flex,none)
|
||||
@@ -54,121 +40,9 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_EXEEXT
|
||||
AC_SUBST(EXEEXT)
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||
AX_WIN32
|
||||
|
||||
# Check to see if we are using the Sun compiler. If so then configure
|
||||
# some of the flags to match the Sun compiler syntax. This is also used
|
||||
# in the aclocal.m4 file to configure the flags used to build and link
|
||||
# dynamic libraries
|
||||
AC_CHECK_DECL(__SUNPRO_C, using_sunpro_c=1, using_sunpro_c=0)
|
||||
if test ${using_sunpro_c} = 1
|
||||
then
|
||||
AC_SUBST(DEPENDENCY_FLAG, [-xMMD])
|
||||
AC_SUBST(WARNING_FLAGS, [""])
|
||||
AC_SUBST(WARNING_FLAGS_CXX, [""])
|
||||
else
|
||||
# Check to see if -Wextra is supported.
|
||||
iverilog_temp_cflags="$CFLAGS"
|
||||
CFLAGS="-Wextra $CFLAGS"
|
||||
AC_MSG_CHECKING(if gcc supports -Wextra)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[[iverilog_wextra_flag="-Wextra";] AC_MSG_RESULT(yes)],
|
||||
[[iverilog_wextra_flag="-W";] AC_MSG_RESULT(no)])
|
||||
CFLAGS="$iverilog_temp_cflags"
|
||||
|
||||
AC_SUBST(DEPENDENCY_FLAG, [-MD])
|
||||
AC_SUBST(WARNING_FLAGS, ["-Wall $iverilog_wextra_flag -Wshadow"])
|
||||
AC_SUBST(WARNING_FLAGS_CC, [""])
|
||||
AC_SUBST(WARNING_FLAGS_CXX, [""])
|
||||
fi
|
||||
|
||||
AC_LANG(C++)
|
||||
|
||||
AC_ARG_WITH([m32], [AC_HELP_STRING([--with-m32], [Compile 32-bit on x86_64])],
|
||||
[ with_m32=yes ],[ with_m32=no ])
|
||||
|
||||
AS_IF( [test "x$with_m32" = xyes],
|
||||
[ AC_MSG_NOTICE([Compiling for 32-bit environment - needs gcc on x86_64])
|
||||
LDTARGETFLAGS="-m elf_i386"
|
||||
CTARGETFLAGS="-m32"
|
||||
],
|
||||
[])
|
||||
|
||||
CFLAGS="$CTARGETFLAGS $CFLAGS"
|
||||
CXXFLAGS="$CTARGETFLAGS $CXXFLAGS"
|
||||
LDFLAGS="$CTARGETFLAGS $LDFLAGS"
|
||||
|
||||
# Check that we are using either the GNU compilers or the Sun compilers
|
||||
# but not a mixture of the two (not currently supported).
|
||||
AC_CHECK_DECL(__SUNPRO_CC, using_sunpro_cc=1, using_sunpro_cc=0)
|
||||
if test ${using_sunpro_c} = 1
|
||||
then
|
||||
if test ${using_sunpro_cc} = 0
|
||||
then
|
||||
echo "*** Error: No support for mixing GNU and Sun compilers. ***"
|
||||
echo " Using Sun C compiler and GNU C++ compiler.."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if test ${using_sunpro_cc} = 1
|
||||
then
|
||||
echo "*** Error: No support for mixing GNU and Sun compilers. ***"
|
||||
echo " Using GNU C compiler and Sun C++ compiler.."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
iverilog_temp_cxxflags="$CXXFLAGS"
|
||||
CXXFLAGS="-DHAVE_DECL_BASENAME $CXXFLAGS"
|
||||
|
||||
AC_CHECK_HEADERS(getopt.h inttypes.h libiberty.h iosfwd sys/wait.h)
|
||||
CXXFLAGS="$iverilog_temp_cxxflags"
|
||||
|
||||
AC_CHECK_SIZEOF(unsigned long long)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
AC_CHECK_SIZEOF(unsigned)
|
||||
|
||||
# vvp uses these...
|
||||
AC_CHECK_LIB(termcap, tputs)
|
||||
AC_CHECK_LIB(readline, readline)
|
||||
AC_CHECK_LIB(history, add_history)
|
||||
AC_CHECK_HEADERS(readline/readline.h readline/history.h sys/resource.h)
|
||||
case "${host}" in *linux*) AC_DEFINE([LINUX], [1], [Host operating system is Linux.]) ;; esac
|
||||
|
||||
# vpi uses these
|
||||
AC_CHECK_LIB(pthread, pthread_create)
|
||||
AC_CHECK_LIB(z, gzwrite)
|
||||
AC_CHECK_LIB(z, gzwrite, HAVE_LIBZ=yes, HAVE_LIBZ=no)
|
||||
AC_SUBST(HAVE_LIBZ)
|
||||
if test "$WIN32" = "yes"; then
|
||||
AC_CHECK_LIB(bz2, main)
|
||||
AC_CHECK_LIB(bz2, main, HAVE_LIBBZ2=yes, HAVE_LIBBZ2=no)
|
||||
else
|
||||
AC_CHECK_LIB(bz2, BZ2_bzdopen)
|
||||
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_CHECK_HEADERS(getopt.h malloc.h iosfwd sys/wait.h)
|
||||
|
||||
AC_MSG_CHECKING(for sys/times)
|
||||
AC_TRY_LINK(
|
||||
@@ -176,11 +50,20 @@ AC_TRY_LINK(
|
||||
#include <sys/times.h>
|
||||
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
|
||||
do_times=yes
|
||||
AC_DEFINE([HAVE_TIMES], [1], [The times system call is available in the host operating system.]),
|
||||
AC_DEFINE(HAVE_TIMES,1),
|
||||
do_times=no
|
||||
)
|
||||
AC_MSG_RESULT($do_times)
|
||||
|
||||
AC_CHECK_HEADER(ipal.h, HAVE_IPAL=yes, HAVE_IPAL=)
|
||||
AC_ARG_WITH(ipal,enable PAL target,
|
||||
if test "$with_ipal" = no; then
|
||||
echo Disabling ipal support
|
||||
HAVE_IPAL=
|
||||
fi
|
||||
)
|
||||
AC_SUBST(HAVE_IPAL)
|
||||
|
||||
# --
|
||||
# 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.
|
||||
@@ -193,130 +76,175 @@ if test -z "$DLLIB" ; then
|
||||
AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
|
||||
fi
|
||||
AC_SUBST(DLLIB)
|
||||
AC_SUBST(LDRELOCFLAGS)
|
||||
|
||||
AC_SUBST(CTARGETFLAGS)
|
||||
AC_SUBST(LDTARGETFLAGS)
|
||||
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_LANG(C)
|
||||
AC_C_BIGENDIAN
|
||||
AC_LANG_C
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
# $host
|
||||
|
||||
AX_ENABLE_SUFFIX
|
||||
|
||||
AX_LD_EXTRALIBS
|
||||
|
||||
# Compiler option for position independent code, needed when making shared objects.
|
||||
# CFLAGS inherited by cadpli/Makefile?
|
||||
AX_C_PICFLAG
|
||||
|
||||
# may modify LDFLAGS
|
||||
AX_C99_STRTOD
|
||||
|
||||
# Processor specific compile flags
|
||||
case "${host}" in
|
||||
alpha*-*-linux*)
|
||||
CPPFLAGS="-mieee $CPPFLAGS"
|
||||
CFLAGS="-mieee $CFLAGS"
|
||||
;;
|
||||
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
|
||||
|
||||
# linker options when building a shared library
|
||||
AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
#######################
|
||||
## test for underscores. The vpi module loader needs to know this
|
||||
## 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
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_MINGW32
|
||||
|
||||
|
||||
WIN32=no
|
||||
AC_MSG_CHECKING("Checking for windows")
|
||||
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
|
||||
then
|
||||
WIN32=yes
|
||||
fi
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
|
||||
AC_MSG_CHECKING("for leading and/or trailing underscores")
|
||||
cat << EOF > underscore.c
|
||||
void underscore(void){}
|
||||
EOF
|
||||
$CC -shared -c underscore.c > /dev/null 2>&1
|
||||
|
||||
CC_LEADING_UNDERSCORE=no
|
||||
CC_TRAILING_UNDERSCORE=no
|
||||
|
||||
output=`nm underscore.o|grep _underscore 2>&1`
|
||||
if test ! -z "$output" -a -z "$CYGWIN" -a -z "$MINGW32"; then
|
||||
CC_LEADING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_LU)
|
||||
fi
|
||||
|
||||
|
||||
|
||||
output=`nm underscore.o|grep underscore_ 2>&1`
|
||||
if test ! -z "$output"; then
|
||||
CC_TRAILING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_TU)
|
||||
fi
|
||||
|
||||
if test "$CC_LEADING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WLU)
|
||||
fi
|
||||
if test "$CC_TRAILING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WTU)
|
||||
fi
|
||||
|
||||
rm underscore.c underscore.o
|
||||
|
||||
AC_MSG_RESULT("$CC_LEADING_UNDERSCORE $CC_TRAILING_UNDERSCORE")
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
#######################
|
||||
# Sanity check the configured results
|
||||
#######################
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
|
||||
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 flag to make position independent code")
|
||||
PICFLAG=-fPIC
|
||||
case "${host}" in
|
||||
|
||||
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)
|
||||
*-*-cygwin*)
|
||||
PICFLAG=
|
||||
;;
|
||||
|
||||
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)
|
||||
*-*-hpux*)
|
||||
PICFLAG=+z
|
||||
;;
|
||||
|
||||
AC_OUTPUT(Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile tgt-blif/Makefile tgt-sizer/Makefile)
|
||||
esac
|
||||
AC_SUBST(PICFLAG)
|
||||
AC_MSG_RESULT($PICFLAG)
|
||||
|
||||
|
||||
# mingw needs to link with libiberty.a, cygwin can tolerate it
|
||||
|
||||
AC_MSG_CHECKING("for extra libs needed")
|
||||
EXTRALIBS=
|
||||
case "${host}" in
|
||||
*-*-cygwin*)
|
||||
EXTRALIBS="-liberty"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXTRALIBS)
|
||||
AC_MSG_RESULT($EXTRALIBS)
|
||||
|
||||
# Darwin requires -no-cpp-precomp
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CPPFLAGS="-no-cpp-precomp"
|
||||
CFLAGS="-no-cpp-precomp"
|
||||
;;
|
||||
esac
|
||||
|
||||
# The -rdynamic flag is used by iverilog when compiling the target,
|
||||
# to know how to export symbols of the main program to loadable modules
|
||||
# that are brought in by -ldl
|
||||
AC_MSG_CHECKING("for -rdynamic compiler flag")
|
||||
|
||||
rdynamic=-rdynamic
|
||||
case "${host}" in
|
||||
|
||||
*-*-netbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-cygwin*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
rdynamic="-Wl,-all_load"
|
||||
strip_dynamic="-SX"
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(rdynamic)
|
||||
AC_MSG_RESULT($rdynamic)
|
||||
AC_SUBST(strip_dynamic)
|
||||
AC_MSG_RESULT($strip_dynamic)
|
||||
|
||||
AC_MSG_CHECKING("for shared library link flag")
|
||||
shared=-shared
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
shared="-shared -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
shared="-b"
|
||||
;;
|
||||
|
||||
*-*-darwin1.[0123])
|
||||
shared="-bundle -undefined suppress"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
shared="-bundle -undefined suppress -flat_namespace"
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(shared)
|
||||
|
||||
AC_MSG_RESULT($shared)
|
||||
|
||||
|
||||
AC_CONFIG_SUBDIRS(vpip vvp tgt-vvp tgt-fpga)
|
||||
|
||||
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
// Mathematical and physical constants
|
||||
|
||||
`ifdef CONSTANTS_VAMS
|
||||
`else
|
||||
`define CONSTANTS_VAMS 1
|
||||
|
||||
// M_ is a mathematical constant
|
||||
`define M_E 2.7182818284590452354
|
||||
`define M_LOG2E 1.4426950408889634074
|
||||
`define M_LOG10E 0.43429448190325182765
|
||||
`define M_LN2 0.69314718055994530942
|
||||
`define M_LN10 2.30258509299404568402
|
||||
`define M_PI 3.14159265358979323846
|
||||
`define M_TWO_PI 6.28318530717958647693
|
||||
`define M_PI_2 1.57079632679489661923
|
||||
`define M_PI_4 0.78539816339744830962
|
||||
`define M_1_PI 0.31830988618379067154
|
||||
`define M_2_PI 0.63661977236758134308
|
||||
`define M_2_SQRTPI 1.12837916709551257390
|
||||
`define M_SQRT2 1.41421356237309504880
|
||||
`define M_SQRT1_2 0.70710678118654752440
|
||||
|
||||
/*
|
||||
* Do we need these? For now they are not available.
|
||||
*
|
||||
// The following constants have been taken from http://physics.nist.gov
|
||||
// P_ is a physical constant
|
||||
// charge of electron in coulombs
|
||||
`define P_Q 1.602176462e-19
|
||||
// speed of light in vacuum in meters/sec
|
||||
`define P_C 2.99792458e8
|
||||
// Boltzmann's constant in joules/kelvin
|
||||
`define P_K 1.3806503e-23
|
||||
// Planck's constant in joules*sec
|
||||
`define P_H 6.62606876e-34
|
||||
// permittivity of vacuum in farads/meter
|
||||
`define P_EPS0 8.854187817e-12
|
||||
// permeability of vacuum in henrys/meter
|
||||
`define P_U0 (4.0e-7 * `M_PI)
|
||||
// zero celsius in kelvin
|
||||
`define P_CELSIUS0 273.15
|
||||
*/
|
||||
`endif
|
||||
@@ -1,3 +0,0 @@
|
||||
// These are correct and are used to find the base (zero) pin.
|
||||
thisSubtraction:netlist.h:4938
|
||||
thisSubtraction:netlist.h:4947
|
||||
+29
-35
@@ -1,35 +1,29 @@
|
||||
|
||||
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Note: Icarus Verilog also compiles to native Windows binaries if you
|
||||
use the instructions in the mingw.txt file. Some people prefer cygwin
|
||||
binaries, and these instructions apply.
|
||||
|
||||
|
||||
To build using cygwin:
|
||||
|
||||
Prerequisites:
|
||||
|
||||
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
|
||||
|
||||
Procedure:
|
||||
o Get the source code - see the main Icarus Verilog page for how to
|
||||
do this
|
||||
o cd to the verilog directory
|
||||
o autoconf.sh
|
||||
o ./configure
|
||||
o make
|
||||
o make install
|
||||
|
||||
That's all that's needed.
|
||||
|
||||
To build your own extensions - just include vpi_user.h and link with
|
||||
a command like this:
|
||||
|
||||
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
|
||||
|
||||
- Venkat Iyer <[email protected]>
|
||||
|
||||
|
||||
|
||||
|
||||
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
|
||||
----------------------------------------------------------------------------
|
||||
To build using cygwin:
|
||||
|
||||
Prerequisites:
|
||||
|
||||
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
|
||||
|
||||
Procedure:
|
||||
o Get the source code - see the main icarus verilog page for how to
|
||||
do this
|
||||
o cd to the verilog directory
|
||||
o autoconf.sh
|
||||
o ./configure
|
||||
o make
|
||||
o make install
|
||||
|
||||
That's all that's needed.
|
||||
|
||||
To build your own extensions - just include vpi_user.h and link with
|
||||
a command like this:
|
||||
|
||||
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
|
||||
|
||||
- Venkat Iyer <[email protected]>
|
||||
|
||||
|
||||
|
||||
|
||||
+402
-1183
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "discipline.h"
|
||||
|
||||
ivl_nature_s::ivl_nature_s(perm_string name__, perm_string access__)
|
||||
: name_(name__), access_(access__)
|
||||
{
|
||||
}
|
||||
|
||||
ivl_nature_s::~ivl_nature_s()
|
||||
{
|
||||
}
|
||||
|
||||
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__)
|
||||
{
|
||||
}
|
||||
|
||||
ivl_discipline_s::~ivl_discipline_s()
|
||||
{
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
#ifndef IVL_discipline_H
|
||||
#define IVL_discipline_H
|
||||
/*
|
||||
* Copyright (c) 2008-2014 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The discipline types include the discipline, nature and other
|
||||
* related types for managing declared and used disciplines in a
|
||||
* Verilog-AMS program.
|
||||
*/
|
||||
|
||||
# include "StringHeap.h"
|
||||
# include <iostream>
|
||||
# include <map>
|
||||
# include "ivl_target.h"
|
||||
# include "LineInfo.h"
|
||||
|
||||
extern std::ostream& operator << (std::ostream&, ivl_dis_domain_t);
|
||||
|
||||
class ivl_nature_s : public LineInfo {
|
||||
public:
|
||||
explicit ivl_nature_s(perm_string name, perm_string access);
|
||||
~ivl_nature_s();
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
// Identifier for the access function for this nature
|
||||
perm_string access() const { return access_; }
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
perm_string access_;
|
||||
};
|
||||
|
||||
class ivl_discipline_s : public LineInfo {
|
||||
public:
|
||||
explicit ivl_discipline_s (perm_string name, ivl_dis_domain_t dom,
|
||||
ivl_nature_t pot, ivl_nature_t flow);
|
||||
~ivl_discipline_s();
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
ivl_dis_domain_t domain() const { return domain_; }
|
||||
ivl_nature_t potential() const { return potential_; }
|
||||
ivl_nature_t flow() const { return flow_; }
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
ivl_dis_domain_t domain_;
|
||||
ivl_nature_t potential_;
|
||||
ivl_nature_t flow_;
|
||||
|
||||
private: // not implemented
|
||||
ivl_discipline_s(const ivl_discipline_s&);
|
||||
ivl_discipline_s& operator = (const ivl_discipline_s&);
|
||||
};
|
||||
|
||||
extern map<perm_string,ivl_nature_t> natures;
|
||||
extern map<perm_string,ivl_discipline_t> disciplines;
|
||||
// Map access function name to the nature that it accesses.
|
||||
extern map<perm_string,ivl_nature_t> access_function_nature;
|
||||
|
||||
#endif /* IVL_discipline_H */
|
||||
@@ -1,72 +0,0 @@
|
||||
|
||||
// Standard definitions for Verilog-AMS
|
||||
`ifdef DISCIPLINES_VAMS
|
||||
`else
|
||||
`define DISCIPLINES_VAMS 1
|
||||
|
||||
discipline \logic ;
|
||||
domain discrete;
|
||||
enddiscipline
|
||||
|
||||
discipline ddiscrete;
|
||||
domain discrete;
|
||||
enddiscipline
|
||||
|
||||
nature Current;
|
||||
units = "A";
|
||||
access = I;
|
||||
idt_nature = Charge;
|
||||
`ifdef CURRENT_ABSTOL
|
||||
abstol = `CURRENT_ABSTOL
|
||||
`else
|
||||
abstol = 1e-12;
|
||||
`endif
|
||||
endnature
|
||||
|
||||
nature Charge;
|
||||
units = "coul";
|
||||
access = Q;
|
||||
ddt_nature = Current;
|
||||
`ifdef CHARGE_ABSTOL
|
||||
abstol = `CHARGE_ABSTOL;
|
||||
`else
|
||||
abstol = 1e-14;
|
||||
`endif
|
||||
endnature
|
||||
|
||||
nature Voltage;
|
||||
units = "V";
|
||||
access = V;
|
||||
idt_nature = Flux;
|
||||
`ifdef VOLTAGE_ABSTOL
|
||||
abstol = `VOLTAGE_ABSTOL;
|
||||
`else
|
||||
abstol = 1e-6;
|
||||
`endif
|
||||
endnature
|
||||
|
||||
nature Flux;
|
||||
units = "Wb";
|
||||
access = Phi;
|
||||
ddt_nature = Voltage;
|
||||
`ifdef FLUX_ABSTOL
|
||||
abstol = `flux_ABSTOL;
|
||||
`else
|
||||
abstol = 1e-9;
|
||||
`endif
|
||||
endnature
|
||||
|
||||
discipline electrical;
|
||||
potential Voltage;
|
||||
flow Current;
|
||||
enddiscipline
|
||||
|
||||
discipline voltage;
|
||||
potential Voltage;
|
||||
enddiscipline
|
||||
|
||||
discipline current;
|
||||
flow Current;
|
||||
enddiscipline
|
||||
|
||||
`endif // !`ifdef DISCIPLINES_VAMS
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2009 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,7 +14,9 @@
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* $Id: dosify.c,v 1.1 2001/08/03 17:06:47 steve Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -48,7 +50,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 +63,13 @@ int main(int argc, char*argv[])
|
||||
pr = ch;
|
||||
}
|
||||
|
||||
fclose(ifile);
|
||||
fclose(ofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: dosify.c,v $
|
||||
* Revision 1.1 2001/08/03 17:06:47 steve
|
||||
* Add install of examples for Windows.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
#
|
||||
# This source code is free software; you can redistribute it
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library 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 Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
suffix = @install_suffix@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
suffix = @install_suffix@
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
libdir = $(exec_prefix)/lib
|
||||
includedir = $(prefix)/include
|
||||
mandir = @mandir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
|
||||
CC = @CC@
|
||||
WINDRES = @WINDRES@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
ifeq (@srcdir@,.)
|
||||
INCLUDE_PATH = -I. -I..
|
||||
else
|
||||
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = main.o res.o
|
||||
|
||||
all: iverilog-vpi@EXEEXT@
|
||||
|
||||
check: all
|
||||
|
||||
clean:
|
||||
rm -f *.o config.h iverilog-vpi@EXEEXT@ res.rc
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: main.c
|
||||
cppcheck --enable=all -f $(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=driver-vpi/$@
|
||||
|
||||
iverilog-vpi@EXEEXT@: $O
|
||||
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
|
||||
|
||||
main.o: $(srcdir)/main.c config.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
|
||||
|
||||
|
||||
config.h: $(srcdir)/config.h.in Makefile
|
||||
sed -e 's;@IVLCC@;@CC@;' -e 's;@IVLCXX@;@CXX@;' \
|
||||
-e 's;@SUFFIX@;$(suffix);g' \
|
||||
-e 's;@IVLCFLAGS@;$(CFLAGS);' \
|
||||
-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@
|
||||
|
||||
$(bindir)/iverilog-vpi$(suffix)@EXEEXT@: ./iverilog-vpi@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(bindir)/iverilog-vpi$(suffix)@EXEEXT@"
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs "$(bindir)"
|
||||
|
||||
uninstall:
|
||||
rm -f $(bindir)/iverilog-vpi$(suffix)@EXEEXT@
|
||||
@@ -1,9 +0,0 @@
|
||||
/* For now do not put the Icarus Verilog include or library paths here.
|
||||
* They are generated from a registry entry the user must set (-ivl=).
|
||||
* This may change in the future once I have thought about it more. */
|
||||
#define IVERILOG_VPI_CC "@IVLCC@"
|
||||
#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@"
|
||||
@@ -1,657 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Gus Baldauf ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* iverilog-vpi.c
|
||||
*
|
||||
* this program provides the functionality of iverilog-vpi.sh under Win32
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static void setup_ivl_environment();
|
||||
static void assign(char **ptr, char *str);
|
||||
|
||||
/* The compile options: compiler, flags, etc. are in here */
|
||||
#include "config.h"
|
||||
|
||||
/* pointers to global strings */
|
||||
|
||||
static struct global_strings {
|
||||
char *pCCSRC; /* list of C source files (*.c) */
|
||||
char *pCXSRC; /* list of C++ source files (*.cc, *.cpp) */
|
||||
char *pOBJ; /* list of object files */
|
||||
char *pLIB; /* list of library files */
|
||||
char *pINCS; /* list of include directories */
|
||||
char *pDEFS; /* list of definitions */
|
||||
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
|
||||
char *pMINGW; /* path to MinGW directory */
|
||||
char *pIVL; /* path to IVL directory */
|
||||
char *pCFLAGS; /* CFLAGS option */
|
||||
char *pLDLIBS; /* LDLIBS option */
|
||||
char *pNewPath; /* new PATH environment variable setting */
|
||||
char *pLD; /* what to use for a linker */
|
||||
} gstr;
|
||||
|
||||
|
||||
static void deInitDynString(char *str)
|
||||
{
|
||||
free(str);
|
||||
}
|
||||
|
||||
/* when finished, free allocated memory and return error code */
|
||||
|
||||
static void myExit(int exitVal)
|
||||
{
|
||||
deInitDynString(gstr.pCCSRC);
|
||||
deInitDynString(gstr.pCXSRC);
|
||||
deInitDynString(gstr.pOBJ);
|
||||
deInitDynString(gstr.pLIB);
|
||||
deInitDynString(gstr.pINCS);
|
||||
deInitDynString(gstr.pDEFS);
|
||||
deInitDynString(gstr.pOUT);
|
||||
deInitDynString(gstr.pMINGW);
|
||||
deInitDynString(gstr.pIVL);
|
||||
deInitDynString(gstr.pCFLAGS);
|
||||
deInitDynString(gstr.pLDLIBS);
|
||||
deInitDynString(gstr.pNewPath);
|
||||
free(gstr.pLD);
|
||||
|
||||
exit(exitVal);
|
||||
}
|
||||
|
||||
/* display usage summary and exit */
|
||||
|
||||
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");
|
||||
myExit(1);
|
||||
}
|
||||
|
||||
static void initDynString(char **str)
|
||||
{
|
||||
*str = (char *) malloc(1);
|
||||
|
||||
if (!*str) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
|
||||
*str[0] = 0;
|
||||
}
|
||||
|
||||
/* initialize dynamic memory buffers */
|
||||
|
||||
static void init()
|
||||
{
|
||||
initDynString(&gstr.pCCSRC);
|
||||
initDynString(&gstr.pCXSRC);
|
||||
initDynString(&gstr.pOBJ);
|
||||
initDynString(&gstr.pLIB);
|
||||
initDynString(&gstr.pINCS);
|
||||
initDynString(&gstr.pDEFS);
|
||||
initDynString(&gstr.pOUT);
|
||||
initDynString(&gstr.pMINGW);
|
||||
initDynString(&gstr.pIVL);
|
||||
initDynString(&gstr.pCFLAGS);
|
||||
initDynString(&gstr.pLDLIBS);
|
||||
initDynString(&gstr.pNewPath);
|
||||
/* By default use the C compiler to link the programs. */
|
||||
assign(&gstr.pLD, IVERILOG_VPI_CC);
|
||||
}
|
||||
|
||||
/* return true if "str" is terminated with with "end", case insensitive */
|
||||
|
||||
static int endsIn (char *end, char *str)
|
||||
{
|
||||
char *ext;
|
||||
|
||||
if (strlen(end) >= strlen(str))
|
||||
return 0;
|
||||
|
||||
ext = str + (strlen(str) - strlen(end));
|
||||
|
||||
return stricmp(end,ext) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* return true if "str" begins with "prefix", case insensitive */
|
||||
|
||||
static int startsWith (char *prefix, char *str)
|
||||
{
|
||||
if (strlen(prefix) >= strlen(str))
|
||||
return 0;
|
||||
|
||||
return strnicmp(prefix,str,strlen(prefix)) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* append "app" to "ptr", allocating memory as needed */
|
||||
/* if count is zero, then copy all characters of "app" */
|
||||
|
||||
static void appendn (char **ptr, char *app, int count)
|
||||
{
|
||||
char *nptr = (char *) realloc(*ptr, strlen(*ptr) +
|
||||
(count?count:strlen(app)) + 1);
|
||||
|
||||
if (nptr == NULL) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
free(*ptr);
|
||||
myExit(4);
|
||||
}
|
||||
*ptr = nptr;
|
||||
|
||||
if (count)
|
||||
strncat(*ptr,app,count);
|
||||
else
|
||||
strcat(*ptr,app);
|
||||
}
|
||||
|
||||
/* append "app" to "ptr", allocating memory as needed */
|
||||
|
||||
static void append (char **ptr, char *app)
|
||||
{
|
||||
appendn(ptr,app,0);
|
||||
}
|
||||
|
||||
/* if the string does not end with a backslash, add one */
|
||||
|
||||
static void appendBackSlash(char **str)
|
||||
{
|
||||
if ((*str)[strlen(*str)-1] != '\\')
|
||||
append(str,"\\");
|
||||
}
|
||||
|
||||
/* copy count characters of "str" to "ptr", allocating memory as needed */
|
||||
/* if count is zero, then copy all characters of "str" */
|
||||
|
||||
static void assignn (char **ptr, char *str, int count)
|
||||
{
|
||||
char *nptr = (char *) realloc(*ptr, (count?count:strlen(str)) + 1);
|
||||
|
||||
if (nptr == NULL) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
free(*ptr);
|
||||
myExit(4);
|
||||
}
|
||||
*ptr = nptr;
|
||||
|
||||
if (count) {
|
||||
strncpy(*ptr,str,count);
|
||||
(*ptr)[count] = 0;
|
||||
}
|
||||
else
|
||||
strcpy(*ptr,str);
|
||||
}
|
||||
|
||||
/* copy count characters of "str" to "ptr", allocating memory as needed */
|
||||
|
||||
static void assign (char **ptr, char *str)
|
||||
{
|
||||
assignn(ptr,str,0);
|
||||
}
|
||||
|
||||
/* get a copy of a Icarus Verilog registry string key */
|
||||
|
||||
static int GetRegistryKey(char *key, char **value)
|
||||
{
|
||||
long lrv;
|
||||
HKEY hkKey;
|
||||
char *regKeyBuffer;
|
||||
DWORD regKeyType, regKeySize;
|
||||
|
||||
lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\Icarus Verilog",0,KEY_QUERY_VALUE,&hkKey);
|
||||
if (lrv != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
||||
lrv = RegQueryValueEx(hkKey,key,NULL,®KeyType,NULL,®KeySize);
|
||||
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
|
||||
lrv = RegCloseKey(hkKey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
regKeyBuffer = (char *) malloc(regKeySize+1);
|
||||
if (!regKeyBuffer) {
|
||||
lrv = RegCloseKey(hkKey);
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
|
||||
|
||||
/* This needs an unsigned char *, but for MinGW the char is signed. */
|
||||
lrv = RegQueryValueEx(hkKey, key, NULL, ®KeyType,
|
||||
(unsigned char *) regKeyBuffer, ®KeySize);
|
||||
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
|
||||
lrv = RegCloseKey(hkKey);
|
||||
free(regKeyBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RegCloseKey(hkKey);
|
||||
|
||||
assign(value,regKeyBuffer);
|
||||
free(regKeyBuffer);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* store a copy of a Icarus Verilog registry string key */
|
||||
|
||||
static void SetRegistryKey(char *key, char *value)
|
||||
{
|
||||
HKEY hkKey;
|
||||
DWORD res;
|
||||
|
||||
if (RegCreateKeyEx(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
"Software\\Icarus Verilog",
|
||||
0,
|
||||
"",
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_ALL_ACCESS,NULL,
|
||||
&hkKey,
|
||||
&res) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
/* This needs an unsigned char *, but for MinGW the char is signed. */
|
||||
RegSetValueEx(hkKey, key, 0, REG_SZ, (unsigned char *) value,
|
||||
strlen(value)+1);
|
||||
RegCloseKey(hkKey);
|
||||
|
||||
printf("info: storing %s in Windows' registry entry\n",value);
|
||||
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n",key);
|
||||
}
|
||||
|
||||
/* parse the command line, assign results to global variable strings */
|
||||
|
||||
static int parse(int argc, char *argv[])
|
||||
{
|
||||
int idx, srcFileCnt=0;
|
||||
|
||||
char dot_c_ext[] = ".c";
|
||||
char dot_cc_ext[] = ".cc";
|
||||
char dot_cpp_ext[] = ".cpp";
|
||||
char dot_o_ext[] = ".o";
|
||||
char name_option[] = "--name=";
|
||||
char lib_option[] = "-l";
|
||||
char inc_option[] = "-I";
|
||||
char mingw_option[] = "-mingw=";
|
||||
char ivl_option[] = "-ivl=";
|
||||
char def_option[] = "-D";
|
||||
|
||||
if (argc == 1) return 0;
|
||||
|
||||
for (idx=1; idx<argc; ++idx) {
|
||||
/* Check for C source files (*.c) */
|
||||
if (endsIn(dot_c_ext, argv[idx])) {
|
||||
++srcFileCnt;
|
||||
append(&gstr.pCCSRC, argv[idx]);
|
||||
append(&gstr.pCCSRC, " ");
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT, argv[idx],
|
||||
strlen(argv[idx])-strlen(dot_c_ext));
|
||||
}
|
||||
/* Check for C++ source files (*.cc) */
|
||||
else if (endsIn(dot_cc_ext, argv[idx])) {
|
||||
/* We need to link with the C++ compiler. */
|
||||
assign(&gstr.pLD, IVERILOG_VPI_CXX);
|
||||
++srcFileCnt;
|
||||
append(&gstr.pCXSRC, argv[idx]);
|
||||
append(&gstr.pCXSRC, " ");
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT, argv[idx],
|
||||
strlen(argv[idx])-strlen(dot_cc_ext));
|
||||
}
|
||||
/* Check for C++ source files (*.cpp) */
|
||||
else if (endsIn(dot_cpp_ext, argv[idx])) {
|
||||
/* We need to link with the C++ compiler. */
|
||||
assign(&gstr.pLD, IVERILOG_VPI_CXX);
|
||||
++srcFileCnt;
|
||||
append(&gstr.pCXSRC, argv[idx]);
|
||||
append(&gstr.pCXSRC, " ");
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT, argv[idx],
|
||||
strlen(argv[idx])-strlen(dot_cpp_ext));
|
||||
}
|
||||
/* Check for compiled object files */
|
||||
else if (endsIn(dot_o_ext, argv[idx])) {
|
||||
++srcFileCnt;
|
||||
append(&gstr.pOBJ," ");
|
||||
append(&gstr.pOBJ, argv[idx]);
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT, argv[idx],
|
||||
strlen(argv[idx])-strlen(dot_o_ext));
|
||||
}
|
||||
/* Check for the -mingw option */
|
||||
else if (startsWith(mingw_option, argv[idx]))
|
||||
assignn(&gstr.pMINGW, argv[idx]+sizeof(mingw_option)-1,
|
||||
strlen(argv[idx])-(sizeof(mingw_option)-1));
|
||||
/* Check for the -ivl option */
|
||||
else if (startsWith(ivl_option, argv[idx]))
|
||||
assignn(&gstr.pIVL, argv[idx]+sizeof(ivl_option)-1,
|
||||
strlen(argv[idx])-(sizeof(ivl_option)-1));
|
||||
/* Check for the --name option */
|
||||
else if (startsWith(name_option, argv[idx])) {
|
||||
assignn(&gstr.pOUT, argv[idx]+sizeof(name_option)-1,
|
||||
strlen(argv[idx])-(sizeof(name_option)-1));
|
||||
}
|
||||
/* Check for the -l option */
|
||||
else if (startsWith(lib_option, argv[idx])) {
|
||||
append(&gstr.pLIB, " ");
|
||||
append(&gstr.pLIB, argv[idx]);
|
||||
}
|
||||
/* Check for the -I option */
|
||||
else if (startsWith(inc_option, argv[idx])) {
|
||||
append(&gstr.pINCS, " ");
|
||||
append(&gstr.pINCS, argv[idx]);
|
||||
}
|
||||
/* Check for the -D option */
|
||||
else if (startsWith(def_option, argv[idx])) {
|
||||
append(&gstr.pDEFS, " ");
|
||||
append(&gstr.pDEFS, argv[idx]);
|
||||
}
|
||||
/* Check for the --cflags option */
|
||||
else if (stricmp("--cflags", argv[idx]) == 0) {
|
||||
setup_ivl_environment();
|
||||
printf("%s\n", gstr.pCFLAGS);
|
||||
myExit(0);
|
||||
}
|
||||
/* Check for the --ldflags option */
|
||||
else if (stricmp("--ldflags", argv[idx]) == 0) {
|
||||
printf("%s\n", IVERILOG_VPI_LDFLAGS);
|
||||
myExit(0);
|
||||
}
|
||||
/* Check for the --ldlibs option */
|
||||
else if (stricmp("--ldlibs", argv[idx]) == 0) {
|
||||
setup_ivl_environment();
|
||||
printf("%s\n", gstr.pLDLIBS);
|
||||
myExit(0);
|
||||
}
|
||||
/* 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);
|
||||
myExit(0);
|
||||
}
|
||||
/* This is different than iverilog-vpi.sh, we don't
|
||||
* ignore unknown arguments */
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/* In case there is a --name without source/object files */
|
||||
if (0 == srcFileCnt) assign(&gstr.pOUT,"");
|
||||
|
||||
/* Normally it's an error if there are no source or object files */
|
||||
/* Unless we are setting the IVL or MinGW registry entries */
|
||||
if (!*gstr.pOUT) {
|
||||
if (!*gstr.pMINGW && !*gstr.pIVL) return 0;
|
||||
} else
|
||||
/* We have a valid result file so add the .vpi extension */
|
||||
append(&gstr.pOUT, ".vpi");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* do minimal check that the MinGW root directory looks valid */
|
||||
|
||||
static void checkMingwDir(char *root)
|
||||
{
|
||||
int irv;
|
||||
struct _stat stat_buf;
|
||||
|
||||
char *path, *comp, *cp;
|
||||
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);
|
||||
|
||||
irv = _stat(path,&stat_buf);
|
||||
deInitDynString(path);
|
||||
|
||||
if (irv) {
|
||||
fprintf(stderr,"error: %s does not appear to be the valid root directory\n",root);
|
||||
fprintf(stderr," of MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
|
||||
fprintf(stderr," point to the MinGW root directory. For a Windows command\n");
|
||||
fprintf(stderr," shell the option would be something like -mingw=c:\\mingw\n");
|
||||
fprintf(stderr," For a Cygwin shell the option would be something like\n");
|
||||
fprintf(stderr," -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
}
|
||||
|
||||
/* do minimal check that the Icarus Verilog root directory looks valid */
|
||||
|
||||
static void checkIvlDir(char *root)
|
||||
{
|
||||
int irv;
|
||||
struct _stat stat_buf;
|
||||
|
||||
char *path;
|
||||
initDynString(&path);
|
||||
assign(&path,gstr.pIVL);
|
||||
appendBackSlash(&path);
|
||||
append(&path,"bin\\vvp" IVERILOG_SUFFIX ".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," point to the Icarus Verilog root directory. For a Windows\n");
|
||||
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
|
||||
fprintf(stderr," For a Cygwin shell the option would be something like\n");
|
||||
fprintf(stderr," -ivl=c:\\\\iverilog\n");
|
||||
myExit(6);
|
||||
}
|
||||
}
|
||||
|
||||
/* see if we can find mingw root */
|
||||
|
||||
#define IVL_REGKEY_MINGW "MingwDir"
|
||||
|
||||
static void setup_mingw_environment()
|
||||
{
|
||||
char *pOldPATH = getenv("PATH"); /* get current path */
|
||||
|
||||
if (*gstr.pMINGW) {
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
SetRegistryKey(IVL_REGKEY_MINGW,gstr.pMINGW);
|
||||
} else if (!GetRegistryKey(IVL_REGKEY_MINGW,&gstr.pMINGW)) {
|
||||
fprintf(stderr,"error: can not locate the MinGW root directory, use the -mingw option of\n");
|
||||
fprintf(stderr," iverilog-vpi.exe to point to the MinGW root directory. For\n");
|
||||
fprintf(stderr," a Windows command shell the option would be something like\n");
|
||||
fprintf(stderr," -mingw=c:\\mingw For a Cygwin shell the option would be\n");
|
||||
fprintf(stderr," something like -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
|
||||
/* Create new path with MinGW in it */
|
||||
assign(&gstr.pNewPath,"PATH=");
|
||||
append(&gstr.pNewPath,gstr.pMINGW);
|
||||
appendBackSlash(&gstr.pNewPath);
|
||||
append(&gstr.pNewPath, "\\");
|
||||
append(&gstr.pNewPath,"bin;");
|
||||
append(&gstr.pNewPath,pOldPATH);
|
||||
|
||||
/* Place new path in environment */
|
||||
_putenv(gstr.pNewPath);
|
||||
}
|
||||
|
||||
/* see if we can find iverilog root */
|
||||
|
||||
#define IVL_REGKEY_IVL "InstallDir"
|
||||
|
||||
static void setup_ivl_environment()
|
||||
{
|
||||
if (*gstr.pIVL) {
|
||||
checkIvlDir(gstr.pIVL);
|
||||
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
|
||||
} else if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
|
||||
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
|
||||
fprintf(stderr," of iverilog-vpi" IVERILOG_SUFFIX " to point to the Icarus Verilog root directory.\n");
|
||||
fprintf(stderr," For a Windows command shell the option would be something like\n");
|
||||
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
|
||||
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
|
||||
myExit(6);
|
||||
}
|
||||
|
||||
/* Build up the CFLAGS option string */
|
||||
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I\"");
|
||||
append(&gstr.pCFLAGS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCFLAGS);
|
||||
append(&gstr.pCFLAGS,"\\include\\\\iverilog\"" IVERILOG_SUFFIX);
|
||||
|
||||
/* Build up the LDFLAGS option string */
|
||||
assign(&gstr.pLDLIBS,"-L\"");
|
||||
append(&gstr.pLDLIBS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pLDLIBS);
|
||||
append(&gstr.pLDLIBS,"\\lib\" " IVERILOG_VPI_LDLIBS);
|
||||
}
|
||||
|
||||
/* compile source modules */
|
||||
|
||||
static void compile(char *pSource, char **pObject, int *compile_errors, char *compiler)
|
||||
{
|
||||
char *ptr1 = pSource;
|
||||
char *ptr2 = strchr(ptr1, ' ');
|
||||
char *buf=0, *src=0, *obj=0;
|
||||
|
||||
while (ptr2) {
|
||||
int len = ptr2 - ptr1;
|
||||
char *ostart;
|
||||
int olen;
|
||||
assignn(&src, ptr1, len);
|
||||
|
||||
/* Build the object file name */
|
||||
ostart = strrchr(ptr1, '/');
|
||||
if (ostart == NULL) ostart = ptr1;
|
||||
else ostart += 1;
|
||||
olen = strrchr(ptr1, '.') - ostart;
|
||||
assignn(&obj, ostart, olen);
|
||||
append(&obj, ".o");
|
||||
|
||||
/* Build the compile line */
|
||||
assign(&buf, compiler);
|
||||
append(&buf, " -c -o ");
|
||||
append(&buf, obj);
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pDEFS);
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pCFLAGS);
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pINCS);
|
||||
append(&buf, " ");
|
||||
append(&buf, src);
|
||||
|
||||
append (pObject, " ");
|
||||
append (pObject, obj);
|
||||
|
||||
printf("Compiling %s...\n", src);
|
||||
|
||||
if (system(buf)) ++*compile_errors;
|
||||
|
||||
/* advance to next token */
|
||||
ptr1 = ptr2 + 1;
|
||||
ptr2 = strchr(ptr1, ' ');
|
||||
}
|
||||
|
||||
free(buf);
|
||||
free(src);
|
||||
free(obj);
|
||||
}
|
||||
|
||||
/* using the global strings, compile and link */
|
||||
|
||||
static void compile_and_link()
|
||||
{
|
||||
char *buf=0;
|
||||
int iRet, compile_errors = 0;
|
||||
|
||||
/* To make the output match iverilog-vpi.sh do not print out the
|
||||
* root directories */
|
||||
|
||||
// printf("MinGW root directory: %s.\n", gstr.pMINGW);
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
|
||||
// printf("Icarus Verilog root directory: %s.\n", gstr.pIVL);
|
||||
checkIvlDir(gstr.pIVL);
|
||||
|
||||
/* compile the C source files (*.c) */
|
||||
compile(gstr.pCCSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CC );
|
||||
/* compile the C++ source files (*.cc, *.cpp) */
|
||||
compile(gstr.pCXSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CXX);
|
||||
|
||||
if (compile_errors) {
|
||||
fprintf(stderr,"iverilog-vpi: %d file(s) failed to compile.\n",
|
||||
compile_errors);
|
||||
myExit(2);
|
||||
}
|
||||
|
||||
/* link */
|
||||
assign(&buf, gstr.pLD);
|
||||
append(&buf, " -o ");
|
||||
append(&buf, gstr.pOUT);
|
||||
append(&buf, " ");
|
||||
append(&buf, IVERILOG_VPI_LDFLAGS);
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pOBJ);
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pLIB);
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pLDLIBS);
|
||||
|
||||
printf("Making %s from %s...\n", gstr.pOUT,gstr.pOBJ);
|
||||
|
||||
iRet = system(buf);
|
||||
free(buf);
|
||||
if (iRet) myExit(3);
|
||||
}
|
||||
|
||||
/* program execution starts here */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
init();
|
||||
|
||||
if (!parse(argc,argv)) usage();
|
||||
|
||||
setup_mingw_environment();
|
||||
setup_ivl_environment();
|
||||
|
||||
/* are there any source or object files specified */
|
||||
if (*gstr.pOUT) compile_and_link();
|
||||
|
||||
myExit(0);
|
||||
return 0; // eliminate warnings.
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
// LANGUAGE ENGLISH
|
||||
LANGUAGE 9, 4
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 2002,11,13,0
|
||||
PRODUCTVERSION @PRODUCTVERSION@
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x2L
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Icarus Verilog\0"
|
||||
VALUE "FileDescription", "Icarus Verilog VPI Tool\0"
|
||||
VALUE "FileVersion", "2002, 11, 13, 0\0"
|
||||
VALUE "InternalName", "iverilog-vpi\0"
|
||||
VALUE "LegalCopyright", "Copyright 2002 Gus Baldauf\0"
|
||||
VALUE "OriginalFilename", "iverilog-vpi.exe\0"
|
||||
VALUE "ProductName", "Icarus Verilog\0"
|
||||
VALUE "ProductVersion", "@PRODUCTVERSION@\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
@@ -0,0 +1,12 @@
|
||||
a.out
|
||||
Makefile
|
||||
parse.c
|
||||
parse.h
|
||||
parse.output
|
||||
lexor.c
|
||||
cfparse.c
|
||||
cfparse.h
|
||||
cfparse.output
|
||||
cflexor.c
|
||||
foo.*
|
||||
iverilog
|
||||
+51
-85
@@ -3,7 +3,9 @@
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
# any later version. In order to redistribute the software in
|
||||
# binary form, you will need a Picture Elements Binary Software
|
||||
# License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -12,17 +14,20 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
# Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.11 2002/02/03 07:05:36 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
suffix = @install_suffix@
|
||||
VERSION = 0.6
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
@@ -32,117 +37,78 @@ includedir = $(prefix)/include
|
||||
mandir = @mandir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
rdynamic=@rdynamic@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
MAN = @MAN@
|
||||
PS2PDF = @PS2PDF@
|
||||
|
||||
ifeq (@srcdir@,.)
|
||||
INCLUDE_PATH = -I. -I..
|
||||
else
|
||||
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = main.o substit.o cflexor.o cfparse.o
|
||||
|
||||
all: dep iverilog@EXEEXT@ iverilog.man
|
||||
|
||||
check: all
|
||||
all: iverilog@EXEEXT@
|
||||
|
||||
clean:
|
||||
rm -f *.o cflexor.c cfparse.c cfparse.h cfparse.output
|
||||
rm -f iverilog@EXEEXT@ iverilog.man iverilog.pdf iverilog.ps
|
||||
rm -rf dep
|
||||
rm -f *.o lexor.c parse.c parse.h parse.output
|
||||
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all -f \
|
||||
-UYY_USER_INIT \
|
||||
-UYYPARSE_PARAM -UYYPRINT -Ushort -Uyyoverflow \
|
||||
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
|
||||
$(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=driver/$@
|
||||
|
||||
dep:
|
||||
mkdir dep
|
||||
O = main.o build_string.o lexor.o parse.o cflexor.o cfparse.o
|
||||
|
||||
iverilog@EXEEXT@: $O
|
||||
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
|
||||
|
||||
cflexor.c: $(srcdir)/cflexor.lex
|
||||
$(LEX) -s -t $< > $@
|
||||
lexor.c: lexor.lex
|
||||
flex -s -olexor.c $(srcdir)/lexor.lex
|
||||
|
||||
# Build this in two steps to avoid parallel build issues (see pr3462585)
|
||||
cfparse.c: $(srcdir)/cfparse.y
|
||||
$(YACC) --verbose -t -p cf -d -o $@ $<
|
||||
cfparse.h: cfparse.c
|
||||
parse.h parse.c: parse.y
|
||||
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
mv $*.d dep
|
||||
cflexor.c: cflexor.lex
|
||||
flex -s -Pcf -ocflexor.c $(srcdir)/cflexor.lex
|
||||
|
||||
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
|
||||
cfparse.h cfparse.c: cfparse.y
|
||||
bison --verbose -t -d -o cfparse.c --name-prefix=cf $(srcdir)/cfparse.y
|
||||
|
||||
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 >> $@
|
||||
main.o: main.c globals.h
|
||||
$(CC) $(CFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DRDYNAMIC=\"$(rdynamic)\" -DDLLIB='"@DLLIB@"' -DEXEEXT='"@EXEEXT@"' $(srcdir)/main.c
|
||||
|
||||
iverilog.ps: iverilog.man
|
||||
$(MAN) -t ./iverilog.man > iverilog.ps
|
||||
build_string.o: build_string.c globals.h
|
||||
lexor.o: lexor.c parse.h globals.h
|
||||
parse.o: parse.c globals.h
|
||||
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
|
||||
cfparse.o: cfparse.c globals.h cfparse_misc.h
|
||||
|
||||
iverilog.pdf: iverilog.ps
|
||||
$(PS2PDF) iverilog.ps iverilog.pdf
|
||||
iverilog.pdf: $(srcdir)/iverilog.man
|
||||
man -t $(srcdir)/iverilog.man | ps2pdf - iverilog.pdf
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
ifeq ($(MAN),none)
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
|
||||
else
|
||||
ifeq ($(PS2PDF),none)
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog$(suffix).1
|
||||
else
|
||||
INSTALL_DOC = $(prefix)/iverilog$(suffix).pdf $(mandir)/man1/iverilog$(suffix).1
|
||||
ifeq (@WIN32@,yes)
|
||||
INSTALL_DOC = $(prefix)/iverilog.pdf
|
||||
INSTALL_DOCDIR =
|
||||
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
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: build_string.c,v 1.6 2001/11/16 05:07:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "globals.h"
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
int build_string(char*output, size_t olen, const char*pattern)
|
||||
{
|
||||
char tmp_buf[1024];
|
||||
|
||||
char*output_save = output;
|
||||
while (*pattern) {
|
||||
|
||||
if (*pattern == '%') {
|
||||
pattern += 1;
|
||||
switch (*pattern) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case '%':
|
||||
*output++ = '%';
|
||||
break;
|
||||
|
||||
case '[': {
|
||||
const char*tail;
|
||||
pattern += 1;
|
||||
assert(*pattern);
|
||||
tail = strchr(pattern+1, ']');
|
||||
assert(tail);
|
||||
strncpy(tmp_buf, pattern+1, tail-pattern-1);
|
||||
tmp_buf[tail-pattern-1] = 0;
|
||||
|
||||
if (((*pattern == 's') && start)
|
||||
|| ((*pattern == 'v') && verbose_flag)
|
||||
|| ((*pattern == 'N') && npath)
|
||||
|| ((*pattern == 'T') && mtm)) {
|
||||
int rc = build_string(output, olen,
|
||||
tmp_buf);
|
||||
output += rc;
|
||||
olen -= rc;
|
||||
}
|
||||
pattern = tail;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'B':
|
||||
strcpy(output, base);
|
||||
output += strlen(base);
|
||||
olen -= strlen(base);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (f_list) {
|
||||
strcpy(output, f_list);
|
||||
output += strlen(f_list);
|
||||
olen -= strlen(f_list);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (mod_list) {
|
||||
strcpy(output, mod_list);
|
||||
output += strlen(mod_list);
|
||||
olen -= strlen(mod_list);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
if (npath) {
|
||||
strcpy(output, npath);
|
||||
output += strlen(npath);
|
||||
olen -= strlen(npath);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
strcpy(output, opath);
|
||||
output += strlen(opath);
|
||||
olen -= strlen(opath);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (start) {
|
||||
strcpy(output, start);
|
||||
output += strlen(start);
|
||||
olen -= strlen(start);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
if (mtm) {
|
||||
strcpy(output, mtm);
|
||||
output += strlen(mtm);
|
||||
olen -= strlen(mtm);
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
strcpy(output, targ);
|
||||
output += strlen(targ);
|
||||
olen -= strlen(targ);
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
strcpy(output, warning_flags);
|
||||
output += strlen(warning_flags);
|
||||
olen -= strlen(warning_flags);
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
if (library_flags) {
|
||||
strcpy(output, library_flags);
|
||||
output += strlen(library_flags);
|
||||
olen -= strlen(library_flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
if (library_flags2) {
|
||||
strcpy(output, library_flags2);
|
||||
output += strlen(library_flags2);
|
||||
olen -= strlen(library_flags2);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
pattern += 1;
|
||||
|
||||
} else {
|
||||
*output++ = *pattern++;
|
||||
olen -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
*output = 0;
|
||||
return output-output_save;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: build_string.c,v $
|
||||
* Revision 1.6 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
*
|
||||
* Revision 1.5 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
* Revision 1.4 2001/07/25 03:10:50 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.3 2001/07/03 04:09:25 steve
|
||||
* Generate verbuse status messages (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.2 2000/10/28 03:45:47 steve
|
||||
* Use the conf file to generate the vvm ivl string.
|
||||
*
|
||||
* Revision 1.1 2000/10/08 22:36:56 steve
|
||||
* iverilog with an iverilog.conf configuration file.
|
||||
*
|
||||
*/
|
||||
|
||||
+22
-148
@@ -1,10 +1,7 @@
|
||||
%option prefix="cf"
|
||||
%option nounput
|
||||
%option noinput
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,48 +16,45 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cflexor.lex,v 1.5 2001/12/08 04:13:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "cfparse.h"
|
||||
# include "cfparse_misc.h"
|
||||
# include "globals.h"
|
||||
# include <string.h>
|
||||
|
||||
static int comment_enter;
|
||||
static char* trim_trailing_white(char*txt, int trim);
|
||||
|
||||
/*
|
||||
* Mostly copied from the flex manual. Do not make this arbitrary
|
||||
* depth without checking for looping files.
|
||||
* Lexical location information is passed in the yylloc variable to th
|
||||
* parser. The file names, strings, are kept in a list so that I can
|
||||
* re-use them. The set_file_name function will return a pointer to
|
||||
* the name as it exists in the list (and delete the passed string.)
|
||||
* If the name is new, it will be added to the list.
|
||||
*/
|
||||
#define MAX_CMDFILE_DEPTH 15
|
||||
YYLTYPE yylloc;
|
||||
|
||||
typedef struct t_cmdfile {
|
||||
char *cmdfile;
|
||||
YY_BUFFER_STATE buffer;
|
||||
} s_cmdfile;
|
||||
s_cmdfile cmdfile_stack[MAX_CMDFILE_DEPTH];
|
||||
int cmdfile_stack_ptr = 0;
|
||||
static int comment_enter;
|
||||
|
||||
%}
|
||||
|
||||
%x CCOMMENT
|
||||
%x LCOMMENT
|
||||
%x PLUS_ARGS
|
||||
%x FILE_NAME
|
||||
|
||||
%%
|
||||
|
||||
/* Accept C++ style comments. */
|
||||
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
|
||||
<LCOMMENT>. { yymore(); }
|
||||
<LCOMMENT>\n { cflloc.first_line += 1; BEGIN(comment_enter); }
|
||||
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
|
||||
|
||||
/* Accept C style comments. */
|
||||
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
|
||||
<CCOMMENT>. { yymore(); }
|
||||
<CCOMMENT>\n { cflloc.first_line += 1; yymore(); }
|
||||
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
|
||||
<CCOMMENT>"*/" { BEGIN(comment_enter); }
|
||||
|
||||
/* Accept shell type comments. */
|
||||
@@ -69,30 +63,15 @@ int cmdfile_stack_ptr = 0;
|
||||
/* Skip white space. */
|
||||
[ \t\f\r] { ; }
|
||||
/* Skip line ends, but also count the line. */
|
||||
\n { cflloc.first_line += 1; }
|
||||
\n { yylloc.first_line += 1; }
|
||||
|
||||
|
||||
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
|
||||
|
||||
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
|
||||
|
||||
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
|
||||
|
||||
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
|
||||
|
||||
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
|
||||
|
||||
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
|
||||
|
||||
"+parameter+" { BEGIN(PLUS_ARGS); return TOK_PARAMETER; }
|
||||
|
||||
"+timescale+" { BEGIN(PLUS_ARGS); return TOK_TIMESCALE; }
|
||||
|
||||
"+vhdl-work+" { BEGIN(PLUS_ARGS); return TOK_VHDL_WORK; }
|
||||
|
||||
"+vhdl-libdir+" { BEGIN(PLUS_ARGS); return TOK_VHDL_LIBDIR; }
|
||||
|
||||
"+width-cap+" { BEGIN(PLUS_ARGS); return TOK_WIDTH_CAP; }
|
||||
|
||||
/* If it is not any known plus-flag, return the generic form. */
|
||||
"+"[^\n \t\b\f\r+]* {
|
||||
@@ -114,16 +93,12 @@ int cmdfile_stack_ptr = 0;
|
||||
<PLUS_ARGS>[ \t\b\f\r] { BEGIN(0); }
|
||||
|
||||
<PLUS_ARGS>\n {
|
||||
cflloc.first_line += 1;
|
||||
yylloc.first_line += 1;
|
||||
BEGIN(0); }
|
||||
|
||||
/* Notice the -a flag. */
|
||||
"-a" { return TOK_Da; }
|
||||
|
||||
/* Notice the -c or -f flag. */
|
||||
"-c" { return TOK_Dc; }
|
||||
"-f" { return TOK_Dc; }
|
||||
|
||||
/* Notice the -v flag. */
|
||||
"-v" { return TOK_Dv; }
|
||||
|
||||
@@ -133,127 +108,26 @@ int cmdfile_stack_ptr = 0;
|
||||
/* This rule matches paths and strings that may be file names. This
|
||||
is a little bit tricky, as we don't want to mistake a comment for
|
||||
a string word. */
|
||||
"/"[\r\n] { /* Special case of file name "/" */
|
||||
cflval.text = trim_trailing_white(yytext, 0);
|
||||
return TOK_STRING; }
|
||||
"/"[^\*\/] { /* A file name that starts with "/". */
|
||||
yymore();
|
||||
BEGIN(FILE_NAME); }
|
||||
[^/\n \t\b\r+-][^/\n\r]* { /* A file name that starts with other than "/" */
|
||||
yymore();
|
||||
BEGIN(FILE_NAME); }
|
||||
"/"[^\*\/].* { cflval.text = strdup(yytext);
|
||||
return TOK_STRING; }
|
||||
|
||||
<FILE_NAME>"//" {
|
||||
/* Found a trailing comment. Returning the terminated name. */
|
||||
cflval.text = trim_trailing_white(yytext, 2);
|
||||
BEGIN(LCOMMENT);
|
||||
return TOK_STRING; }
|
||||
<FILE_NAME>"/"?[^/\n\r]* {
|
||||
yymore();
|
||||
/* not a comment... continuing */; }
|
||||
<FILE_NAME>[\n\r] {
|
||||
/* No trailing comment. Return the file name. */
|
||||
cflval.text = trim_trailing_white(yytext, 0);
|
||||
BEGIN(0);
|
||||
return TOK_STRING; }
|
||||
[^/\n \t\b\r+-].* { cflval.text = strdup(yytext);
|
||||
return TOK_STRING; }
|
||||
|
||||
/* Fallback match. */
|
||||
. { return yytext[0]; }
|
||||
|
||||
/* At the end of file switch back to the previous buffer. */
|
||||
<<EOF>> {
|
||||
if (--cmdfile_stack_ptr < 0) {
|
||||
free(current_file);
|
||||
yyterminate();
|
||||
} else {
|
||||
yy_delete_buffer(YY_CURRENT_BUFFER);
|
||||
yy_switch_to_buffer(cmdfile_stack[cmdfile_stack_ptr].buffer);
|
||||
free(current_file);
|
||||
current_file = cmdfile_stack[cmdfile_stack_ptr].cmdfile;
|
||||
} }
|
||||
|
||||
%%
|
||||
|
||||
static char* trim_trailing_white(char*text, int trim)
|
||||
{
|
||||
char*cp = text + strlen(text);
|
||||
while (cp > text && trim > 0) {
|
||||
trim -= 1;
|
||||
cp -= 1;
|
||||
*cp = 0;
|
||||
}
|
||||
while (cp > text && strchr("\n\r\t\b", cp[-1]))
|
||||
cp -= 1;
|
||||
|
||||
cp[0] = 0;
|
||||
return strdup(text);
|
||||
}
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void switch_to_command_file(const char *file)
|
||||
{
|
||||
char path[4096];
|
||||
|
||||
if (cmdfile_stack_ptr >= MAX_CMDFILE_DEPTH) {
|
||||
fprintf(stderr, "Error: command files nested too deeply (%d) "
|
||||
"at %s:%d.\n", MAX_CMDFILE_DEPTH, current_file,
|
||||
cflloc.first_line);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cmdfile_stack[cmdfile_stack_ptr].buffer = YY_CURRENT_BUFFER;
|
||||
cmdfile_stack[cmdfile_stack_ptr].cmdfile = current_file;
|
||||
cmdfile_stack_ptr += 1;
|
||||
|
||||
/*
|
||||
* If this is a relative file then add the current path to the
|
||||
* file name.
|
||||
*/
|
||||
if (file[0] != '/') {
|
||||
char *cp;
|
||||
strcpy(path, current_file);
|
||||
cp = strrchr(path, '/');
|
||||
if (cp == 0) strcpy(path, file); /* A base file. */
|
||||
else {
|
||||
*(cp+1) = '\0';
|
||||
strcat(path, file);
|
||||
}
|
||||
} else strcpy(path, file); /* An absolute path. */
|
||||
|
||||
yyin = fopen(path, "r");
|
||||
if (yyin == NULL) {
|
||||
fprintf(stderr, "Error: unable to read nested command file (%s) "
|
||||
"at %s:%d.\n", path, current_file, cflloc.first_line);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_file = strdup(path);
|
||||
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
|
||||
cflloc.first_line = 1;
|
||||
}
|
||||
|
||||
void cfreset(FILE*fd, const char*path)
|
||||
{
|
||||
yyin = fd;
|
||||
yyrestart(fd);
|
||||
current_file = strdup(path);
|
||||
cflloc.first_line = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
||||
*/
|
||||
void destroy_lexor(void)
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
||||
yylex_destroy();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
yylloc.first_line = 1;
|
||||
yylloc.text = (char*)path;
|
||||
}
|
||||
|
||||
+18
-105
@@ -1,6 +1,6 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 20001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -15,17 +15,16 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cfparse.y,v 1.6 2002/01/02 02:39:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
# include "globals.h"
|
||||
# include "cfparse_misc.h"
|
||||
# include <ctype.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include "ivl_alloc.h"
|
||||
|
||||
|
||||
/*
|
||||
* This flag is set to 0, 1 or 2 if file names are to be translated to
|
||||
@@ -39,13 +38,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;
|
||||
@@ -58,10 +57,8 @@ static void translate_file_name(char*text)
|
||||
char*text;
|
||||
};
|
||||
|
||||
%token TOK_Da TOK_Dc TOK_Dv TOK_Dy
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_INTEGER_WIDTH TOK_LIBDIR TOK_LIBDIR_NOCASE
|
||||
%token TOK_LIBEXT TOK_PARAMETER TOK_TIMESCALE TOK_VHDL_WORK TOK_VHDL_LIBDIR
|
||||
%token TOK_WIDTH_CAP
|
||||
%token TOK_Da TOK_Dv TOK_Dy
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_LIBEXT
|
||||
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
||||
|
||||
%%
|
||||
@@ -81,36 +78,24 @@ item
|
||||
of a source file. Add the file to the file list. */
|
||||
|
||||
: TOK_STRING
|
||||
{ char*tmp = substitutions($1);
|
||||
translate_file_name(tmp);
|
||||
process_file_name(tmp, 0);
|
||||
{ translate_file_name($1);
|
||||
process_file_name($1);
|
||||
free($1);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* The -a flag is completely ignored. */
|
||||
|
||||
| TOK_Da { }
|
||||
|
||||
/* Match a -c <cmdfile> or -f <cmdfile> */
|
||||
|
||||
| TOK_Dc TOK_STRING
|
||||
{ char*tmp = substitutions($2);
|
||||
translate_file_name(tmp);
|
||||
switch_to_command_file(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* The -v <libfile> flag is ignored, and the <libfile> is processed
|
||||
as an ordinary source file. */
|
||||
|
||||
| TOK_Dv TOK_STRING
|
||||
{ char*tmp = substitutions($2);
|
||||
translate_file_name(tmp);
|
||||
process_file_name(tmp, 1);
|
||||
{ translate_file_name($2);
|
||||
process_file_name($2);
|
||||
fprintf(stderr, "%s:%u: Ignoring -v in front of %s\n",
|
||||
@1.text, @1.first_line, $2);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* This rule matches "-y <path>" sequences. This does the same thing
|
||||
@@ -118,40 +103,8 @@ item
|
||||
directory list. */
|
||||
|
||||
| TOK_Dy TOK_STRING
|
||||
{ char*tmp = substitutions($2);
|
||||
process_library_switch(tmp);
|
||||
{ process_library_switch($2);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_LIBDIR TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
process_library_switch(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_LIBDIR_NOCASE TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
process_library_nocase_switch(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_PARAMETER TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
process_parameter(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* The +timescale token is used to set the default timescale for
|
||||
the simulator. */
|
||||
| TOK_TIMESCALE TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
process_timescale(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_DEFINE TOK_PLUSARG
|
||||
@@ -159,20 +112,6 @@ item
|
||||
free($2);
|
||||
}
|
||||
|
||||
| TOK_VHDL_WORK TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
vhdlpp_work = tmp;
|
||||
free($2);
|
||||
}
|
||||
|
||||
| TOK_VHDL_LIBDIR TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
vhdlpp_libdir = realloc(vhdlpp_libdir, (vhdlpp_libdir_cnt+1)*sizeof(char*));
|
||||
vhdlpp_libdir[vhdlpp_libdir_cnt] = tmp;
|
||||
vhdlpp_libdir_cnt += 1;
|
||||
free($2);
|
||||
}
|
||||
|
||||
/* The +incdir token introduces a list of +<path> arguments that are
|
||||
the include directories to search. */
|
||||
|
||||
@@ -183,22 +122,6 @@ item
|
||||
|
||||
| TOK_LIBEXT libext_args
|
||||
|
||||
/* These are various misc flags that are supported. */
|
||||
|
||||
| TOK_INTEGER_WIDTH TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
free($2);
|
||||
integer_width = strtoul(tmp,0,10);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_WIDTH_CAP TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
free($2);
|
||||
width_cap = strtoul(tmp,0,10);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* The +<word> tokens that are not otherwise matched, are
|
||||
ignored. The skip_args rule arranges for all the argument words
|
||||
to be consumed. */
|
||||
@@ -219,12 +142,6 @@ item
|
||||
}
|
||||
free($1);
|
||||
}
|
||||
|
||||
| error
|
||||
{ fprintf(stderr, "Error: unable to parse line %u in "
|
||||
"%s.\n", cflloc.first_line, current_file);
|
||||
return 1;
|
||||
}
|
||||
;
|
||||
|
||||
/* inc_args are +incdir+ arguments in order. */
|
||||
@@ -234,10 +151,8 @@ inc_args
|
||||
;
|
||||
|
||||
inc_arg : TOK_PLUSARG
|
||||
{ char*tmp = substitutions($1);
|
||||
process_include_dir(tmp);
|
||||
{ process_include_dir($1);
|
||||
free($1);
|
||||
free(tmp);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -270,6 +185,4 @@ skip_arg : TOK_PLUSARG
|
||||
|
||||
int yyerror(const char*msg)
|
||||
{
|
||||
(void)msg; /* Parameter is not used. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
+22
-12
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_cfparse_misc_H
|
||||
#define IVL_cfparse_misc_H
|
||||
#ifndef __cfparse_misc_H
|
||||
#define __cfparse_misc_H
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Picture Elements, Inc.
|
||||
* Copyright (c) 2001 Picture Elements, Inc.
|
||||
* Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -17,8 +17,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: cfparse_misc.h,v 1.3 2002/01/02 02:39:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The vlltype supports the passing of detailed source file location
|
||||
@@ -33,12 +36,19 @@ struct cfltype {
|
||||
const char*text;
|
||||
};
|
||||
# define YYLTYPE struct cfltype
|
||||
extern YYLTYPE yylloc;
|
||||
|
||||
int cflex(void);
|
||||
int cferror(const char *);
|
||||
int cfparse(void);
|
||||
void switch_to_command_file(const char *);
|
||||
void destroy_lexor(void);
|
||||
char *current_file;
|
||||
|
||||
#endif /* IVL_cfparse_misc_H */
|
||||
/*
|
||||
* $Log: cfparse_misc.h,v $
|
||||
* Revision 1.3 2002/01/02 02:39:34 steve
|
||||
* Use my own cfltype to defend against bison 1.30.
|
||||
*
|
||||
* Revision 1.2 2001/11/12 18:47:32 steve
|
||||
* Support +incdir in command files, and ignore other
|
||||
* +args flags. Also ignore -a and -v flags.
|
||||
*
|
||||
* Revision 1.1 2001/11/12 01:26:36 steve
|
||||
* More sophisticated command file parser.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
+78
-20
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_globals_H
|
||||
#define IVL_globals_H
|
||||
#ifndef __globals_H
|
||||
#define __globals_H
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,30 +16,46 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: globals.h,v 1.10 2001/11/16 05:07:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stddef.h>
|
||||
|
||||
/* This is the integer-width argument that will be passed to ivl. */
|
||||
extern unsigned integer_width;
|
||||
/* This is the base (i.e. -B<value>) of the Icarus Verilog files. */
|
||||
extern const char*base;
|
||||
|
||||
/* This is the width-cap argument that will be passed to ivl. */
|
||||
extern unsigned width_cap;
|
||||
/* This is a list of all the -f<key>=<value> options from the
|
||||
command line, concatenated together. */
|
||||
extern char*f_list;
|
||||
|
||||
extern const char*vhdlpp_work;
|
||||
extern const char**vhdlpp_libdir;
|
||||
extern unsigned vhdlpp_libdir_cnt;
|
||||
extern char*mod_list;
|
||||
|
||||
/* Perform variable substitutions on the string. */
|
||||
extern char* substitutions(const char*str);
|
||||
/* This is the optional -Tmin|typ|max setting. */
|
||||
extern const char*mtm;
|
||||
|
||||
/* Ths 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;
|
||||
|
||||
/* Add the name to the list of source files. */
|
||||
extern void process_file_name(const char*name, int lib_flag);
|
||||
extern void process_file_name(const char*name);
|
||||
|
||||
/* Add the name to the list of library directories. */
|
||||
extern void process_library_switch(const char*name);
|
||||
extern void process_library_nocase_switch(const char*name);
|
||||
extern void process_library2_switch(const char*name);
|
||||
|
||||
/* Add a new include file search directory */
|
||||
@@ -48,10 +64,52 @@ extern void process_include_dir(const char*name);
|
||||
/* Add a new -D define. */
|
||||
extern void process_define(const char*name);
|
||||
|
||||
/* Add a new parameter definition */
|
||||
extern void process_parameter(const char*name);
|
||||
/* -v */
|
||||
extern int verbose_flag;
|
||||
|
||||
/* Set the default timescale for the simulator. */
|
||||
extern void process_timescale(const char*ts_string);
|
||||
extern char warning_flags[];
|
||||
|
||||
#endif /* IVL_globals_H */
|
||||
/* -y and -Y flags from the command line. */
|
||||
extern char* library_flags;
|
||||
extern char* library_flags2;
|
||||
|
||||
extern const char*lookup_pattern(const char*key);
|
||||
|
||||
extern int build_string(char*out, size_t olen, const char*pattern);
|
||||
|
||||
/*
|
||||
* $Log: globals.h,v $
|
||||
* Revision 1.10 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
*
|
||||
* Revision 1.9 2001/11/13 03:30:26 steve
|
||||
* The +incdir+ plusarg can take multiple directores,
|
||||
* and add initial support for +define+ in the command file.
|
||||
*
|
||||
* Revision 1.8 2001/11/12 18:47:32 steve
|
||||
* Support +incdir in command files, and ignore other
|
||||
* +args flags. Also ignore -a and -v flags.
|
||||
*
|
||||
* Revision 1.7 2001/11/12 01:26:36 steve
|
||||
* More sophisticated command file parser.
|
||||
*
|
||||
* Revision 1.6 2001/10/23 00:37:30 steve
|
||||
* The -s flag can now be repeated on the iverilog command.
|
||||
*
|
||||
* Revision 1.5 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
* Revision 1.4 2001/07/03 04:09:25 steve
|
||||
* Generate verbuse status messages (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.3 2000/11/09 21:58:00 steve
|
||||
* Remember to include the -S condition.
|
||||
*
|
||||
* Revision 1.2 2000/10/28 03:45:47 steve
|
||||
* Use the conf file to generate the vvm ivl string.
|
||||
*
|
||||
* Revision 1.1 2000/10/08 22:36:56 steve
|
||||
* iverilog with an iverilog.conf configuration file.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
.TH iverilog 1 "$Date: 2002/02/16 03:18:54 $" Version "$Date: 2002/02/16 03:18:54 $"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[-ESVv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-Iincludedir] [-mmodule] [-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 \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 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 different set of programs. The path
|
||||
given is used to locate \fIivlpp\fP, \fIivl\fP and the VPI modules.
|
||||
.TP 8
|
||||
.B -c\fIfile\fP
|
||||
This flag specifies an input file that contains a list of Verilog
|
||||
source files. This is similar to the \fIcommand file\fP of other
|
||||
Verilog simulators, in that it is a file that contains the file names
|
||||
instead of taking them on the command line. See \fBCommand Files\fP below.
|
||||
.TP 8
|
||||
.B -C\fIpath\fP
|
||||
This flag selects the driver configuration file to use. Normally, the
|
||||
iverilog program will read its configuration file from
|
||||
/usr/lib/ivl/iverilog.conf (or the install path configured at compile
|
||||
time) but the user can specify the path to a different configuration
|
||||
file. This is useful when testing new configuration files. See the
|
||||
installed configuration file for a summary of the file format.
|
||||
.TP 8
|
||||
.B -D\fImacro\fP
|
||||
Defines macro \fImacro\fP with the string `1' as its definition. This
|
||||
form is normally only used to trigger ifdef conditionals in the
|
||||
Verilog source.
|
||||
.TP 8
|
||||
.B -D\fImacro=defn\fP
|
||||
Defines macro \fImacro\fP as \fIdefn\fP.
|
||||
.TP 8
|
||||
.B -E
|
||||
Preprocess the Verilog source, but do not compile it. The output file
|
||||
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 -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
|
||||
to specify several directories to search, the directories are searched
|
||||
in the order they appear on the command line.
|
||||
.TP 8
|
||||
.B -m\fImodule\fP
|
||||
Add this module to the list of VPI modules to be loaded by the
|
||||
simulation. Many modules can be specified, and all will be loaded, in
|
||||
the order specified. The system module is implicit and always included.
|
||||
.TP 8
|
||||
.B -N\fIpath\fP
|
||||
This is used for debugging the compiler proper. Dump the final netlist
|
||||
form of the design to the specified file. It otherwise does not affect
|
||||
operation of the compiler. The dump happens after the design is
|
||||
elaborated and optimized.
|
||||
.TP 8
|
||||
.B -o \fIfilename\fP
|
||||
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
|
||||
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.
|
||||
.TP 8
|
||||
.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
|
||||
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.
|
||||
.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
|
||||
they will be used as root modules instead.
|
||||
.TP 8
|
||||
.B -T\fImin|typ|max\fP
|
||||
Use this switch to select min, typ or max times from min:typ:max
|
||||
expressions. Normally, the compiler will simply use the typ value from
|
||||
these expressions (with a warning) but this switch will tell the
|
||||
compiler explicitly which value to use. This will suppress the
|
||||
warning that the compiler is making a choice.
|
||||
.TP 8
|
||||
.B -t\fItarget\fP
|
||||
Use this switch to specify the target output format. See the
|
||||
\fBTARGETS\fP section below for a list of valid output formats.
|
||||
.TP 8
|
||||
.B -v
|
||||
Turn on verbose messages. This will print the command lines that are
|
||||
executed to perform the actual compilation, along with version
|
||||
information from the various components, as well as the version of the
|
||||
product as a whole.
|
||||
.TP 8
|
||||
.B -V
|
||||
Print the version of the compiler, and exit.
|
||||
.TP 8
|
||||
.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
|
||||
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.
|
||||
|
||||
.SH MODULE LIBRARIES
|
||||
|
||||
The Icarus Verilog compiler supports module libraries as directories
|
||||
that contain Verilog source files. During elaboration, the compiler
|
||||
notices the instantiation of undefined module types. If the user
|
||||
specifies library search directories, the compiler will search the
|
||||
directory for files with the name of the missing module type. If it
|
||||
finds such a file, it loads it as a Verilog source file, they tries
|
||||
again to elaborate the module.
|
||||
|
||||
Library module files should contain only a single module, but this is
|
||||
not a requirement. Library modules may reference other modules in the
|
||||
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
|
||||
desired target.
|
||||
|
||||
.TP 8
|
||||
.B null
|
||||
The null target causes no code to be generated. It is useful for
|
||||
checking the syntax of the Verilog source.
|
||||
.TP 8
|
||||
.B vvp
|
||||
This is the default. The vvp target generates code for the vvp
|
||||
runtime. The output is a complete program that simulates the design
|
||||
but must be run by the \fBvvp\fP command.
|
||||
.TP 8
|
||||
.B xnf
|
||||
This is the Xilinx Netlist Format used by many tools for placing
|
||||
devices in FPGAs or other programmable devices. The Icarus Verilog XNF
|
||||
code generator can generate complete designs or XNF macros that can be
|
||||
imported into larger designs by other tools. (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.
|
||||
|
||||
.SH "WARNING TYPES"
|
||||
These are the types of warnings that can be selected by the \fB-W\fP
|
||||
switch.
|
||||
|
||||
.TP 8
|
||||
.B all
|
||||
This enables all supported warning categories.
|
||||
|
||||
.TP 8
|
||||
.B implicit
|
||||
This enables warnings for creation of implicit declarations. For
|
||||
example, if a scalar wire X is used but not declared in the Verilog
|
||||
source, this will print a warning at its first use.
|
||||
|
||||
.SH "COMMAND FILES"
|
||||
The command file allows the user to place source file names and
|
||||
certain command line switches into a text file instead of on a long
|
||||
command line. Command files can include C or C++ style comments, as
|
||||
well as # comments, if the # starts the line.
|
||||
|
||||
.TP 8
|
||||
.I "file name"
|
||||
A simple file name or file path is taken to be the name of a Verilog
|
||||
source file. The path starts with the first non-white-space character.
|
||||
|
||||
.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
|
||||
flag may be on the same line or the next non-comment line.
|
||||
|
||||
.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
|
||||
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.
|
||||
|
||||
.TP 8
|
||||
.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
|
||||
on to the next library directory.
|
||||
|
||||
.TP 8
|
||||
.B +define+\fINAME\fP=\fIvalue\fP
|
||||
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 +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\fP
|
||||
This is similar to the \fB+toupper-filename\fP hack described above.
|
||||
|
||||
.SH EXAMPLES
|
||||
These examples assume that you have a Verilog source file called hello.v in
|
||||
the current directory
|
||||
|
||||
To compile hello.v to an executable file called a.out:
|
||||
|
||||
iverilog hello.v
|
||||
|
||||
To compile hello.v to an executable file called hello:
|
||||
|
||||
iverilog -o hello hello.v
|
||||
|
||||
To compile and run explicitly using the vvp runtime:
|
||||
|
||||
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
|
||||
Steve Williams ([email protected])
|
||||
|
||||
.SH SEE ALSO
|
||||
vvp(1),
|
||||
.BR "<http://www.icarus.com/eda/verilog/>"
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2000 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
@@ -1,527 +0,0 @@
|
||||
.TH iverilog 1 "February 26th, 2014" "" "Version %M.%m.%n %E"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
|
||||
[\-Pparameter=value] [\-pflag=value]
|
||||
[\-dname] [\-g1995|\-g2001|\-g2005|\-g2005-sv|\-g2009|\-g2012|\-g<feature>]
|
||||
[\-Iincludedir] [\-mmodule] [\-M[mode=]file] [\-Nfile] [\-ooutputfilename]
|
||||
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] sourcefile
|
||||
|
||||
.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
|
||||
types are added as code generators are implemented.
|
||||
|
||||
.SH OPTIONS
|
||||
\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
|
||||
different set of programs. The path given is used to locate
|
||||
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
|
||||
.TP 8
|
||||
.B -c\fIfile\fP -f\fIfile\fP
|
||||
These flags specifies an input file that contains a list of Verilog
|
||||
source files. This is similar to the \fIcommand file\fP of other
|
||||
Verilog simulators, in that it is a file that contains the file names
|
||||
instead of taking them on the command line. See \fBCommand Files\fP below.
|
||||
.TP 8
|
||||
.B -D\fImacro\fP
|
||||
Defines macro \fImacro\fP with the string `1' as its definition. This
|
||||
form is normally only used to trigger ifdef conditionals in the
|
||||
Verilog source.
|
||||
.TP 8
|
||||
.B -D\fImacro=defn\fP
|
||||
Defines macro \fImacro\fP as \fIdefn\fP.
|
||||
.TP 8
|
||||
.B -P\fIparameter=value\fP
|
||||
Override (i.e. defparam) a parameter in a root module. This allows the
|
||||
user to override at compile time (defparam) a parameter in a root
|
||||
module instance. For example, \fB\-Pmain.foo=2\fP overrides the
|
||||
parameter foo in the root instance main with the value 2.
|
||||
.TP 8
|
||||
.B -d\fIname\fP
|
||||
Activate a class of compiler debugging messages. The \fB\-d\fP switch may
|
||||
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.
|
||||
.TP 8
|
||||
.B -E
|
||||
Preprocess the Verilog source, but do not compile it. The output file
|
||||
is the Verilog input, but with file inclusions and macro references
|
||||
expanded and removed. This is useful, for example, to preprocess
|
||||
Verilog source for use by other compilers.
|
||||
.TP 8
|
||||
.B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005\fI|\fP-g2005-sv\fI|\fP-g2009\fI|\fP-g2012
|
||||
Select the Verilog language \fIgeneration\fP to support in the compiler.
|
||||
This selects between \fIIEEE1364\-1995\fP, \fIIEEE1364\-2001\fP,
|
||||
\fIIEEE1364\-2005\fP, \fIIEEE1800\-2005\fP, \fIIEEE1800\-2009\fP, or
|
||||
\fIIEEE1800\-2012\fP.
|
||||
Icarus Verilog currently defaults to the \fIIEEE1364\-2005\fP generation
|
||||
of the language. This flag is used to restrict the language to a set of
|
||||
keywords/features, this allows simulation of older Verilog code that may
|
||||
use newer keywords and for compatibility with other tools. Much of the
|
||||
\fIIEEE1800\fP generations functionality is not currently supported.
|
||||
The \fIIEEE1800\fP generations do parse all the keywords, so they can
|
||||
be used to verify that \fIIEEE1364\fP compliant Verilog code does not
|
||||
use any of the new \fIIEEE1800\fP keywords.
|
||||
.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.
|
||||
.TP 8
|
||||
.B -gspecify\fI|\fP-gno-specify
|
||||
Enable or disable (default) 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
|
||||
simulation. However, disabling specify blocks reduces accuracy of
|
||||
full-timing simulations.
|
||||
.TP 8
|
||||
.B -gstd-include\fI|\fP-gno-std-include
|
||||
Enable (default) or disable the search of a standard installation
|
||||
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
|
||||
Verilog as extensions beyond the baseline Verilog. It may be necessary
|
||||
to disable extended types if compiling code that clashes with the few
|
||||
new keywords used to implement the type system.
|
||||
.TP 8
|
||||
.B -gio-range-error\fI|\fP-gno-io-range-error
|
||||
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
|
||||
warning instead of a fatal error for the case of a vectored net/register
|
||||
and a scalar port declaration.
|
||||
.TP 8
|
||||
.B -gstrict-ca-eval\fI|\fP-gno-strict-ca-eval
|
||||
The standard requires that if any input to a continuous assignment
|
||||
expression changes value, the entire expression is re-evaluated. By
|
||||
default, parts of the expression that do not depend on the changed
|
||||
input value(s) are not re-evaluated. If an expression contains a call
|
||||
to a function that doesn't depend solely on its input values or that
|
||||
has side effects, the resulting behavior will differ from that
|
||||
required by the standard. Using \fI\-gstrict\-ca\-eval\fP will force
|
||||
standard compliant behavior (with some loss in performance).
|
||||
.TP 8
|
||||
.B -gstrict-expr-width\fI|\fP-gno-strict-expr-width
|
||||
Enable or disable (default) strict compliance with the standard rules
|
||||
for determining expression bit lengths. When disabled, the RHS of a
|
||||
parameter assignment is evaluated as a lossless expression, as is any
|
||||
expression containing an unsized constant number, and unsized constant
|
||||
numbers are not truncated to integer width.
|
||||
.TP 8
|
||||
.B -I\fIincludedir\fP
|
||||
Append directory \fIincludedir\fP to list of directories searched
|
||||
for Verilog include files. The \fB\-I\fP switch may be used many times
|
||||
to specify several directories to search, the directories are searched
|
||||
in the order they appear on the command line.
|
||||
.TP 8
|
||||
.B -M\fIpath\fP
|
||||
This is equivalent to \fB\-Mall=path\fP. Preserved for backwards
|
||||
compatibility.
|
||||
.TP 8
|
||||
.B -M\fImode=path\fP
|
||||
Write into the file specified by path a list of files that contribute to
|
||||
the compilation of the design. If \fBmode\fP is \fBall\fP or \fBprefix\fP,
|
||||
this includes files that are included by include directives and files
|
||||
that are automatically loaded by library support as well as the files
|
||||
explicitly specified by the user. If \fBmode\fP is \fBinclude\fP, only
|
||||
files that are included by include directives are listed. If \fBmode\fP
|
||||
is \fBmodule\fP, only files that are specified by the user or that are
|
||||
automatically loaded by library support are listed. The output is one
|
||||
file name per line, with no leading or trailing space. If \fBmode\fP
|
||||
is \fBprefix\fP, files that are included by include directives are
|
||||
prefixed by "I " and other files are prefixed by "M ".
|
||||
.TP 8
|
||||
.B -m\fImodule\fP
|
||||
Add this module to the list of VPI modules to be loaded by the
|
||||
simulation. Many modules can be specified, and all will be loaded, in
|
||||
the order specified. The system module is implicit and always included.
|
||||
If a System Function Table file (<module>.sft) exists for the module it
|
||||
will be loaded automatically.
|
||||
.TP 8
|
||||
.B -N\fIpath\fP
|
||||
This is used for debugging the compiler proper. Dump the final netlist
|
||||
form of the design to the specified file. It otherwise does not affect
|
||||
operation of the compiler. The dump happens after the design is
|
||||
elaborated and optimized.
|
||||
.TP 8
|
||||
.B -o \fIfilename\fP
|
||||
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
|
||||
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.
|
||||
.TP 8
|
||||
.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
|
||||
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.
|
||||
.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
|
||||
they will be used as root modules instead.
|
||||
.TP 8
|
||||
.B -T\fImin|typ|max\fP
|
||||
Use this switch to select min, typ or max times from min:typ:max
|
||||
expressions. Normally, the compiler will simply use the typ value from
|
||||
these expressions (printing a warning for the first ten it finds) but
|
||||
this switch will tell the compiler explicitly which value to use. This
|
||||
will suppress the warning that the compiler is making a choice.
|
||||
.TP 8
|
||||
.B -t\fItarget\fP
|
||||
Use this switch to specify the target output format. See the
|
||||
\fBTARGETS\fP section below for a list of valid output formats.
|
||||
.TP 8
|
||||
.B -v
|
||||
Turn on verbose messages. This will print the command lines that are
|
||||
executed to perform the actual compilation, along with version
|
||||
information from the various components, as well as the version of the
|
||||
product as a whole. You will notice that the command lines include
|
||||
a reference to a key temporary file that passes information to the
|
||||
compiler proper. To keep that file from being deleted at the end
|
||||
of the process, provide a file name of your own in the environment
|
||||
variable \fBIVERILOG_ICONFIG\fP.
|
||||
.TP 8
|
||||
.B -V
|
||||
Print the version of the compiler, and exit.
|
||||
.TP 8
|
||||
.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
|
||||
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
|
||||
|
||||
The Icarus Verilog compiler supports module libraries as directories
|
||||
that contain Verilog source files. During elaboration, the compiler
|
||||
notices the instantiation of undefined module types. If the user
|
||||
specifies library search directories, the compiler will search the
|
||||
directory for files with the name of the missing module type. If it
|
||||
finds such a file, it loads it as a Verilog source file, they tries
|
||||
again to elaborate the module.
|
||||
|
||||
Library module files should contain only a single module, but this is
|
||||
not a requirement. Library modules may reference other modules in the
|
||||
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
|
||||
desired target.
|
||||
|
||||
.TP 8
|
||||
.B null
|
||||
The null target causes no code to be generated. It is useful for
|
||||
checking the syntax of the Verilog source.
|
||||
.TP 8
|
||||
.B vvp
|
||||
This is the default. The vvp target generates code for the vvp
|
||||
runtime. The output is a complete program that simulates the design
|
||||
but must be run by the \fBvvp\fP command. The -pfileline=1 option
|
||||
can be used to add procedural statement debugging opcodes to the
|
||||
generated code.
|
||||
.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.
|
||||
|
||||
.SH "WARNING TYPES"
|
||||
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.
|
||||
|
||||
.TP 8
|
||||
.B all
|
||||
This enables the implicit, portbind, select\-range, timescale, and
|
||||
sensitivity\-entire\-array warning categories.
|
||||
|
||||
.TP 8
|
||||
.B implicit
|
||||
This enables warnings for creation of implicit declarations. For
|
||||
example, if a scalar wire X is used but not declared in the Verilog
|
||||
source, this will print a warning at its first use.
|
||||
|
||||
.TP 8
|
||||
.B portbind
|
||||
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
|
||||
directive. It detects if some modules have no timescale, or if modules
|
||||
inherit timescale from another file. Both probably mean that
|
||||
timescales are inconsistent, and simulation timing can be confusing
|
||||
and dependent on compilation order.
|
||||
|
||||
.TP 8
|
||||
.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.
|
||||
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).
|
||||
|
||||
When you suspect an always statement is producing a runtime infinite loop
|
||||
use this flag to find the always statements that need to have their logic
|
||||
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
|
||||
describe to the compiler the return types for system functions. This
|
||||
is necessary because the compiler needs this information to elaborate
|
||||
expressions that contain these system functions, but cannot run the
|
||||
sizetf functions since it has no run-time.
|
||||
|
||||
The format of the table is ASCII, one function per line. Empty lines
|
||||
are ignored, and lines that start with the '\fI#\fP' character are
|
||||
comment lines. Each non-comment line starts with the function name,
|
||||
then the vpi type (i.e. vpiSysFuncReal). The following types are
|
||||
supported:
|
||||
|
||||
.TP 8
|
||||
.B vpiSysFuncReal
|
||||
The function returns a real/realtime value.
|
||||
|
||||
.TP 8
|
||||
.B vpiSysFuncInt
|
||||
The function returns an integer.
|
||||
|
||||
.TP 8
|
||||
.B vpiSysFuncSized <wid> <signed|unsigned>
|
||||
The function returns a vector with the given width, and is signed or
|
||||
unsigned according to the flag.
|
||||
|
||||
.SH "COMMAND FILES"
|
||||
The command file allows the user to place source file names and
|
||||
certain command line switches into a text file instead of on a long
|
||||
command line. Command files can include C or C++ style comments, as
|
||||
well as # comments, if the # starts the line.
|
||||
|
||||
.TP 8
|
||||
.I "file name"
|
||||
A simple file name or file path is taken to be the name of a Verilog
|
||||
source file. The path starts with the first non-white-space
|
||||
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
|
||||
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
|
||||
flag may be on the same line or the next non-comment line.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
Variables in the \fIincludedir\fP are substituted.
|
||||
|
||||
.TP 8
|
||||
.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
|
||||
on to the next library directory.
|
||||
|
||||
.TP 8
|
||||
.B +libdir+\fIdir\fP
|
||||
This is another way to specify library directories. See the \-y flag.
|
||||
|
||||
.TP 8
|
||||
.B +libdir-nocase+\fIdir\fP
|
||||
This is like the \fB+libdir\fP statement, but file names inside the
|
||||
directories declared here are case insensitive. The missing module
|
||||
name in a lookup need not match the file name case, as long as the
|
||||
letters are correct. For example, "foo" matches "Foo.v" but not
|
||||
"bar.v".
|
||||
|
||||
.TP 8
|
||||
.B +define+\fINAME\fP=\fIvalue\fP
|
||||
The \fB+define+\fP token is the same as the \fB\-D\fP option on the
|
||||
command line. The value part of the token is optional.
|
||||
|
||||
.TP 8
|
||||
.B +parameter+\fINAME\fP=\fIvalue\fP
|
||||
The \fB+parameter+\fP token is the same as the \fB\-P\fP option on the
|
||||
command line.
|
||||
|
||||
.TP 8
|
||||
.B +timescale+\fIvalue\fP
|
||||
The \fB+timescale+\fP token is used to set the default timescale for
|
||||
the simulation. This is the time units and precision before any
|
||||
`timescale directive or after a `resetall directive. The default is
|
||||
1s/1s.
|
||||
|
||||
.TP 8
|
||||
.B +toupper-filename
|
||||
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.
|
||||
|
||||
.TP 8
|
||||
.B +integer-width+\fIvalue\fP
|
||||
This allows the programmer to select the width for integer variables
|
||||
in the Verilog source. The default is 32, the value can be any desired
|
||||
integer value.
|
||||
|
||||
.TP 8
|
||||
.B +width-cap+\fIvalue\fP
|
||||
This allows the programmer to select the width cap for unsized expressions.
|
||||
If the calculated width for an unsized expression exceeds this value, the
|
||||
compiler will issue a warning and limit the expression width to this value.
|
||||
|
||||
.SH "VARIABLES IN COMMAND FILES"
|
||||
|
||||
In certain cases, iverilog supports variables in command files. These
|
||||
are strings of the form "$(\fIvarname\fP)" or "${\fIvarname\fP}", where
|
||||
\fIvarname\fP is the
|
||||
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
|
||||
and directory strings.
|
||||
|
||||
Variable values come from the operating system environment, and not
|
||||
from preprocessor defines elsewhere in the file or the command line.
|
||||
|
||||
.SH PREDEFINED MACROS
|
||||
|
||||
The following macros are predefined by the compiler:
|
||||
.TP 8
|
||||
.B __ICARUS__ = 1
|
||||
This is always defined when compiling with Icarus Verilog.
|
||||
|
||||
.TP 8
|
||||
.B __VAMS_ENABLE__ = 1
|
||||
This is defined if Verilog\-AMS is enabled.
|
||||
|
||||
.SH EXAMPLES
|
||||
These examples assume that you have a Verilog source file called hello.v in
|
||||
the current directory
|
||||
|
||||
To compile hello.v to an executable file called a.out:
|
||||
|
||||
iverilog hello.v
|
||||
|
||||
To compile hello.v to an executable file called hello:
|
||||
|
||||
iverilog \-o hello hello.v
|
||||
|
||||
To compile and run explicitly using the vvp runtime:
|
||||
|
||||
iverilog \-ohello.vvp \-tvvp hello.v
|
||||
|
||||
.SH "AUTHOR"
|
||||
.nf
|
||||
Steve Williams ([email protected])
|
||||
|
||||
.SH SEE ALSO
|
||||
vvp(1),
|
||||
.BR "<http://www.icarus.com/eda/verilog/>"
|
||||
|
||||
Tips on using, debugging, and developing the compiler can be found at
|
||||
.BR "<http://iverilog.wikia.com/>"
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002\-2014 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: lexor.lex,v 1.5 2001/07/25 03:10:50 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <string.h>
|
||||
# include "parse.h"
|
||||
|
||||
%}
|
||||
|
||||
%x CTOKENS
|
||||
%x PATTERN
|
||||
|
||||
%%
|
||||
|
||||
"#".* { /* eat comments */; }
|
||||
|
||||
"\n" { /* eat line-ends */; }
|
||||
"\r" { /* eat line-ends */; }
|
||||
|
||||
"[" { BEGIN(CTOKENS); return '['; }
|
||||
|
||||
<CTOKENS>"]" { BEGIN(0); return ']'; }
|
||||
|
||||
<CTOKENS>[ \t\b]+ { /* skip white space */; }
|
||||
|
||||
<CTOKENS>"-S" { return CT_S; }
|
||||
|
||||
<CTOKENS>"-t"[a-zA-Z0-9\-_]+ {
|
||||
yylval.text = strdup(yytext+2);
|
||||
return CT_t; }
|
||||
|
||||
"<"[^>]*">" {
|
||||
BEGIN(PATTERN);
|
||||
yylval.text = strdup(yytext);
|
||||
return PATTERN_NAME; }
|
||||
|
||||
<PATTERN>.* {
|
||||
BEGIN(0);
|
||||
/* Trim off a trailing \r. This is an issue in the DOS world. */
|
||||
if (yytext[strlen(yytext)-1] == '\r')
|
||||
yytext[strlen(yytext)-1] = 0;
|
||||
|
||||
yylval.text = strdup(yytext);
|
||||
return PATTERN_TEXT; }
|
||||
|
||||
. { fprintf(stderr, "driver lexor: Unmatched character: %c\n", yytext[0]); }
|
||||
|
||||
%%
|
||||
|
||||
void reset_lexor(FILE*fd)
|
||||
{
|
||||
yyrestart(fd);
|
||||
}
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
+439
-935
File diff suppressed because it is too large
Load Diff
+167
@@ -0,0 +1,167 @@
|
||||
%{
|
||||
/*
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse.y,v 1.4 2001/09/15 18:27:04 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <stdio.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <stdlib.h>
|
||||
# include "globals.h"
|
||||
|
||||
|
||||
void yyerror(const char*);
|
||||
|
||||
enum drive_code_t {
|
||||
CODE_S,
|
||||
CODE_t,
|
||||
};
|
||||
|
||||
struct drive_cond {
|
||||
struct drive_cond*next;
|
||||
enum drive_code_t code;
|
||||
char* text;
|
||||
};
|
||||
|
||||
static struct drive_cond *cur_cond = 0;
|
||||
|
||||
static void add_cond(enum drive_code_t code, char*text)
|
||||
{
|
||||
struct drive_cond*tmp;
|
||||
tmp = calloc(1, sizeof(struct drive_cond));
|
||||
tmp->code = code;
|
||||
tmp->text = text;
|
||||
|
||||
tmp->next = cur_cond;
|
||||
cur_cond = tmp;
|
||||
}
|
||||
|
||||
struct drive_pattern {
|
||||
struct drive_pattern*next;
|
||||
char*name;
|
||||
char*text;
|
||||
struct drive_cond*cond;
|
||||
};
|
||||
|
||||
static struct drive_pattern *patterns = 0;
|
||||
static struct drive_pattern *plast = 0;
|
||||
|
||||
static void add_pattern(char*name, char*text)
|
||||
{
|
||||
struct drive_pattern*tmp;
|
||||
tmp = calloc(1, sizeof(struct drive_pattern));
|
||||
tmp->name = name;
|
||||
tmp->text = text;
|
||||
tmp->cond = cur_cond;
|
||||
tmp->next = 0;
|
||||
|
||||
|
||||
if (plast) {
|
||||
plast->next = tmp;
|
||||
plast = tmp;
|
||||
} else {
|
||||
patterns = tmp;
|
||||
plast = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
const char*lookup_pattern(const char*key)
|
||||
{
|
||||
struct drive_pattern*cur;
|
||||
struct drive_cond*cc;
|
||||
|
||||
for (cur = patterns ; cur ; cur = cur->next) {
|
||||
|
||||
if (strcmp(key, cur->name) != 0)
|
||||
continue;
|
||||
|
||||
for (cc = cur->cond ; cc ; cc = cc->next) {
|
||||
|
||||
switch (cc->code) {
|
||||
case CODE_S:
|
||||
if (synth_flag)
|
||||
continue;
|
||||
break;
|
||||
case CODE_t:
|
||||
if (strcmp(targ, cc->text) == 0)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (cc) continue;
|
||||
|
||||
return cur->text;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char*text;
|
||||
};
|
||||
|
||||
%token <text> PATTERN_NAME PATTERN_TEXT
|
||||
%token <text> CT_t
|
||||
%token CT_S
|
||||
|
||||
%%
|
||||
|
||||
start: section_list
|
||||
|
||||
section_list
|
||||
: section
|
||||
| section_list section
|
||||
;
|
||||
|
||||
section : '[' ctoken_list ']' pattern_list { cur_cond = 0; } ;
|
||||
|
||||
ctoken_list
|
||||
: ctoken
|
||||
| ctoken_list ctoken
|
||||
;
|
||||
|
||||
ctoken : CT_S { add_cond(CODE_S, 0); }
|
||||
| CT_t { add_cond(CODE_t, $1); }
|
||||
;
|
||||
|
||||
pattern_list
|
||||
: pattern
|
||||
| pattern_list pattern
|
||||
;
|
||||
|
||||
pattern : PATTERN_NAME PATTERN_TEXT
|
||||
{ add_pattern($1, $2); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void yyerror(const char*msg)
|
||||
{
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2010 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include "ivl_alloc.h"
|
||||
# include "globals.h"
|
||||
|
||||
|
||||
char* substitutions(const char*str)
|
||||
{
|
||||
size_t nbuf = strlen(str) + 1;
|
||||
char*buf = malloc(nbuf);
|
||||
char*cp = buf;
|
||||
|
||||
while (*str) {
|
||||
|
||||
if ((str[0] == '$') && ((str[1] == '(') || str[1] == '{')) {
|
||||
/* If I find a $(x) or ${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]=='(') ? ')' : '}');
|
||||
str += 2;
|
||||
|
||||
name = malloc(ep-str+1);
|
||||
strncpy(name, str, ep-str);
|
||||
name[ep-str] = 0;
|
||||
|
||||
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 (strlen(value) >= (nbuf - (cp-buf))) {
|
||||
size_t old_size = cp - buf;
|
||||
nbuf = (cp - buf) + strlen(value) + 1;
|
||||
buf = realloc(buf, nbuf);
|
||||
cp = buf + old_size;
|
||||
}
|
||||
|
||||
strcpy(cp, value);
|
||||
cp += strlen(cp);
|
||||
|
||||
} else {
|
||||
if ( cp == (buf + nbuf) ) {
|
||||
size_t old_size = nbuf;
|
||||
nbuf = old_size + 32;
|
||||
buf = realloc(buf, nbuf);
|
||||
cp = buf + old_size;
|
||||
}
|
||||
|
||||
*cp++ = *str++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the trailing nul to the string, and reallocate the
|
||||
buffer to be a tight fit. */
|
||||
if ( cp == (buf + nbuf) ) {
|
||||
size_t old_size = nbuf;
|
||||
nbuf = old_size + 1;
|
||||
buf = realloc(buf, nbuf);
|
||||
buf[old_size] = 0;
|
||||
} else {
|
||||
*cp++ = 0;
|
||||
nbuf = cp - buf;
|
||||
buf = realloc(buf, nbuf);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
+47
-267
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2013 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
|
||||
@@ -14,251 +14,46 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: dup_expr.cc,v 1.7 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# 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;
|
||||
}
|
||||
|
||||
NetEArrayPattern*NetEArrayPattern::dup_expr() const
|
||||
{
|
||||
vector<NetExpr*>tmp (items_.size());
|
||||
for (size_t idx = 0 ; idx < tmp.size() ; idx += 1)
|
||||
tmp[idx] = items_[idx]->dup_expr();
|
||||
|
||||
NetEArrayPattern*res = new NetEArrayPattern(net_type(), tmp);
|
||||
res->set_line(*this);
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEBinary* NetEBinary::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEBAdd* NetEBAdd::dup_expr() const
|
||||
{
|
||||
NetEBAdd*tmp = new NetEBAdd(op_, left_->dup_expr(), right_->dup_expr(),
|
||||
expr_width(), has_sign());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEBBits* NetEBBits::dup_expr() const
|
||||
{
|
||||
NetEBBits*tmp = new NetEBBits(op_, left_->dup_expr(), right_->dup_expr(),
|
||||
expr_width(), has_sign());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEBComp* NetEBComp::dup_expr() const
|
||||
{
|
||||
NetEBComp*tmp = new NetEBComp(op_, left_->dup_expr(), right_->dup_expr());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEBDiv* NetEBDiv::dup_expr() const
|
||||
{
|
||||
NetEBDiv*tmp = new NetEBDiv(op_, left_->dup_expr(), right_->dup_expr(),
|
||||
expr_width(), has_sign());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEBLogic* NetEBLogic::dup_expr() const
|
||||
{
|
||||
NetEBLogic*tmp = new NetEBLogic(op_, left_->dup_expr(), right_->dup_expr());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEBMult* NetEBMult::dup_expr() const
|
||||
{
|
||||
NetEBMult*tmp = new NetEBMult(op_, left_->dup_expr(), right_->dup_expr(),
|
||||
expr_width(), has_sign());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEBPow* NetEBPow::dup_expr() const
|
||||
{
|
||||
NetEBPow*tmp = new NetEBPow(op_, left_->dup_expr(), right_->dup_expr(),
|
||||
expr_width(), has_sign());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEBShift* NetEBShift::dup_expr() const
|
||||
{
|
||||
NetEBShift*tmp = new NetEBShift(op_, left_->dup_expr(), right_->dup_expr(),
|
||||
expr_width(), has_sign());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEConcat* NetEConcat::dup_expr() const
|
||||
{
|
||||
NetEConcat*dup = new NetEConcat(parms_.size(), repeat_, expr_type_);
|
||||
ivl_assert(*this, dup);
|
||||
dup->set_line(*this);
|
||||
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1)
|
||||
if (parms_[idx]) {
|
||||
NetExpr*tmp = parms_[idx]->dup_expr();
|
||||
ivl_assert(*this, tmp);
|
||||
dup->parms_[idx] = tmp;
|
||||
}
|
||||
|
||||
dup->expr_width(expr_width());
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
NetEConst* NetEConst::dup_expr() const
|
||||
{
|
||||
NetEConst*tmp = new NetEConst(value_);
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEConstEnum* NetEConstEnum::dup_expr() const
|
||||
{
|
||||
NetEConstEnum*tmp = new NetEConstEnum(scope_, name_, enum_set_, value());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEConstParam* NetEConstParam::dup_expr() const
|
||||
{
|
||||
NetEConstParam*tmp = new NetEConstParam(scope_, name_, value());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetECReal* NetECReal::dup_expr() const
|
||||
{
|
||||
NetECReal*tmp = new NetECReal(value_);
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetECRealParam* NetECRealParam::dup_expr() const
|
||||
{
|
||||
NetECRealParam*tmp = new NetECRealParam(scope_, name_, value());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEEvent* NetEEvent::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetELast* NetELast::dup_expr() const
|
||||
{
|
||||
NetELast*tmp = new NetELast(sig_);
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetENetenum* NetENetenum::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetENew* NetENew::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetENull* NetENull::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEProperty* NetEProperty::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEScope* NetEScope::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetESelect* NetESelect::dup_expr() const
|
||||
{
|
||||
NetESelect*tmp = new NetESelect(expr_->dup_expr(),
|
||||
base_? base_->dup_expr() : 0,
|
||||
expr_width(), sel_type_);
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->cast_signed(has_sign());
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
return new NetESelect(expr_->dup_expr(), base_->dup_expr(),
|
||||
expr_width());
|
||||
}
|
||||
|
||||
NetESFunc* NetESFunc::dup_expr() const
|
||||
{
|
||||
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms());
|
||||
ivl_assert(*this, tmp);
|
||||
|
||||
tmp->cast_signed(has_sign());
|
||||
NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
|
||||
assert(tmp);
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
||||
ivl_assert(*this, 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);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEShallowCopy* NetEShallowCopy::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetESignal* NetESignal::dup_expr() const
|
||||
{
|
||||
NetESignal*tmp = new NetESignal(net_, word_);
|
||||
ivl_assert(*this, tmp);
|
||||
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
|
||||
assert(tmp);
|
||||
tmp->expr_width(expr_width());
|
||||
tmp->cast_signed(has_sign());
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -266,60 +61,45 @@ NetETernary* NetETernary::dup_expr() const
|
||||
{
|
||||
NetETernary*tmp = new NetETernary(cond_->dup_expr(),
|
||||
true_val_->dup_expr(),
|
||||
false_val_->dup_expr(),
|
||||
expr_width(),
|
||||
has_sign());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEUFunc* NetEUFunc::dup_expr() const
|
||||
{
|
||||
NetEUFunc*tmp;
|
||||
vector<NetExpr*> tmp_parms (parms_.size());
|
||||
|
||||
for (unsigned idx = 0 ; idx < tmp_parms.size() ; idx += 1) {
|
||||
ivl_assert(*this, parms_[idx]);
|
||||
tmp_parms[idx] = parms_[idx]->dup_expr();
|
||||
}
|
||||
|
||||
tmp = new NetEUFunc(scope_, func_, result_sig_->dup_expr(), tmp_parms,
|
||||
need_const_);
|
||||
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEUBits* NetEUBits::dup_expr() const
|
||||
{
|
||||
NetEUBits*tmp = new NetEUBits(op_, expr_->dup_expr(), expr_width(), has_sign());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
false_val_->dup_expr());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEUnary* NetEUnary::dup_expr() const
|
||||
{
|
||||
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr(), expr_width(), has_sign());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr());
|
||||
assert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEUReduce* NetEUReduce::dup_expr() const
|
||||
{
|
||||
NetEUReduce*tmp = new NetEUReduce(op_, expr_->dup_expr());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
/*
|
||||
* $Log: dup_expr.cc,v $
|
||||
* Revision 1.7 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.6 2001/11/19 01:54:14 steve
|
||||
* Port close cropping behavior from mcrgb
|
||||
* Move window array reset to libmc.
|
||||
*
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2000/05/07 18:20:07 steve
|
||||
* Import MCD support from Stephen Tell, and add
|
||||
* system function parameter support to the IVL core.
|
||||
*
|
||||
* Revision 1.3 2000/05/04 03:37:58 steve
|
||||
* Add infrastructure for system functions, move
|
||||
* $time to that structure and add $random.
|
||||
*
|
||||
* Revision 1.2 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.1 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
*/
|
||||
|
||||
NetECast* NetECast::dup_expr() const
|
||||
{
|
||||
NetECast*tmp = new NetECast(op_, expr_->dup_expr(), expr_width(), has_sign());
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
+37
-36
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2003 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected].com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,8 +14,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_anet.cc,v 1.4 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
@@ -26,13 +29,12 @@
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include <iostream>
|
||||
|
||||
NetNet* PExpr::elaborate_anet(Design*des, NetScope*scope) const
|
||||
{
|
||||
cerr << get_line() << ": error: Invalid expression on left side "
|
||||
<< "of procedural continuous assignment." << endl;
|
||||
<< "of precedural continuous asignment." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -81,18 +83,15 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
|
||||
concat operator from least significant to most significant,
|
||||
which is opposite from how they are given in the list.
|
||||
|
||||
Allow for a repeat count other than 1 by repeating the
|
||||
Allow for a repeat count other then 1 by repeating the
|
||||
connect loop as many times as necessary. */
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet*osig = new NetNet(scope, des->local_symbol(scope->name()),
|
||||
NetNet::IMPLICIT_REG, pins);
|
||||
/* Assume that all the data types are the same. */
|
||||
osig->data_type(nets[0]->data_type());
|
||||
|
||||
pins = 0;
|
||||
for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
|
||||
NetNet*cur = nets[idx-1];
|
||||
assert(cur->data_type() == osig->data_type());
|
||||
for (unsigned pin = 0; pin < cur->pin_count(); pin += 1) {
|
||||
connect(osig->pin(pins), cur->pin(pin));
|
||||
pins += 1;
|
||||
@@ -105,33 +104,17 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
NetNet* sig = 0;
|
||||
NetMemory* mem = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
symbol_search(this, des, scope, path_, sig, mem, par, eve);
|
||||
|
||||
|
||||
if (mem != 0) {
|
||||
cerr << get_line() << ": error: memories not allowed "
|
||||
<< "on left side of procedural continuous "
|
||||
<< "assignment." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (eve != 0) {
|
||||
cerr << get_line() << ": error: named events not allowed "
|
||||
<< "on left side of procedural continuous "
|
||||
<< "assignment." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
NetNet*sig = des->find_signal(scope, path_);
|
||||
|
||||
if (sig == 0) {
|
||||
if (NetMemory*mem = des->find_memory(scope, path_)) {
|
||||
cerr << get_line() << ": error: memories not allowed "
|
||||
<< "on left side of procedural continuous "
|
||||
<< "asignment." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cerr << get_line() << ": error: reg ``" << path_ << "'' "
|
||||
<< "is undefined in this scope." << endl;
|
||||
des->errors += 1;
|
||||
@@ -155,8 +138,8 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
if (msb_ || lsb_) {
|
||||
|
||||
cerr << get_line() << ": error: bit/part selects not allowed "
|
||||
<< "on left side of procedural continuous assignment."
|
||||
<< endl;
|
||||
<< "on left side of procedural continuous asignment."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -164,3 +147,21 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
return sig;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_anet.cc,v $
|
||||
* 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)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+421
-5743
File diff suppressed because it is too large
Load Diff
+193
-1139
File diff suppressed because it is too large
Load Diff
+1815
-836
File diff suppressed because it is too large
Load Diff
+278
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_pexpr.cc,v 1.13 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "util.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
NetExpr*PExpr::elaborate_pexpr(Design*des, NetScope*sc) const
|
||||
{
|
||||
cerr << get_line() << ": error: invalid parameter expression: "
|
||||
<< *this << endl;
|
||||
des->errors += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Binary operators have sub-expressions that must be elaborated as
|
||||
* parameter expressions. If either of them fail, then give up. Once
|
||||
* they are taken care of, make the base object just as in any other
|
||||
* expression.
|
||||
*/
|
||||
NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
{
|
||||
NetExpr*lp = left_->elaborate_pexpr(des, scope);
|
||||
NetExpr*rp = right_->elaborate_pexpr(des, scope);
|
||||
if ((lp == 0) || (rp == 0)) {
|
||||
delete lp;
|
||||
delete rp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Event though parameters are not generally sized, parameter
|
||||
* expressions can include concatenation expressions. This requires
|
||||
* that the subexpressions all have well-defined size (in spite of
|
||||
* being in a parameter expression) in order to get a defined
|
||||
* value. The sub-expressions themsilves must also be value parameter
|
||||
* expressions.
|
||||
*/
|
||||
NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
unsigned repeat = 1;
|
||||
|
||||
/* If there is a repeat expression, then evaluate the constant
|
||||
value and set the repeat count.
|
||||
|
||||
XXXX Potential bug XXX In principle, the repeat expression
|
||||
can have a parameter name in it. Since where are in the
|
||||
working of parameters now, we will not be able to
|
||||
accurately evaluate such expressions. So eventually, I will
|
||||
need to be able to defer the evaluation of the expression. */
|
||||
if (repeat_) {
|
||||
verinum*vrep = repeat_->eval_const(des, scope);
|
||||
if (vrep == 0) {
|
||||
cerr << get_line() << ": error: "
|
||||
"concatenation repeat expression cannot be evaluated."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
repeat = vrep->as_ulong();
|
||||
delete vrep;
|
||||
}
|
||||
|
||||
/* Make the empty concat expression. */
|
||||
NetEConcat*tmp = new NetEConcat(parms_.count(), repeat);
|
||||
tmp->set_line(*this);
|
||||
|
||||
/* Elaborate all the operands and attach them to the concat
|
||||
node. Use the elaborate_pexpr method instead of the
|
||||
elaborate_expr method. */
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
assert(parms_[idx]);
|
||||
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
|
||||
if (ex == 0) continue;
|
||||
|
||||
ex->set_line(*parms_[idx]);
|
||||
|
||||
if (! ex->has_width()) {
|
||||
cerr << ex->get_line() << ": error: operand of "
|
||||
<< "concatenation has indefinite width: "
|
||||
<< *ex << endl;
|
||||
des->errors += 1;
|
||||
|
||||
} else if (ex->expr_width() == 0) {
|
||||
cerr << ex->get_line() << ": internal error: "
|
||||
<< "Operand of concatenation has no width: "
|
||||
<< *ex << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
tmp->set(idx, ex);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
return elaborate_expr(des, scope);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parameter expressions may reference other parameters, but only in
|
||||
* the current scope. Preserve the parameter reference in the
|
||||
* parameter expression I'm generating, instead of evaluating it now,
|
||||
* because the referenced parameter may yet be overridden.
|
||||
*/
|
||||
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
hname_t path = path_;
|
||||
char*name = path.remove_tail_name();
|
||||
|
||||
NetScope*pscope = scope;
|
||||
if (path.peek_name(0))
|
||||
pscope = des->find_scope(scope, path);
|
||||
|
||||
const NetExpr*ex = pscope->get_parameter(name);
|
||||
if (ex == 0) {
|
||||
cerr << get_line() << ": error: identifier ``" << path_ <<
|
||||
"'' is not a parameter in " << scope->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
delete name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (msb_ || lsb_ || idx_) {
|
||||
cerr << get_line() << ": error: Cannot bit/part select "
|
||||
"bits of parameters." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
|
||||
assert(res);
|
||||
delete name;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple numbers can be elaborated by the elaborate_expr method.
|
||||
*/
|
||||
NetExpr*PENumber::elaborate_pexpr(Design*des, NetScope*sc) const
|
||||
{
|
||||
return elaborate_expr(des, sc);
|
||||
}
|
||||
|
||||
|
||||
NetEConst* PEString::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
return elaborate_expr(des, scope);
|
||||
}
|
||||
|
||||
NetETernary* PETernary::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetExpr*c = expr_->elaborate_pexpr(des, scope);
|
||||
NetExpr*t = tru_->elaborate_pexpr(des, scope);
|
||||
NetExpr*f = fal_->elaborate_pexpr(des, scope);
|
||||
if (c == 0) return 0;
|
||||
if (t == 0) return 0;
|
||||
if (f == 0) return 0;
|
||||
return new NetETernary(c, t, f);
|
||||
}
|
||||
|
||||
NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
{
|
||||
NetExpr*ip = expr_->elaborate_pexpr(des, scope);
|
||||
if (ip == 0) return 0;
|
||||
|
||||
/* Should we evaluate expressions ahead of time,
|
||||
* just like in PEBinary::elaborate_expr() ?
|
||||
*/
|
||||
|
||||
NetEUnary*tmp;
|
||||
switch (op_) {
|
||||
default:
|
||||
tmp = new NetEUnary(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
case '~':
|
||||
tmp = new NetEUBits(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
case '!': // Logical NOT
|
||||
case '&': // Reduction AND
|
||||
case '|': // Reduction OR
|
||||
case '^': // Reduction XOR
|
||||
case 'A': // Reduction NAND (~&)
|
||||
case 'N': // Reduction NOR (~|)
|
||||
case 'X': // Reduction NXOR (~^)
|
||||
tmp = new NetEUReduce(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_pexpr.cc,v $
|
||||
* Revision 1.13 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.12 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.11 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.10 2001/10/07 03:38:08 steve
|
||||
* parameter names do not have defined size.
|
||||
*
|
||||
* Revision 1.9 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.8 2001/01/14 23:04:56 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
* Revision 1.7 2001/01/02 04:21:13 steve
|
||||
* Support a bunch of unary operators in parameter expressions.
|
||||
*
|
||||
* Revision 1.6 2000/12/16 19:03:30 steve
|
||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||
*
|
||||
* Revision 1.5 2000/06/13 05:22:16 steve
|
||||
* Support concatenation in parameter expressions.
|
||||
*
|
||||
* Revision 1.4 2000/06/01 02:31:39 steve
|
||||
* Parameters can be strings.
|
||||
*
|
||||
* Revision 1.3 2000/03/12 18:22:11 steve
|
||||
* Binary and unary operators in parameter expressions.
|
||||
*
|
||||
* Revision 1.2 2000/03/12 04:35:22 steve
|
||||
* Allow parameter identifiers in parameter expressions.
|
||||
*
|
||||
* Revision 1.1 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
*/
|
||||
|
||||
+220
-1816
File diff suppressed because it is too large
Load Diff
+415
-1138
File diff suppressed because it is too large
Load Diff
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "AStatement.h"
|
||||
|
||||
# include <cstdlib>
|
||||
# include <iostream>
|
||||
|
||||
-246
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "pform_types.h"
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "netdarray.h"
|
||||
# include "netenum.h"
|
||||
# include "netparray.h"
|
||||
# include "netscalar.h"
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
# include "netmisc.h"
|
||||
# include <typeinfo>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
* Elaborations of types may vary depending on the scope that it is
|
||||
* done in, so keep a per-scope cache of the results.
|
||||
*/
|
||||
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope)
|
||||
{
|
||||
Definitions*use_definitions = scope;
|
||||
if (use_definitions == 0)
|
||||
use_definitions = des;
|
||||
|
||||
map<Definitions*,ivl_type_s*>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
|
||||
if (pos->first == use_definitions)
|
||||
return pos->second;
|
||||
|
||||
ivl_type_s*tmp = elaborate_type_raw(des, scope);
|
||||
cache_type_elaborate_.insert(pos, pair<NetScope*,ivl_type_s*>(scope, tmp));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ivl_type_s* data_type_t::elaborate_type_raw(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Elaborate method not implemented for " << typeid(*this).name()
|
||||
<< "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ivl_type_s* atom2_type_t::elaborate_type_raw(Design*des, NetScope*) const
|
||||
{
|
||||
switch (type_code) {
|
||||
case 64:
|
||||
if (signed_flag)
|
||||
return &netvector_t::atom2s64;
|
||||
else
|
||||
return &netvector_t::atom2u64;
|
||||
|
||||
case 32:
|
||||
if (signed_flag)
|
||||
return &netvector_t::atom2s32;
|
||||
else
|
||||
return &netvector_t::atom2u32;
|
||||
|
||||
case 16:
|
||||
if (signed_flag)
|
||||
return &netvector_t::atom2s16;
|
||||
else
|
||||
return &netvector_t::atom2u16;
|
||||
|
||||
case 8:
|
||||
if (signed_flag)
|
||||
return &netvector_t::atom2s8;
|
||||
else
|
||||
return &netvector_t::atom2u8;
|
||||
|
||||
default:
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "atom2_type_t type_code=" << type_code << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ivl_type_s* class_type_t::elaborate_type_raw(Design*, NetScope*) const
|
||||
{
|
||||
ivl_assert(*this, save_elaborated_type);
|
||||
return save_elaborated_type;
|
||||
}
|
||||
|
||||
/*
|
||||
* elaborate_type_raw for enumerations is actually mostly performed
|
||||
* during scope elaboration so that the enumeration literals are
|
||||
* available at the right time. At that time, the netenum_t* object is
|
||||
* stashed in the scope so that I can retrieve it here.
|
||||
*/
|
||||
ivl_type_s* enum_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
ivl_assert(*this, scope);
|
||||
ivl_type_s*tmp = scope->enumeration_for_key(this);
|
||||
if (tmp) return tmp;
|
||||
|
||||
tmp = des->enumeration_for_key(this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ivl_type_s* vector_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
vector<netrange_t> packed;
|
||||
|
||||
if (pdims.get()) {
|
||||
for (list<pform_range_t>::const_iterator cur = pdims->begin()
|
||||
; cur != pdims->end() ; ++ cur) {
|
||||
|
||||
NetExpr*me = elab_and_eval(des, scope, cur->first, 0, true);
|
||||
|
||||
NetExpr*le = elab_and_eval(des, scope, cur->second, 0, true);
|
||||
|
||||
/* If elaboration failed for either expression, we
|
||||
should have already reported the error, so just
|
||||
skip the following evaluation to recover. */
|
||||
|
||||
long mnum = 0, lnum = 0;
|
||||
if ( me && ! eval_as_long(mnum, me) ) {
|
||||
assert(0);
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if ( le && ! eval_as_long(lnum, le) ) {
|
||||
assert(0);
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
packed.push_back(netrange_t(mnum, lnum));
|
||||
}
|
||||
}
|
||||
|
||||
netvector_t*tmp = new netvector_t(packed, base_type);
|
||||
tmp->set_signed(signed_flag);
|
||||
tmp->set_isint(integer_flag);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ivl_type_s* real_type_t::elaborate_type_raw(Design*, NetScope*) const
|
||||
{
|
||||
switch (type_code) {
|
||||
case REAL:
|
||||
return &netreal_t::type_real;
|
||||
case SHORTREAL:
|
||||
return &netreal_t::type_shortreal;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ivl_type_s* string_type_t::elaborate_type_raw(Design*, NetScope*) const
|
||||
{
|
||||
return &netstring_t::type_string;
|
||||
}
|
||||
|
||||
ivl_type_s* parray_type_t::elaborate_type_raw(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_fileline() << " : sorry: "
|
||||
<< "Packed arrays are not currently supported in this context."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
netstruct_t* struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
netstruct_t*res = new netstruct_t;
|
||||
|
||||
res->packed(packed_flag);
|
||||
|
||||
if (union_flag)
|
||||
res->union_flag(true);
|
||||
|
||||
for (list<struct_member_t*>::iterator cur = members->begin()
|
||||
; cur != members->end() ; ++ cur) {
|
||||
|
||||
// Elaborate the type of the member.
|
||||
struct_member_t*curp = *cur;
|
||||
ivl_type_t mem_vec = curp->type->elaborate_type(des, scope);
|
||||
if (mem_vec == 0)
|
||||
continue;
|
||||
|
||||
// There may be several names that are the same type:
|
||||
// <data_type> name1, name2, ...;
|
||||
// Process all the member, and give them a type.
|
||||
for (list<decl_assignment_t*>::iterator name = curp->names->begin()
|
||||
; name != curp->names->end() ; ++ name) {
|
||||
decl_assignment_t*namep = *name;
|
||||
|
||||
netstruct_t::member_t memb;
|
||||
memb.name = namep->name;
|
||||
memb.net_type = mem_vec;
|
||||
res->append_member(des, memb);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ivl_type_s* uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
|
||||
ivl_type_t btype = base_type->elaborate_type(des, scope);
|
||||
|
||||
assert(dims->size() >= 1);
|
||||
list<pform_range_t>::const_iterator cur = dims->begin();
|
||||
|
||||
// Special case: if the dimension is nil:nil, this is a
|
||||
// dynamic array. Note that we only know how to handle dynamic
|
||||
// arrays with 1 dimension at a time.
|
||||
if (cur->first==0 && cur->second==0) {
|
||||
assert(dims->size()==1);
|
||||
ivl_type_s*res = new netdarray_t(btype);
|
||||
return res;
|
||||
}
|
||||
|
||||
vector<netrange_t> dimensions;
|
||||
bool bad_range = evaluate_ranges(des, scope, dimensions, *dims);
|
||||
|
||||
if (bad_range) {
|
||||
cerr << get_fileline() << " : warning: "
|
||||
<< "Bad dimensions for type here." << endl;
|
||||
}
|
||||
|
||||
ivl_assert(*this, btype);
|
||||
ivl_type_s*res = new netuarray_t(dimensions, btype);
|
||||
return res;
|
||||
}
|
||||
+1126
-4935
File diff suppressed because it is too large
Load Diff
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "AStatement.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
|
||||
# include <typeinfo>
|
||||
|
||||
NetProc* AContrib::elaborate(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetExpr*lval = elab_and_eval(des, scope, lval_, -1);
|
||||
NetExpr*rval = elab_and_eval(des, scope, rval_, -1);
|
||||
|
||||
NetEAccess*lacc = dynamic_cast<NetEAccess*> (lval);
|
||||
if (lacc == 0) {
|
||||
cerr << get_fileline() << ": error: The l-value of a contribution"
|
||||
<< " statement must be a branch probe access function." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetContribution*st = new NetContribution(lacc, rval);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,8 +14,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: emit.cc,v 1.65 2002/01/28 00:52:41 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
@@ -26,14 +29,11 @@
|
||||
* target.
|
||||
*/
|
||||
# include "target.h"
|
||||
# include "netclass.h"
|
||||
# include "netlist.h"
|
||||
# include "compiler.h"
|
||||
# include <typeinfo>
|
||||
# include <cassert>
|
||||
# include <cstring>
|
||||
|
||||
bool NetNode::emit_node(struct target_t*) const
|
||||
bool NetNode::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
cerr << "EMIT: Gate type? " << typeid(*this).name() << endl;
|
||||
return false;
|
||||
@@ -51,42 +51,22 @@ bool NetUDP::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAbs::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_abs(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAddSub::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_add_sub(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetArrayDq::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->lpm_array_dq(this);
|
||||
}
|
||||
|
||||
bool NetCaseCmp::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_case_cmp(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCastInt2::emit_node(struct target_t*tgt) const
|
||||
bool NetCAssign::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->lpm_cast_int2(this);
|
||||
}
|
||||
|
||||
bool NetCastInt4::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->lpm_cast_int4(this);
|
||||
}
|
||||
|
||||
bool NetCastReal::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->lpm_cast_real(this);
|
||||
tgt->net_cassign(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCLShift::emit_node(struct target_t*tgt) const
|
||||
@@ -101,11 +81,6 @@ bool NetCompare::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetConcat::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->concat(this);
|
||||
}
|
||||
|
||||
bool NetConst::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->net_const(this);
|
||||
@@ -123,9 +98,10 @@ bool NetFF::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetLiteral::emit_node(struct target_t*tgt) const
|
||||
bool NetForce::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->net_literal(this);
|
||||
tgt->net_force(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetModulo::emit_node(struct target_t*tgt) const
|
||||
@@ -146,52 +122,12 @@ bool NetMux::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetPartSelect::emit_node(struct target_t*tgt) const
|
||||
bool NetRamDq::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->part_select(this);
|
||||
}
|
||||
|
||||
bool NetPow::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_pow(this);
|
||||
tgt->lpm_ram_dq(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetReplicate::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->replicate(this);
|
||||
}
|
||||
|
||||
bool NetSignExtend::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->sign_extend(this);
|
||||
}
|
||||
|
||||
bool NetSubstitute::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->substitute(this);
|
||||
}
|
||||
|
||||
bool NetUReduce::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->ureduce(this);
|
||||
}
|
||||
|
||||
bool NetSysFunc::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->net_sysfunction(this);
|
||||
}
|
||||
|
||||
bool NetUserFunc::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->net_function(this);
|
||||
}
|
||||
|
||||
bool NetTran::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->tran(this);
|
||||
}
|
||||
|
||||
bool NetBUFZ::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->bufz(this);
|
||||
@@ -202,26 +138,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*) const
|
||||
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
|
||||
@@ -230,6 +156,18 @@ bool NetAssignNB::emit_proc(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAssignMem::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_assign_mem(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAssignMemNB::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_assign_mem_nb(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetBlock::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_block(this);
|
||||
@@ -251,11 +189,6 @@ bool NetCondit::emit_proc(struct target_t*tgt) const
|
||||
return tgt->proc_condit(this);
|
||||
}
|
||||
|
||||
bool NetContribution::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_contribution(this);
|
||||
}
|
||||
|
||||
bool NetDeassign::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_deassign(this);
|
||||
@@ -266,17 +199,6 @@ bool NetDisable::emit_proc(struct target_t*tgt) const
|
||||
return tgt->proc_disable(this);
|
||||
}
|
||||
|
||||
bool NetDoWhile::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_do_while(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetDoWhile::emit_proc_recurse(struct target_t*tgt) const
|
||||
{
|
||||
proc_->emit_proc(tgt);
|
||||
}
|
||||
|
||||
bool NetForce::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_force(this);
|
||||
@@ -288,17 +210,6 @@ bool NetForever::emit_proc(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetForLoop::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_block(as_block_);
|
||||
}
|
||||
|
||||
bool NetFree::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_free(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetPDelay::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_delay(this);
|
||||
@@ -339,11 +250,6 @@ bool NetWhile::emit_proc(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
|
||||
{
|
||||
proc_->emit_proc(tgt);
|
||||
}
|
||||
|
||||
void NetBlock::emit_recurse(struct target_t*tgt) const
|
||||
{
|
||||
if (last_ == 0)
|
||||
@@ -406,196 +312,97 @@ void NetRepeat::emit_recurse(struct target_t*tgt) const
|
||||
statement_->emit_proc(tgt);
|
||||
}
|
||||
|
||||
void netclass_t::emit_scope(struct target_t*tgt) const
|
||||
{
|
||||
class_scope_->emit_scope(tgt);
|
||||
}
|
||||
|
||||
void NetScope::emit_scope(struct target_t*tgt) const
|
||||
{
|
||||
if (debug_emit) {
|
||||
cerr << "NetScope::emit_scope: "
|
||||
<< "Emit scope " << scope_path(this) << endl;
|
||||
}
|
||||
|
||||
tgt->scope(this);
|
||||
|
||||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
|
||||
tgt->event(cur);
|
||||
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
cur->second->emit_scope(tgt);
|
||||
tgt->class_type(this, cur->second);
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->emit_scope(tgt);
|
||||
|
||||
if (signals_) {
|
||||
NetNet*cur = signals_->sig_next_;
|
||||
do {
|
||||
tgt->signal(cur);
|
||||
cur = cur->sig_next_;
|
||||
} while (cur != signals_->sig_next_);
|
||||
}
|
||||
|
||||
for (map<const enum_type_t*,netenum_t*>::const_iterator cur = enum_sets_.begin()
|
||||
; cur != enum_sets_.end() ; ++cur)
|
||||
tgt->enumeration(this, cur->second);
|
||||
|
||||
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
|
||||
; cur != children_.end() ; ++ cur )
|
||||
cur->second->emit_scope(tgt);
|
||||
|
||||
for (signals_map_iter_t cur = signals_map_.begin()
|
||||
; cur != signals_map_.end() ; ++ cur ) {
|
||||
tgt->signal(cur->second);
|
||||
if (memories_) {
|
||||
NetMemory*cur = memories_->snext_;
|
||||
do {
|
||||
tgt->memory(cur);
|
||||
cur = cur->snext_;
|
||||
} while (cur != memories_->snext_);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
if (type_ == MODULE) tgt->convert_module_ports(this);
|
||||
}
|
||||
|
||||
bool NetScope::emit_defs(struct target_t*tgt) const
|
||||
void NetScope::emit_defs(struct target_t*tgt) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
if (debug_emit) {
|
||||
cerr << "NetScope::emit_defs: "
|
||||
<< "Emit definitions for " << scope_path(this) << endl;
|
||||
}
|
||||
|
||||
switch (type_) {
|
||||
case PACKAGE:
|
||||
case MODULE:
|
||||
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
|
||||
; cur != children_.end() ; ++ cur )
|
||||
flag &= cur->second->emit_defs(tgt);
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++ cur)
|
||||
flag &= cur->second->emit_defs(tgt);
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->emit_defs(tgt);
|
||||
break;
|
||||
|
||||
case FUNC:
|
||||
flag &= tgt->func_def(this);
|
||||
tgt->func_def(this);
|
||||
break;
|
||||
case TASK:
|
||||
tgt->task_def(this);
|
||||
break;
|
||||
default: /* BEGIN_END and FORK_JOIN, GENERATE... */
|
||||
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
|
||||
; cur != children_.end() ; ++ cur )
|
||||
flag &= cur->second->emit_defs(tgt);
|
||||
break;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool netclass_t::emit_defs(struct target_t*tgt) const
|
||||
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
|
||||
{
|
||||
return class_scope_->emit_defs(tgt);
|
||||
proc_->emit_proc(tgt);
|
||||
}
|
||||
|
||||
int Design::emit(struct target_t*tgt) const
|
||||
bool Design::emit(struct target_t*tgt) const
|
||||
{
|
||||
int rc = 0;
|
||||
bool rc = true;
|
||||
|
||||
if (tgt->start_design(this) == false)
|
||||
return -2;
|
||||
rc = rc && tgt->start_design(this);
|
||||
if (rc == false)
|
||||
return false;
|
||||
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
|
||||
; scope != root_tasks_.end() ; ++ scope) {
|
||||
scope->first->emit_scope(tgt);
|
||||
scope->first->emit_defs(tgt);
|
||||
}
|
||||
|
||||
// enumerate package scopes
|
||||
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
||||
; scope != packages_.end() ; ++ scope) {
|
||||
scope->second->emit_scope(tgt);
|
||||
}
|
||||
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
const NetScope*use_scope = cur->second->class_scope();
|
||||
cur->second->emit_scope(tgt);
|
||||
tgt->class_type(use_scope, cur->second);
|
||||
cur->second->emit_defs(tgt);
|
||||
}
|
||||
|
||||
// enumerate root scopes
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||
; scope != root_scopes_.end(); ++ scope ) {
|
||||
// enumerate the scopes
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->emit_scope(tgt);
|
||||
}
|
||||
|
||||
|
||||
// emit nodes
|
||||
bool nodes_rc = true;
|
||||
if (nodes_) {
|
||||
NetNode*cur = nodes_->node_next_;
|
||||
do {
|
||||
nodes_rc = nodes_rc && cur->emit_node(tgt);
|
||||
rc = rc && cur->emit_node(tgt);
|
||||
cur = cur->node_next_;
|
||||
} while (cur != nodes_->node_next_);
|
||||
}
|
||||
|
||||
|
||||
bool branches_rc = true;
|
||||
for (NetBranch*cur = branches_ ; cur ; cur = cur->next_) {
|
||||
branches_rc = tgt->branch(cur) && branches_rc;
|
||||
}
|
||||
|
||||
// emit task and function definitions
|
||||
bool tasks_rc = true;
|
||||
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
||||
; scope != packages_.end() ; ++ scope )
|
||||
tasks_rc &= scope->second->emit_defs(tgt);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||
; scope != root_scopes_.end(); ++ scope )
|
||||
tasks_rc &= (*scope)->emit_defs(tgt);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->emit_defs(tgt);
|
||||
|
||||
|
||||
// emit the processes
|
||||
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 = rc && idx->emit(tgt);
|
||||
|
||||
if (nodes_rc == false)
|
||||
tgt->errors += 1;
|
||||
if (tasks_rc == false)
|
||||
tgt->errors += 1;
|
||||
if (proc_rc == false)
|
||||
tgt->errors += 1;
|
||||
if (branches_rc == false)
|
||||
tgt->errors += 1;
|
||||
|
||||
rc = tgt->end_design(this);
|
||||
|
||||
if (nodes_rc == false)
|
||||
return -1;
|
||||
if (tasks_rc == false)
|
||||
return -2;
|
||||
if (proc_rc == false)
|
||||
return -3;
|
||||
if (branches_rc == false)
|
||||
return -4;
|
||||
if (tgt->end_design(this) != 0)
|
||||
rc = false;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void NetEAccess::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_access_func(this);
|
||||
}
|
||||
|
||||
void NetEArrayPattern::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_array_pattern(this);
|
||||
}
|
||||
|
||||
void NetEBinary::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_binary(this);
|
||||
@@ -611,54 +418,15 @@ void NetEConst::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_const(this);
|
||||
}
|
||||
|
||||
void NetEConstEnum::expr_scan(struct expr_scan_t*tgt) const
|
||||
void NetEMemory::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_const(this);
|
||||
tgt->expr_memory(this);
|
||||
}
|
||||
|
||||
void NetEConstParam::expr_scan(struct expr_scan_t*tgt) const
|
||||
void NetEParam::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_param(this);
|
||||
}
|
||||
|
||||
void NetECReal::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_creal(this);
|
||||
}
|
||||
|
||||
void NetECRealParam::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_rparam(this);
|
||||
}
|
||||
|
||||
void NetEEvent::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_event(this);
|
||||
}
|
||||
|
||||
void NetELast::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_last(this);
|
||||
}
|
||||
|
||||
void NetENetenum::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_netenum(this);
|
||||
}
|
||||
|
||||
void NetENew::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_new(this);
|
||||
}
|
||||
|
||||
void NetENull::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_null(this);
|
||||
}
|
||||
|
||||
void NetEProperty::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_property(this);
|
||||
cerr << get_line() << ":internal error: unexpected NetEParam."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
void NetEScope::expr_scan(struct expr_scan_t*tgt) const
|
||||
@@ -676,21 +444,6 @@ void NetESFunc::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_sfunc(this);
|
||||
}
|
||||
|
||||
void NetEShallowCopy::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_scopy(this);
|
||||
}
|
||||
|
||||
void NetEShallowCopy::expr_scan_oper1(struct expr_scan_t*tgt) const
|
||||
{
|
||||
arg1_->expr_scan(tgt);
|
||||
}
|
||||
|
||||
void NetEShallowCopy::expr_scan_oper2(struct expr_scan_t*tgt) const
|
||||
{
|
||||
arg2_->expr_scan(tgt);
|
||||
}
|
||||
|
||||
void NetEUFunc::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_ufunc(this);
|
||||
@@ -701,6 +454,11 @@ void NetESignal::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_signal(this);
|
||||
}
|
||||
|
||||
void NetEBitSel::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_subsignal(this);
|
||||
}
|
||||
|
||||
void NetETernary::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_ternary(this);
|
||||
@@ -710,3 +468,125 @@ void NetEUnary::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_unary(this);
|
||||
}
|
||||
|
||||
bool 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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.65 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.64 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.63 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.62 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.61 2001/07/27 04:51:44 steve
|
||||
* Handle part select expressions as variants of
|
||||
* NetESignal/IVL_EX_SIGNAL objects, instead of
|
||||
* creating new and useless temporary signals.
|
||||
*
|
||||
* Revision 1.60 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.59 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.58 2001/04/06 02:28:02 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
*
|
||||
* Revision 1.57 2001/04/02 02:28:12 steve
|
||||
* Generate code for task calls.
|
||||
*
|
||||
* Revision 1.56 2001/03/27 03:31:06 steve
|
||||
* Support error code from target_t::end_design method.
|
||||
*
|
||||
* Revision 1.55 2000/11/04 01:54:01 steve
|
||||
* Modifications in support of gcc 2.96
|
||||
*
|
||||
* Revision 1.54 2000/09/26 01:35:42 steve
|
||||
* Remove the obsolete NetEIdent class.
|
||||
*
|
||||
* Revision 1.53 2000/09/17 21:26:15 steve
|
||||
* Add support for modulus (Eric Aardoom)
|
||||
*
|
||||
* Revision 1.52 2000/09/02 20:54:20 steve
|
||||
* Rearrange NetAssign to make NetAssign_ separate.
|
||||
*
|
||||
* Revision 1.51 2000/08/14 04:39:56 steve
|
||||
* add th t-dll functions for net_const, net_bufz and processes.
|
||||
*
|
||||
* Revision 1.50 2000/08/09 03:43:45 steve
|
||||
* Move all file manipulation out of target class.
|
||||
*
|
||||
* Revision 1.49 2000/08/08 01:50:42 steve
|
||||
* target methods need not take a file stream.
|
||||
*
|
||||
* Revision 1.48 2000/07/30 18:25:43 steve
|
||||
* Rearrange task and function elaboration so that the
|
||||
* NetTaskDef and NetFuncDef functions are created during
|
||||
* signal enaboration, and carry these objects in the
|
||||
* NetScope class instead of the extra, useless map in
|
||||
* the Design class.
|
||||
*
|
||||
* Revision 1.47 2000/07/29 16:21:08 steve
|
||||
* Report code generation errors through proc_delay.
|
||||
*
|
||||
* Revision 1.46 2000/07/27 05:13:44 steve
|
||||
* Support elaboration of disable statements.
|
||||
*
|
||||
* Revision 1.45 2000/05/11 23:37:27 steve
|
||||
* Add support for procedural continuous assignment.
|
||||
*
|
||||
* Revision 1.44 2000/05/04 03:37:58 steve
|
||||
* Add infrastructure for system functions, move
|
||||
* $time to that structure and add $random.
|
||||
*
|
||||
* Revision 1.43 2000/05/02 03:13:31 steve
|
||||
* Move memories to the NetScope object.
|
||||
*
|
||||
* Revision 1.42 2000/05/02 00:58:12 steve
|
||||
* Move signal tables to the NetScope class.
|
||||
*
|
||||
* Revision 1.41 2000/04/23 03:45:24 steve
|
||||
* Add support for the procedural release statement.
|
||||
*
|
||||
* Revision 1.40 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.39 2000/04/12 04:23:58 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
*
|
||||
* Handle named events within the mix of net events
|
||||
* and edges. As a unified lot they get caught together.
|
||||
* wait statements are broken into more complex statements
|
||||
* that include a conditional.
|
||||
*
|
||||
* Do not generate NetPEvent or NetNEvent objects in
|
||||
* elaboration. NetEvent, NetEvWait and NetEvProbe
|
||||
* take over those functions in the netlist.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,25 +14,26 @@
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval.cc,v 1.26 2001/12/29 22:10:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <cstring>
|
||||
# include <iostream>
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "compiler.h"
|
||||
|
||||
verinum* PExpr::eval_const(Design*, NetScope*) const
|
||||
verinum* PExpr::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
|
||||
verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*l = left_->eval_const(des, scope);
|
||||
if (l == 0) return 0;
|
||||
@@ -44,17 +45,11 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
|
||||
verinum*res;
|
||||
|
||||
switch (op_) {
|
||||
case 'p': {
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
res = new verinum(pow(*l, *r));
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '+': {
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
res = new verinum(*l + *r);
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv+rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
@@ -62,7 +57,9 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
|
||||
}
|
||||
case '-': {
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
res = new verinum(*l - *r);
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv-rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
@@ -70,7 +67,9 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
|
||||
}
|
||||
case '*': {
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
res = new verinum(*l * *r);
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv * rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
@@ -96,26 +95,6 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '>': {
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv > rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '<': {
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv < rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'l': { // left shift (<<)
|
||||
assert(r->is_defined());
|
||||
unsigned long rv = r->as_ulong();
|
||||
@@ -149,89 +128,45 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
|
||||
delete r;
|
||||
return res;
|
||||
}
|
||||
verinum* PEConcat::eval_const(Design*des, NetScope*scope) const
|
||||
{
|
||||
verinum*accum = parms_[0]->eval_const(des, scope);
|
||||
if (accum == 0)
|
||||
return 0;
|
||||
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
|
||||
verinum*tmp = parms_[idx]->eval_const(des, scope);
|
||||
if (tmp == 0) {
|
||||
delete accum;
|
||||
return 0;
|
||||
}
|
||||
assert(tmp);
|
||||
|
||||
*accum = concat(*accum, *tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return accum;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Evaluate an identifier as a constant expression. This is only
|
||||
* possible if the identifier is that of a parameter.
|
||||
*/
|
||||
verinum* PEIdent::eval_const(Design*des, NetScope*scope) const
|
||||
verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
assert(scope);
|
||||
NetNet*net;
|
||||
NetEvent*eve;
|
||||
const NetExpr*expr;
|
||||
|
||||
const name_component_t&name_tail = path_.back();
|
||||
|
||||
// Handle the special case that this ident is a genvar
|
||||
// variable name. In that case, the genvar meaning preempts
|
||||
// everything and we just return that value immediately.
|
||||
if (scope->genvar_tmp
|
||||
&& strcmp(name_tail.name,scope->genvar_tmp) == 0) {
|
||||
return new verinum(scope->genvar_tmp_val);
|
||||
}
|
||||
|
||||
symbol_search(this, des, scope, path_, net, expr, eve);
|
||||
const NetExpr*expr = des->find_parameter(scope, path_);
|
||||
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
||||
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
|
||||
if (eval == 0) {
|
||||
cerr << get_fileline() << ": internal error: Unable to evaluate "
|
||||
<< "constant expression (parameter=" << path_
|
||||
<< "): " << *expr << endl;
|
||||
assert(msb_ == 0);
|
||||
|
||||
if (dynamic_cast<const NetEParam*>(expr)) {
|
||||
cerr << get_line() << ": sorry: I cannot evaluate ``" <<
|
||||
path_ << "'' in this scope: " << scope->name() << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
|
||||
assert(eval);
|
||||
|
||||
if (!name_tail.index.empty())
|
||||
return 0;
|
||||
|
||||
|
||||
return new verinum(eval->value());
|
||||
}
|
||||
|
||||
verinum* PEFNumber::eval_const(Design*, NetScope*) const
|
||||
verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
long val = value_->as_long();
|
||||
return new verinum(val);
|
||||
}
|
||||
|
||||
verinum* PENumber::eval_const(Design*, NetScope*) const
|
||||
verinum* PENumber::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
return new verinum(value());
|
||||
}
|
||||
|
||||
verinum* PEString::eval_const(Design*, NetScope*) const
|
||||
{
|
||||
return new verinum(string(text_));
|
||||
}
|
||||
|
||||
verinum* PETernary::eval_const(Design*des, NetScope*scope) const
|
||||
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*test = expr_->eval_const(des, scope);
|
||||
if (test == 0)
|
||||
@@ -251,7 +186,7 @@ verinum* PETernary::eval_const(Design*des, NetScope*scope) const
|
||||
}
|
||||
}
|
||||
|
||||
verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
|
||||
verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*val = expr_->eval_const(des, scope);
|
||||
if (val == 0)
|
||||
@@ -265,11 +200,11 @@ verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
|
||||
/* We need to expand the value a bit if we are
|
||||
taking the 2's complement so that we are
|
||||
guaranteed to not overflow. */
|
||||
verinum tmp ((uint64_t)0, val->len()+1);
|
||||
verinum tmp (0UL, val->len()+1);
|
||||
for (unsigned idx = 0 ; idx < val->len() ; idx += 1)
|
||||
tmp.set(idx, val->get(idx));
|
||||
|
||||
*val = -tmp;
|
||||
*val = v_not(tmp) + verinum(verinum::V1, 1);
|
||||
val->has_sign(true);
|
||||
return val;
|
||||
}
|
||||
@@ -278,3 +213,49 @@ verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
|
||||
delete val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: eval.cc,v $
|
||||
* Revision 1.26 2001/12/29 22:10:10 steve
|
||||
* constant eval of arithmetic with x and z.
|
||||
*
|
||||
* Revision 1.25 2001/12/29 00:43:55 steve
|
||||
* Evaluate constant right shifts.
|
||||
*
|
||||
* Revision 1.24 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.23 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.22 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* Revision 1.21 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.20 2001/02/09 02:49:59 steve
|
||||
* Be more clear about scope of failure.
|
||||
*
|
||||
* Revision 1.19 2001/01/27 05:41:48 steve
|
||||
* Fix sign extension of evaluated constants. (PR#91)
|
||||
*
|
||||
* Revision 1.18 2001/01/14 23:04:56 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
* Revision 1.17 2001/01/04 04:47:51 steve
|
||||
* Add support for << is signal indices.
|
||||
*
|
||||
* Revision 1.16 2000/12/10 22:01:36 steve
|
||||
* Support decimal constants in behavioral delays.
|
||||
*
|
||||
* Revision 1.15 2000/09/07 22:38:13 steve
|
||||
* Support unary + and - in constants.
|
||||
*/
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user