mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-23 14:27:01 +02:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afa2478801 | ||
|
|
79feb44f10 | ||
|
|
c03d76a0d7 | ||
|
|
d0f303463d | ||
|
|
35fe8fae00 | ||
|
|
2e95a740da | ||
|
|
2f4e5bf5b6 |
+27
@@ -0,0 +1,27 @@
|
||||
lexor_keyword.cc
|
||||
parse.h
|
||||
parse.cc
|
||||
parse.cc.output
|
||||
parse.output
|
||||
syn-rules.cc
|
||||
syn-rules.cc.output
|
||||
syn-rules.output
|
||||
lexor.cc
|
||||
iverilog-vpi
|
||||
iverilog-vpi.pdf
|
||||
iverilog-vpi.ps
|
||||
ivl
|
||||
ivl.exp
|
||||
dep
|
||||
configure
|
||||
Makefile
|
||||
check
|
||||
check.cc
|
||||
check.vvp
|
||||
config.status
|
||||
config.log
|
||||
config.cache
|
||||
autom4te.cache
|
||||
config.h
|
||||
_pli_types.h
|
||||
dosify
|
||||
@@ -1,2 +0,0 @@
|
||||
# gperf in MSYS chokes on DOS line endings
|
||||
*.gperf text eol=lf
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
echo "Using the bundled ivtest to run regression tests."
|
||||
echo " pwd = $(pwd)"
|
||||
|
||||
cd ivtest
|
||||
|
||||
status=0
|
||||
|
||||
perl vvp_reg.pl || status=1
|
||||
|
||||
perl vpi_reg.pl || status=1
|
||||
|
||||
exit $status
|
||||
@@ -1,36 +0,0 @@
|
||||
|
||||
name: Deploy documentation
|
||||
|
||||
on:
|
||||
# Every push onto the main branch regerenates the documentation
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
|
||||
do-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
name: 'Build documentation on Linux'
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt update -qq
|
||||
sudo apt install -y make autoconf python3-sphinx
|
||||
|
||||
- name: Make Documentation
|
||||
run: |
|
||||
cd Documentation
|
||||
make html
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: crazy-max/ghaction-github-pages@v2
|
||||
with:
|
||||
target_branch: gh-pages
|
||||
build_dir: Documentation/_build/html
|
||||
jekyll: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,119 +0,0 @@
|
||||
name: test
|
||||
|
||||
on:
|
||||
# Every push onto the main branch and releases triggers a retest.
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- v12-branch
|
||||
# All pull_requests trigger a retest.
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
|
||||
mac:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
runs-on: macos-latest
|
||||
name: '🍏 macOS'
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install bison
|
||||
|
||||
- name: Build, check and install
|
||||
run: |
|
||||
export PATH="/usr/local/opt/bison/bin:$PATH"
|
||||
autoconf
|
||||
./configure
|
||||
make check
|
||||
sudo make install
|
||||
|
||||
- name: Test
|
||||
run: ./.github/test.sh
|
||||
|
||||
|
||||
lin:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [
|
||||
'20.04',
|
||||
'22.04'
|
||||
]
|
||||
runs-on: ubuntu-${{ matrix.os }}
|
||||
name: '🐧 Ubuntu ${{ matrix.os }}'
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt update -qq
|
||||
sudo apt install -y make g++ git bison flex gperf libreadline-dev autoconf python3-sphinx
|
||||
|
||||
- name: Build, check and install
|
||||
run: |
|
||||
autoconf
|
||||
./configure
|
||||
make check
|
||||
sudo make install
|
||||
|
||||
- name: Test
|
||||
run: ./.github/test.sh
|
||||
|
||||
- name: Documentation
|
||||
run: |
|
||||
cd Documentation
|
||||
make html
|
||||
|
||||
win:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include: [
|
||||
{ msystem: MINGW64, arch: x86_64 },
|
||||
{ msystem: MINGW32, arch: i686 }
|
||||
]
|
||||
name: 🟪 ${{ matrix.msystem}} · ${{ matrix.arch }}
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
env:
|
||||
MINGW_ARCH: ${{ matrix.msystem }}
|
||||
steps:
|
||||
|
||||
- run: git config --global core.autocrlf input
|
||||
shell: bash
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
update: true
|
||||
install: >
|
||||
git
|
||||
base-devel
|
||||
gperf
|
||||
mingw-w64-${{ matrix.arch }}-toolchain
|
||||
|
||||
- name: Build and check
|
||||
run: |
|
||||
cd msys2
|
||||
makepkg-mingw --noconfirm --noprogressbar -sCLf
|
||||
|
||||
- name: Install
|
||||
run: pacman -U --noconfirm msys2/*.zst
|
||||
|
||||
- name: Test
|
||||
run: ./.github/test.sh
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.msystem }}-${{ matrix.arch }}
|
||||
path: msys2/*.zst
|
||||
-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,37 +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 "config.h"
|
||||
|
||||
# include "AStatement.h"
|
||||
|
||||
AContrib::AContrib(PExpr*lv, PExpr*rv)
|
||||
: lval_(lv), rval_(rv)
|
||||
{
|
||||
}
|
||||
|
||||
AContrib::~AContrib()
|
||||
{
|
||||
delete lval_;
|
||||
delete rval_;
|
||||
}
|
||||
|
||||
AProcess::~AProcess()
|
||||
{
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
#ifndef IVL_AStatement_H
|
||||
#define IVL_AStatement_H
|
||||
/*
|
||||
* Copyright (c) 2008-2021 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(std::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_; }
|
||||
|
||||
std::map<perm_string,PExpr*> attributes;
|
||||
|
||||
// Dump the analog process
|
||||
void dump(std::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
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.cc,v 1.6 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Attrib.h"
|
||||
# include <cassert>
|
||||
# include <assert.h>
|
||||
|
||||
Attrib::Attrib()
|
||||
{
|
||||
@@ -99,3 +102,37 @@ const verinum& Attrib::attr_value(unsigned idx) const
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].val;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: Attrib.cc,v $
|
||||
* Revision 1.6 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.5 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.4 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.3 2002/05/23 03:08:50 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/12/04 17:37:03 steve
|
||||
* Add Attrib class for holding NetObj attributes.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_Attrib_H
|
||||
#define IVL_Attrib_H
|
||||
#ifndef __Attrib_H
|
||||
#define __Attrib_H
|
||||
/*
|
||||
* Copyright (c) 2000-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,8 +16,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.h,v 1.5 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "StringHeap.h"
|
||||
# include "verinum.h"
|
||||
@@ -30,7 +33,7 @@ class Attrib {
|
||||
|
||||
public:
|
||||
Attrib();
|
||||
virtual ~Attrib();
|
||||
~Attrib();
|
||||
|
||||
const verinum&attribute(perm_string key) const;
|
||||
void attribute(perm_string key, const verinum&value);
|
||||
@@ -57,4 +60,31 @@ class Attrib {
|
||||
Attrib& operator= (const Attrib&);
|
||||
};
|
||||
|
||||
#endif /* IVL_Attrib_H */
|
||||
/*
|
||||
* $Log: Attrib.h,v $
|
||||
* Revision 1.5 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.2 2002/05/23 03:08:50 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.1 2000/12/04 17:37:03 steve
|
||||
* Add Attrib class for holding NetObj attributes.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -4,24 +4,23 @@ HOW TO REPORT BUGS
|
||||
Before I can fix an error, I need to understand what the problem
|
||||
is. Try to explain what is wrong and why you think it is wrong. Please
|
||||
try to include sample code that demonstrates the problem. Include a
|
||||
description of what Icarus Verilog does that is wrong, and what you
|
||||
expect should happen. And include the command line flags passed to the
|
||||
compiler to make the error happen. (This is often overlooked, and
|
||||
sometimes important.)
|
||||
description of what ivl does that is wrong, and what you expect should
|
||||
happen. And include the command line flags passed to the compiler to make
|
||||
the error happen. (This is often overlooked, and sometimes important.)
|
||||
|
||||
* The Compiler Doesn't Compile
|
||||
|
||||
If Icarus Verilog doesn't compile, I need to know about the
|
||||
If the Icarus Verilog don't compile, I need to know about the
|
||||
compilation tools you are using. Specifically, I need to know:
|
||||
|
||||
- Operating system and processor type,
|
||||
- Compiler w/ version,
|
||||
- Versions of any libraries being linked, and
|
||||
- Library version, and
|
||||
- anything else you think relevant.
|
||||
|
||||
Be aware that I do not have at my disposal a porting lab. I have the
|
||||
workstation on my desk, a Mac laptop, and the Linux/Intel box with a
|
||||
logic analyzer and 'scope hanging off it.
|
||||
alpha on my desk, and the Linux/Intel box with a logic analyzer and
|
||||
'scope hanging off it.
|
||||
|
||||
* The Compiler Crashes
|
||||
|
||||
@@ -29,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,
|
||||
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
|
||||
|
||||
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,13 +91,13 @@ demonstrates the problem. If the error occurs after elaboration,
|
||||
please include a top level module in the program that is suitable for
|
||||
the target format. If I have to write the module myself, I might not
|
||||
write it in a way that tickles the bug. So please, send all the
|
||||
Verilog source that I need to invoke the error.
|
||||
Verilog source (after preprocessing) that I need to invoke the error.
|
||||
|
||||
Also, include the command line you use to invoke the compiler. For
|
||||
example:
|
||||
|
||||
iverilog -o foo.out -tvvp foo.v
|
||||
iverilog foo.vl -s starthere
|
||||
ivl foo.vl -o foo.cc -tvvm
|
||||
ivl foo.vl -s starthere
|
||||
|
||||
If the error occurs with the null target (``-tnull'') then a top level
|
||||
module may not be needed as long as the ``-s <name>'' switch is
|
||||
@@ -110,23 +108,15 @@ invoke the error without any Verilog other than what is included?" And
|
||||
while we are at it, please place a copyright notice in your test
|
||||
program and include a GPL license statement if you can. Your test
|
||||
program may find its way into the test suite, and the notices will
|
||||
make it all nice and legal. Please look at the existing tests in the
|
||||
test suite <http://sourceforge.net/ivtest> for examples of good test
|
||||
programs.
|
||||
make it all nice and legal.
|
||||
|
||||
RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS
|
||||
|
||||
The URL <https://sourceforge.net/p/iverilog/bugs/> is the main
|
||||
bug tracking system, although some users have reported bugs at
|
||||
<https://github.com/steveicarus/iverilog/issues/>. 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.
|
||||
|
||||
system (although you will also find bug rep
|
||||
|
||||
The URL <http://www.icarus.com/cgi-bin/ivl-bugs> is the main bug
|
||||
tracking system. Once you believe you have found a bug, you may browse
|
||||
the bugs database for existing bugs that may be related to yours. You
|
||||
might find that your bug has already been fixed in a later release or
|
||||
snapshot. If that's the case, then you are set.
|
||||
|
||||
The bug database supports basic keyword searches, and you can
|
||||
optionally limit your search to active bugs, or fixed bugs. You may
|
||||
@@ -135,7 +125,8 @@ broken. You may for example find a related bug that explains your
|
||||
symptom.
|
||||
|
||||
The root page of the bug report database describes how to submit your
|
||||
completed bug report.
|
||||
completed bug report. You may submit it via the web form, or via
|
||||
e-mail.
|
||||
|
||||
HOW TO SEND PATCHES
|
||||
|
||||
@@ -143,26 +134,21 @@ Bug reports with patches are very welcome, especially if they are
|
||||
formatted such that I can inspect them, decide that they are obviously
|
||||
correct, and apply them without worry.
|
||||
|
||||
I prefer patches generated by the git source code tracking system. If
|
||||
you are editing the source, you really should be using the latest
|
||||
version from git. Please see the developer documentation for more
|
||||
detailed instructions -- <http://iverilog.wikia.com/wiki/>.
|
||||
I prefer context diffs as emitted by diff from GNU diffutils. Human
|
||||
beings can read such things, and they are resilient to changing
|
||||
originals. A good set of flags to diff are ``diff -cNB''. With such
|
||||
diffs, I can look at the changes you are offering and probably tell at
|
||||
a glance that they are plausible. Then I can use patch(1) to apply
|
||||
them. Or I can apply them by hand.
|
||||
|
||||
When you make a patch, submit it to the "Patches" tracker at
|
||||
<https://sourceforge.net/p/iverilog/patches/>. 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-2018 Stephen Williams except
|
||||
Icarus Verilog is Copyright (c) 1998-2003 Stephen Williams except
|
||||
where otherwise noted. Minor patches are covered as derivative works
|
||||
(or editorial comment or whatever the appropriate legal term is) and
|
||||
folded into the rest of ivl. However, if a submission can reasonably
|
||||
@@ -172,3 +158,19 @@ then falls under the "otherwise noted" category.
|
||||
|
||||
I must insist that any copyright material submitted for inclusion
|
||||
include the GPL license notice as shown in the rest of the source.
|
||||
|
||||
|
||||
$Id: BUGS.txt,v 1.5 2007/03/22 16:08:14 steve Exp $
|
||||
$Log: BUGS.txt,v $
|
||||
Revision 1.5 2007/03/22 16:08:14 steve
|
||||
Spelling fixes from Larry
|
||||
|
||||
Revision 1.4 2003/02/19 04:36:31 steve
|
||||
Notes on hte bug database.
|
||||
|
||||
Revision 1.3 2003/01/30 16:23:07 steve
|
||||
Spelling fixes.
|
||||
|
||||
Revision 1.2 1999/08/06 04:05:28 steve
|
||||
Handle scope of parameters.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
_build/
|
||||
!Makefile
|
||||
@@ -1,20 +0,0 @@
|
||||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
SPHINXPROJ = IcarusVerilog
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
@@ -1,155 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file does only contain a selection of the most common options. For a
|
||||
# full list see the documentation:
|
||||
# http://www.sphinx-doc.org/en/master/config
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'Icarus Verilog'
|
||||
copyright = '2022, Stephen Williams'
|
||||
author = 'Stephen Williams'
|
||||
|
||||
# The short X.Y version
|
||||
version = ''
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = ''
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
#
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path .
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'alabaster'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
#
|
||||
# The default sidebars (for documents that don't match any pattern) are
|
||||
# defined by theme itself. Builtin themes are using these templates by
|
||||
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
|
||||
# 'searchbox.html']``.
|
||||
#
|
||||
# html_sidebars = {}
|
||||
|
||||
|
||||
# -- Options for HTMLHelp output ---------------------------------------------
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'IcarusVerilogdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ------------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'IcarusVerilog.tex', 'Icarus Verilog Documentation',
|
||||
'Stephen Williams', 'manual'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for manual page output ------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'icarusverilog', 'Icarus Verilog Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Texinfo output ----------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'IcarusVerilog', 'Icarus Verilog Documentation',
|
||||
author, 'IcarusVerilog', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
@@ -1,225 +0,0 @@
|
||||
|
||||
Getting Started as a Contributer
|
||||
================================
|
||||
|
||||
Icarus Verilog development is centered around the github repository at
|
||||
`github.com/steveicarus/iverilog <http://github.com/steveicarus/iverilog>`_.
|
||||
Contributing to Icarus Verilog requires a basic knowledge of git and github,
|
||||
so see the github documentation for more information. The sections below will
|
||||
step you through the basics of getting the source code from github, making a
|
||||
branch, and submitting a pull request for review.
|
||||
|
||||
Getting Icarus Verilog
|
||||
----------------------
|
||||
|
||||
To start, you will need to clone the code. It is preferred that you use the
|
||||
"ssh" method, and the ssh based clone with the command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% git clone [email protected]:steveicarus/iverilog.git
|
||||
|
||||
This assumes that you have a github account (accounts are free) and you have
|
||||
set up your ssh authentication keys. See the
|
||||
`Authentication Guides here <https://docs.github.com/en/authentication>`_.
|
||||
|
||||
The "git clone" command will get you all the source:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% git clone [email protected]:steveicarus/iverilog.git
|
||||
Cloning into 'iverilog'...
|
||||
remote: Enumerating objects: 66234, done.
|
||||
remote: Counting objects: 100% (6472/6472), done.
|
||||
remote: Compressing objects: 100% (4123/4123), done.
|
||||
remote: Total 66234 (delta 2412), reused 6039 (delta 2190), pack-reused 59762
|
||||
Receiving objects: 100% (66234/66234), 27.98 MiB | 2.53 MiB/s, done.
|
||||
Resolving deltas: 100% (50234/50234), done.
|
||||
% cd iverilog/
|
||||
|
||||
Normally, this is enough as you are now pointing at the most current
|
||||
development code, and you have implicitly created a branch "master" that
|
||||
tracks the development head. However, If you want to actually be working on a
|
||||
specific version, say for example version 11, the v11-branch, you checkout
|
||||
that branch with the command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% git checkout --track -b v11-branch origin/v11-branch
|
||||
|
||||
This creates a local branch that tracks the v11-branch in the repository, and
|
||||
switches you over to your new v11-branch. The tracking is important as it
|
||||
causes pulls from the repository to re-merge your local branch with the remote
|
||||
v11-branch. You always work on a local branch, then merge only when you
|
||||
push/pull from the remote repository.
|
||||
|
||||
Now that you've cloned the repository and optionally selected the branch you
|
||||
want to work on, your local source tree may later be synced up with the
|
||||
development source by using the git command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% git pull
|
||||
Already up to date.
|
||||
|
||||
Finally, configuration files are built by the extra step:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% sh autoconf.sh
|
||||
Autoconf in root...
|
||||
Precompiling lexor_keyword.gperf
|
||||
Precompiling vhdlpp/lexor_keyword.gperf
|
||||
|
||||
You will need autoconf and gperf installed in order for the script to work.
|
||||
If you get errors such as:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% sh autoconf.sh
|
||||
Autoconf in root...
|
||||
autoconf.sh: 10: autoconf: not found
|
||||
Precompiling lexor_keyword.gperf
|
||||
autoconf.sh: 13: gperf: not found.
|
||||
|
||||
You will need to install download and install the autoconf and gperf tools.
|
||||
|
||||
Now you are ready to configure and compile the source.
|
||||
|
||||
Icarus Specific Configuration Options
|
||||
-------------------------------------
|
||||
|
||||
Icarus takes many of the standard configuration options and those will not be
|
||||
described here. The following are specific to Icarus Verilog:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
--enable-suffix[=suffix]
|
||||
|
||||
This option allows the user to build Icarus with a default suffix or when
|
||||
provided a user defined suffix. All programs or directories are tagged with
|
||||
this suffix. e.g.(iverilog-0.8, vvp-0.8, etc.). The output of iverilog will
|
||||
reference the correct run time files and directories. The run time will check
|
||||
that it is running a file with a compatible version e.g.(you can not run a
|
||||
V0.9 file with the V0.8 run time).
|
||||
|
||||
A debug options is:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
--with-valgrind
|
||||
|
||||
This option adds extra memory cleanup code and pool management code to allow
|
||||
better memory leak checking when valgrind is available. This option is not
|
||||
need when checking for basic errors with valgrind.
|
||||
|
||||
Compiling on Linux
|
||||
------------------
|
||||
|
||||
(Note: You will need to install bison, flex, g++ and gcc) This is probably the
|
||||
easiest step. Given that you have the source tree from the above instructions,
|
||||
the compile and install is generally as simple as:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% ./configure
|
||||
configure: loading site script /usr/share/site/x86_64-unknown-linux-gnu
|
||||
checking build system type... x86_64-unknown-linux-gnu
|
||||
checking host system type... x86_64-unknown-linux-gnu
|
||||
checking for gcc... gcc
|
||||
checking whether the C compiler works... yes
|
||||
checking for C compiler default output file name... a.out
|
||||
checking for suffix of executables...
|
||||
[...and so on...]
|
||||
|
||||
% make
|
||||
mkdir dep
|
||||
Using git-describe for VERSION_TAG
|
||||
g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c main.cc -o main.o
|
||||
mv main.d dep/main.d
|
||||
g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c async.cc -o async.o
|
||||
mv async.d dep/async.d
|
||||
g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c design_dump.cc -o design_dump.o
|
||||
mv design_dump.d dep/design_dump.d
|
||||
g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c discipline.cc -o discipline.o
|
||||
[...and so on...]
|
||||
|
||||
The end result is a complete build of Icarus Verilog. You can install your
|
||||
compiled version with a command like this:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% sudo make install
|
||||
|
||||
Regression Tests
|
||||
----------------
|
||||
|
||||
Icarus Verilog comes with a fairly extensive regression test suite. As of
|
||||
2022, that test suite is included with the source in the "ivtest"
|
||||
directory. Contained in that directory are a couple driver scripts that run
|
||||
all the regression tests on the installed version of Icarus Verilog. So for
|
||||
example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% cd ivtest
|
||||
% ./vvp_reg.pl --strict
|
||||
|
||||
will run all the regression tests for the simulation engine. (This is what
|
||||
most people will want to do.) You should rerun this test before submitting
|
||||
patches to the developers. Also, if you are adding a new feature, you should
|
||||
add test programs to the regression test suite to validate your new feature
|
||||
(or bug fix.)
|
||||
|
||||
Note that pull requests will be required to pass these regression tests before
|
||||
being merged.
|
||||
|
||||
Forks, Branches and Pull Requests
|
||||
---------------------------------
|
||||
|
||||
Currently, the preferred way to submit patches to Icarus Verilog is via pull
|
||||
requests.
|
||||
`Pull requests <https://docs.github.com/en/github-ae@latest/pull-requests>`_
|
||||
can be created from the main repository if you have write access (very few
|
||||
people have write access) or more commonly from a fork, so the first step is
|
||||
to create a fork that you can work with. It is easy enough to create a fork,
|
||||
just go to the
|
||||
`github.com/steveicarus/iverilog <http://github.com/steveicarus/iverilog>`_
|
||||
page and use the "fork" button in the upper right corner. This will create
|
||||
a new repository that you can clone instead of the steveicarus/iverilog
|
||||
repository. You then use your local repository to create feature branches,
|
||||
then submit them for inclusion in the main repository as pull
|
||||
requests. Remember to `synchronize your fork
|
||||
<https://docs.github.com/en/github-ae@latest/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork>`_
|
||||
periodically with the main repository. This will make sure your work is based
|
||||
on the latest upstream and avoid merge conflicts.
|
||||
|
||||
Create your patch by first creating a branch that contains your commits:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% git checkout -b my-github-id/branch-name
|
||||
|
||||
We are encouraging using this scheme for naming your branches that are
|
||||
destined for pull requests. Use your github id in the branch name. So for
|
||||
example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% git checkout -b steveicarus/foo-feature
|
||||
|
||||
Do your work in this branch, then when you are ready to create a pull request,
|
||||
first push the branch up to github:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% git push -u origin my-github-id/branch-name
|
||||
|
||||
Then go to github.com to create your pull request. `Create your pull request
|
||||
against the "master" branch of the upstream repository
|
||||
<https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork>`_,
|
||||
or the version branch that you are working on. Your pull reuqest will be run
|
||||
through continuous integration, and reviewed by one of the main
|
||||
authors. Feedback may be offered to your PR, and once accepted, an approved
|
||||
individual will merge it for you. Then you are done.
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
Icarus Verilog Developer Support
|
||||
================================
|
||||
|
||||
This section contains documents to help support developers who contribute to
|
||||
Icarus Verilog.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
getting_started
|
||||
version_stamps
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
|
||||
Files With Version Information
|
||||
==============================
|
||||
|
||||
These are the only files that have version information in them:
|
||||
|
||||
* version_base.h -- This should be the 1 source for version info.
|
||||
* version_tag.h -- Generated automatically with git tag information.
|
||||
* verilog.spec -- Used to stamp RPM packages
|
||||
|
||||
When versions are changed, the above files need to be edited to account for
|
||||
the new version information. The following used to have verion information in
|
||||
them, but now their version information is generated:
|
||||
|
||||
Replaced with version_base.h, which is edited manually, and
|
||||
version_tag.h which is generated from git tag information.
|
||||
|
||||
* version-base.in -- Most compiled code gets version from here
|
||||
|
||||
These are now edited by the makefile and the version.exe program.
|
||||
|
||||
* iverilog-vpi.man -- The .TH tag has a version string
|
||||
* driver/iverilog.man -- The .TH tag has a version string
|
||||
* driver-vpi/res.rc -- Used to build Windows version stamp
|
||||
* vvp/vvp.man -- The .TH tag has a version string
|
||||
|
||||
This now includes version_base.h to get the version
|
||||
|
||||
* vpi/vams_simparam.c -- Hard coded result to simulatorVersion query
|
||||
@@ -1,25 +0,0 @@
|
||||
.. Icarus Verilog documentation master file, created by
|
||||
sphinx-quickstart on Sun Apr 10 16:28:38 2022.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Icarus Verilog
|
||||
==============
|
||||
|
||||
Welcome to the documentation for Icarus Verilog.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
usage/index
|
||||
targets/index
|
||||
developer/index
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
@@ -1,36 +0,0 @@
|
||||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=.
|
||||
set BUILDDIR=_build
|
||||
set SPHINXPROJ=IcarusVerilog
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
|
||||
|
||||
:end
|
||||
popd
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
The Icarus Verilog Targets
|
||||
==========================
|
||||
|
||||
Icarus Verilog elaborates the design, then sends to the design to code
|
||||
generates (targets) for processing. new code generators can be added by
|
||||
external packages, but these are the code generators that are bundled with
|
||||
Icarus Verilog. The code generator is selected by the "-t" command line flag.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
vvp
|
||||
stub
|
||||
null
|
||||
vhdl
|
||||
verilog95
|
||||
pcb
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
The null Code Generator (-tnull)
|
||||
================================
|
||||
|
||||
The null target generates no code. Invoking this code generator causes no code
|
||||
generation to happen.
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
|
||||
Using the PCB code generator
|
||||
============================
|
||||
|
||||
The PCB target code generator is designed to allow a user to enter a netlist
|
||||
in Verilog format, then generate input files for the GNU PCB layout program.
|
||||
|
||||
Invocation
|
||||
----------
|
||||
|
||||
The PCB target code generation is invoked with the -tpcb flag to the iverilog
|
||||
command. The default output file, "a.out", contains the generated .PCB
|
||||
file. Use the "-o" flag to set the output file name explicitly. The default
|
||||
output file contains only the elements. To generate a "netlist" file, add the
|
||||
flag "-pnetlist=<path>" command line flag.
|
||||
|
||||
Altogether, this example generates the foo.net and foo.pcb files from the
|
||||
foo.v source file::
|
||||
|
||||
% iverilog -tpcb -ofoo.pcb -pnetlist=foo.net foo.v
|
||||
|
||||
Flags
|
||||
-----
|
||||
|
||||
* -o <path>
|
||||
|
||||
Set the output (pcb) file path
|
||||
|
||||
* -pnetlist=path
|
||||
|
||||
Write a netlist file to the given path.
|
||||
|
||||
Attributes Summary
|
||||
------------------
|
||||
|
||||
Attributes are attached to various constructs using the Verilog "(\* \*)"
|
||||
attribute syntax.
|
||||
|
||||
* ivl_black_box
|
||||
|
||||
Attached to a module declaration or module instantiation, this indicates
|
||||
that the module is a black box. The code generator will create an element
|
||||
for black box instances.
|
||||
|
||||
Parameters Summary
|
||||
------------------
|
||||
|
||||
Within modules, The PCB code generator uses certain parameters to control
|
||||
details. Parameters may have defaults, and can be overridden using the usual
|
||||
Verilog parameter override syntax. Parameters have preferred types.
|
||||
|
||||
* description (string, default="")
|
||||
|
||||
The "description" is a text string that describes the black box. This string
|
||||
is written into the description field of the PCB Element.
|
||||
|
||||
* value (string, default="")
|
||||
|
||||
The "value" is a text tring that describes some value for the black
|
||||
box. Like the description, the code generator does not interpret this value,
|
||||
other then to write it to the appropriate field in the PCB Element."
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
The stub Code Generator (-tstub)
|
||||
================================
|
||||
|
||||
The stub code generator is a debugging aid for the Icarus Verilog compiler
|
||||
itself. It outputs a text dump of the elaborated design as it is passed to
|
||||
code generators.
|
||||
@@ -1,101 +0,0 @@
|
||||
|
||||
Using The Verilog '95 Code Generator
|
||||
====================================
|
||||
|
||||
Icarus Verilog contains a code generator to emit 1995 compliant Verilog from
|
||||
the input Verilog netlist. This allows Icarus Verilog to function as a Verilog
|
||||
> 1995 to Verilog 1995 translator. The main goal of the project was to convert
|
||||
@*, ANSI style arguments and other constructs to something allowed in 1995
|
||||
Verilog.
|
||||
|
||||
Invocation
|
||||
----------
|
||||
|
||||
To translate a Verilog program to 1995 compliant Verilog, invoke "iverilog"
|
||||
with the -tvlog95 flag::
|
||||
|
||||
% iverilog -tvlog95 -o my_design_95.v my_design.v
|
||||
|
||||
The generated Verilog will be placed in a single file (a.out by default), even
|
||||
if the input Verilog is spread over multiple files.
|
||||
|
||||
Generator Flags
|
||||
---------------
|
||||
|
||||
* -pspacing=N
|
||||
|
||||
Set the indent spacing (the default is 2).
|
||||
|
||||
* -pallowsigned=1
|
||||
|
||||
Allow emitting the various signed constructs as an extension to 1995 Verilog
|
||||
(off by default).
|
||||
|
||||
* -pfileline=1
|
||||
|
||||
Emit the original file and line information as a comment for each generated
|
||||
line (off by default).
|
||||
|
||||
Structures that cannot be converted to 1995 compatible Verilog
|
||||
--------------------------------------------------------------
|
||||
|
||||
The following Verilog constructs are not translatable to 1995 compatible Verilog:
|
||||
|
||||
* Automatic tasks or functions.
|
||||
|
||||
* The power operator (**). Expressions of the form (2**N)**<variable> (where N
|
||||
is a constant) can be converter to a shift.
|
||||
|
||||
* Some System Verilog constructs (e.g. final blocks, ++/-- operators,
|
||||
etc.). 2-state variables are converted to 4-state variables.
|
||||
|
||||
Icarus extensions that cannot be translated:
|
||||
|
||||
* Integer constants greater than 32 bits.
|
||||
|
||||
* Real valued nets.
|
||||
|
||||
* Real modulus.
|
||||
|
||||
* Most Verilog-A constructs.
|
||||
|
||||
|
||||
Known Issues and Limitations
|
||||
----------------------------
|
||||
|
||||
Some things are just not finished and should generate an appropriate
|
||||
warning. Here is a list of the major things that still need to be looked at.
|
||||
|
||||
* There are still a few module instantiation port issues (pr1723367 and
|
||||
partselsynth).
|
||||
|
||||
* inout ports are not converted (tran-VP).
|
||||
|
||||
* Variable selects of a non-zero based vector in a continuous assignment are
|
||||
not converted.
|
||||
|
||||
* There is no support for translating a zero repeat in a continuous
|
||||
assignment. It is currently just dropped.
|
||||
|
||||
* A pull device connected to a signal select is not translated correctly (this
|
||||
may be fixed).
|
||||
|
||||
* L-value indexed part selects with a constant undefined base in a continuous
|
||||
assignment are not translated.
|
||||
|
||||
* Logic gates are not arrayed exactly the same as the input and the instance
|
||||
name is not always the same.
|
||||
|
||||
* The signed support does not generate $signed() or $unsigned() function calls
|
||||
in a continuous assignment expression.
|
||||
|
||||
* The special power operator cases are not converted in a continuous
|
||||
assignment.
|
||||
|
||||
* Currently a signed constant that sets the MSB in an unsigned context will be
|
||||
displayed as a negative value (e.g. bit = 1 translates to bit = -1).
|
||||
|
||||
* Can net arrays, etc. be unrolled?
|
||||
|
||||
* Can generate blocks be converted?
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
|
||||
The VHDL Code Generator (-tvhdl)
|
||||
================================
|
||||
|
||||
Icarus Verilog contains a code generator to emit VHDL from the Verilog
|
||||
netlist. This allows Icarus Verilog to function as a Verilog to VHDL
|
||||
translator.
|
||||
|
||||
Invocation
|
||||
----------
|
||||
|
||||
To translate a Verilog program to VHDL, invoke "iverilog" with the -tvhdl
|
||||
flag::
|
||||
|
||||
% iverilog -t vhdl -o my_design.vhd my_design.v
|
||||
|
||||
The generated VHDL will be placed in a single file (a.out by default), even if
|
||||
the Verilog is spread over multiple files.
|
||||
|
||||
Flags
|
||||
-----
|
||||
|
||||
* -pdebug=1
|
||||
|
||||
Print progress messages as the code generator visits each part of the
|
||||
design.
|
||||
|
||||
* -pdepth=N
|
||||
|
||||
Only output VHDL entities for modules found at depth < N in the
|
||||
hierarchy. N=0, the default, outputs all entities. For example, -pdepth=1
|
||||
outputs only the top-level entity.
|
||||
|
||||
Supported Constructs
|
||||
--------------------
|
||||
|
||||
TODO
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
Signal Values and Resolution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There are several cases where the behaviour of the translated VHDL deviates
|
||||
from the source Verilog:
|
||||
|
||||
* The result of division by zero is x in Verilog but raises an exception in
|
||||
VHDL.
|
||||
|
||||
* Similarly, the result of reading past the end of an array in Verilog is x,
|
||||
whereas VHDL raises an exception.
|
||||
|
||||
* Any signal that is driven by two or more processes will have the value
|
||||
'U'. This is the result of the signal resolution function in the
|
||||
std_logic_1164 package.
|
||||
|
||||
Constructs Not Supported
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The following Verilog constructs cannot be translated to VHDL:
|
||||
|
||||
* fork and join
|
||||
|
||||
* force and release
|
||||
|
||||
* disable
|
||||
|
||||
* real-valued variables
|
||||
|
||||
* switches
|
||||
|
||||
* hierarchical dereferencing
|
||||
|
||||
Other Limitations
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
* The test expressions in case statements must be constant.
|
||||
|
||||
* Translation of a parameter to a corresponding VHDL generic
|
||||
declaration. Instead the default parameter value is used.
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
The vvp Code Generator (-tvvp)
|
||||
==============================
|
||||
|
||||
The vvp target generates code for the "vvp" run time. This is the most
|
||||
commonly used target for Icarus Verilog, as it is the main simulation engine.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 40 KiB |
@@ -1,198 +0,0 @@
|
||||
|
||||
Command File Format
|
||||
===================
|
||||
|
||||
The basic format of a command file is one source file or compiler argument per
|
||||
line. Command files may also have comments of various form, and options for
|
||||
controlling the compiler.
|
||||
|
||||
Comments
|
||||
--------
|
||||
|
||||
Lines that start with a "#" character are comments. All text after the "#"
|
||||
character, is ignored.
|
||||
|
||||
The "//" character sequence also starts a comment that continues to the end of
|
||||
the line.
|
||||
|
||||
The "/\*" and "\*/" character sequences surround multi-line comments. All the
|
||||
text between the comment start and comment end sequences is ignored, even when
|
||||
that text spans multiple lines. This style of comment does not nest, so a "/\*"
|
||||
sequence within a multi-line comment is probably an error.
|
||||
|
||||
Plus-args
|
||||
---------
|
||||
|
||||
Outside of comments, lines that start with a "+" character are compiler
|
||||
arguments. These are called plusargs but they are not the same as extended
|
||||
arguments passed to the "vvp" command. The supported plusargs are definitively
|
||||
listed in the iverilog manual page.
|
||||
|
||||
The plusargs lines are generally "+<name>+..." where the name is the name of
|
||||
an switch, and the arguments are separated by "+" characters, as in::
|
||||
|
||||
+libext+.v+.V+.ver
|
||||
|
||||
With plusargs lines, the "+" character separates tokens, and not white space,
|
||||
so arguments, which may include file paths, may include spaces. A plusarg line
|
||||
is terminated by the line end.
|
||||
|
||||
The line in the command file may also be a "-y" argument. This works exactly
|
||||
the same as the::
|
||||
|
||||
-y <path>
|
||||
|
||||
argument to the compiler; it declares a library directory. The "-y" syntax is
|
||||
also a shorthand for the "+libdir" plusarg, which is a more general form::
|
||||
|
||||
+libdir+<path>...
|
||||
|
||||
File Names
|
||||
----------
|
||||
|
||||
Any lines that are not comments, compiler arguments or plusargs are taken by
|
||||
the compiler to be a source file. The path can contain any characters (other
|
||||
then comment sequences) including blanks, although leading and trailing white
|
||||
space characters are stripped. The restriction of one file name per line is in
|
||||
support of operating systems that can name files any which way. It is not
|
||||
appropriate to expect white spaces to separate file names.
|
||||
|
||||
Variable Substitution
|
||||
---------------------
|
||||
|
||||
The syntax "$(name)" is a variable reference, and may be used anywhere within
|
||||
filenames or directory names. The contents of the variable are read from the
|
||||
environment and substituted in place of the variable reference. In Windows,
|
||||
these environment variables are the very same variables that are set through
|
||||
the Control Panel->System dialog box, and in UNIX these variables are
|
||||
environment variables as exported by your shell.
|
||||
|
||||
Variables are useful for giving command files some installation
|
||||
independence. For example, one can import a vendor library with the line::
|
||||
|
||||
-y $(VENDOR)/verilog/library
|
||||
|
||||
in the command file, and the next programmer will be able to use this command
|
||||
file without editing it to point to the location of VENDOR on his
|
||||
machine. Note the use of forward slashes as a directory separator. This works
|
||||
even under Windows, so always use forward slashes in file paths and Windows
|
||||
and UNIX users will be able to share command files.
|
||||
|
||||
An Example
|
||||
----------
|
||||
|
||||
This sample::
|
||||
|
||||
# This is a comment in a command file.
|
||||
# The -y statement declares a library
|
||||
# search directory
|
||||
-y $(PROJ_LIBRARY)/prims
|
||||
#
|
||||
# This plusarg tells the compiler that
|
||||
# files in libraries may have .v or .vl
|
||||
# extensions.
|
||||
+libext+.v+.vl
|
||||
#
|
||||
main.v // This is a source file
|
||||
#
|
||||
# This is a file name with blanks.
|
||||
C:/Project Directory/file name.vl
|
||||
|
||||
is a command file that demonstrates the major syntactic elements of command
|
||||
files. It demonstrates the use of comments, variables, plusargs and file
|
||||
names. It contains a lot of information about the hypothetical project, and
|
||||
suggests that command files can be used to describe the project as a whole
|
||||
fairly concisely.
|
||||
|
||||
The syntax of command files is rich enough that they can be used to document
|
||||
and control the assembly and compilation of large Verilog programs. It is not
|
||||
unusual to have command files that are hundreds of lines long, although
|
||||
judicious use of libraries can lead to very short command files even for large
|
||||
designs. It is also practical to have different command files that pull
|
||||
together combinations of sources and compiler arguments to make different
|
||||
designs from the same Verilog source files.
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
Given the above description of the command file format, the following is a
|
||||
list of the special records with their meaning.
|
||||
|
||||
* +libdir+*dir-path*
|
||||
|
||||
Specify directories to be searched for library modules. The *dir-path* can
|
||||
have multiple directories, separated by "+" characters.
|
||||
|
||||
* +libdir-nocase+dir-path
|
||||
|
||||
This is the same as "+libdir+", but when searching "nocase" libraries for
|
||||
module files, case will not be taken as significant. This is useful when the
|
||||
library is on a case insensitive file system.
|
||||
|
||||
* +libext+*suffix-string*
|
||||
|
||||
Declare the suffix strings to use when searching library directories for
|
||||
Verilog files. The compiler may test a list of suffix strings to support a
|
||||
variety of naming conventions.
|
||||
|
||||
* -y dir-path
|
||||
|
||||
This is like "+libdir+" but each line takes only one path. Like "+libdir+"
|
||||
there can be multiple "-y" records to declare multiple library
|
||||
directories. This is similar to the "-y" flag on the iverilog command line.
|
||||
|
||||
* -v *file-name* or -l *file-name*
|
||||
|
||||
This declares a library file. A library file is just like any other Verilog
|
||||
source file, except that modules declared within it are not implicitly
|
||||
possible root modules.
|
||||
|
||||
NOTE: The "-l" alias is new as of 2 October 2016. It will become available
|
||||
in releases and snapshots made after that date.
|
||||
|
||||
* +incdir+*include-dir-path*
|
||||
|
||||
Declare a directory or list of directories to search for files included by
|
||||
the "include" compiler directive. The directories are searched in
|
||||
order. This is similar to the "-I" flag on the iverilog command line.
|
||||
|
||||
* +define+*name=value*
|
||||
|
||||
Define the preprocessor symbol "name" to have the string value "value". If
|
||||
the value (and the "=") are omitted, then it is assumed to be the string
|
||||
"1". This is similar to the "-D" on the iverilog command line.
|
||||
|
||||
* +timescale+*units/precision*
|
||||
|
||||
Define the default timescale. This is the timescale that is used if there is
|
||||
no other timescale directive in the Verilog source. The compiler default
|
||||
default is "+timescale+1s/1s", which this command file setting can
|
||||
change. The format of the units/precision is the same as that for the
|
||||
timescale directive in the verilog source.
|
||||
|
||||
* +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 (or a FAT file system) and in the process the file
|
||||
names become munged. This is not meant to be used in general, but only in
|
||||
emergencies.
|
||||
|
||||
* +tolower-filename
|
||||
|
||||
The is the lowercase version of "+toupper-filename".
|
||||
|
||||
* +parameter+*name=value*
|
||||
|
||||
This token causes the compiler to override a parameter value for a top-level
|
||||
module. For example, if the module main has the parameter WIDTH, set the
|
||||
width like this "+parameter+main.WIDTH=5". Note the use of the complete
|
||||
hierarchical name. This currently only works for parameters defined in root
|
||||
(top level) modules and a defparam may override the command file value.
|
||||
|
||||
* +vhdl-work+*path*
|
||||
|
||||
When compiling VHDL, this token allows control over the directory to use for
|
||||
holding working package declarations. For example, "+vhdl-work+workdir" will
|
||||
cause the directory "workdir" to be used as a directory for holding working
|
||||
working copies of package headers.
|
||||
@@ -1,444 +0,0 @@
|
||||
|
||||
|
||||
iverilog Command Line Flags
|
||||
===========================
|
||||
|
||||
The iverilog command is the compiler/driver that takes the Verilog input and
|
||||
generates the output format, whether the simulation file or synthesis
|
||||
results. This information is at least summarized in the iverilog man page
|
||||
distributed in typical installations, but here we try to include more detail.
|
||||
|
||||
General
|
||||
-------
|
||||
|
||||
These flags affect the general behavior of the compiler.
|
||||
|
||||
* -c <cmdfile>
|
||||
|
||||
This flag selects the command file to use. The command file is an
|
||||
alternative to writing a long command line with a lot of file names and
|
||||
compiler flags. See the Command File Format page for more information.
|
||||
|
||||
* -d <flag>
|
||||
|
||||
Enable compiler debug output. These are aids for debugging Icarus Verilog,
|
||||
and this flag is not commonly used.
|
||||
The flag is one of these debug classes:
|
||||
|
||||
* scope
|
||||
* eval_tree
|
||||
* elaborate
|
||||
* synth2
|
||||
|
||||
* -g <generation flag>
|
||||
the generation is the compiler language, and specifies the language and
|
||||
extensions to use during the compile. The language level can be selected
|
||||
by a major level selector, and by controlling various features. Various
|
||||
"-g" flags can be compined. For example, to get Verilog 2001 without
|
||||
specify supoprt, use "-g2001 -gno-specify".
|
||||
|
||||
The supported flags are:
|
||||
|
||||
* 1995
|
||||
|
||||
This flag enables the IEEE1364-1995 standard.
|
||||
|
||||
* 2001
|
||||
|
||||
This flag enables the IEEE1364-2001 standard.
|
||||
|
||||
* 2001-noconfig
|
||||
|
||||
This flag enables the IEEE1364-2001 standard with config file support
|
||||
disabled. This eliminates the config file keywords from the language and
|
||||
so helps some programs written to older 2001 support compile.
|
||||
|
||||
* 2005
|
||||
This flag enables the IEEE1364-2005 standard. This is default enabled
|
||||
after v0.9.
|
||||
|
||||
* 2009
|
||||
This flag enables the IEEE1800-2009 standard, which includes
|
||||
SystemVerilog. The SystemVerilog support is not present in v0.9 and
|
||||
earlier. It is new to git master as of November 2009. Actual SystemVerilog
|
||||
support is ongoing.
|
||||
|
||||
* 2012
|
||||
|
||||
This flag enables the IEEE1800-2012 standard, which includes
|
||||
SystemVerilog.
|
||||
|
||||
* verilog-ams
|
||||
|
||||
This flag enables Verilog-AMS features that are supported by Icarus
|
||||
Verilog. (This is new as of 5 May 2008.)
|
||||
|
||||
* assertions/supported-assertions/no-assertions
|
||||
|
||||
Enable or disable SystemVerilog assertions. When enabled, assertion
|
||||
statements are elaborated. When disabled, assertion statements are parsed
|
||||
but ignored. The supported-assertions option only enables assertions that
|
||||
are currently supported by the compiler.
|
||||
|
||||
* specify/no-specify
|
||||
|
||||
Enable or disable support for specify block timing controls. When
|
||||
disabled, specify blocks are parsed but ignored. When enabled, specify
|
||||
blocks cause timing path and timing checks to be active.
|
||||
|
||||
* std-include/no-std-include
|
||||
|
||||
Enable 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.
|
||||
|
||||
* relative-include/no-relative-include
|
||||
|
||||
Enable or disable 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.
|
||||
|
||||
* xtypes/no-xtypes
|
||||
|
||||
Enable or disable support for extended types. Enabling types allows for
|
||||
new types and type syntax that are Icarus Verilog extensions.
|
||||
|
||||
* io-range-error/no-io-range-error
|
||||
|
||||
When enabled the range for a port and any associated net declaration must
|
||||
match exactly. When disabled a scalar port is allowed to have a net
|
||||
declaration with a range (obsolete usage). A warning message will be
|
||||
printed for this combination. All other permutations are still considered
|
||||
an error.
|
||||
|
||||
* strict-ca-eval/no-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. Enabling strict-ca-eval will force standard compliant behavior
|
||||
(with some loss in performance).
|
||||
|
||||
* strict-expr-width/no-strict-expr-width
|
||||
|
||||
Enable or disable 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.
|
||||
|
||||
* shared-loop-index/no-shared-loop-index
|
||||
|
||||
Enable or disable the exclusion of for-loop control variables from
|
||||
implicit event_expression lists. When enabled, if a for-loop control
|
||||
variable (loop index) is only used inside the for-loop statement, the
|
||||
compiler will not include it in an implicit event_expression list it
|
||||
calculates for that statement or any enclosing statement. This allows the
|
||||
same control variable to be used in multiple processes without risk of
|
||||
entering an infinite loop caused by each process triggering all other
|
||||
processes that use the same variable. For strict compliance with the
|
||||
standards, this behaviour should be disabled.
|
||||
|
||||
* -i
|
||||
|
||||
Ignore missing modules. Normally it is an error if a module instantiation
|
||||
refers to an undefined module. This option causes the compiler to skip over
|
||||
that instantiation. It will also stop the compiler returning an error if
|
||||
there are no top level modules. This allows the compiler to be used to check
|
||||
incomplete designs for errors.
|
||||
|
||||
NOTE: The "-i" flag was added in v11.0.
|
||||
|
||||
* -L <path>
|
||||
|
||||
Add the specified directory to the path list used to locate VPI modules. The
|
||||
default path includes only the install directory for the system.vpi module,
|
||||
but this flag can add other directories. Multiple paths are allowed, and the
|
||||
paths will be searched in order.
|
||||
|
||||
NOTE: The "-L" flag was added in v11.0.
|
||||
|
||||
* -l <path>
|
||||
|
||||
Add the specified file to the list of source files to be compiled, but mark
|
||||
it as a library file. All modules contained within that file will be treated
|
||||
as library modules, and only elaborated if they are instantiated by other
|
||||
modules in the design.
|
||||
|
||||
NOTE: The "-l" flag is new as of 2 October 2016. It will become available in
|
||||
releases and snapshots made after that date.
|
||||
|
||||
* -M<mode>=<path>
|
||||
|
||||
Write into the file specified by path a list of files that contribute to the
|
||||
compilation of the design.
|
||||
|
||||
If _mode_ is *all* or *prefix*, 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 _mode_ is *include*, only files that are included by include directives
|
||||
are listed.
|
||||
|
||||
If _mode_ is *module*, 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 _mode_ is *prefix*, files that are included by include directives are
|
||||
prefixed by "I " and other files are prefixed by "M ".
|
||||
|
||||
* -m<module>
|
||||
|
||||
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 (and
|
||||
loaded last).
|
||||
|
||||
If the specified name includes at least one directory character, it is
|
||||
assumed to be prefixed by the path to the module, otherwise the module is
|
||||
searched for in the paths specified by preceding -L options, and if not
|
||||
found there, in the iverilog base directory.
|
||||
|
||||
NOTE: The "-m" flag was added in v11.0.
|
||||
|
||||
* -o <path>
|
||||
|
||||
Specify the output file. The <path> is the name of the file to hold the
|
||||
output. The default is "a.out".
|
||||
|
||||
* -S
|
||||
|
||||
Activate synthesis. This flag tells the compiler to do what synthesis it can
|
||||
do before calling the code generator. This flag is rarely used explicitly,
|
||||
and certain code generators will implicitly enable this flag.
|
||||
|
||||
* -u
|
||||
|
||||
Treat each source file as a separate compilation unit (as defined in
|
||||
SystemVerilog). If compiling for an IEEE1364 generation, this will just
|
||||
reset all compiler directives (including macro definitions) before each new
|
||||
file is processed.
|
||||
|
||||
NOTE: The "-u" flag was added in v11.0.
|
||||
|
||||
* -v
|
||||
|
||||
Be verbose. Print copyright information, progress messages, and some timing
|
||||
information about various compilation phases.
|
||||
|
||||
(New in snapshots after 2014-12-16) If the selected target is vvp, the -v
|
||||
switch is appended to the shebang line in the compiler output file, so
|
||||
directly executing the compiler output file will turn on verbose messages in
|
||||
vvp. This extra verbosity can be avoided by using the vvp command to
|
||||
indirectly execute the compiler output file.
|
||||
|
||||
* -V
|
||||
|
||||
Print the version information. This skips all compilation. Just print the
|
||||
version information, including version details for the various components of
|
||||
the compiler.
|
||||
|
||||
* -R
|
||||
|
||||
Print the runtime paths of the compiler. This can be useful to find, e.g.,
|
||||
the include path of vpi_user.h.
|
||||
|
||||
* -W<warning class>
|
||||
|
||||
Enable/disable warnings. All the warning types (other then "all") can be
|
||||
prefixed with no- to disable that warning.
|
||||
|
||||
* all
|
||||
|
||||
This enables almost all of the available warnings. More specifically, it
|
||||
enables these warnings::
|
||||
|
||||
-Wanachronisms
|
||||
-Wimplicit
|
||||
-Wimplicit-dimensions
|
||||
-Wmacro-replacement
|
||||
-Wportbind
|
||||
-Wselect-range
|
||||
-Wtimescale
|
||||
-Wsensitivity-entire-array
|
||||
|
||||
* anachronisms
|
||||
|
||||
This enables warnings for use of features that have been deprecated or
|
||||
removed in the selected generation of the Verilog language.
|
||||
|
||||
* 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.
|
||||
|
||||
* implicit-dimensions
|
||||
|
||||
This enables warnings for the case where a port declaration or a var/net
|
||||
declaration for the same name is missing dimensions. Normally, Verilog
|
||||
allows you to do this (the undecorated declaration gets its dimensions
|
||||
form the decorated declaration) but this is no longer common, and some
|
||||
other tools (notable Xilix synthesizers) do not handle this correctly.
|
||||
|
||||
This flag is supported in release 10.1 or master branch snapshots after
|
||||
2016-02-06.
|
||||
|
||||
* macro-redefinition
|
||||
|
||||
This enables warnings when a macro is redefined, even if the macro text
|
||||
remains the same.
|
||||
|
||||
NOTE: The "macro-redefinition" flag was added in v11.0.
|
||||
|
||||
* macro-replacement
|
||||
|
||||
This enables warnings when a macro is redefined and the macro text
|
||||
changes. Use no-macro-redefinition to disable this,
|
||||
|
||||
NOTE: The "macro-replacement" flag was added in v11.0.
|
||||
|
||||
* portbind
|
||||
|
||||
This enables warnings for ports of module instantiations that are not
|
||||
connected properly, but probably should be. Dangling input ports, for
|
||||
example, will generate a warning.
|
||||
|
||||
* select-range
|
||||
|
||||
This enables warnings for constant out-of-bound selects. This includes
|
||||
partial or fully out-of-bound select as well as a select containing a 'bx
|
||||
or 'bz in the index.
|
||||
|
||||
* 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.
|
||||
|
||||
* infloop
|
||||
|
||||
This enables warnings for always statements that may have runtime infinite
|
||||
loops (i.e. has paths with zero or no delay). This class of warnings is
|
||||
not included in -Wall and hence does not have a no- 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 runtine 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
|
||||
indeterninite.
|
||||
|
||||
* sensitivity-entire-vector
|
||||
|
||||
This enables warnings for when a part select with an "always @*" statement
|
||||
results in the entire vector being added to the implicit sensitivity
|
||||
list. Although this behavior is prescribed by the IEEE standard, it is not
|
||||
what might be expected and can have performance implications if the vector
|
||||
is large.
|
||||
|
||||
* sensitivity-entire-array
|
||||
|
||||
This enables warnings for when a word select with an "always @*" statement
|
||||
results in the entire array being added to the implicit sensitivity
|
||||
list. Although this behavior is prescribed by the IEEE standard, it is not
|
||||
what might be expected and can have performance implications if the array
|
||||
is large.
|
||||
|
||||
* floating-nets
|
||||
|
||||
This enables warnings for nets that are present but have no drivers.
|
||||
|
||||
This flag was added in version 11.0 or later (and is in the master branch
|
||||
as of 2015-10-01).
|
||||
|
||||
* -y<libdir>
|
||||
|
||||
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.
|
||||
|
||||
* -Y<suf>
|
||||
|
||||
Appends suf to the list of file extensions that are used to resolve an
|
||||
undefined module to a file name. Should be specified before any -y flag. For
|
||||
example, this command::
|
||||
|
||||
% iverilog -Y .sv -y sources src.v
|
||||
|
||||
will try to resolve any undefined module m by looking into the directory
|
||||
sources and checking if there exist files named m.v or m.sv.
|
||||
|
||||
|
||||
Preprocessor Flags
|
||||
------------------
|
||||
|
||||
These flags control the behavior of the preprocessor. They are similar to
|
||||
flags for the typical "C" compiler, so C programmers will find them familiar.
|
||||
|
||||
* -E
|
||||
|
||||
This flag is special in that it tells the compiler to only run the
|
||||
preprocessor. This is useful for example as a way to resolve preprocessing
|
||||
for other tools. For example, this command::
|
||||
|
||||
% iverilog -E -ofoo.v -DKEY=10 src1.v src2.v
|
||||
|
||||
runs the preprocessor on the source files src1.v and src2.v and produces the
|
||||
single output file foo.v that has all the preprocessing (including header
|
||||
includes and ifdefs) processed.
|
||||
|
||||
* -D<macro>
|
||||
|
||||
Assign a value to the macro name. The format of this flag is one of::
|
||||
|
||||
-Dkey=value
|
||||
-Dkey
|
||||
|
||||
The key is defined to have the given value. If no value is given, then it is
|
||||
assumed to be "1". The above examples are the same as these defines in
|
||||
Verilog source::
|
||||
|
||||
`define key value
|
||||
`define key
|
||||
|
||||
* -I<path>
|
||||
|
||||
Append directory <path> to list of directories searched for Verilog include
|
||||
files. The -I 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.
|
||||
|
||||
Elaboration Flags
|
||||
-----------------
|
||||
|
||||
These are flags that pass information to the elaboration steps.
|
||||
|
||||
* -P<symbol>=<value>
|
||||
|
||||
Define a parameter using the defparam behavior to override a parameter
|
||||
values. This can only be used for parameters of root module instances.
|
||||
|
||||
* -s <topmodule>
|
||||
|
||||
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 "-s" flags, then they will be used
|
||||
as root modules instead.
|
||||
|
||||
* -Tmin, -Ttyp, -Tmax
|
||||
|
||||
Select the timings to use. The Verilog language allows many timings to be
|
||||
specified as three numbers, min:typical:max, but for simulation you need to
|
||||
choose which set to use. The "-Tmin" flag tells the compiler to at
|
||||
elaboration time choose "min" times. The default is "-Ttyp".
|
||||
|
||||
Target Flags
|
||||
------------
|
||||
@@ -1,167 +0,0 @@
|
||||
|
||||
Getting Started With Icarus Verilog
|
||||
===================================
|
||||
|
||||
Before getting started with actual examples, here are a few notes on
|
||||
conventions. First, command lines and sequences take the same arguments on all
|
||||
supported operating environments, including Linux, Windows and the various
|
||||
Unix systems. When an example command is shown in a figure, the generic prompt
|
||||
character "% " takes the place of whatever prompt string is appropriate for
|
||||
your system. Under Windows, the commands are invoked in a command window.
|
||||
|
||||
Second, when creating a file to hold Verilog code, it is common to use the
|
||||
".v" or the ".vl" suffix. This is not a requirement imposed by Icarus Verilog,
|
||||
but a useful convention. Some people also use the suffixes ".ver" or even
|
||||
".vlg". Examples in this book will use the ".v" suffix.
|
||||
|
||||
So let us start. Given that you are going to use Icarus Verilog as part of
|
||||
your design process, the first thing to do as a designer is learn how to
|
||||
compile and execute even the most trivial design. For the purposes of
|
||||
simulation, we use as our example the most trivial simulation, a simple Hello,
|
||||
World program.
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module hello;
|
||||
initial
|
||||
begin
|
||||
$display("Hello, World");
|
||||
$finish ;
|
||||
end
|
||||
endmodule
|
||||
|
||||
Use a text editor to place the program in a text file, hello.v, then compile
|
||||
this program with the command::
|
||||
|
||||
% iverilog -o hello hello.v
|
||||
|
||||
The results of this compile are placed into the file "hello", because the "-o"
|
||||
flag tells the compiler where to place the compiled result. Next, execute the
|
||||
compiled program like so::
|
||||
|
||||
% vvp hello
|
||||
Hello, World
|
||||
|
||||
And there it is, the program has been executed. So what happened? The first
|
||||
step, the "iverilog" command, read and interpreted the source file, then
|
||||
generated a compiled result. The compiled form may be selected by command line
|
||||
switches, but the default is the "vvp" format, which is actually run later, as
|
||||
needed. The "vvp" command of the second step interpreted the "hello" file from
|
||||
the first step, causing the program to execute.
|
||||
|
||||
The "iverilog" and "vvp" commands are the most important commands available to
|
||||
users of Icarus Verilog. The "iverilog" command is the compiler, and the "vvp"
|
||||
command is the simulation runtime engine. What sort of output the compiler
|
||||
actually creates is controlled by command line switches, but normally it
|
||||
produces output in the default vvp format, which is in turn executed by the
|
||||
vvp program.
|
||||
|
||||
As designs get larger and more complex, they gain hierarchy in the form of
|
||||
modules that are instantiated within others, and it becomes convenient to
|
||||
organize them into multiple files. A common convention is to write one
|
||||
moderate sized module per file (or group related tiny modules into a single
|
||||
file) then combine the files of the design together during compilation. For
|
||||
example, the counter model in counter.v
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module counter(output, clk, reset);
|
||||
|
||||
parameter WIDTH = 8;
|
||||
|
||||
output [WIDTH-1 : 0] output;
|
||||
input clk, reset;
|
||||
|
||||
reg [WIDTH-1 : 0] out;
|
||||
wire clk, reset;
|
||||
|
||||
always @(posedge clk or posedge reset)
|
||||
if (reset)
|
||||
output <= 0;
|
||||
else
|
||||
output <= output + 1;
|
||||
|
||||
endmodule // counter
|
||||
|
||||
and the test bench in counter_tb.v
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module test;
|
||||
|
||||
/* Make a reset that pulses once. */
|
||||
reg reset = 0;
|
||||
initial begin
|
||||
# 17 reset = 1;
|
||||
# 11 reset = 0;
|
||||
# 29 reset = 1;
|
||||
# 11 reset = 0;
|
||||
# 100 $stop;
|
||||
end
|
||||
|
||||
/* Make a regular pulsing clock. */
|
||||
reg clk = 0;
|
||||
always #5 clk = !clk;
|
||||
|
||||
wire [7:0] value;
|
||||
counter c1 (value, clk, reset);
|
||||
|
||||
initial
|
||||
$monitor("At time %t, value = %h (%0d)",
|
||||
$time, value, value);
|
||||
endmodule // test
|
||||
|
||||
are written into different files.
|
||||
|
||||
The "iverilog" command supports multi-file designs by two methods. The
|
||||
simplest is to list the files on the command line::
|
||||
|
||||
% iverilog -o my_design counter_tb.v counter.v
|
||||
% vvp my_design
|
||||
|
||||
This command compiles the design, which is spread across two input files, and
|
||||
generates the compiled result into the "my_design" file. This works for small
|
||||
to medium sized designs, but gets cumbersome when there are lots of files.
|
||||
|
||||
Another technique is to use a commandfile, which lists the input files in a
|
||||
text file. For example, create a text file called "file_list.txt" with the
|
||||
files listed one per line::
|
||||
|
||||
counter.v
|
||||
counter_tb.v
|
||||
|
||||
Then compile and execute the design with a command like so::
|
||||
|
||||
% iverilog -o my_design -c file_list.txt
|
||||
% vvp my_design
|
||||
|
||||
The command file technique clearly supports much larger designs simply by
|
||||
saving you the trouble of listing all the source files on the command
|
||||
line. Name the files that are part of the design in the command file and use
|
||||
the "-c" flag to tell iverilog to read the command file as a list of Verilog
|
||||
input files.
|
||||
|
||||
As designs get more complicated, they almost certainly contain many Verilog
|
||||
modules that represent the hierarchy of your design. Typically, there is one
|
||||
module that instantiates other modules but is not instantiated by any other
|
||||
modules. This is called a root module. Icarus Verilog chooses as roots (There
|
||||
can be more than one root) all the modules that are not instantiated by other
|
||||
modules. If there are no such modules, the compiler will not be able to choose
|
||||
any root, and the designer must use the "-sroot" switch to identify the root
|
||||
module, like this::
|
||||
|
||||
% iverilog -s main -o hello hello.v
|
||||
|
||||
If there are multiple candidate roots, all of them will be elaborated. The
|
||||
compiler will do this even if there are many root modules that you do not
|
||||
intend to simulate, or that have no effect on the simulation. This can happen,
|
||||
for example, if you include a source file that has multiple modules, but are
|
||||
only really interested in some of them. The "-s" flag identifies a specific
|
||||
root module and also turns off the automatic search for other root
|
||||
modules. You can use this feature to prevent instantiation of unwanted roots.
|
||||
|
||||
As designs get even larger, they become spread across many dozens or even
|
||||
hundreds of files. When designs are that complex, more advanced source code
|
||||
management techniques become necessary. These are described in later chapters,
|
||||
along with other advanced design management techniques supported by Icarus
|
||||
Verilog.
|
||||
@@ -1,118 +0,0 @@
|
||||
|
||||
Waveforms With GTKWave
|
||||
======================
|
||||
|
||||
GTKWave is a VCD waveform viewer based on the GTK library. This viewer support
|
||||
VCD and LXT formats for signal dumps. GTKWAVE is available on github
|
||||
`here <https://github.com/gtkwave/gtkwave>`_. Most Linux distributions already
|
||||
include gtkwave prepackaged.
|
||||
|
||||
.. image:: GTKWave_Example2.png
|
||||
|
||||
Generating VCD/FST files for GTKWAVE ------------------------------------
|
||||
Waveform dumps are written by the Icarus Verilog runtime program vvp. The user
|
||||
uses $dumpfile and $dumpvars system tasks to enable waveform dumping, then the
|
||||
vvp runtime takes care of the rest. The output is written into the file
|
||||
specified by the $dumpfile system task. If the $dumpfile call is absent, the
|
||||
compiler will choose the file name dump.vcd or dump.lxt or dump.fst, depending
|
||||
on runtime flags. The example below dumps everything in and below the test
|
||||
module:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
// Do this in your test bench
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile("test.vcd");
|
||||
$dumpvars(0,test);
|
||||
end
|
||||
|
||||
By default, the vvp runtime will generate VCD dump output. This is the default
|
||||
because it is the most portable. However, when using gtkwave, the FST output
|
||||
format is faster and most compact. Use the "-fst" extended argument to
|
||||
activate LXT output. For example, if your compiled output is written into the
|
||||
file "foo.vvp", the command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% vvp foo.vvp -fst <other-plusargs>
|
||||
|
||||
will cause the dumpfile output to be written in FST format. Absent any
|
||||
specific $dumpfile command, this file will be called dump.fst, which can be
|
||||
viewed with the command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% gtkwave dump.fst
|
||||
|
||||
A Working Example
|
||||
-----------------
|
||||
|
||||
First, the design itself:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module counter(out, clk, reset);
|
||||
|
||||
parameter WIDTH = 8;
|
||||
|
||||
output [WIDTH-1 : 0] out;
|
||||
input clk, reset;
|
||||
|
||||
reg [WIDTH-1 : 0] out;
|
||||
wire clk, reset;
|
||||
|
||||
always @(posedge clk)
|
||||
out <= out + 1;
|
||||
|
||||
always @reset
|
||||
if (reset)
|
||||
assign out = 0;
|
||||
else
|
||||
deassign out;
|
||||
|
||||
endmodule // counter
|
||||
|
||||
Then the simulation file:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module test;
|
||||
|
||||
/* Make a reset that pulses once. */
|
||||
reg reset = 0;
|
||||
initial begin
|
||||
$dumpfile("test.vcd");
|
||||
$dumpvars(0,test);
|
||||
|
||||
# 17 reset = 1;
|
||||
# 11 reset = 0;
|
||||
# 29 reset = 1;
|
||||
# 5 reset =0;
|
||||
# 513 $finish;
|
||||
end
|
||||
|
||||
/* Make a regular pulsing clock. */
|
||||
reg clk = 0;
|
||||
always #1 clk = !clk;
|
||||
|
||||
wire [7:0] value;
|
||||
counter c1 (value, clk, reset);
|
||||
|
||||
initial
|
||||
$monitor("At time %t, value = %h (%0d)",
|
||||
$time, value, value);
|
||||
endmodule // test
|
||||
|
||||
Compile, run, and view waveforms with these commands:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% iverilog -o dsn counter_tb.v counter.v
|
||||
% vvp dsn
|
||||
% gtkwave test.vcd &
|
||||
|
||||
Click on the 'test', then 'c1' in the top left box on GTKWAVE, then drag the
|
||||
signals to the Signals box. You will be able to add signals to display,
|
||||
scanning by scope.
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
Icarus Verilog Usage
|
||||
====================
|
||||
|
||||
This section contains documents to help support developers who contribute to
|
||||
Icarus Verilog.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
installation
|
||||
getting_started
|
||||
simulation
|
||||
command_line_flags
|
||||
command_files
|
||||
verilog_attributes
|
||||
vvp_flags
|
||||
gtkwave
|
||||
vvp_debug
|
||||
vpi
|
||||
ivl_target
|
||||
reporting_issues
|
||||
@@ -1,146 +0,0 @@
|
||||
|
||||
Installation Guide
|
||||
==================
|
||||
|
||||
Icarus Verilog may be installed from source code, or from pre-packaged binary
|
||||
distributions. If you don't have need for the very latest, and prepackaged
|
||||
binaries are available, that would be the best place to start.
|
||||
|
||||
Installation From Source
|
||||
------------------------
|
||||
|
||||
Icarus is developed for Unix-like environments but can also be compiled on
|
||||
Windows systems using the Cygwin environment or MinGW compilers. The following
|
||||
instructions are the common steps for obtaining the Icarus Verilog source,
|
||||
compiling and installing. Note that there are precompiled and/or prepackaged
|
||||
versions for a variety of systems, so if you find an appropriate packaged
|
||||
version, then that is the easiest way to install.
|
||||
|
||||
The source code for Icarus is stored under the git source code control
|
||||
system. You can use git to get the latest development head or the latest of a
|
||||
specific branch. Stable releases are placed on branches, and in particular v11
|
||||
stable releases are on the branch "v11-branch" To get the development version
|
||||
of the code follow these steps::
|
||||
|
||||
% git config --global user.name "Your Name Goes Here"
|
||||
% git config --global user.email [email protected]
|
||||
% git clone https://github.com/steveicarus/iverilog.git
|
||||
|
||||
The first two lines are optional and are used to tell git who you are. This
|
||||
information is important if/when you submit a patch. We suggest that you add
|
||||
this information now so you don't forget to do it later. The clone will create
|
||||
a directory, named iverilog, containing the source tree, and will populate
|
||||
that directory with the most current source from the HEAD of the repository.
|
||||
|
||||
Change into this directory using::
|
||||
|
||||
% cd iverilog
|
||||
|
||||
Normally, this is enough as you are now pointing at the most current
|
||||
development code, and you have implicitly created a branch "master" that
|
||||
tracks the development head. However, If you want to actually be working on
|
||||
the v11-branch (the branch where the latest v11 patches are) then you checkout
|
||||
that branch with the command::
|
||||
|
||||
% git checkout --track -b v11-branch origin/v11-branch
|
||||
|
||||
This creates a local branch that tracks the v11-branch in the repository, and
|
||||
switches you over to your new v11-branch. The tracking is important as it
|
||||
causes pulls from the repository to re-merge your local branch with the remote
|
||||
v11-branch. You always work on a local branch, then merge only when you
|
||||
push/pull from the remote repository.
|
||||
|
||||
Now that you've cloned the repository and optionally selected the branch you
|
||||
want to work on, your local source tree may later be synced up with the
|
||||
development source by using the git command::
|
||||
|
||||
% git pull
|
||||
|
||||
The git system remembers the repository that it was cloned from, so you don't
|
||||
need to re-enter it when you pull.
|
||||
|
||||
Finally, configuration files are built by the extra step::
|
||||
|
||||
% sh autoconf.sh
|
||||
|
||||
The source is then compiled as appropriate for your system. See the specific
|
||||
build instructions below for your operation system for what to do next.
|
||||
|
||||
You will need autoconf and gperf installed in order for the script to work.
|
||||
If you get errors such as::
|
||||
|
||||
Autoconf in root...
|
||||
autoconf.sh: 10: autoconf: not found
|
||||
Precompiling lexor_keyword.gperf
|
||||
autoconf.sh: 13: gperf: not found.
|
||||
|
||||
You will need to install download and install the autoconf and gperf tools.
|
||||
|
||||
Icarus Specific Configuration Options
|
||||
-------------------------------------
|
||||
|
||||
Icarus takes many of the standard configuration options and those will not be
|
||||
described here. The following are specific to Icarus::
|
||||
|
||||
--enable-suffix[=suffix]
|
||||
|
||||
This option allows the user to build Icarus with a default suffix or when
|
||||
provided a user defined suffix. Older stable releases have this flag on by
|
||||
default e.g.(V0.8 by default will build with a "-0.8" suffix). All versions
|
||||
have an appropriate default suffix ("-<base_version>").
|
||||
|
||||
All programs or directories are tagged with this suffix. e.g.(iverilog-0.8,
|
||||
vvp-0.8, etc.). The output of iverilog will reference the correct run time
|
||||
files and directories. The run time will check that it is running a file with
|
||||
a compatible version e.g.(you can not run a V0.9 file with the V0.8 run
|
||||
time). ::
|
||||
|
||||
--with-valgrind
|
||||
|
||||
This option adds extra memory cleanup code and pool management code to allow
|
||||
better memory leak checking when valgrind is available. This option is not
|
||||
need when checking for basic errors with valgrind.
|
||||
|
||||
Compiling on Linux/Unix
|
||||
-----------------------
|
||||
|
||||
(Note: You will need to install bison, flex, g++ and gcc) This is probably the
|
||||
easiest case. Given that you have the source tree from the above instructions,
|
||||
the compile and install is generally as simple as::
|
||||
|
||||
% ./configure
|
||||
% make
|
||||
(su to root)
|
||||
# make install
|
||||
|
||||
The "make install" typically needs to be done as root so that it can install
|
||||
in directories such as "/usr/local/bin" etc. You can change where you want to
|
||||
install by passing a prefix to the "configure" command::
|
||||
|
||||
% ./configure --prefix=/my/special/directory
|
||||
|
||||
This will configure the source for eventual installation in the directory that
|
||||
you specify. Note that "rpm" packages of binaries for Linux are typically
|
||||
configured with "--prefix=/usr" per the Linux File System Standard.
|
||||
|
||||
Make sure you have the latest version of flex otherwise you will get an error
|
||||
when parsing lexor.lex.
|
||||
|
||||
Compiling on Macintosh OS X
|
||||
---------------------------
|
||||
|
||||
Since Mac OS X is a BSD flavor of Unix, you can install Icarus Verilog from
|
||||
source using the procedure described above. You need to install the Xcode
|
||||
software, which includes the C and C++ compilers for Mac OS X. The package is
|
||||
available for free download from Apple's developer site. Once Xcode is
|
||||
installed, you can build Icarus Verilog in a terminal window just like any
|
||||
other Unix install.
|
||||
|
||||
For versions newer than 10.3 the GNU Bison tool (packaged with Xcode) needs to
|
||||
be updated to version 3. ::
|
||||
|
||||
brew install bison
|
||||
echo 'export PATH="/usr/local/opt/bison/bin:$PATH"' >> ~/.bash_profile
|
||||
|
||||
Icarus Verilog is also available through the Homebrew package manager: "brew
|
||||
install icarus-verilog".
|
||||
@@ -1,106 +0,0 @@
|
||||
|
||||
Loadable Target API (ivl_target.h)
|
||||
==================================
|
||||
|
||||
In addition to the standard VPI API, Icarus Verilog supports a non-standard
|
||||
loadable target module API. This API helps C programmers write modules that
|
||||
Icarus Verilog can use to generate code. These modules are used at compile
|
||||
time to write the elaborated design to the simulation or netlist files. For
|
||||
example, the vvp code generator is a loadable target module that writes vvp
|
||||
code into the specified file.
|
||||
|
||||
Loadable target modules gain access to the 'elaborated' design. That means,
|
||||
the source files have been checked for syntax and correctness, any synthesis
|
||||
and general optimization steps have been performed, and what is left is a
|
||||
design that reflects but is not exactly the same as the input Verilog source
|
||||
code. This relieves the modules of the burden of supporting all the odd
|
||||
corners and complexities of the Verilog language.
|
||||
|
||||
The Target Module API
|
||||
---------------------
|
||||
|
||||
The API is defined in the header file "ivl_target.h" which is installed with
|
||||
Icarus Verilog. The header defines the functions that the module writer can
|
||||
use to get at the elaborated design during the course of writing the output
|
||||
format.
|
||||
|
||||
The target module API function "target_design" is special in that the API does
|
||||
not provide this function: The target module itself provides it. When the
|
||||
compiler loads the target module, it invokes the "target_design" function with
|
||||
a handle to the design. This is the point where the target module takes over
|
||||
to process the design.
|
||||
|
||||
Compiling Target Modules
|
||||
------------------------
|
||||
|
||||
Compiling loadable target modules is similar to compiling VPI modules, in that
|
||||
the module must be compiled with the "-fPIC" flag to gcc, and linked with the
|
||||
"-shared" flag. The module that you compile is then installed in a place where
|
||||
the "iverilog" command can find it, and configuration files are adjusted to
|
||||
account for the new module.
|
||||
|
||||
This code::
|
||||
|
||||
# include <ivl_target.h>
|
||||
|
||||
int target_design(ivl_design_t des)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
is an example module that we can write into the file "empty.c"; and let us
|
||||
compile it into the module file "empty.tgt" like so::
|
||||
|
||||
% gcc -o empty.tgt -fpic -shared empty.c
|
||||
|
||||
This makes the "empty.tgt" file an a dynamically loaded shared object.
|
||||
|
||||
Creating the Target Config File
|
||||
-------------------------------
|
||||
|
||||
The target config file tells the Icarus Verilog core how to process your new
|
||||
code generator. The ivl core expects two configuration files: the name.conf
|
||||
and the name-s.config files. The "-s" version is what is used if the user
|
||||
gives the "-S" (synthesis) flag on the command line.
|
||||
|
||||
The stub target, included in most distributions, demonstrates the config
|
||||
files. The "stub.conf" file is::
|
||||
|
||||
functor:cprop
|
||||
functor:nodangle
|
||||
-t:dll
|
||||
flag:DLL=stub.tgt
|
||||
|
||||
and the "stub-s.conf" file is::
|
||||
|
||||
functor:synth2
|
||||
functor:synth
|
||||
functor:syn-rules
|
||||
functor:cprop
|
||||
functor:nodangle
|
||||
-t:dll
|
||||
flag:DLL=stub.tgt
|
||||
|
||||
Note that the "stub-s.conf" file contains more lines to invoke internal
|
||||
synthesis functions, whereas the "stub.conf" invokes only the basic
|
||||
optimization steps.
|
||||
|
||||
In general, only the last line (The "flag:DLL=<name>.tgt" record) varies for
|
||||
each target. For your target, replace the <name> with the name of your target
|
||||
and you have a configuration file ready to install. Note that this is the name
|
||||
of your target module. This is in fact how the config file tells the compiler
|
||||
the name of your module.
|
||||
|
||||
The rest of the config file is best taken as boiler plate and installed as is,
|
||||
with one difference. If your target is a synthesis target (for example a mosis
|
||||
code generator or a pld code generator) that expects synthesis to happen, then
|
||||
it makes the most sense to create both your config file like the "stub-s.conf"
|
||||
config file. This causes the compiler to do synthesis for your target whether
|
||||
the user gives the "-S" flag or not.
|
||||
|
||||
Installing the Target Module
|
||||
----------------------------
|
||||
|
||||
Finally, the "empty.conf", the "empty-s.conf" and the "empty.tgt" files need
|
||||
to be installed. Where they go depends on your system, but in Linux they are
|
||||
normally installed in "/usr/lib/ivl".
|
||||
@@ -1,37 +0,0 @@
|
||||
|
||||
Reporting Issues
|
||||
================
|
||||
|
||||
The developers of and contributers to Icarus Verilog use github to track
|
||||
issues and to create patches for the product. If you believe you have found a
|
||||
problem, use the Issues tracker at the
|
||||
`Icarus Verilog github page <https://github.com/steveicarus/iverilog>`_.
|
||||
|
||||
On the main page, you will find a row of selections near the top. Click the
|
||||
`Issues <https://github.com/steveicarus/iverilog/issues>`_ link to get to the
|
||||
list of issues, open and closed. You will find a friendly green button where
|
||||
you can create a new issue. You will be asked to create a title for your
|
||||
issue, and to write a detailed description of your issue. Please include
|
||||
enough information that anyone who sees your issue can understand and
|
||||
reproduce it.
|
||||
|
||||
One key characteristic of a well reported issue is a small sample program that
|
||||
demonstrates the issue. The smaller the better. No developer wants to wade
|
||||
through hundreds of lines of working Verilog to find the few lines that cause
|
||||
trouble, so if you can get it down to a 10 line sample program, then your
|
||||
issue will be far more likely to be addressed.
|
||||
|
||||
Be prepared to have a conversation about your issue. More often then you would
|
||||
expect, the issue turns out to be a bug in your program, and the person
|
||||
looking into your issue may point out a bug in your code. You learn something,
|
||||
and we all win. We are not always correct, though, so if we are incorrect,
|
||||
help us see our error, if that's appropriate. If we don't understand what your
|
||||
issue is, we will label your issue with a "Need info" label, and if we never
|
||||
hear from you again, your issue may be closed summarily.
|
||||
|
||||
If you can submit a complete, working program that we can use in the
|
||||
regression test suite, then that is the best. Check out the existing tests in
|
||||
the regression test suite to see how they are structured. If you have a
|
||||
complete test that can go into the test suite, then that saves everyone a lot
|
||||
of grief, and again you increase the odds that your issue will be addressed.
|
||||
|
||||
@@ -1,495 +0,0 @@
|
||||
|
||||
Simulation Using Icarus Verilog
|
||||
===============================
|
||||
|
||||
Simulation is the process of creating models that mimic the behavior of the
|
||||
device you are designing (simulation models) and creating models to exercise
|
||||
the device (test benches). The simulation model need not reflect any
|
||||
understanding of the underlying technology, and the simulator need not know
|
||||
that the design is intended for any specific technology.
|
||||
|
||||
The Verilog simulator, in fact, is usually a different program than the
|
||||
synthesizer. It may even come from a different vendor. The simulator need not
|
||||
know of or generate netlists for the target technology, so it is possible to
|
||||
write one simulator that can be used to model designs intended for a wide
|
||||
variety of technologies. A synthesizer, on the other hand, does need to know a
|
||||
great deal about the target technology in order to generate efficient
|
||||
netlists. Synthesizers are often technology specific and come from vendors
|
||||
with specialized knowledge, whereas simulators are more general purpose.
|
||||
|
||||
Simulation models and test benches, therefore, can use the full range of
|
||||
Verilog features to model the intended design as clearly as possible. This is
|
||||
the time to test the algorithms of the design using language that is
|
||||
relatively easy for humans to read. The simulator, along with the test bench,
|
||||
can test that the clearly written model really does behave as intended, and
|
||||
that the intended behavior really does meet expectations.
|
||||
|
||||
The test benches model the world outside the design, so they are rarely
|
||||
destined for real hardware. They are written in Verilog simply as a matter of
|
||||
convenience, and sometimes they are not written in Verilog at all. The test
|
||||
benches are not throw-away code either, as they are used to retest the device
|
||||
under test as it is transformed from a simulation model to a synthesizeable
|
||||
description.
|
||||
|
||||
Compilation and Elaboration
|
||||
---------------------------
|
||||
|
||||
Simulation of a design amounts to compiling and executing a program. The
|
||||
Verilog source that represents the simulation model and the test bench is
|
||||
compiled into an executable form and executed by a simulation
|
||||
engine. Internally, Icarus Verilog divides the compilation of program source
|
||||
to an executable form into several steps, and basic understanding of these
|
||||
steps helps understand the nature of failures and errors. The first step is
|
||||
macro preprocessing, then compilation, elaboration, optional optimizations and
|
||||
finally code generation. The boundary between these steps is often blurred,
|
||||
but this progression remains a useful model of the compilation process.
|
||||
|
||||
The macro preprocessing step performs textual substitutions of macros defined
|
||||
with "\`define" statements, textual inclusion with "\`include" statements, and
|
||||
conditional compilation by "\`ifdef" and "\`ifndef" statements. The
|
||||
macropreprocessor for Icarus Verilog is internally a separate program that can
|
||||
be accessed independently by using the "-E" flag to the "iverilog" command,
|
||||
like so::
|
||||
|
||||
% iverilog -E -o out.v example.v
|
||||
|
||||
This command causes the input Verilog file "example.v" to be preprocessed, and
|
||||
the output, a Verilog file without preprocessor statements, written into
|
||||
"out.v". The "\`include" and "\`ifdef" directives in the input file are interpreted,
|
||||
and defined macros substituted, so that the output, a single file, is the same
|
||||
Verilog but with the preprocessor directives gone. All the explicitly
|
||||
specified source files are also combined by the preprocessor, so that the
|
||||
preprocessed result is a single Verilog stream.
|
||||
|
||||
Normally, however, the "-E" flag is not used and the preprocessed Verilog is
|
||||
instead sent directly to the next step, the compiler. The compiler core takes
|
||||
as input preprocessed Verilog and generates an internal parsed form. The
|
||||
parsed form is an internal representation of the Verilog source, in a format
|
||||
convenient for further processing, and is not accessible to the user.
|
||||
|
||||
The next step, elaboration, takes the parsed form, chooses the root modules,
|
||||
and instantiates (makes *instances* of) those roots. The root instances may
|
||||
contain instances of other modules, which may in turn contain instances of yet
|
||||
other modules. The elaboration process creates a hierarchy of module instances
|
||||
that ends with primitive gates and statements.
|
||||
|
||||
Note that there is a difference between a module and a module instance. A
|
||||
module is a type. It is a description of the contents of module instances that
|
||||
have its type. When a module is instantiated within another module, the module
|
||||
name identifies the type of the instance, and the instance name identifies the
|
||||
specific instance of the module. There can be many instances of any given
|
||||
module.
|
||||
|
||||
Root modules are a special case, in that the programmer does not give them
|
||||
instance names. Instead, the instance names of root modules are the same as
|
||||
the name of the module. This is valid because, due to the nature of the
|
||||
Verilog syntax, a module can be a root module only once, so the module name
|
||||
itself is a safe instance name.
|
||||
|
||||
Elaboration creates a hierarchy of scopes. Each module instance creates a new
|
||||
scope within its parent module, with each root module starting a
|
||||
hierarchy. Every module instance in the elaborated program has a unique scope
|
||||
path, a hierarchical name, that starts with its root scope and ends with its
|
||||
own instance name. Every named object, including variables, parameters, nets
|
||||
and gates, also has a hierarchical name that starts with a root scope and ends
|
||||
with its own base name. The compiler uses hierarchical names in error messages
|
||||
generated during or after elaboration, so that erroneous items can be
|
||||
completely identified. These hierarchical names are also used by waveform
|
||||
viewers that display waveform output from simulations.
|
||||
|
||||
The elaboration process creates from the parsed form the scope hierarchy
|
||||
including the primitive objects within each scope. The elaborated design then
|
||||
is optimized to reduce it to a more optimal, but equivalent design. The
|
||||
optimization step takes the fully elaborated design and transforms it to an
|
||||
equivalent design that is smaller or more efficient. These optimizations are,
|
||||
for example, forms of constant propagation and dead code elimination. Useless
|
||||
logic is eliminated, and constant expressions are pre-calculated. The
|
||||
resulting design behaves as if the optimizations were not performed, but is
|
||||
smaller and more efficient. The elimination (and spontaneous creation) of
|
||||
gates and statements only affects the programmer when writing VPI modules,
|
||||
which through the API have limited access to the structures of the design.
|
||||
|
||||
Finally, the optimized design, which is still in an internal form not
|
||||
accessible to users, is passed to a code generator that writes the design into
|
||||
an executable form. For simulation, the code generator is selected to generate
|
||||
the vvp format--a text format that can be executed by the simulation
|
||||
engine. Other code generators may be selected by the Icarus Verilog user, even
|
||||
third party code generators, but the vvp code generator is the default for
|
||||
simulation purposes.
|
||||
|
||||
Making and Using Libraries
|
||||
--------------------------
|
||||
|
||||
Although simple programs may be written into a single source file, this gets
|
||||
inconvenient as the designs get larger. Also, writing the entire program into
|
||||
a single file makes it difficult for different programs to share common
|
||||
code. It therefore makes sense to divide large programs into several source
|
||||
files, and to put generally useful source code files somewhere accessible to
|
||||
multiple designs.
|
||||
|
||||
Once the program is divided into many files, the compiler needs to be told how
|
||||
to find the files of the program. The simplest way to do that is to list the
|
||||
source files on the command line or in a command file. This is for example the
|
||||
best way to divide up and integrate test bench code with the simulation model
|
||||
of the device under test.
|
||||
|
||||
The Macro Preprocessor
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Another technique is to use the macro preprocessor to include library files
|
||||
into a main file. The `include` directive takes the name of a source file to
|
||||
include. The preprocessor inserts the entire contents of the included file in
|
||||
place of the `include` directive. The preprocessor normally looks in the
|
||||
current working directory (the current working directory of the running
|
||||
compiler, and not the directory where the source file is located) for the
|
||||
included file, but the "-I" switch to "iverilog" can add directories to the
|
||||
search locations list. ::
|
||||
|
||||
% iverilog -I/directory/to/search example.v
|
||||
|
||||
It is common to create include directories shared by a set of programs. The
|
||||
preprocessor `include` directive can be used by the individual programs to
|
||||
include the source files that it needs.
|
||||
|
||||
The preprocessor method of placing source code into libraries is general
|
||||
(arbitrary source code can be placed in the included files) but is static, in
|
||||
the sense that the programmer must explicitly include the desired library
|
||||
files. The automatic module library is a bit more constrained, but is
|
||||
automatic.
|
||||
|
||||
Automatic Module Libraries
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A common use for libraries is to store module definitions that may be of use
|
||||
to a variety of programs. If modules are divided into a single module per
|
||||
file, and the files are named appropriately, and the compiler is told where to
|
||||
look, then the compiler can automatically locate library files when it finds
|
||||
that a module definition is missing.
|
||||
|
||||
For this to work properly, the library files must be Verilog source, they
|
||||
should contain a single module definition, and the files must be named after
|
||||
the module they contain. For example, if the module "AND2" is a module in the
|
||||
library, then it belongs in a file called "AND2.v" and that file contains only
|
||||
the "AND2" module. A library, then, is a directory that contains properly
|
||||
named and formatted source files. ::
|
||||
|
||||
% iverilog -y/library/to/search example.v
|
||||
|
||||
The "-y" flag to "iverilog" tells the compiler to look in the specified
|
||||
directory for library modules whenever the program instantiates a module that
|
||||
is not otherwise defined. The programmer may include several "-y" flags on the
|
||||
command line (or in a command file) and the compiler will search each
|
||||
directory in order until an appropriate library file is found to resolve the
|
||||
module.
|
||||
|
||||
Once a module is defined, either in the program or by reading a library
|
||||
module, the loaded definition is used from then on within the program. If the
|
||||
module is defined within a program file or within an included file, then the
|
||||
included definition is used instead of any library definition. If a module is
|
||||
defined in multiple libraries, then the first definition that the compiler
|
||||
finds is used, and later definitions are never read.
|
||||
|
||||
Icarus Verilog accesses automatic libraries during elaboration, after it has
|
||||
already preprocessed and parsed the non-library source files. Modules in
|
||||
libraries are not candidates for root modules, and are not even parsed unless
|
||||
they are instantiated in other source files. However, a library module may
|
||||
reference other library modules, and reading in a library module causes it to
|
||||
be parsed and elaborated, and further library references resolved, just like a
|
||||
non-library module. The library lookup and resolution process iterates until
|
||||
all referenced modules are resolved, or known to be missing from the
|
||||
libraries.
|
||||
|
||||
The automatic module library technique is useful for including vendor or
|
||||
technology libraries into a program. Many EDA vendors offer module libraries
|
||||
that are formatted appropriately; and with this technique, Icarus Verilog can
|
||||
use them for simulation.
|
||||
|
||||
Advanced Command Files
|
||||
----------------------
|
||||
|
||||
Command files were mentioned in the "Getting Started" chapter, but only
|
||||
briefly. In practice, Verilog programs quickly grow far beyond the usefulness
|
||||
of simple command line options, and even the macro preprocessor lacks the
|
||||
flexibility to combine source and library modules according to the advancing
|
||||
development process.
|
||||
|
||||
The main contents of a command file is a list of Verilog source files. You can
|
||||
name in a command file all the source files that make up your design. This is
|
||||
a convenient way to collect together all the files that make up your
|
||||
design. Compiling the design can then be reduced to a simple command line like
|
||||
the following::
|
||||
|
||||
% iverilog -c example.cf
|
||||
|
||||
The command file describes a configuration. That is, it lists the specific
|
||||
files that make up your design. It is reasonable, during the course of
|
||||
development, to have a set of different but similar variations of your
|
||||
design. These variations may have different source files but also many common
|
||||
source files. A command file can be written for each variation, and each
|
||||
command file lists the source file names used by each variation.
|
||||
|
||||
A configuration may also specify the use of libraries. For example, different
|
||||
configurations may be implementations for different technologies so may use
|
||||
different parts libraries. To make this work, command files may include "-y"
|
||||
statements. These work in command files exactly how they work on "iverilog"
|
||||
command line. Each "-y" flag is followed by a directory name, and the
|
||||
directories are searched for library modules in the order that they are listed
|
||||
in the command file.
|
||||
|
||||
The include search path can also be specified in configuration files with
|
||||
"+incdir+" tokens. These tokens start with the "+incdir+" string, then
|
||||
continue with directory paths, separated from each other with "+" characters
|
||||
(not spaces) for the length of the line.
|
||||
|
||||
Other information can be included in the command file. See the section Command
|
||||
File Format for complete details on what can go in a command file.
|
||||
|
||||
Input Data at Runtime
|
||||
---------------------
|
||||
|
||||
Often, it is useful to compile a program into an executable simulation, then
|
||||
run the simulation with various inputs. This requires some means to pass data
|
||||
and arguments to the compiled program each time it is executed. For example,
|
||||
if the design models a micro-controller, one would like to run the compiled
|
||||
simulation against a variety of different ROM images.
|
||||
|
||||
There are a variety of ways for a Verilog program to get data from the outside
|
||||
world into the program at run time. Arguments can be entered on the command
|
||||
line, and larger amounts of data can be read from files. The simplest method
|
||||
is to take arguments from the command line.
|
||||
|
||||
Consider this running example of a square root calculator
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module sqrt32(clk, rdy, reset, x, .y(acc));
|
||||
input clk;
|
||||
output rdy;
|
||||
input reset;
|
||||
|
||||
input [31:0] x;
|
||||
output [15:0] acc;
|
||||
|
||||
// acc holds the accumulated result, and acc2 is
|
||||
// the accumulated square of the accumulated result.
|
||||
reg [15:0] acc;
|
||||
reg [31:0] acc2;
|
||||
|
||||
// Keep track of which bit I'm working on.
|
||||
reg [4:0] bitl;
|
||||
wire [15:0] bit = 1 << bitl;
|
||||
wire [31:0] bit2 = 1 << (bitl << 1);
|
||||
|
||||
// The output is ready when the bitl counter underflows.
|
||||
wire rdy = bitl[4];
|
||||
|
||||
// guess holds the potential next values for acc,
|
||||
// and guess2 holds the square of that guess.
|
||||
wire [15:0] guess = acc | bit;
|
||||
wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1);
|
||||
|
||||
task clear;
|
||||
begin
|
||||
acc = 0;
|
||||
acc2 = 0;
|
||||
bitl = 15;
|
||||
end
|
||||
endtask
|
||||
|
||||
initial clear;
|
||||
|
||||
always @(reset or posedge clk)
|
||||
if (reset)
|
||||
clear;
|
||||
else begin
|
||||
if (guess2 <= x) begin
|
||||
acc <= guess;
|
||||
acc2 <= guess2;
|
||||
end
|
||||
bitl <= bitl - 1;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
One could write the test bench as a program that passes a representative set
|
||||
of input values into the device and checks the output result. However, we can
|
||||
also write a program that takes on the command line an integer value to be
|
||||
used as input to the device. We can write and compile this program, then pass
|
||||
different input values on the run time command line without recompiling the
|
||||
simulation.
|
||||
|
||||
This example demonstrates the use of the "$value$plusargs" to access command
|
||||
line arguments of a simulation
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module main;
|
||||
|
||||
reg clk, reset;
|
||||
reg [31:0] x;
|
||||
wire [15:0] y;
|
||||
wire rdy;
|
||||
|
||||
sqrt32 dut (clk, rdy, reset, x, y);
|
||||
|
||||
always #10 clk = ~clk;
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
reset = 1;
|
||||
|
||||
if (! $value$plusargs("x=%d", x)) begin
|
||||
$display("ERROR: please specify +x=<value> to start.");
|
||||
$finish;
|
||||
end
|
||||
|
||||
#35 reset = 0;
|
||||
|
||||
wait (rdy) $display("y=%d", y);
|
||||
$finish;
|
||||
end // initial begin
|
||||
|
||||
endmodule // main
|
||||
|
||||
The "$value$plusargs" system function takes a string pattern that describes
|
||||
the format of the command line argument, and a reference to a variable that
|
||||
receives the value. The "sqrt_plusargs" program can be compiled and executed
|
||||
like this::
|
||||
|
||||
% iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v
|
||||
% vvp sqrt_plusargs.vvp +x=81
|
||||
y= 9
|
||||
|
||||
Notice that the "x=%d" string of the "$value$plusargs" function describes the
|
||||
format of the argument. The "%d" matches a decimal value, which in the sample
|
||||
run is "81". This gets assigned to "x" by the "$value$plusargs" function,
|
||||
which returns TRUE, and the simulation continues from there.
|
||||
|
||||
If two arguments have to be passed to the testbench then the main module would
|
||||
be modified as follows
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module main;
|
||||
|
||||
reg clk, reset;
|
||||
reg [31:0] x;
|
||||
reg [31:0] z;
|
||||
wire [15:0] y1,y2;
|
||||
wire rdy1,rdy2;
|
||||
|
||||
sqrt32 dut1 (clk, rdy1, reset, x, y1);
|
||||
sqrt32 dut2 (clk, rdy2, reset, z, y2);
|
||||
|
||||
always #10 clk = ~clk;
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
reset = 1;
|
||||
|
||||
if (! $value$plusargs("x=%d", x)) begin
|
||||
$display("ERROR: please specify +x=<value> to start.");
|
||||
$finish;
|
||||
end
|
||||
|
||||
if (! $value$plusargs("z=%d", z)) begin
|
||||
$display("ERROR: please specify +z=<value> to start.");
|
||||
$finish;
|
||||
end
|
||||
|
||||
|
||||
#35 reset = 0;
|
||||
|
||||
wait (rdy1) $display("y1=%d", y1);
|
||||
wait (rdy2) $display("y2=%d", y2);
|
||||
$finish;
|
||||
end // initial begin
|
||||
|
||||
endmodule // main
|
||||
|
||||
and the "sqrt_plusargs" program would be compiled and executed as follows::
|
||||
|
||||
% iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v
|
||||
% vvp sqrt_plusargs.vvp +x=81 +z=64
|
||||
y1= 9
|
||||
y2= 8
|
||||
|
||||
In general, the "vvp" command that executes the compiled simulation takes a
|
||||
few predefined argument flags, then the file name of the simulation. All the
|
||||
arguments after the simulation file name are extended arguments to "vvp" and
|
||||
are passed to the executed design. Extended arguments that start with a "+"
|
||||
character are accessible through the "$test$plusargs" and "$value$plusargs"
|
||||
system functions. Extended arguments that do not start with a "+" character
|
||||
are only accessible to system tasks and functions written in C using the VPI.
|
||||
|
||||
In the previous example, the program pulls the argument from the command line,
|
||||
assigns it to the variable "x", and runs the sqrt device under test with that
|
||||
value. This program can take the integer square root of any single value. Of
|
||||
course, if you wish to test with a large number of input values, executing the
|
||||
program many times may become tedious.
|
||||
|
||||
Another technique would be to put a set of input values into a data file, and
|
||||
write the test bench to read the file. We can then edit the file to add new
|
||||
input values, then rerun the simulation without compiling it again. The
|
||||
advantage of this technique is that we can accumulate a large set of test
|
||||
input values, and run the lot as a batch.
|
||||
|
||||
This example
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module main;
|
||||
|
||||
reg clk, reset;
|
||||
reg [31:0] data[4:0];
|
||||
reg [31:0] x;
|
||||
wire [15:0] y;
|
||||
wire rdy;
|
||||
|
||||
sqrt32 dut (clk, rdy, reset, x, y);
|
||||
|
||||
always #10 clk = ~clk;
|
||||
|
||||
integer i;
|
||||
initial begin
|
||||
/* Load the data set from the hex file. */
|
||||
$readmemh("sqrt.hex", data);
|
||||
for (i = 0 ; i <= 4 ; i = i + 1) begin
|
||||
clk = 0;
|
||||
reset = 1;
|
||||
|
||||
x = data[i];
|
||||
|
||||
#35 reset = 0;
|
||||
|
||||
wait (rdy) $display("y=%d", y);
|
||||
end
|
||||
$finish;
|
||||
end // initial begin
|
||||
|
||||
endmodule // main
|
||||
|
||||
demonstrates the use of "$readmemh" to read data samples from a file into a
|
||||
Verilog array. Start by putting into the file "sqrt.hex" the numbers::
|
||||
|
||||
51
|
||||
19
|
||||
1a
|
||||
18
|
||||
1
|
||||
|
||||
Then run the simulation with the command sequence::
|
||||
|
||||
% iverilog -osqrt_readmem.vvp sqrt_readmem.vl sqrt.vl
|
||||
% vvp sqrt_readmem.vvp
|
||||
y= 9
|
||||
y= 5
|
||||
y= 5
|
||||
y= 4
|
||||
y= 1
|
||||
|
||||
It is easy enough to change this program to work with larger data sets, or to
|
||||
change the "data.hex" file to contain different data. This technique is also
|
||||
common for simulating algorithms that take in larger data sets. One can extend
|
||||
this idea slightly by using a "$value$plusargs" statement to select the file
|
||||
to read.
|
||||
@@ -1,35 +0,0 @@
|
||||
|
||||
Verilog Attributes
|
||||
==================
|
||||
|
||||
This is a description of the various attributes that the Icarus Verilog tools
|
||||
understand. The attributes are attached to objects using the "(\* ... \*)"
|
||||
syntax, which is described by the Verilog LRM.
|
||||
|
||||
Attributes that start with "ivl\_" are Icarus Verilog specific are are probably
|
||||
ignored by other tools.
|
||||
|
||||
Optimizations
|
||||
-------------
|
||||
|
||||
* ivl_do_not_elide (snapshot 20140619 or later)
|
||||
|
||||
This applies to signals (i.e. reg, wire, etc.) and tells the optimizer to
|
||||
not elide the signal, even if it is not referenced anywhere in the
|
||||
design. This is useful if the signal is for some reason only accessed by
|
||||
VPI/PLI code.
|
||||
|
||||
Synthesis
|
||||
---------
|
||||
|
||||
* ivl_synthesis_cell
|
||||
|
||||
Applied to a module definition, this tells the synthesizer that the module
|
||||
is a cell. The synthesizer does not descend into synthesis cells, as they
|
||||
are assumed to be primitives in the target technology.
|
||||
|
||||
* ivl_synthesis_off
|
||||
|
||||
Attached to an "always" statement, this tells the synthesizer that the
|
||||
statement is not to be synthesized. This may be useful, for example, to tell
|
||||
the compiler that a stretch of code is test-bench code.
|
||||
@@ -1,246 +0,0 @@
|
||||
|
||||
Using VPI
|
||||
=========
|
||||
|
||||
Icarus Verilog implements a portion of the PLI 2.0 API to Verilog. This allows
|
||||
programmers to write C code that interfaces with Verilog simulations to
|
||||
perform tasks otherwise impractical with straight Verilog. Many Verilog
|
||||
designers, especially those who only use Verilog as a synthesis tool, can
|
||||
safely ignore the entire matter of the PLI (and this chapter) but the designer
|
||||
who wishes to interface a simulation with the outside world cannot escape VPI.
|
||||
|
||||
The rest of this article assumes some knowledge of C programming, Verilog PLI,
|
||||
and of the compiler on your system. In most cases, Icarus Verilog assumes the
|
||||
GNU Compilation System is the compiler you are using, so tips and instructions
|
||||
that follow reflect that. If you are not a C programmer, or are not planning
|
||||
any VPI modules, you can skip this entire article. There are references at the
|
||||
bottom for information about more general topics.
|
||||
|
||||
How It Works
|
||||
------------
|
||||
|
||||
The VPI modules are compiled loadable object code that the runtime loads at
|
||||
the user's request. The user commands vvp to locate and load modules with the
|
||||
"-m" switch. For example, to load the "sample.vpi" module::
|
||||
|
||||
% vvp -msample foo.vvp
|
||||
|
||||
The vvp run-time loads the modules first, before executing any of the
|
||||
simulation, or even before compiling the vvp code. Part of the loading
|
||||
includes invoking initialization routines. These routines register with the
|
||||
run-time all the system tasks and functions that the module implements. Once
|
||||
this is done, the run time loader can match names of the called system tasks
|
||||
of the design with the implementations in the VPI modules.
|
||||
|
||||
(There is a special module, the system.vpi module, that is always loaded to
|
||||
provide the core system tasks.)
|
||||
|
||||
The simulator run time (The "vvp" program) gets a handle on a freshly loaded
|
||||
module by looking for the symbol "vlog_startup_routines" in the loaded
|
||||
module. This table, provided by the module author and compiled into the
|
||||
module, is a null terminated table of function pointers. The simulator calls
|
||||
each of the functions in the table in order. The following simple C definition
|
||||
defines a sample table::
|
||||
|
||||
void (*vlog_startup_routines[])() = {
|
||||
hello_register,
|
||||
0
|
||||
};
|
||||
|
||||
Note that the "vlog_startup_routines" table is an array of function pointers,
|
||||
with the last pointer a 0 to mark the end. The programmer can organize the
|
||||
module to include many startup functions in this table, if desired.
|
||||
|
||||
The job of the startup functions that are collected in the startup table is to
|
||||
declare the system tasks and functions that the module provides. A module may
|
||||
implement as many tasks/functions as desired, so a module can legitimately be
|
||||
called a library of system tasks and functions.
|
||||
|
||||
Compiling VPI Modules
|
||||
---------------------
|
||||
|
||||
To compile and link a VPI module for use with Icarus Verilog, you must compile
|
||||
all the source files of a module as if you were compiling for a DLL or shared
|
||||
object. With gcc under Linux, this means compiling with the "-fpic" flag. The
|
||||
module is then linked together with the vpi library like so::
|
||||
|
||||
% gcc -c -fpic hello.c
|
||||
% gcc -shared -o hello.vpi hello.o -lvpi
|
||||
|
||||
This assumes that the "vpi_user.h header file and the libvpi.a library file
|
||||
are installed on your system so that gcc may find them. This is normally the
|
||||
case under Linux and UNIX systems. An easier, the preferred method that works
|
||||
on all supported systems is to use the single command::
|
||||
|
||||
% iverilog-vpi hello.c
|
||||
|
||||
The "iverilog-vpi" command takes as command arguments the source files for
|
||||
your VPI module, compiles them with proper compiler flags, and links them into
|
||||
a vpi module with any system specific libraries and linker flags that are
|
||||
required. This simple command makes the "hello.vpi" module with minimum fuss.
|
||||
|
||||
A Worked Example
|
||||
----------------
|
||||
|
||||
Let us try a complete, working example. Place the C code that follows into the
|
||||
file hello.c::
|
||||
|
||||
# include <vpi_user.h>
|
||||
|
||||
static int hello_compiletf(char*user_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hello_calltf(char*user_data)
|
||||
{
|
||||
vpi_printf("Hello, World!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hello_register()
|
||||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$hello";
|
||||
tf_data.calltf = hello_calltf;
|
||||
tf_data.compiletf = hello_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = 0;
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
void (*vlog_startup_routines[])() = {
|
||||
hello_register,
|
||||
0
|
||||
};
|
||||
|
||||
and place the Verilog code that follows into hello.v::
|
||||
|
||||
module main;
|
||||
initial $hello;
|
||||
endmodule
|
||||
|
||||
Next, compile and execute the code with these steps::
|
||||
|
||||
% iverilog-vpi hello.c
|
||||
% iverilog -ohello.vvp hello.v
|
||||
% vvp -M. -mhello hello.vvp
|
||||
Hello, World!
|
||||
|
||||
The compile and link in this example are conveniently combined into the
|
||||
"iverilog-vpi" command. The "iverilog" command then compiles the "hello.v"
|
||||
Verilog source file to the "hello.vvp" program. Next, the "vvp" command
|
||||
demonstrates the use of the "-M" and "-m" flags to specify a vpi module search
|
||||
directory and vpi module name. Specifically, they tell the "vvp" command where
|
||||
to find the module we just compiled.
|
||||
|
||||
The "vvp" command, when executed as above, loads the "hello.vpi" module that
|
||||
it finds in the current working directory. When the module is loaded, the
|
||||
vlog_startup_routines table is scanned, and the "hello_register" function is
|
||||
executed. The "hello_register" function in turn tells "vvp" about the system
|
||||
tasks that are included in this module.
|
||||
|
||||
After the modules are all loaded, the "hello.vvp" design file is loaded and
|
||||
its call to the "$hello" system task is matched up to the version declared by
|
||||
the module. While "vvp" compiles the "hello.vvp" source, any calls to "$hello"
|
||||
are referred to the "compiletf" function. This function is called at compile
|
||||
time and can be used to check parameters to system tasks or function. It can
|
||||
be left empty like this, or left out completely. The "compiletf" function can
|
||||
help performance by collecting parameter checks in compile time, so they do
|
||||
not need to be done each time the system task is run, thus potentially saving
|
||||
execution time overall.
|
||||
|
||||
When the run-time executes the call to the hello system task, the
|
||||
"hello_calltf" function is invoked in the loaded module, and thus the output
|
||||
is generated. The "calltf" function is called at run time when the Verilog
|
||||
code actually executes the system task. This is where the active code of the
|
||||
task belongs.
|
||||
|
||||
System Function Return Types
|
||||
----------------------------
|
||||
|
||||
Icarus Verilog supports system functions as well as system tasks, but there is
|
||||
a complication. Notice how the module that you compile is only loaded by the
|
||||
"vvp" program. This is mostly not an issue, but elaboration of expressions
|
||||
needs to keep track of types, so the main compiler needs to know the return
|
||||
type of functions.
|
||||
|
||||
Starting with Icarus Verilog v11, the solution is quite simple. The names and
|
||||
locations of the user's VPI modules can be passed to the compiler via the
|
||||
"iverilog" -m and -L flags and the IVERILOG_VPI_MODULE_PATH environment
|
||||
variable. The compiler will load and analyse the specified modules to
|
||||
automatically determine any function return types. The compiler will also
|
||||
automatically pass the names and locations of the specified modules to the
|
||||
"vvp" program, so that they don't need to be specified again on the "vvp"
|
||||
command line.
|
||||
|
||||
For Icarus Verilog versions prior to v11, the solution requires that the
|
||||
developer of a module include the table in a form that the compiler can
|
||||
read. The System Function Table file carries this information. A simple
|
||||
example looks like this::
|
||||
|
||||
# Example sft declarations of some common functions
|
||||
$random vpiSysFuncInt
|
||||
$bitstoreal vpiSysFuncReal
|
||||
$realtobits vpiSysFuncSized 64 unsigned
|
||||
|
||||
This demonstrates the format of the file and support types. Each line contains
|
||||
a comment (starts with "#") or a type declaration for a single function. The
|
||||
declaration starts with the name of the system function (including the leading
|
||||
"$") and ends with the type. The supported types are:
|
||||
|
||||
* vpiSysFuncInt
|
||||
* vpiSysFuncReal
|
||||
* vpiSysFuncSized <wid> <signed|unsigned>
|
||||
|
||||
Any functions that do not have an explicit type declaration in an SFT file are
|
||||
implicitly taken to be "vpiSysFuncSized 32 unsigned".
|
||||
|
||||
The module author provides, along with the ".vpi" file that is the module, a
|
||||
".sft" that declares all the function return types. For example, if the file
|
||||
is named "example.sft", pass it to the "iverilog" command line or in the
|
||||
command file exactly as if it were an ordinary source file.
|
||||
|
||||
Cadence PLI Modules
|
||||
-------------------
|
||||
|
||||
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. In addition, a 64-bit
|
||||
version of vvp can only load 64-bit PLI1 applications, etc.
|
||||
|
||||
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.
|
||||
|
||||
Other References
|
||||
----------------
|
||||
|
||||
Since the above only explains how to get PLI/VPI working with Icarus Verilog,
|
||||
here are some references to material to help with the common aspects of
|
||||
PLI/VPI.
|
||||
|
||||
* Principles of Verilog PLI by Swapnajit Mittra. ISBN 0-7923-8477-6
|
||||
* The Verilog PLI Handbook by Stuart Sutherland. ISBN 0-7923-8489-X
|
||||
@@ -1,148 +0,0 @@
|
||||
Vvp Interactive Mode
|
||||
====================
|
||||
|
||||
The vvp command has an interactive debug mode, where you can stop the
|
||||
simulation and browse the current state of the simulation. There are
|
||||
a couple ways to enter the debug mode, but once in interactive debug
|
||||
mode, the usage is the same. Consider the example below:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module clock(output reg clock);
|
||||
initial clock = 1'b1;
|
||||
always #100 clock = !clock;
|
||||
endmodule // clock
|
||||
|
||||
module main;
|
||||
|
||||
reg [2:0] foo;
|
||||
wire clk;
|
||||
|
||||
clock foo_clock(clk);
|
||||
|
||||
always @(posedge clk)
|
||||
foo <= foo + 1;
|
||||
|
||||
initial begin
|
||||
foo = 3'b000;
|
||||
#250 $stop;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
In examples that follow, we will use the above sample program.
|
||||
|
||||
Enter Interactive Mode
|
||||
----------------------
|
||||
|
||||
The first and most common method is to put "$stop" system task
|
||||
calls in the simulation at the times where you want to simulation
|
||||
to break and enter interactive mode. The example above has a $stop,
|
||||
so the output looks like this::
|
||||
|
||||
../foo.vl:25: $stop called at 250 (1s)
|
||||
** VVP Stop(0) **
|
||||
** Flushing output streams.
|
||||
** Current simulation time is 250 ticks.
|
||||
>
|
||||
|
||||
You can get some interactive help by using the "help" command::
|
||||
|
||||
> help
|
||||
Commands can be from the following table of base commands,
|
||||
or can be invocations of system tasks/functions.
|
||||
|
||||
cd - Synonym for push.
|
||||
cont - Resume (continue) the simulation
|
||||
finish - Finish the simulation.
|
||||
help - Get help.
|
||||
list - List items in the current scope.
|
||||
load - Load a VPI module, a la vvp -m.
|
||||
ls - Shorthand for "list".
|
||||
pop - Pop one scope from the scope stack.
|
||||
push - Descend into the named scope.
|
||||
step - Single-step the scheduler for 1 event.
|
||||
time - Print the current simulation time.
|
||||
trace - Control statement tracing (on/off) when the code is instrumented.
|
||||
where - Show current scope, and scope hierarchy stack.
|
||||
|
||||
If the command name starts with a '$' character, it
|
||||
is taken to be the name of a system task, and a call is
|
||||
built up and executed. For example, "$display foo" will
|
||||
call the function as $display(foo).
|
||||
|
||||
You can also enter interactive mode at the terminal by interrupting the
|
||||
execution with a "^C" (Control-C) character. The vvp engine catches the
|
||||
terminal interrupt and drops you into the interactive prompt::
|
||||
|
||||
^C** VVP Stop(0) **
|
||||
** Flushing output streams.
|
||||
** Current simulation time is 533928600 ticks.
|
||||
>
|
||||
|
||||
This could be useful if you suspect that your simulation is stuck in
|
||||
an infinite loop and you want to rummage around and see what's going on.
|
||||
|
||||
And finally, you can pass the "-s" command line flag to vvp to tell it
|
||||
to execute "$stop" at the beginning of the simulation, before any other
|
||||
events are executed. This may be useful as a way to manually set up some
|
||||
details about the simulation.
|
||||
|
||||
Browsing the Design
|
||||
-------------------
|
||||
|
||||
Now that you are in the interactive prompt, you can browse
|
||||
around the design::
|
||||
|
||||
> ls
|
||||
2 items in this scope:
|
||||
package : $unit
|
||||
module : main
|
||||
> cd main
|
||||
> ls
|
||||
3 items in this scope:
|
||||
reg : foo[2:0]
|
||||
module : foo_clock
|
||||
net : clk
|
||||
> where
|
||||
module main
|
||||
> $display foo
|
||||
1
|
||||
> cd foo_clock
|
||||
> where
|
||||
module foo_clock
|
||||
module main
|
||||
> ls
|
||||
2 items in this scope:
|
||||
port : clock -- output
|
||||
reg : clock
|
||||
|
||||
In the above example, the 'cd' and 'pop' commands descend into a scope
|
||||
or pop back up a scope level. The 'where' command shows the scope stack,
|
||||
and the 'ls' command lists the items present in the scope. With these
|
||||
commands, one can browse freely throughout the design scope hierarchy.
|
||||
|
||||
It is also possible to call system tasks within the debug mode. The call
|
||||
to the "$display" function is an example of this. In general, any system
|
||||
task can be invoked, in the current context, with the objects that are
|
||||
included on the command line passed as arguments. The arguments can be
|
||||
variables or nets, and various kinds of literals::
|
||||
|
||||
> ls
|
||||
2 items in this scope:
|
||||
port : clock -- output
|
||||
reg : clock
|
||||
> $display "Hello, World! " 10 " " clock
|
||||
Hello, World! 10 1
|
||||
|
||||
This is a great way to call custom system tasks as well. And system task
|
||||
that vvp knows about can be invoked this way.
|
||||
|
||||
Leave Interactive Mode
|
||||
----------------------
|
||||
|
||||
After you are done probing around in the interactive mode, you can
|
||||
resume the simulation, or termimate execution. Resume the simulation
|
||||
with the "cont" command, and terminate the simulation with the
|
||||
"finish" command. The latter is the same as executing the
|
||||
"$finish" system task.
|
||||
@@ -1,109 +0,0 @@
|
||||
VVP Command Line Flags
|
||||
======================
|
||||
|
||||
The vvp command is the simulation run-time engine. The command line for vvp
|
||||
execution is first the options and flags, then the vvp input file, and finally
|
||||
extended arguments. Typical usage looks like this::
|
||||
|
||||
% vvp <flags> foo.vvp <extended arguments>
|
||||
|
||||
Options/Flags
|
||||
-------------
|
||||
|
||||
These options/flags go before the path to the vvp-executable program. They
|
||||
effect behavior of the vvp runtime engine, including preparation for
|
||||
simulation.
|
||||
|
||||
* -l<logfile>
|
||||
|
||||
This flag specifies a logfile where all MCI <stdlog> output goes. Specify
|
||||
logfile as '-' to send log output to <stderr>. $display and friends send
|
||||
their output both to <stdout> and <stdlog>.
|
||||
|
||||
* -M<path>
|
||||
|
||||
Add the directory path to the (VPI) module search path. Multiple "-M" flags
|
||||
are allowed, and the directories are added in the order that they are given
|
||||
on the command line.
|
||||
|
||||
The string "-M-" is special, in that it doesn't add a directory to the
|
||||
path. It instead *removes* the compiled directory. This is generally used
|
||||
only for development of the vvp engine.
|
||||
|
||||
* -m<module>
|
||||
|
||||
Name a VPI module that should be loaded. The vvp engine looks for the named
|
||||
module in the module search path, which includes the compiled in default
|
||||
directory and directories given by "-M" flags.
|
||||
|
||||
NOTE: Starting with v11.0, the VPI modules to be loaded can be specified
|
||||
when you compile your design. This allows the compiler to automatically
|
||||
determine the return types of user-defined system functions. If specified at
|
||||
compile-time, there is no need to specify them again here.
|
||||
|
||||
* -s
|
||||
|
||||
$stop right away, in the beginning of the simulation. This kicks the
|
||||
vvp program into interactive debug mode.
|
||||
|
||||
* -v
|
||||
|
||||
Show verbose progress while setting up or cleaning up the runtime
|
||||
engine. This also displays some performance information.
|
||||
|
||||
Extended Arguments
|
||||
------------------
|
||||
|
||||
The extended arguments are available to the simulation runtime, especially
|
||||
system tasks, system functions and any VPI/PLI code. Extended arguments that
|
||||
start with a "+" character are left for use by the user via the $plus$flag and
|
||||
$plus$value functions.
|
||||
|
||||
VCD/FST/LXT Arguments
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If not otherwise specified, the vvp engine will by default use VCD formats to
|
||||
support the $dumpvars system task. The flags described here can alter that
|
||||
behavior.
|
||||
|
||||
* -none/-vcd-none/-vcd-off/-fst-none
|
||||
|
||||
Disable trace output. The trace output will be stubbed so that no trace file
|
||||
is created and the cost of dumping is avoided. All off these options are
|
||||
synonyms for turning of dumping.
|
||||
|
||||
* -fst
|
||||
|
||||
Generate FST format outputs instead of VCD format waveform dumps. This is
|
||||
the preferred output format if using GTKWave for viewing waveforms.
|
||||
|
||||
* -lxt/-lxt2
|
||||
|
||||
Generate LXT or LXT2format instead of VCD format waveform dumps. The LXT2
|
||||
format is more advanced.
|
||||
|
||||
SDF Support
|
||||
^^^^^^^^^^^
|
||||
|
||||
The Icarus Verilog support for SDF back-annotation can take some extended
|
||||
arguments to control aspects of SDF support.
|
||||
|
||||
* -sdf-warn
|
||||
|
||||
Print warnings during load of/annotation from an SDF file.
|
||||
|
||||
* -sdf-info
|
||||
|
||||
Print interesting information about an SDF file while parsing it.
|
||||
|
||||
* -sdf-verbose
|
||||
|
||||
Print warnings and info messages.
|
||||
|
||||
Environment Variables
|
||||
---------------------
|
||||
|
||||
The vvp program pays attention to certain environment variables.
|
||||
|
||||
* IVERILOG_DUMPER
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,40 +14,44 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: HName.cc,v 1.8 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "HName.h"
|
||||
# include <iostream>
|
||||
# include <cstring>
|
||||
# include <cstdlib>
|
||||
# include <climits>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
hname_t::hname_t()
|
||||
{
|
||||
number_ = INT_MIN;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text)
|
||||
: name_(text)
|
||||
{
|
||||
name_ = text;
|
||||
number_ = INT_MIN;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text, int num)
|
||||
: name_(text), number_(1)
|
||||
{
|
||||
number_[0] = num;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text, const vector<int>&nums)
|
||||
: name_(text), number_(nums)
|
||||
{
|
||||
name_ = text;
|
||||
number_ = num;
|
||||
}
|
||||
|
||||
hname_t::hname_t(const hname_t&that)
|
||||
: name_(that.name_), number_(that.number_)
|
||||
{
|
||||
name_ = that.name_;
|
||||
number_ = that.number_;
|
||||
}
|
||||
|
||||
hname_t& hname_t::operator = (const hname_t&that)
|
||||
@@ -57,55 +61,51 @@ hname_t& hname_t::operator = (const hname_t&that)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool hname_t::operator < (const hname_t&r) const
|
||||
hname_t::~hname_t()
|
||||
{
|
||||
int cmp = strcmp(name_, r.name_);
|
||||
}
|
||||
|
||||
perm_string hname_t::peek_name(void) const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
bool hname_t::has_number() const
|
||||
{
|
||||
return number_ != INT_MIN;
|
||||
}
|
||||
|
||||
int hname_t::peek_number() const
|
||||
{
|
||||
return number_;
|
||||
}
|
||||
|
||||
bool operator < (const hname_t&l, const hname_t&r)
|
||||
{
|
||||
int cmp = strcmp(l.peek_name(), r.peek_name());
|
||||
if (cmp < 0) return true;
|
||||
if (cmp > 0) return false;
|
||||
|
||||
// The text parts are equal, so compare then number
|
||||
// parts. Finish as soon as we find one to be less or more
|
||||
// than the other.
|
||||
size_t idx = 0;
|
||||
while (number_.size() > idx || r.number_.size() > idx) {
|
||||
|
||||
// Ran out of l numbers, so less.
|
||||
if (number_.size() <= idx)
|
||||
return true;
|
||||
|
||||
// Ran out of r numbers, so greater.
|
||||
if (r.number_.size() <= idx)
|
||||
return false;
|
||||
|
||||
if (number_[idx] < r.number_[idx])
|
||||
return true;
|
||||
|
||||
if (number_[idx] > r.number_[idx])
|
||||
return false;
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
// Fall-through means that we are equal, including all the
|
||||
// number parts, so not less.
|
||||
return false;
|
||||
if (l.has_number() && r.has_number())
|
||||
return l.peek_number() < r.peek_number();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hname_t::operator == (const hname_t&r) const
|
||||
bool operator == (const hname_t&l, const hname_t&r)
|
||||
{
|
||||
if (name_ == r.name_) {
|
||||
if (number_.size() != r.number_.size())
|
||||
return false;
|
||||
|
||||
for (size_t idx = 0 ; idx < number_.size() ; idx += 1)
|
||||
if (number_[idx] != r.number_[idx]) return false;
|
||||
|
||||
return true;
|
||||
if (l.peek_name() == r.peek_name()) {
|
||||
if (l.has_number() && r.has_number())
|
||||
return l.peek_number() == r.peek_number();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator != (const hname_t&l, const hname_t&r)
|
||||
{ return ! (l==r); }
|
||||
|
||||
ostream& operator<< (ostream&out, const hname_t&that)
|
||||
{
|
||||
if (that.peek_name() == 0) {
|
||||
@@ -114,8 +114,39 @@ ostream& operator<< (ostream&out, const hname_t&that)
|
||||
}
|
||||
|
||||
out << that.peek_name();
|
||||
for (size_t idx = 0 ; idx < that.number_.size() ; idx += 1)
|
||||
out << "[" << that.number_[idx] << "]";
|
||||
if (that.has_number())
|
||||
out << "[" << that.peek_number() << "]";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: HName.cc,v $
|
||||
* Revision 1.8 2007/06/02 03:42:12 steve
|
||||
* Properly evaluate scope path expressions.
|
||||
*
|
||||
* Revision 1.7 2007/05/16 19:12:33 steve
|
||||
* Fix hname_t use of space for 1 perm_string.
|
||||
*
|
||||
* Revision 1.6 2007/04/26 03:06:21 steve
|
||||
* Rework hname_t to use perm_strings.
|
||||
*
|
||||
* Revision 1.5 2002/11/02 03:27:52 steve
|
||||
* Allow named events to be referenced by
|
||||
* hierarchical names.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/01/05 04:36:06 steve
|
||||
* include malloc.h only when available.
|
||||
*
|
||||
* Revision 1.2 2001/12/18 04:52:45 steve
|
||||
* Include config.h for namespace declaration.
|
||||
*
|
||||
* Revision 1.1 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_HName_H
|
||||
#define IVL_HName_H
|
||||
#ifndef __HName_H
|
||||
#define __HName_H
|
||||
/*
|
||||
* Copyright (c) 2001-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001-2007 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,15 +16,19 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: HName.h,v 1.7 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
# include <list>
|
||||
# include <vector>
|
||||
# include "StringHeap.h"
|
||||
|
||||
# include <cassert>
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 2
|
||||
using namespace std;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This class represents a component of a Verilog hierarchical name. A
|
||||
@@ -36,77 +40,60 @@
|
||||
|
||||
class hname_t {
|
||||
|
||||
friend std::ostream& operator<< (std::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, const std::vector<int>&nums);
|
||||
hname_t (const hname_t&that);
|
||||
~hname_t();
|
||||
|
||||
hname_t& operator= (const hname_t&);
|
||||
|
||||
bool operator == (const hname_t&that) const;
|
||||
bool operator < (const hname_t&that) const;
|
||||
|
||||
// Return the string part of the hname_t.
|
||||
perm_string peek_name(void) const;
|
||||
|
||||
size_t has_numbers() const;
|
||||
int peek_number(size_t idx) const;
|
||||
const std::vector<int>&peek_numbers() const;
|
||||
bool has_number() const;
|
||||
int peek_number() const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
// If this vector has size, then the numbers all together make
|
||||
// up part of the hierarchical name.
|
||||
std::vector<int> number_;
|
||||
// If the number is anything other then INT_MIN, then this is
|
||||
// the numeric part of the name. Otherwise, it is not part of
|
||||
// the name at all.
|
||||
int number_;
|
||||
|
||||
private: // not implemented
|
||||
};
|
||||
|
||||
inline hname_t::~hname_t()
|
||||
{
|
||||
}
|
||||
extern bool operator < (const hname_t&, const hname_t&);
|
||||
extern bool operator == (const hname_t&, const hname_t&);
|
||||
extern bool operator != (const hname_t&, const hname_t&);
|
||||
extern ostream& operator<< (ostream&, const hname_t&);
|
||||
|
||||
inline 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 const std::vector<int>& hname_t::peek_numbers(void) const
|
||||
{
|
||||
return number_;
|
||||
}
|
||||
|
||||
inline size_t hname_t::has_numbers() const
|
||||
{
|
||||
return number_.size();
|
||||
}
|
||||
|
||||
extern std::ostream& operator<< (std::ostream&, const hname_t&);
|
||||
|
||||
inline bool operator != (const hname_t&l, const hname_t&r)
|
||||
{ return ! (l == r); }
|
||||
|
||||
inline std::ostream& operator<< (std::ostream&out, const std::list<hname_t>&ll)
|
||||
{
|
||||
std::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.7 2007/06/02 03:42:12 steve
|
||||
* Properly evaluate scope path expressions.
|
||||
*
|
||||
* Revision 1.6 2007/05/16 19:12:33 steve
|
||||
* Fix hname_t use of space for 1 perm_string.
|
||||
*
|
||||
* Revision 1.5 2007/04/26 03:06:21 steve
|
||||
* Rework hname_t to use perm_strings.
|
||||
*
|
||||
* Revision 1.4 2002/11/02 03:27:51 steve
|
||||
* Allow named events to be referenced by
|
||||
* hierarchical names.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/06/14 03:25:51 steve
|
||||
* Compiler portability.
|
||||
*
|
||||
* Revision 1.1 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -19,8 +19,8 @@ diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.ac' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.ac' if you want to change
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
@@ -178,3 +178,4 @@ operates.
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
||||
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
LineInfo::LineInfo()
|
||||
: lineno_(0)
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_LineInfo_H
|
||||
#define IVL_LineInfo_H
|
||||
#ifndef __LineInfo_H
|
||||
#define __LineInfo_H
|
||||
/*
|
||||
* Copyright (c) 1999-2021 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,12 +16,14 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
* This class holds line information for an internal object.
|
||||
*
|
||||
@@ -34,11 +36,11 @@
|
||||
class LineInfo {
|
||||
public:
|
||||
LineInfo();
|
||||
virtual ~LineInfo();
|
||||
~LineInfo();
|
||||
|
||||
// Get a fully formatted file/lineno
|
||||
std::string get_fileline() const;
|
||||
// Set the file/line from another LineInfo object.
|
||||
string get_fileline() const;
|
||||
// Set the file/line fro another LineInfo object.
|
||||
void set_line(const LineInfo&that);
|
||||
|
||||
// Access parts of LineInfo data
|
||||
@@ -52,4 +54,4 @@ class LineInfo {
|
||||
unsigned lineno_;
|
||||
};
|
||||
|
||||
#endif /* IVL_LineInfo_H */
|
||||
#endif
|
||||
+168
-237
@@ -12,68 +12,36 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
# Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
# The interesting make targets are:
|
||||
#
|
||||
# make version
|
||||
# Force the version_tag.h file to be rebuilt. Otherwise, it will only
|
||||
# be built if it is missing.
|
||||
#
|
||||
# make all
|
||||
# make install
|
||||
#
|
||||
# The "suffix" is used as an installation suffix. It modifies certain
|
||||
# key install paths/files such that a build and install of Icarus Verilog
|
||||
# with the same $(prefix) but a different $(suffix) will not interfere.
|
||||
# The normal configuration leaves suffix empty
|
||||
suffix = @install_suffix@
|
||||
# This version string is only used in the version message printed
|
||||
# by the compiler. It reflects the assigned version number for the
|
||||
# product as a whole. Most components also print the CVS Name: token
|
||||
# in order to get a more automatic version stamp as well.
|
||||
VERSION = 0.9.devel
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
SUBDIRS = ivlpp vhdlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
|
||||
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver
|
||||
# Only run distclean for these directories.
|
||||
NOTUSED = tgt-fpga tgt-pal tgt-verilog
|
||||
SUBDIRS = @subdirs@
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
else
|
||||
NOTUSED += driver-vpi
|
||||
endif
|
||||
|
||||
# To get the version headers to build correctly we only want to look
|
||||
# for C++ files in the source directory. All other files will require
|
||||
# an explicit $(srcdir). The one exception to this is if we need to
|
||||
# rebuild the lexor_keyword.cc file. If we do, then we want to use the
|
||||
# local version instead of the one is $(srcdir).
|
||||
vpath lexor_keyword.cc .
|
||||
vpath %.cc $(srcdir)/libmisc
|
||||
vpath %.cc $(srcdir)
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
# This is actually the directory where we install our own header files.
|
||||
# It is a little different from the generic includedir.
|
||||
includedir = @includedir@/iverilog$(suffix)
|
||||
includedir = @includedir@
|
||||
mandir = @mandir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
|
||||
# For a cross compile these defines will need to be set accordingly.
|
||||
HOSTCC = @CC@
|
||||
HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
|
||||
BUILDCC = @CC_FOR_BUILD@
|
||||
BUILDEXT = @BUILD_EXEEXT@
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
@@ -84,132 +52,73 @@ MAN = @MAN@
|
||||
PS2PDF = @PS2PDF@
|
||||
GIT = @GIT@
|
||||
|
||||
ifeq (@srcdir@,.)
|
||||
INCLUDE_PATH = -I. -Ilibmisc
|
||||
else
|
||||
INCLUDE_PATH = -I. -I$(srcdir) -I$(srcdir)/libmisc
|
||||
endif
|
||||
|
||||
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
||||
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
|
||||
CXXFLAGS = -Wall @CXXFLAGS@
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
CTARGETFLAGS = @CTARGETFLAGS@
|
||||
|
||||
# Source files in the libmisc directory
|
||||
M = LineInfo.o StringHeap.o
|
||||
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o
|
||||
FF = cprop.o exposenodes.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_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_types.o \
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o vpi_modules.o target.o \
|
||||
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PFunction.o \
|
||||
PGate.o PGenerate.o PModport.o PNamedItem.o PPackage.o PScope.o PSpec.o \
|
||||
PTask.o PUdp.o PWire.o Statement.o AStatement.o $M $(FF) $(TT)
|
||||
|
||||
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
all: dep version.h ivl@EXEEXT@
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for dir in ivlpp ; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
cd driver ; $(MAKE) VERSION=$(VERSION) $@
|
||||
|
||||
# In the windows world, the installer will need a dosify program to
|
||||
# dosify text files.
|
||||
ifeq (@MINGW32@,yes)
|
||||
all: dosify$(BUILDEXT)
|
||||
dosify$(BUILDEXT): $(srcdir)/dosify.c
|
||||
$(BUILDCC) $(CFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c
|
||||
all: dep dosify.exe
|
||||
dosify.exe: dosify.c
|
||||
$(CC) -o dosify.exe dosify.c
|
||||
endif
|
||||
|
||||
# This rule rules the compiler in the trivial hello.vl program to make
|
||||
# sure the basics were compiled properly.
|
||||
check: all
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
|
||||
test -r check.conf || cp $(srcdir)/check.conf .
|
||||
driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@install_suffix@,)
|
||||
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
else
|
||||
# On Windows if we have a suffix we must run the vvp part of
|
||||
# the test with a suffix since it was built/linked that way.
|
||||
ln vvp/vvp.exe vvp/vvp$(suffix).exe
|
||||
vvp/vvp$(suffix) -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
rm vvp/vvp$(suffix).exe
|
||||
endif
|
||||
else
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
endif
|
||||
|
||||
clean:
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
rm -f *.o parse.cc parse.h lexor.cc
|
||||
rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps
|
||||
rm -f parse.output syn-rules.output dosify$(BUILDEXT) ivl@EXEEXT@ check.vvp
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
|
||||
rm -f ivl.exp iverilog-vpi.pdf iverilog-vpi.ps parse.output
|
||||
rm -f syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc*
|
||||
rm -rf dep
|
||||
rm -f version.exe
|
||||
|
||||
distclean: clean
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) $@ && ) true
|
||||
rm -f Makefile config.status config.log config.cache
|
||||
rm -f stamp-config-h config.h
|
||||
rm -f stamp-_pli_types-h _pli_types.h
|
||||
ifneq (@srcdir@,.)
|
||||
rm -f version_tag.h check.conf
|
||||
rmdir $(SUBDIRS) $(NOTUSED)
|
||||
endif
|
||||
rm -rf autom4te.cache
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
rm -f Makefile config.status config.log config.cache config.h
|
||||
rm -f _pli_types.h
|
||||
|
||||
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c
|
||||
cppcheck --enable=all --std=c99 --std=c++03 -f \
|
||||
--suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
|
||||
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
|
||||
-UYYSTYPE -U__SIZE_TYPE__ -Umalloc -Ufree \
|
||||
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o
|
||||
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o
|
||||
|
||||
cppcheck-all:
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) cppcheck && ) true
|
||||
$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) cppcheck && ) true
|
||||
$(MAKE) cppcheck
|
||||
O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o elab_expr.o \
|
||||
elab_lval.o elab_net.o elab_pexpr.o elab_scope.o \
|
||||
elab_sig.o emit.o eval.o eval_attrib.o \
|
||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||
load_module.o netlist.o netmisc.o net_assign.o \
|
||||
net_design.o net_event.o net_expr.o net_force.o net_func.o \
|
||||
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
|
||||
net_proc.o net_scope.o net_tran.o net_udp.o pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_disciplines.o pform_dump.o pform_types.o \
|
||||
set_width.o symbol_search.o sync.o sys_funcs.o \
|
||||
verinum.o verireal.o target.o targets.o \
|
||||
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
|
||||
PExpr.o PGate.o PGenerate.o PScope.o PSpec.o \
|
||||
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
|
||||
$(FF) $(TT)
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in config.status
|
||||
./config.status --file=$@
|
||||
|
||||
dep:
|
||||
mkdir dep
|
||||
|
||||
stamp-config-h: $(srcdir)/config.h.in config.status
|
||||
@rm -f $@
|
||||
./config.status config.h
|
||||
config.h: stamp-config-h
|
||||
|
||||
stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
|
||||
@rm -f $@
|
||||
./config.status _pli_types.h
|
||||
_pli_types.h: stamp-_pli_types-h
|
||||
|
||||
$(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/aclocal.m4
|
||||
cd $(srcdir) && autoconf
|
||||
|
||||
config.status: $(srcdir)/configure
|
||||
./config.status --recheck
|
||||
Makefile: Makefile.in config.h.in config.status
|
||||
./config.status
|
||||
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
# Under Windows (mingw) I need to make the ivl.exe in two steps.
|
||||
# The first step makes an ivl.exe that dlltool can use to make an
|
||||
@@ -217,7 +126,7 @@ ifeq (@WIN32@,yes)
|
||||
# that really exports the things that the import library imports.
|
||||
ivl@EXEEXT@: $O $(srcdir)/ivl.def
|
||||
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
|
||||
$(DLLTOOL) --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
|
||||
dlltool --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
|
||||
--output-lib libivl.a --output-exp ivl.exp
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||
else
|
||||
@@ -225,163 +134,185 @@ ivl@EXEEXT@: $O
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,no)
|
||||
all: iverilog-vpi
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
else
|
||||
all: dep iverilog-vpi
|
||||
|
||||
iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
|
||||
iverilog-vpi: iverilog-vpi.sh
|
||||
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
||||
-e 's;@SUFFIX@;$(suffix);' \
|
||||
-e 's;@IVCC@;$(CC);' \
|
||||
-e 's;@IVCXX@;$(CXX);' \
|
||||
-e 's;@IVCFLAGS@;$(CFLAGS);' \
|
||||
-e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@IVCTARGETFLAGS@;$(CTARGETFLAGS);' \
|
||||
-e 's;@INCLUDEDIR@;$(includedir);' \
|
||||
-e 's;@IVCFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@INCLUDEDIR@;@includedir@;' \
|
||||
-e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||
chmod +x $@
|
||||
endif
|
||||
|
||||
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
|
||||
$(BUILDCC) $(CFLAGS) -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
|
||||
dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.cc config.h
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
%.o: %.cc
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
# Here are some explicit dependencies needed to get things going.
|
||||
main.o: main.cc version_tag.h
|
||||
|
||||
lexor.o: lexor.cc parse.h
|
||||
|
||||
parse.o: parse.cc
|
||||
|
||||
# Use pattern rules to avoid parallel build issues (see pr3462585)
|
||||
parse%cc parse%h: $(srcdir)/parse%y
|
||||
$(YACC) --verbose -t -p VL --defines=parse.h -o parse.cc $<
|
||||
parse.cc parse.h: $(srcdir)/parse.y
|
||||
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
|
||||
mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
|
||||
|
||||
syn-rules.cc: $(srcdir)/syn-rules.y
|
||||
$(YACC) --verbose -t -p syn_ -o $@ $<
|
||||
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
|
||||
|
||||
lexor.cc: $(srcdir)/lexor.lex
|
||||
$(LEX) -s -t $< > $@
|
||||
$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex
|
||||
|
||||
lexor_keyword.o: lexor_keyword.cc parse.h
|
||||
|
||||
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
|
||||
gperf -o -i 7 -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
|
||||
lexor_keyword.cc: lexor_keyword.gperf
|
||||
gperf -o -i 7 -C -k 1-4,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
|
||||
|
||||
iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
|
||||
./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@
|
||||
tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@
|
||||
|
||||
iverilog-vpi.ps: iverilog-vpi.man
|
||||
$(MAN) -t ./iverilog-vpi.man > iverilog-vpi.ps
|
||||
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
|
||||
$(MAN) -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
|
||||
|
||||
iverilog-vpi.pdf: iverilog-vpi.ps
|
||||
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
|
||||
|
||||
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
|
||||
# version_tag.h file in the source tree (included in snapshots and releases),
|
||||
# and finally use nothing.
|
||||
|
||||
# version.h file in the source tree (included in snapshots and releases), and
|
||||
# finally use nothing.
|
||||
.PHONY: version.h
|
||||
# "true" and "false" in the next few lines are Unix shell command names
|
||||
ifeq ($(GIT),none)
|
||||
GIT_PRESENT = false
|
||||
else
|
||||
GIT_PRESENT = true
|
||||
endif
|
||||
version_tag.h version:
|
||||
version.h:
|
||||
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
|
||||
echo "Using git-describe for VERSION_TAG"; \
|
||||
tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \
|
||||
tmp=`$(GIT) --git-dir $(srcdir)/.git describe \
|
||||
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
|
||||
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
|
||||
elif test -r $(srcdir)/version_tag.h; then \
|
||||
echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \
|
||||
diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \
|
||||
echo "$$tmp" | diff - $@ > /dev/null 2>&1 || echo "$$tmp" > $@ || exit 1; \
|
||||
elif test -r $(srcdir)/$@; then \
|
||||
echo "Using $(srcdir)/$@ for VERSION_TAG"; \
|
||||
diff $(srcdir)/$@ $@ > /dev/null 2>&1 || cp $(srcdir)/$@ $@; \
|
||||
else \
|
||||
echo "Using empty VERSION_TAG"; \
|
||||
echo '#define VERSION_TAG ""' > version_tag.h; \
|
||||
echo '#define VERSION_TAG ""' > $@; \
|
||||
fi
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
ifeq ($(MAN),none)
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
|
||||
else
|
||||
ifeq ($(PS2PDF),none)
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
|
||||
else
|
||||
INSTALL_DOC = installpdf installman
|
||||
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf $(mandir)/man1/iverilog-vpi.1
|
||||
all: dep iverilog-vpi.pdf
|
||||
endif
|
||||
endif
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
else
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
WIN32_INSTALL =
|
||||
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
|
||||
else
|
||||
WIN32_INSTALL = installwin32
|
||||
WIN32_INSTALL = $(bindir)/iverilog-vpi
|
||||
endif
|
||||
|
||||
install: all installdirs installfiles
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf
|
||||
|
||||
F = ./ivl@EXEEXT@ \
|
||||
$(srcdir)/constants.vams \
|
||||
$(srcdir)/disciplines.vams \
|
||||
$(srcdir)/ivl_target.h \
|
||||
./_pli_types.h \
|
||||
$(srcdir)/sv_vpi_user.h \
|
||||
$(srcdir)/vpi_user.h \
|
||||
$(srcdir)/acc_user.h \
|
||||
$(srcdir)/veriuser.h \
|
||||
$(INSTALL_DOC) \
|
||||
$(WIN32_INSTALL)
|
||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/include/constants.vams $(libdir)/ivl/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp driver; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
|
||||
installwin32: ./iverilog-vpi installdirs
|
||||
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
|
||||
$(bindir)/iverilog-vpi: ./iverilog-vpi
|
||||
$(INSTALL_SCRIPT) ./iverilog-vpi $(DESTDIR)$(bindir)/iverilog-vpi
|
||||
|
||||
installman: iverilog-vpi.man installdirs
|
||||
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
|
||||
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(DESTDIR)$(libdir)/ivl/ivl@EXEEXT@
|
||||
|
||||
installpdf: iverilog-vpi.pdf installdirs
|
||||
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
|
||||
$(libdir)/ivl/include/constants.vams: $(srcdir)/constants.vams
|
||||
$(INSTALL_DATA) $(srcdir)/constants.vams $@
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@"
|
||||
$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
|
||||
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h"
|
||||
$(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(includedir)/_pli_types.h"
|
||||
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(includedir)/sv_vpi_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
|
||||
$(libdir)/ivl/include/disciplines.vams: $(srcdir)/disciplines.vams
|
||||
$(INSTALL_DATA) $(srcdir)/disciplines.vams $@
|
||||
|
||||
installdirs: $(srcdir)/mkinstalldirs
|
||||
$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \
|
||||
"$(DESTDIR)$(includedir)" \
|
||||
"$(DESTDIR)$(libdir)/ivl$(suffix)" \
|
||||
"$(DESTDIR)$(libdir)/ivl$(suffix)/include" \
|
||||
"$(DESTDIR)$(mandir)" \
|
||||
"$(DESTDIR)$(mandir)/man1"
|
||||
$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf
|
||||
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(DESTDIR)$(libdir)/ivl/xnf-s.conf
|
||||
|
||||
$(libdir)/ivl/xnf.conf: $(srcdir)/xnf.conf
|
||||
$(INSTALL_DATA) $(srcdir)/xnf.conf $(DESTDIR)$(libdir)/ivl/xnf.conf
|
||||
|
||||
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(DESTDIR)$(includedir)/ivl_target.h
|
||||
|
||||
$(includedir)/_pli_types.h: _pli_types.h
|
||||
$(INSTALL_DATA) $< $(DESTDIR)$(includedir)/_pli_types.h
|
||||
|
||||
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(DESTDIR)$(includedir)/vpi_user.h
|
||||
|
||||
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/acc_user.h $(DESTDIR)$(includedir)/acc_user.h
|
||||
|
||||
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
|
||||
$(INSTALL_DATA) $(srcdir)/veriuser.h $(DESTDIR)$(includedir)/veriuser.h
|
||||
|
||||
$(mandir)/man1/iverilog-vpi.1: $(srcdir)/iverilog-vpi.man
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(DESTDIR)$(mandir)/man1/iverilog-vpi.1
|
||||
|
||||
$(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
|
||||
$(INSTALL_DATA) iverilog-vpi.pdf $(DESTDIR)$(prefix)/iverilog-vpi.pdf
|
||||
|
||||
# In windows installations, put a few examples and the quick_start
|
||||
# into the destination directory.
|
||||
ifeq (@MINGW32@,yes)
|
||||
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
|
||||
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
|
||||
mv tmp.vl $(prefix)/hello.vl
|
||||
|
||||
$(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
|
||||
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
|
||||
mv tmp.vl $(prefix)/sqrt.vl
|
||||
|
||||
$(prefix)/sqrt-virtex.v: $(srcdir)/examples/sqrt-virtex.v
|
||||
./dosify.exe $(srcdir)/examples/sqrt-virtex.v tmp.vl
|
||||
mv tmp.vl $(prefix)/sqrt-virtex.v
|
||||
|
||||
$(prefix)/QUICK_START.txt: $(srcdir)/QUICK_START.txt
|
||||
./dosify.exe $(srcdir)/QUICK_START.txt tmp.txt
|
||||
mv tmp.txt $(prefix)/QUICK_START.txt
|
||||
endif
|
||||
|
||||
installdirs: mkinstalldirs
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) $(DESTDIR)$(includedir) $(DESTDIR)$(libdir)/ivl \
|
||||
$(DESTDIR)$(libdir)/ivl/include $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1
|
||||
|
||||
uninstall:
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
|
||||
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
|
||||
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
|
||||
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)"
|
||||
for f in verilog$(suffix) iverilog-vpi$(suffix) gverilog$(suffix)@EXEEXT@; \
|
||||
do rm -f "$(DESTDIR)$(bindir)/$$f"; done
|
||||
for 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"
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp driver; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
for f in xnf.conf xnf-s.conf ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
|
||||
do rm -f $(DESTDIR)$(libdir)/ivl/$$f; done
|
||||
-rmdir $(DESTDIR)$(libdir)/ivl/include
|
||||
-rmdir $(DESTDIR)$(libdir)/ivl
|
||||
for f in verilog iverilog-vpi gverilog@EXEEXT@; \
|
||||
do rm -f $(DESTDIR)$(bindir)/$$f; done
|
||||
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
|
||||
do rm -f $(DESTDIR)$(includedir)/$$f; done
|
||||
rm -f $(DESTDIR)$(mandir)/man1/iverilog-vpi.1 $(DESTDIR)$(prefix)/iverilog-vpi.pdf
|
||||
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
-include $(patsubst %.o, dep/%.d, vpithunk.o)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
@@ -22,21 +22,14 @@
|
||||
# include "Module.h"
|
||||
# include "PGate.h"
|
||||
# include "PWire.h"
|
||||
# include <cassert>
|
||||
|
||||
using namespace std;
|
||||
|
||||
list<Module::named_expr_t> Module::user_defparms;
|
||||
# include <assert.h>
|
||||
|
||||
/* n is a permallocated string. */
|
||||
Module::Module(LexicalScope*parent, perm_string n)
|
||||
: PScopeExtra(n, parent)
|
||||
Module::Module(perm_string n)
|
||||
: PScope(n, 0)
|
||||
{
|
||||
library_flag = false;
|
||||
is_cell = false;
|
||||
is_interface = false;
|
||||
program_block = false;
|
||||
uc_drive = UCD_NONE;
|
||||
default_nettype = NetNet::NONE;
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
@@ -48,9 +41,19 @@ void Module::add_gate(PGate*gate)
|
||||
gates_.push_back(gate);
|
||||
}
|
||||
|
||||
void Module::add_task(perm_string name, PTask*task)
|
||||
{
|
||||
tasks_[name] = task;
|
||||
}
|
||||
|
||||
void Module::add_function(perm_string name, PFunction *func)
|
||||
{
|
||||
funcs_[name] = func;
|
||||
}
|
||||
|
||||
unsigned Module::port_count() const
|
||||
{
|
||||
return ports.size();
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -58,10 +61,10 @@ unsigned Module::port_count() const
|
||||
* module. If the port is internally unconnected, return an empty
|
||||
* array.
|
||||
*/
|
||||
const vector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
const svector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
{
|
||||
assert(idx < ports.size());
|
||||
static const vector<PEIdent*> zero;
|
||||
assert(idx < ports.count());
|
||||
static svector<PEIdent*> zero;
|
||||
|
||||
if (ports[idx])
|
||||
return ports[idx]->expr;
|
||||
@@ -72,7 +75,7 @@ const vector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
unsigned Module::find_port(const char*name) const
|
||||
{
|
||||
assert(name != 0);
|
||||
for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
if (ports[idx] == 0) {
|
||||
/* It is possible to have undeclared ports. These
|
||||
are ports that are skipped in the declaration,
|
||||
@@ -86,37 +89,15 @@ unsigned Module::find_port(const char*name) const
|
||||
return idx;
|
||||
}
|
||||
|
||||
return ports.size();
|
||||
}
|
||||
|
||||
perm_string Module::get_port_name(unsigned idx) const
|
||||
{
|
||||
|
||||
assert(idx < ports.size());
|
||||
if (ports[idx] == 0 || ports[idx]->name.str() == 0) {
|
||||
/* It is possible to have undeclared ports. These
|
||||
are ports that are skipped in the declaration,
|
||||
for example like so: module foo(x ,, y); The
|
||||
port between x and y is unnamed and thus
|
||||
inaccessible to binding by name. Port references
|
||||
that aren't simple or escaped identifiers are
|
||||
also inaccessible to binding by name. */
|
||||
return perm_string::literal("unnamed");
|
||||
}
|
||||
return ports[idx]->name;
|
||||
}
|
||||
|
||||
PExpr* Module::get_port_default_value(unsigned idx) const
|
||||
{
|
||||
assert(idx < ports.size());
|
||||
return ports[idx] ? ports[idx]->default_value : 0;
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
|
||||
PGate* Module::get_gate(perm_string name)
|
||||
{
|
||||
for (list<PGate*>::iterator cur = gates_.begin()
|
||||
; cur != gates_.end() ; ++ cur ) {
|
||||
; cur != gates_.end()
|
||||
; cur ++ ) {
|
||||
|
||||
if ((*cur)->get_name() == name)
|
||||
return *cur;
|
||||
@@ -130,28 +111,3 @@ const list<PGate*>& Module::get_gates() const
|
||||
return gates_;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType Module::symbol_type() const
|
||||
{
|
||||
if (program_block)
|
||||
return PROGRAM;
|
||||
if (is_interface)
|
||||
return INTERFACE;
|
||||
|
||||
return MODULE;
|
||||
}
|
||||
|
||||
bool Module::can_be_toplevel() const
|
||||
{
|
||||
// Don't choose library modules.
|
||||
if (library_flag)
|
||||
return false;
|
||||
|
||||
// Don't choose modules with parameters without default value
|
||||
for (std::map<perm_string,param_expr_t*>::const_iterator cur =
|
||||
parameters.begin(); cur != parameters.end(); cur++) {
|
||||
if (cur->second->expr == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_Module_H
|
||||
#define IVL_Module_H
|
||||
#ifndef __Module_H
|
||||
#define __Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2008 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,26 +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
|
||||
*/
|
||||
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include <vector>
|
||||
# include <utility>
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "HName.h"
|
||||
# include "named.h"
|
||||
# include "PScope.h"
|
||||
# include "PNamedItem.h"
|
||||
# include "LineInfo.h"
|
||||
# include "netlist.h"
|
||||
# include "pform_types.h"
|
||||
class PExpr;
|
||||
class PEIdent;
|
||||
class PGate;
|
||||
class PGenerate;
|
||||
class PModport;
|
||||
class PSpecPath;
|
||||
class PTask;
|
||||
class PFunction;
|
||||
@@ -48,31 +46,25 @@ class NetScope;
|
||||
* A module is a named container and scope. A module holds a bunch of
|
||||
* semantic quantities such as wires and gates. The module is
|
||||
* therefore the handle for grasping the described circuit.
|
||||
*
|
||||
* SystemVerilog introduces program blocks and interfaces. These have
|
||||
* much in common with modules, so the Module class is used to represent
|
||||
* these containers as well.
|
||||
*/
|
||||
|
||||
class Module : public PScopeExtra, public PNamedItem {
|
||||
class Module : public PScope, public LineInfo {
|
||||
|
||||
/* The module ports are in general a vector of port_t
|
||||
objects. Each port has a name and an ordered list of
|
||||
wires. The name is the means that the outside uses to
|
||||
access the port, the wires are the internal connections to
|
||||
the port. In SystemVerilog, input ports may also have a
|
||||
default value. */
|
||||
the port. */
|
||||
public:
|
||||
struct port_t {
|
||||
perm_string name;
|
||||
std::vector<PEIdent*> expr;
|
||||
PExpr*default_value;
|
||||
svector<PEIdent*> expr;
|
||||
};
|
||||
|
||||
public:
|
||||
/* The name passed here is the module name, not the instance
|
||||
name. This name must be a permallocated string. */
|
||||
explicit Module(LexicalScope*parent, perm_string name);
|
||||
name. This make must be a permallocated string. */
|
||||
explicit Module(perm_string name);
|
||||
~Module();
|
||||
|
||||
/* Initially false. This is set to true if the module has been
|
||||
@@ -81,33 +73,52 @@ class Module : public PScopeExtra, public PNamedItem {
|
||||
other effect. */
|
||||
bool library_flag;
|
||||
|
||||
bool is_cell;
|
||||
NetNet::Type default_nettype;
|
||||
|
||||
/* This is true if the module represents a program block
|
||||
instead of a module/cell. Program blocks have content
|
||||
restrictions and slightly modify scheduling semantics. */
|
||||
bool program_block;
|
||||
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;
|
||||
};
|
||||
|
||||
/* This is true if the module represents a interface
|
||||
instead of a module/cell. Interfaces have different
|
||||
content restrictions and some extra allowed items. */
|
||||
bool is_interface;
|
||||
/* The module has parameters that are evaluated when the
|
||||
module is elaborated. During parsing, I put the parameters
|
||||
into this map. */
|
||||
struct param_expr_t : public LineInfo {
|
||||
param_expr_t() : type(IVL_VT_NO_TYPE), msb(0), lsb(0), signed_flag(false), expr(0), range(0) { }
|
||||
// Type information
|
||||
ivl_variable_type_t type;
|
||||
PExpr*msb;
|
||||
PExpr*lsb;
|
||||
bool signed_flag;
|
||||
// Value expression
|
||||
PExpr*expr;
|
||||
// If there are range constrants, list them here
|
||||
range_t*range;
|
||||
};
|
||||
map<perm_string,param_expr_t>parameters;
|
||||
map<perm_string,param_expr_t>localparams;
|
||||
|
||||
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. */
|
||||
std::map<perm_string,param_expr_t*>specparams;
|
||||
/* specparams are simpler then other params, in that they have
|
||||
no type information. They are merely constant
|
||||
expressions. */
|
||||
map<perm_string,PExpr*>specparams;
|
||||
|
||||
/* The module also has defparam assignments which don't create
|
||||
new parameters within the module, but may be used to set
|
||||
values within this module (when instantiated) or in other
|
||||
instantiated modules. */
|
||||
typedef std::pair<pform_name_t,PExpr*> named_expr_t;
|
||||
std::list<named_expr_t>defparms;
|
||||
static std::list<named_expr_t>user_defparms;
|
||||
map<pform_name_t,PExpr*>defparms;
|
||||
|
||||
/* Parameters may be overridden at instantiation time;
|
||||
the overrides do not contain explicit parameter names,
|
||||
@@ -115,66 +126,62 @@ class Module : public PScopeExtra, public PNamedItem {
|
||||
appear in the instantiated module. Therefore a
|
||||
list of names in module-order is needed to pass from
|
||||
a parameter-index to its name. */
|
||||
std::list<perm_string> param_names;
|
||||
list<perm_string> param_names;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
std::vector<port_t*> ports;
|
||||
svector<port_t*> ports;
|
||||
|
||||
std::map<perm_string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
/* The module has a list of generate schemes that appear in
|
||||
/* These are the timescale for this module. The default is
|
||||
set by the `timescale directive. */
|
||||
int time_unit, time_precision;
|
||||
|
||||
/* The module has a list of genvars that may be used in
|
||||
various generate schemes. */
|
||||
map<perm_string,LineInfo*> genvars;
|
||||
|
||||
/* the module has a list of generate schemes that appear in
|
||||
the module definition. These are used at elaboration time. */
|
||||
std::list<PGenerate*> generate_schemes;
|
||||
list<PGenerate*> generate_schemes;
|
||||
|
||||
/* Nested modules are placed here, and are not elaborated
|
||||
unless they are instantiated, implicitly or explicitly. */
|
||||
std::map<perm_string,Module*> nested_modules;
|
||||
|
||||
/* An interface can contain one or more named modport lists.
|
||||
The parser will ensure these don't appear in modules or
|
||||
program blocks. */
|
||||
std::map<perm_string,PModport*> modports;
|
||||
|
||||
std::list<PSpecPath*> specify_paths;
|
||||
list<PSpecPath*> specify_paths;
|
||||
|
||||
// The mod_name() is the name of the module type.
|
||||
perm_string mod_name() const { return pscope_name(); }
|
||||
|
||||
void add_gate(PGate*gate);
|
||||
void add_task(perm_string name, PTask*def);
|
||||
void add_function(perm_string name, PFunction*def);
|
||||
|
||||
unsigned port_count() const;
|
||||
const std::vector<PEIdent*>& get_port(unsigned idx) const;
|
||||
const svector<PEIdent*>& get_port(unsigned idx) const;
|
||||
unsigned find_port(const char*name) const;
|
||||
|
||||
// Return port name ("" for undeclared port)
|
||||
perm_string get_port_name(unsigned idx) const;
|
||||
|
||||
PExpr* get_port_default_value(unsigned idx) const;
|
||||
|
||||
PGate* get_gate(perm_string name);
|
||||
|
||||
const std::list<PGate*>& get_gates() const;
|
||||
const list<PGate*>& get_gates() const;
|
||||
|
||||
void dump(std::ostream&out) const;
|
||||
void dump(ostream&out) const;
|
||||
bool elaborate(Design*, NetScope*scope) const;
|
||||
|
||||
typedef std::map<perm_string,PExpr*> replace_t;
|
||||
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep);
|
||||
typedef map<perm_string,NetExpr*> replace_t;
|
||||
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep) const;
|
||||
|
||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
bool can_be_toplevel() const;
|
||||
|
||||
private:
|
||||
void dump_specparams_(std::ostream&out, unsigned indent) const;
|
||||
std::list<PGate*> gates_;
|
||||
list<PGate*> gates_;
|
||||
map<perm_string,PTask*> tasks_;
|
||||
map<perm_string,PFunction*> funcs_;
|
||||
|
||||
static void elaborate_parm_item_(perm_string name, const param_expr_t&cur,
|
||||
Design*des, NetScope*scope);
|
||||
|
||||
private: // Not implemented
|
||||
Module(const Module&);
|
||||
Module& operator= (const Module&);
|
||||
};
|
||||
|
||||
#endif /* IVL_Module_H */
|
||||
#endif
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2019 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()
|
||||
{
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PClass::symbol_type() const
|
||||
{
|
||||
return CLASS;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#ifndef IVL_PClass_H
|
||||
#define IVL_PClass_H
|
||||
/*
|
||||
* Copyright (c) 2012-2019 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 "PNamedItem.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 PNamedItem {
|
||||
|
||||
public:
|
||||
explicit PClass (perm_string name, LexicalScope*parent);
|
||||
~PClass();
|
||||
|
||||
void dump(std::ostream&out, unsigned indent) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
public:
|
||||
class_type_t*type;
|
||||
};
|
||||
|
||||
#endif /* IVL_PClass_H */
|
||||
+31
-53
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
@@ -26,8 +26,6 @@
|
||||
# include "verinum.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
PDelays::PDelays()
|
||||
{
|
||||
delete_flag_ = true;
|
||||
@@ -52,42 +50,36 @@ void PDelays::set_delay(PExpr*del)
|
||||
}
|
||||
|
||||
|
||||
void PDelays::set_delays(const list<PExpr*>*del, bool df)
|
||||
void PDelays::set_delays(const svector<PExpr*>*del, bool df)
|
||||
{
|
||||
assert(del);
|
||||
assert(del->size() <= 3);
|
||||
|
||||
list<PExpr*>::const_iterator cur = del->begin();
|
||||
for (unsigned idx = 0 ; cur != del->end() ; idx += 1, ++cur)
|
||||
delay_[idx] = *cur;
|
||||
assert(del->count() <= 3);
|
||||
for (unsigned idx = 0 ; idx < del->count() ; idx += 1)
|
||||
delay_[idx] = (*del)[idx];
|
||||
|
||||
delete_flag_ = df;
|
||||
}
|
||||
|
||||
unsigned PDelays::delay_count() const
|
||||
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
|
||||
{
|
||||
unsigned dly_cnt = 0;
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
if (delay_[idx]) dly_cnt += 1;
|
||||
|
||||
return dly_cnt;
|
||||
}
|
||||
|
||||
static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
|
||||
{
|
||||
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
|
||||
|
||||
check_for_inconsistent_delays(scope);
|
||||
NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
|
||||
eval_expr(dex);
|
||||
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
units, and return an adjusted value. */
|
||||
|
||||
if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
|
||||
uint64_t delay = get_scaled_time_from_real(des, scope, tmp);
|
||||
verireal fn = tmp->value();
|
||||
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
long delay = fn.as_long(shift);
|
||||
if (delay < 0)
|
||||
delay = 0;
|
||||
|
||||
delete tmp;
|
||||
NetEConst*tmp2 = new NetEConst(verinum(delay, 64));
|
||||
NetEConst*tmp2 = new NetEConst(verinum(delay));
|
||||
tmp2->set_line(*expr);
|
||||
return tmp2;
|
||||
}
|
||||
@@ -95,10 +87,12 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
|
||||
verinum fn = tmp->value();
|
||||
uint64_t delay = des->scale_to_precision(fn.as_ulong64(), scope);
|
||||
|
||||
unsigned long delay =
|
||||
des->scale_to_precision(fn.as_ulong(), scope);
|
||||
|
||||
delete tmp;
|
||||
NetEConst*tmp2 = new NetEConst(verinum(delay, 64));
|
||||
NetEConst*tmp2 = new NetEConst(verinum(delay));
|
||||
tmp2->set_line(*expr);
|
||||
return tmp2;
|
||||
}
|
||||
@@ -107,22 +101,18 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
|
||||
return dex;
|
||||
}
|
||||
|
||||
static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
|
||||
static NetExpr* make_delay_nets(Design*des, NetExpr*expr)
|
||||
{
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
||||
if (dynamic_cast<NetESignal*> (expr))
|
||||
return expr;
|
||||
|
||||
if (dynamic_cast<NetEConst*> (expr))
|
||||
return expr;
|
||||
|
||||
NetNet*sig = expr->synthesize(des, scope, expr);
|
||||
NetNet*sig = expr->synthesize(des);
|
||||
if (sig == 0) {
|
||||
cerr << expr->get_fileline() << ": error: Expression " << *expr
|
||||
<< " is not suitable as a delay expression." << endl;
|
||||
des->errors += 1;
|
||||
<< " is not suitable for delay expression." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -130,18 +120,6 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
|
||||
return expr;
|
||||
}
|
||||
|
||||
static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
|
||||
{
|
||||
NetEConst *c_rise = dynamic_cast<NetEConst*>(rise);
|
||||
NetEConst *c_fall = dynamic_cast<NetEConst*>(fall);
|
||||
if (c_rise && c_fall) {
|
||||
if (c_rise->value() < c_fall->value()) return rise;
|
||||
else return fall;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
@@ -154,23 +132,23 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
if (delay_[0]) {
|
||||
rise_time = calculate_val(des, scope, delay_[0]);
|
||||
if (as_nets_flag)
|
||||
rise_time = make_delay_nets(des, scope, rise_time);
|
||||
rise_time = make_delay_nets(des, rise_time);
|
||||
|
||||
if (delay_[1]) {
|
||||
fall_time = calculate_val(des, scope, delay_[1]);
|
||||
if (as_nets_flag)
|
||||
fall_time = make_delay_nets(des, scope, fall_time);
|
||||
fall_time = make_delay_nets(des, fall_time);
|
||||
|
||||
if (delay_[2]) {
|
||||
decay_time = calculate_val(des, scope, delay_[2]);
|
||||
if (as_nets_flag)
|
||||
decay_time = make_delay_nets(des, scope,
|
||||
decay_time);
|
||||
if (as_nets_flag)
|
||||
decay_time = make_delay_nets(des, decay_time);
|
||||
|
||||
} else {
|
||||
// If this is zero then we need to do the min()
|
||||
// at run time.
|
||||
decay_time = calc_decay_time(rise_time, fall_time);
|
||||
if (rise_time < fall_time)
|
||||
decay_time = rise_time;
|
||||
else
|
||||
decay_time = fall_time;
|
||||
}
|
||||
} else {
|
||||
assert(delay_[2] == 0);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PDelays_H
|
||||
#define IVL_PDelays_H
|
||||
#ifndef __PDelays_H
|
||||
#define __PDelays_H
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2002 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,13 +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
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PDelays.h,v 1.9 2006/01/03 05:22:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
# include <string>
|
||||
# include <list>
|
||||
# include <iostream>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 2
|
||||
using namespace std;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class NetExpr;
|
||||
@@ -42,9 +51,7 @@ class PDelays {
|
||||
this object takes ownership of the expressions, and will
|
||||
delete it in the destructor. */
|
||||
void set_delay(PExpr*);
|
||||
void set_delays(const std::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,
|
||||
@@ -52,7 +59,7 @@ class PDelays {
|
||||
NetExpr*&decay_time,
|
||||
bool as_nets_flag =false) const;
|
||||
|
||||
void dump_delays(std::ostream&out) const;
|
||||
void dump_delays(ostream&out) const;
|
||||
|
||||
private:
|
||||
PExpr* delay_[3];
|
||||
@@ -63,6 +70,36 @@ class PDelays {
|
||||
PDelays& operator= (const PDelays&);
|
||||
};
|
||||
|
||||
std::ostream& operator << (std::ostream&o, const PDelays&);
|
||||
ostream& operator << (ostream&o, const PDelays&);
|
||||
|
||||
#endif /* IVL_PDelays_H */
|
||||
/*
|
||||
* $Log: PDelays.h,v $
|
||||
* Revision 1.9 2006/01/03 05:22:14 steve
|
||||
* Handle complex net node delays.
|
||||
*
|
||||
* Revision 1.8 2006/01/02 05:33:19 steve
|
||||
* Node delays can be more general expressions in structural contexts.
|
||||
*
|
||||
* Revision 1.7 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2002/06/14 03:25:51 steve
|
||||
* Compiler portability.
|
||||
*
|
||||
* Revision 1.5 2001/12/29 20:19:31 steve
|
||||
* Do not delete delay expressions of UDP instances.
|
||||
*
|
||||
* Revision 1.4 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.3 2001/01/16 02:44:17 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
* Revision 1.2 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.1 1999/09/04 19:11:46 steve
|
||||
* Add support for delayed non-blocking assignments.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2019 Stephen Williams ([email protected])
|
||||
* Copyright (c) 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
|
||||
@@ -14,8 +14,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.cc,v 1.5 2004/02/19 06:57:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
@@ -35,7 +38,26 @@ perm_string PEvent::name() const
|
||||
return name_;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PEvent::symbol_type() const
|
||||
{
|
||||
return EVENT;
|
||||
}
|
||||
/*
|
||||
* $Log: PEvent.cc,v $
|
||||
* Revision 1.5 2004/02/19 06:57:10 steve
|
||||
* Memory and Event names use perm_string.
|
||||
*
|
||||
* Revision 1.4 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PEvent_H
|
||||
#define IVL_PEvent_H
|
||||
#ifndef __PEvent_H
|
||||
#define __PEvent_H
|
||||
/*
|
||||
* Copyright (c) 2000-2019 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,10 +16,13 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.h,v 1.9 2004/02/19 06:57:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PNamedItem.h"
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
|
||||
@@ -31,7 +34,7 @@ class NetScope;
|
||||
* are declared in Verilog as ``event foo;'' The name passed to the
|
||||
* constructor is the "foo" part of the declaration.
|
||||
*/
|
||||
class PEvent : public PNamedItem {
|
||||
class PEvent : public LineInfo {
|
||||
|
||||
public:
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
@@ -43,8 +46,6 @@ class PEvent : public PNamedItem {
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
|
||||
@@ -53,4 +54,38 @@ class PEvent : public PNamedItem {
|
||||
PEvent& operator= (const PEvent&);
|
||||
};
|
||||
|
||||
#endif /* IVL_PEvent_H */
|
||||
/*
|
||||
* $Log: PEvent.h,v $
|
||||
* Revision 1.9 2004/02/19 06:57:10 steve
|
||||
* Memory and Event names use perm_string.
|
||||
*
|
||||
* Revision 1.8 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*
|
||||
* Revision 1.7 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.5 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.4 2001/01/16 02:44:18 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
* Revision 1.3 2000/04/09 17:44:30 steve
|
||||
* Catch event declarations during scope elaborate.
|
||||
*
|
||||
* Revision 1.2 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
* Revision 1.1 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams <[email protected]>
|
||||
* Copyright CERN 2013 / Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2007 Stephen Williams <[email protected]>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -15,103 +14,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
|
||||
*/
|
||||
|
||||
# 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>
|
||||
|
||||
using namespace std;
|
||||
|
||||
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::is_the_same(const PExpr*that) const
|
||||
{
|
||||
return typeid(this) == typeid(that);
|
||||
}
|
||||
|
||||
bool PExpr::has_aa_term(Design*, NetScope*) const
|
||||
bool PExpr::is_constant(Module*) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_lnet(Design*, NetScope*) const
|
||||
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "expression not valid in assign l-value: "
|
||||
<< *this << endl;
|
||||
cerr << get_fileline() << ": error: expression not valid in assign l-value: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_bi_net(Design*, NetScope*) const
|
||||
NetNet* PExpr::elaborate_bi_net(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "expression not valid as argument to inout port: "
|
||||
<< *this << endl;
|
||||
<< "expression not valid as argument to inout port: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool PExpr::is_collapsible_net(Design*, NetScope*, NetNet::PortType) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const char* PExpr::width_mode_name(width_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case PExpr::SIZED:
|
||||
return "sized";
|
||||
case PExpr::UNSIZED:
|
||||
return "unsized";
|
||||
case PExpr::EXPAND:
|
||||
return "expand";
|
||||
case PExpr::LOSSLESS:
|
||||
return "lossless";
|
||||
case PExpr::UPSIZE:
|
||||
return "upsize";
|
||||
default:
|
||||
return "??";
|
||||
}
|
||||
}
|
||||
|
||||
PEAssignPattern::PEAssignPattern()
|
||||
{
|
||||
}
|
||||
|
||||
PEAssignPattern::PEAssignPattern(const list<PExpr*>&p)
|
||||
: parms_(p.size())
|
||||
{
|
||||
size_t idx = 0;
|
||||
for (list<PExpr*>::const_iterator cur = p.begin()
|
||||
; cur != p.end() ; ++cur) {
|
||||
parms_[idx] = *cur;
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
PEAssignPattern::~PEAssignPattern()
|
||||
{
|
||||
}
|
||||
|
||||
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
|
||||
: op_(op), left_(l), right_(r)
|
||||
{
|
||||
@@ -121,98 +67,22 @@ PEBinary::~PEBinary()
|
||||
{
|
||||
}
|
||||
|
||||
void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
bool PEBinary::is_constant(Module*mod) const
|
||||
{
|
||||
if (left_) left_->declare_implicit_nets(scope, type);
|
||||
if (right_) right_->declare_implicit_nets(scope, type);
|
||||
}
|
||||
|
||||
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(left_ && right_);
|
||||
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
|
||||
}
|
||||
|
||||
PECastSize::PECastSize(PExpr*si, PExpr*b)
|
||||
: size_(si), base_(b)
|
||||
{
|
||||
}
|
||||
|
||||
PECastSize::~PECastSize()
|
||||
{
|
||||
}
|
||||
|
||||
bool PECastSize::has_aa_term(Design *des, NetScope *scope) const
|
||||
{
|
||||
return base_->has_aa_term(des, scope);
|
||||
}
|
||||
|
||||
PECastType::PECastType(data_type_t*t, PExpr*b)
|
||||
: target_(t), base_(b)
|
||||
{
|
||||
}
|
||||
|
||||
PECastType::~PECastType()
|
||||
{
|
||||
}
|
||||
|
||||
bool PECastType::has_aa_term(Design *des, NetScope *scope) const
|
||||
{
|
||||
return base_->has_aa_term(des, scope);
|
||||
}
|
||||
|
||||
PECastSign::PECastSign(bool signed_flag, PExpr *base)
|
||||
: base_(base)
|
||||
{
|
||||
signed_flag_ = signed_flag;
|
||||
}
|
||||
|
||||
bool PECastSign::has_aa_term(Design *des, NetScope *scope) const
|
||||
{
|
||||
return base_->has_aa_term(des, scope);
|
||||
return left_->is_constant(mod) && right_->is_constant(mod);
|
||||
}
|
||||
|
||||
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
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' || op == 'q' || op == 'Q');
|
||||
}
|
||||
|
||||
PEBLogic::~PEBLogic()
|
||||
{
|
||||
}
|
||||
|
||||
PEBLeftWidth::PEBLeftWidth(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBLeftWidth::~PEBLeftWidth()
|
||||
{
|
||||
}
|
||||
|
||||
PEBPower::PEBPower(char op, PExpr*l, PExpr*r)
|
||||
: PEBLeftWidth(op, l, r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBPower::~PEBPower()
|
||||
{
|
||||
}
|
||||
|
||||
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
|
||||
: PEBLeftWidth(op, l, r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -220,13 +90,8 @@ PEBShift::~PEBShift()
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
|
||||
: package_(0), path_(n), parms_(parms), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector<PExpr *> &parms)
|
||||
: package_(pkg), path_(n), parms_(parms), is_overridden_(false)
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
|
||||
: path_(n), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -238,78 +103,32 @@ static pform_name_t pn_from_ps(perm_string n)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *> &parms)
|
||||
: package_(pkg), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false)
|
||||
{
|
||||
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), is_overridden_(false)
|
||||
PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
|
||||
: path_(pn_from_ps(n)), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n)
|
||||
: package_(0), path_(pn_from_ps(n)), is_overridden_(false)
|
||||
: 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()), is_overridden_(false)
|
||||
{
|
||||
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()), is_overridden_(false)
|
||||
{
|
||||
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()
|
||||
@@ -317,25 +136,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)
|
||||
{
|
||||
@@ -350,25 +150,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)
|
||||
{
|
||||
@@ -384,133 +170,56 @@ const verireal& PEFNumber::value() const
|
||||
return *value_;
|
||||
}
|
||||
|
||||
bool PEFNumber::is_constant(Module*) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(const pform_name_t&that)
|
||||
: package_(0), path_(that), no_implicit_sig_(false)
|
||||
: path_(that)
|
||||
{
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
|
||||
: package_(0), no_implicit_sig_(no_implicit_sig)
|
||||
PEIdent::PEIdent(perm_string s)
|
||||
{
|
||||
path_.push_back(name_component_t(s));
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
|
||||
: package_(pkg), path_(that), no_implicit_sig_(true)
|
||||
{
|
||||
}
|
||||
|
||||
PEIdent::~PEIdent()
|
||||
{
|
||||
}
|
||||
|
||||
static bool find_enum_constant(LexicalScope*scope, perm_string name)
|
||||
/*
|
||||
* An identifier can be in a constant expression if (and only if) it is
|
||||
* a parameter or genvar.
|
||||
*
|
||||
* NOTE: This test does not work if the name is hierarchical!
|
||||
*/
|
||||
bool PEIdent::is_constant(Module*mod) const
|
||||
{
|
||||
for (vector<enum_type_t*>::const_iterator cur = scope->enum_sets.begin() ;
|
||||
cur != scope->enum_sets.end() ; ++ cur) {
|
||||
for (list<named_pexpr_t>::const_iterator idx = (*cur)->names->begin() ;
|
||||
idx != (*cur)->names->end() ; ++ idx) {
|
||||
if (idx->name == name) return true;
|
||||
}
|
||||
if (mod == 0) return false;
|
||||
|
||||
/* */
|
||||
perm_string tmp = path_.back().name;
|
||||
|
||||
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->parameters.find(tmp);
|
||||
if (cur != mod->parameters.end()) return true;
|
||||
}
|
||||
|
||||
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->localparams.find(tmp);
|
||||
if (cur != mod->localparams.end()) return true;
|
||||
}
|
||||
|
||||
{ map<perm_string,LineInfo*>::const_iterator cur;
|
||||
cur = mod->genvars.find(tmp);
|
||||
if (cur != mod->genvars.end()) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
{
|
||||
/* We create an implicit wire if:
|
||||
- this is a simple identifier
|
||||
- an identifier of that name has not already been declared in
|
||||
any enclosing scope.
|
||||
- this is not an implicit named port connection */
|
||||
if (no_implicit_sig_)
|
||||
return;
|
||||
if ((path_.size() == 1) && (path_.front().index.size() == 0)) {
|
||||
perm_string name = path_.front().name;
|
||||
LexicalScope*ss = scope;
|
||||
while (ss) {
|
||||
if (ss->wires.find(name) != ss->wires.end())
|
||||
return;
|
||||
if (ss->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;
|
||||
if (find_enum_constant(ss, name))
|
||||
return;
|
||||
/* Strictly speaking, we should also check for name clashes
|
||||
with tasks, functions, named blocks, module instances,
|
||||
and generate blocks. However, this information is not
|
||||
readily available. As these names would not be legal in
|
||||
this context, we can declare implicit nets here and rely
|
||||
on later checks for name clashes to report the error. */
|
||||
|
||||
ss = ss->parent_scope();
|
||||
}
|
||||
PWire*net = new PWire(name, type, NetNet::NOT_A_PORT);
|
||||
net->set_file(get_file());
|
||||
net->set_lineno(get_lineno());
|
||||
scope->wires[name] = net;
|
||||
if (warn_implicit) {
|
||||
cerr << get_fileline() << ": warning: implicit "
|
||||
"definition of wire '" << name << "'." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
symbol_search_results sr;
|
||||
if (!symbol_search(this, des, scope, path_, &sr))
|
||||
return false;
|
||||
|
||||
// Class properties are not considered automatic since a non-blocking
|
||||
// assignment to an object stored in an automatic variable is supposed to
|
||||
// capture a reference to the object, not the variable.
|
||||
if (!sr.path_tail.empty() && sr.net && sr.net->class_type())
|
||||
return false;
|
||||
|
||||
return sr.scope->is_auto();
|
||||
}
|
||||
|
||||
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, data_type_t *class_type)
|
||||
: parms_(p.size()), class_type_(class_type)
|
||||
{
|
||||
size_t tmp_idx = 0;
|
||||
for (list<PExpr*>::const_iterator cur = p.begin()
|
||||
; cur != p.end() ; ++ cur) {
|
||||
parms_[tmp_idx++] = *cur;
|
||||
}
|
||||
}
|
||||
|
||||
PENewClass::~PENewClass()
|
||||
{
|
||||
}
|
||||
|
||||
PENewCopy::PENewCopy(PExpr*src)
|
||||
: src_(src)
|
||||
{
|
||||
}
|
||||
|
||||
PENewCopy::~PENewCopy()
|
||||
{
|
||||
}
|
||||
|
||||
PENumber::PENumber(verinum*vp)
|
||||
: value_(vp)
|
||||
{
|
||||
@@ -527,6 +236,20 @@ const verinum& PENumber::value() const
|
||||
return *value_;
|
||||
}
|
||||
|
||||
bool PENumber::is_the_same(const PExpr*that) const
|
||||
{
|
||||
const PENumber*obj = dynamic_cast<const PENumber*>(that);
|
||||
if (obj == 0)
|
||||
return false;
|
||||
|
||||
return *value_ == *obj->value_;
|
||||
}
|
||||
|
||||
bool PENumber::is_constant(Module*) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
PEString::PEString(char*s)
|
||||
: text_(s)
|
||||
{
|
||||
@@ -542,6 +265,11 @@ string PEString::value() const
|
||||
return text_;
|
||||
}
|
||||
|
||||
bool PEString::is_constant(Module*) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
PETernary::PETernary(PExpr*e, PExpr*t, PExpr*f)
|
||||
: expr_(e), tru_(t), fal_(f)
|
||||
{
|
||||
@@ -551,29 +279,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)
|
||||
@@ -585,22 +295,8 @@ 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);
|
||||
}
|
||||
|
||||
PEVoid::PEVoid()
|
||||
{
|
||||
}
|
||||
|
||||
PEVoid::~PEVoid()
|
||||
{
|
||||
}
|
||||
|
||||
+13
-67
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,28 +14,29 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
# include "PTask.h"
|
||||
# include "Statement.h"
|
||||
# include <cassert>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
using namespace std;
|
||||
#include "PTask.h"
|
||||
|
||||
PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
|
||||
: PTaskFunc(name, parent), statement_(0)
|
||||
PFunction::PFunction(perm_string name, PScope*parent)
|
||||
: PScope(name, parent), ports_(0), statement_(0)
|
||||
{
|
||||
is_auto_ = is_auto__;
|
||||
return_type_ = 0;
|
||||
return_type_.type = PTF_NONE;
|
||||
}
|
||||
|
||||
PFunction::~PFunction()
|
||||
{
|
||||
}
|
||||
|
||||
void PFunction::set_ports(svector<PWire *>*p)
|
||||
{
|
||||
assert(ports_ == 0);
|
||||
ports_ = p;
|
||||
}
|
||||
|
||||
void PFunction::set_statement(Statement*s)
|
||||
{
|
||||
assert(s != 0);
|
||||
@@ -43,62 +44,7 @@ void PFunction::set_statement(Statement*s)
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
void PFunction::push_statement_front(Statement*stmt)
|
||||
{
|
||||
// This should not be possible.
|
||||
ivl_assert(*this, statement_);
|
||||
|
||||
// Get the PBlock of the statement. If it is not a PBlock,
|
||||
// then create one to wrap the existing statement and the new
|
||||
// statement that we're pushing.
|
||||
PBlock*blk = dynamic_cast<PBlock*> (statement_);
|
||||
if (blk == 0) {
|
||||
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
||||
tmp->set_line(*this);
|
||||
vector<Statement*>tmp_list(1);
|
||||
tmp_list[0] = statement_;
|
||||
tmp->set_statement(tmp_list);
|
||||
|
||||
statement_ = tmp;
|
||||
blk = tmp;
|
||||
}
|
||||
|
||||
// Now do the push.
|
||||
blk->push_statement_front(stmt);
|
||||
}
|
||||
|
||||
void PFunction::set_return(data_type_t*t)
|
||||
void PFunction::set_return(PTaskFuncArg t)
|
||||
{
|
||||
return_type_ = t;
|
||||
}
|
||||
|
||||
PChainConstructor* PFunction::extract_chain_constructor()
|
||||
{
|
||||
PChainConstructor*res = 0;
|
||||
|
||||
if ((res = dynamic_cast<PChainConstructor*> (statement_))) {
|
||||
statement_ = new PBlock(PBlock::BL_SEQ);
|
||||
statement_->set_line(*this);
|
||||
|
||||
} else if (PBlock*blk = dynamic_cast<PBlock*>(statement_)) {
|
||||
res = blk->extract_chain_constructor();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PFunction::symbol_type() const
|
||||
{
|
||||
return FUNCTION;
|
||||
}
|
||||
|
||||
|
||||
PLet::PLet(perm_string name, LexicalScope*parent, list<let_port_t*>*ports,
|
||||
PExpr*expr)
|
||||
: PTaskFunc(name, parent), ports_(ports), expr_(expr)
|
||||
{
|
||||
}
|
||||
|
||||
PLet::~PLet()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2007 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
@@ -22,76 +22,55 @@
|
||||
# include "PGate.h"
|
||||
# include "PExpr.h"
|
||||
# include "verinum.h"
|
||||
# include <cassert>
|
||||
# include <assert.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void PGate::set_pins_(list<PExpr*>*pins)
|
||||
PGate::PGate(perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
const svector<PExpr*>*del)
|
||||
: name_(name), pins_(pins)
|
||||
{
|
||||
assert(pins);
|
||||
assert(pins->size() == pins_.size());
|
||||
|
||||
for (size_t idx = 0 ; idx < pins_.size() ; idx += 1) {
|
||||
pins_[idx] = pins->front();
|
||||
pins->pop_front();
|
||||
}
|
||||
|
||||
assert(pins->empty());
|
||||
delete pins;
|
||||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(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), ranges_(0)
|
||||
PGate::PGate(perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: name_(name), pins_(pins)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
if (del) delay_.set_delay(del);
|
||||
str0_ = IVL_DR_STRONG;
|
||||
str1_ = IVL_DR_STRONG;
|
||||
str0_ = STRONG;
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
|
||||
PGate::PGate(perm_string name, svector<PExpr*>*pins)
|
||||
: name_(name), pins_(pins)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
str0_ = IVL_DR_STRONG;
|
||||
str1_ = IVL_DR_STRONG;
|
||||
str0_ = STRONG;
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::~PGate()
|
||||
{
|
||||
}
|
||||
|
||||
void PGate::set_ranges(list<pform_range_t>*ranges)
|
||||
{
|
||||
assert(ranges_ == 0);
|
||||
ranges_ = ranges;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -120,26 +99,69 @@ void PGate::eval_delays(Design*des, NetScope*scope,
|
||||
as_net_flag);
|
||||
}
|
||||
|
||||
unsigned PGate::delay_count() const
|
||||
void PGate::eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const
|
||||
{
|
||||
return delay_.delay_count();
|
||||
NetExpr*rise_expr, *fall_expr, *decay_expr;
|
||||
delay_.eval_delays(des, scope, rise_expr, fall_expr, decay_expr);
|
||||
|
||||
if (rise_expr == 0) {
|
||||
rise_time = 0;
|
||||
fall_time = 0;
|
||||
decay_time = 0;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*> (rise_expr)) {
|
||||
rise_time = tmp->value().as_ulong();
|
||||
|
||||
} else {
|
||||
cerr << get_fileline() << ": error: Delay expressions must be "
|
||||
<< "constant here." << endl;
|
||||
cerr << get_fileline() << ": : Cannot calculate "
|
||||
<< *rise_expr << endl;
|
||||
des->errors += 1;
|
||||
rise_time = 0;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*> (fall_expr)) {
|
||||
fall_time = tmp->value().as_ulong();
|
||||
|
||||
} else {
|
||||
if (fall_expr != rise_expr) {
|
||||
cerr << get_fileline() << ": error: Delay expressions must be "
|
||||
<< "constant here." << endl;
|
||||
cerr << get_fileline() << ": : Cannot calculate "
|
||||
<< *rise_expr << endl;
|
||||
}
|
||||
des->errors += 1;
|
||||
fall_time = 0;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*> (decay_expr)) {
|
||||
decay_time = tmp->value().as_ulong();
|
||||
|
||||
} else {
|
||||
cerr << get_fileline() << ": error: Delay expressions must be "
|
||||
<< "constant here." << endl;
|
||||
cerr << get_fileline() << ": : Cannot calculate "
|
||||
<< *rise_expr << endl;
|
||||
des->errors += 1;
|
||||
decay_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PGate::symbol_type() const
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(list<PExpr*>*pins)
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins)
|
||||
: PGate(perm_string(), pins)
|
||||
{
|
||||
assert(pin_count() == 2);
|
||||
assert(pins->count() == 2);
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(list<PExpr*>*pins, list<PExpr*>*dels)
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels)
|
||||
: PGate(perm_string(), pins, dels)
|
||||
{
|
||||
assert(pin_count() == 2);
|
||||
assert(pins->count() == 2);
|
||||
}
|
||||
|
||||
PGAssign::~PGAssign()
|
||||
@@ -147,16 +169,16 @@ PGAssign::~PGAssign()
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
list<PExpr*>*pins,
|
||||
list<PExpr*>*del)
|
||||
: PGate(name, pins, del), type_(t)
|
||||
svector<PExpr*>*pins,
|
||||
svector<PExpr*>*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
list<PExpr*>*pins,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: PGate(name, pins, del), type_(t)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -165,128 +187,35 @@ PGBuiltin::~PGBuiltin()
|
||||
{
|
||||
}
|
||||
|
||||
const char* PGBuiltin::gate_name() const
|
||||
void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
|
||||
{
|
||||
switch(type_) {
|
||||
case AND:
|
||||
return "AND";
|
||||
break;
|
||||
case NAND:
|
||||
return "NAND";
|
||||
break;
|
||||
assert(msb_ == 0);
|
||||
assert(lsb_ == 0);
|
||||
|
||||
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>";
|
||||
msb_ = msb;
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
|
||||
: PGate(name, pins), bound_type_(0), type_(type), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0)
|
||||
PGModule::PGModule(perm_string type, perm_string name, svector<PExpr*>*pins)
|
||||
: PGate(name, pins), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins)
|
||||
: PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PGModule::PGModule(Module*type, perm_string name)
|
||||
: PGate(name, 0), bound_type_(type), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0)
|
||||
: PGate(name, 0), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::~PGModule()
|
||||
{
|
||||
}
|
||||
|
||||
void PGModule::set_parameters(list<PExpr*>*o)
|
||||
void PGModule::set_parameters(svector<PExpr*>*o)
|
||||
{
|
||||
assert(overrides_ == 0);
|
||||
overrides_ = o;
|
||||
@@ -300,7 +229,17 @@ void PGModule::set_parameters(named<PExpr*>*pa, unsigned npa)
|
||||
nparms_ = npa;
|
||||
}
|
||||
|
||||
perm_string PGModule::get_type() const
|
||||
void PGModule::set_range(PExpr*msb, PExpr*lsb)
|
||||
{
|
||||
assert(msb_ == 0);
|
||||
assert(lsb_ == 0);
|
||||
|
||||
msb_ = msb;
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
perm_string PGModule::get_type()
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PGate_H
|
||||
#define IVL_PGate_H
|
||||
#ifndef __PGate_H
|
||||
#define __PGate_H
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,17 +16,19 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.h,v 1.32 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "named.h"
|
||||
# include "PNamedItem.h"
|
||||
# include "LineInfo.h"
|
||||
# include "PDelays.h"
|
||||
# include "netlist.h"
|
||||
# include <map>
|
||||
# include <list>
|
||||
# include <vector>
|
||||
# include <string>
|
||||
class PExpr;
|
||||
class PUdp;
|
||||
@@ -46,24 +48,32 @@ class Module;
|
||||
* single strength pair. There is a strength of the 0 drive, and a
|
||||
* strength of the 1 drive.
|
||||
*/
|
||||
class PGate : public PNamedItem {
|
||||
class PGate : public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PGate(perm_string name, std::list<PExpr*>*pins,
|
||||
const std::list<PExpr*>*del);
|
||||
enum strength_t { HIGHZ, WEAK, PULL, STRONG, SUPPLY };
|
||||
|
||||
explicit PGate(perm_string name, std::list<PExpr*>*pins,
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins,
|
||||
const svector<PExpr*>*del);
|
||||
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
|
||||
explicit PGate(perm_string name, std::list<PExpr*>*pins);
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins);
|
||||
|
||||
virtual ~PGate();
|
||||
|
||||
void set_ranges(std::list<pform_range_t>*ranges);
|
||||
bool is_array() const { return ranges_ != 0; }
|
||||
|
||||
perm_string get_name() const { return name_; }
|
||||
|
||||
// This method evaluates the delays all the way to an
|
||||
// integer. If the delay is non-constant, then set the times
|
||||
// to 0, print an error message and mark an error to the
|
||||
// design.
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const;
|
||||
|
||||
// This evaluates the delays as far as possible, but returns
|
||||
// an expression, and do not signal errors.
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
@@ -72,46 +82,34 @@ class PGate : public PNamedItem {
|
||||
NetExpr*&decay_time,
|
||||
bool as_net_flag =false) 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<perm_string,PExpr*> attributes;
|
||||
|
||||
std::map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind =4) const;
|
||||
virtual void dump(ostream&out, unsigned ind =4) 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;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
protected:
|
||||
const std::vector<PExpr*>& get_pins() const { return pins_; }
|
||||
const svector<PExpr*>& get_pins() const { return *pins_; }
|
||||
|
||||
unsigned calculate_array_size_(Design*, NetScope*,
|
||||
long&high, long&low) const;
|
||||
|
||||
void dump_pins(std::ostream&out) const;
|
||||
void dump_delays(std::ostream&out) const;
|
||||
void dump_ranges(std::ostream&out) const;
|
||||
void dump_pins(ostream&out) const;
|
||||
void dump_delays(ostream&out) const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
PDelays delay_;
|
||||
std::vector<PExpr*>pins_;
|
||||
svector<PExpr*>*pins_;
|
||||
|
||||
std::list<pform_range_t>*ranges_;
|
||||
|
||||
ivl_drive_t str0_, str1_;
|
||||
|
||||
void set_pins_(std::list<PExpr*>*pins);
|
||||
strength_t str0_, str1_;
|
||||
|
||||
private: // not implemented
|
||||
PGate(const PGate&);
|
||||
@@ -125,16 +123,15 @@ class PGate : public PNamedItem {
|
||||
class PGAssign : public PGate {
|
||||
|
||||
public:
|
||||
explicit PGAssign(std::list<PExpr*>*pins);
|
||||
explicit PGAssign(std::list<PExpr*>*pins, std::list<PExpr*>*dels);
|
||||
explicit PGAssign(svector<PExpr*>*pins);
|
||||
explicit PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels);
|
||||
~PGAssign();
|
||||
|
||||
void dump(std::ostream&out, unsigned ind =4) const;
|
||||
void dump(ostream&out, unsigned ind =4) 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -158,31 +155,25 @@ class PGBuiltin : public PGate {
|
||||
|
||||
public:
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
std::list<PExpr*>*pins,
|
||||
std::list<PExpr*>*del);
|
||||
svector<PExpr*>*pins,
|
||||
svector<PExpr*>*del);
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
std::list<PExpr*>*pins,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
~PGBuiltin();
|
||||
|
||||
Type type() const { return type_; }
|
||||
const char * gate_name() const;
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind =4) const;
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
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_;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -199,39 +190,37 @@ class PGModule : public PGate {
|
||||
// If the binding of ports is by position, this constructor
|
||||
// builds everything all at once.
|
||||
explicit PGModule(perm_string type, perm_string name,
|
||||
std::list<PExpr*>*pins);
|
||||
svector<PExpr*>*pins);
|
||||
|
||||
// If the binding of ports is by name, this constructor takes
|
||||
// the bindings and stores them for later elaboration.
|
||||
explicit PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins);
|
||||
|
||||
// If the module type is known by design, then use this
|
||||
// constructor.
|
||||
explicit PGModule(Module*type, perm_string name);
|
||||
|
||||
~PGModule();
|
||||
|
||||
// Parameter overrides can come as an ordered list, or a set
|
||||
// of named expressions.
|
||||
void set_parameters(std::list<PExpr*>*o);
|
||||
void set_parameters(svector<PExpr*>*o);
|
||||
void set_parameters(named<PExpr*>*pa, unsigned npa);
|
||||
|
||||
std::map<perm_string,PExpr*> attributes;
|
||||
// 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(std::ostream&out, unsigned ind =4) const;
|
||||
virtual void dump(ostream&out, unsigned ind =4) 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;
|
||||
perm_string get_type();
|
||||
|
||||
private:
|
||||
Module*bound_type_;
|
||||
perm_string type_;
|
||||
std::list<PExpr*>*overrides_;
|
||||
svector<PExpr*>*overrides_;
|
||||
named<PExpr*>*pins_;
|
||||
unsigned npins_;
|
||||
|
||||
@@ -239,20 +228,19 @@ class PGModule : public PGate {
|
||||
named<PExpr*>*parms_;
|
||||
unsigned nparms_;
|
||||
|
||||
friend class delayed_elaborate_scope_mod_instances;
|
||||
// Arrays of modules are give if these are set.
|
||||
PExpr*msb_;
|
||||
PExpr*lsb_;
|
||||
|
||||
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
|
||||
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
|
||||
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
|
||||
void elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const;
|
||||
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
|
||||
// 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;
|
||||
NetNet::PortType dir) const;
|
||||
};
|
||||
|
||||
#endif /* IVL_PGate_H */
|
||||
#endif
|
||||
|
||||
+19
-43
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2006 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,64 +14,40 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGenerate.cc,v 1.4 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PGenerate.h"
|
||||
# include "PWire.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
PGenerate::PGenerate(LexicalScope*parent, unsigned id)
|
||||
: LexicalScope(parent), id_number(id)
|
||||
PGenerate::PGenerate(unsigned id)
|
||||
: id_number(id)
|
||||
{
|
||||
scheme_type = GS_NONE;
|
||||
directly_nested = false;
|
||||
local_index = false;
|
||||
loop_init = 0;
|
||||
loop_test = 0;
|
||||
loop_step = 0;
|
||||
parent = 0;
|
||||
}
|
||||
|
||||
PGenerate::~PGenerate()
|
||||
{
|
||||
}
|
||||
|
||||
PWire* PGenerate::get_wire(perm_string name) const
|
||||
{
|
||||
map<perm_string,PWire*>::const_iterator obj = wires.find(name);
|
||||
if (obj == wires.end())
|
||||
return 0;
|
||||
else
|
||||
return (*obj).second;
|
||||
}
|
||||
|
||||
void PGenerate::add_gate(PGate*gate)
|
||||
{
|
||||
gates.push_back(gate);
|
||||
}
|
||||
|
||||
ostream& operator << (ostream&out, PGenerate::scheme_t type)
|
||||
void PGenerate::add_behavior(PProcess*proc)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PGenerate::symbol_type() const
|
||||
{
|
||||
return GENBLOCK;
|
||||
behaviors.push_back(proc);
|
||||
}
|
||||
|
||||
+21
-47
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PGenerate_H
|
||||
#define IVL_PGenerate_H
|
||||
#ifndef __PGenerate_H
|
||||
#define __PGenerate_H
|
||||
/*
|
||||
* Copyright (c) 2006-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2006 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,24 +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
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGenerate.h,v 1.4 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PNamedItem.h"
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include "HName.h"
|
||||
# include "PScope.h"
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include <valarray>
|
||||
# include "pform_types.h"
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class PExpr;
|
||||
class PFunction;
|
||||
class PProcess;
|
||||
class PTask;
|
||||
class PGate;
|
||||
class PWire;
|
||||
|
||||
@@ -50,10 +49,10 @@ class PWire;
|
||||
* The parent points to the GS_CASE that contains this item.
|
||||
* the loop_test is compared with the parent->loop_test expression.
|
||||
*/
|
||||
class PGenerate : public PNamedItem, public LexicalScope {
|
||||
class PGenerate : public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PGenerate(LexicalScope*parent, unsigned id_number);
|
||||
PGenerate(unsigned id_number);
|
||||
~PGenerate();
|
||||
|
||||
// Generate schemes have an ID number, for when the scope is
|
||||
@@ -61,44 +60,28 @@ class PGenerate : public PNamedItem, public LexicalScope {
|
||||
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};
|
||||
GS_CASE, GS_CASE_ITEM};
|
||||
scheme_t scheme_type;
|
||||
|
||||
bool directly_nested;
|
||||
|
||||
// generate loops have an index variable and three
|
||||
// expressions: for (index = <init>; <test>; index=<step>)
|
||||
// the index is local if it was declared in the init expression,
|
||||
// e.g. for (genvar index = <init>; <test>; index=<step>)
|
||||
bool local_index;
|
||||
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 std::pair<pform_name_t,PExpr*> named_expr_t;
|
||||
std::list<named_expr_t>defparms;
|
||||
map<perm_string,PWire*>wires;
|
||||
PWire* get_wire(perm_string name) const;
|
||||
|
||||
std::list<PGate*> gates;
|
||||
list<PGate*> gates;
|
||||
void add_gate(PGate*);
|
||||
|
||||
// Tasks instantiated within this scheme.
|
||||
std::map<perm_string,PTask*> tasks;
|
||||
std::map<perm_string,PFunction*>funcs;
|
||||
list<PProcess*> behaviors;
|
||||
void add_behavior(PProcess*behave);
|
||||
|
||||
// Generate schemes can contain further generate schemes.
|
||||
std::list<PGenerate*> generate_schemes;
|
||||
// PGenerate*parent;
|
||||
list<PGenerate*> generates;
|
||||
PGenerate*parent;
|
||||
|
||||
// This method is called by the elaboration of a module to
|
||||
// generate scopes. the container is the scope that is to
|
||||
@@ -110,34 +93,25 @@ class PGenerate : public PNamedItem, public LexicalScope {
|
||||
bool elaborate_sig(Design*des, NetScope*container) const;
|
||||
bool elaborate(Design*des, NetScope*container) const;
|
||||
|
||||
void dump(std::ostream&out, unsigned indent) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
void dump(ostream&out, unsigned indent) const;
|
||||
|
||||
private:
|
||||
void check_for_valid_genvar_value_(long value);
|
||||
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);
|
||||
|
||||
// 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.
|
||||
std::list<NetScope*>scope_list_;
|
||||
list<NetScope*>scope_list_;
|
||||
// internal function called on each scope generated by this scheme.
|
||||
bool elaborate_sig_(Design*des, NetScope*scope) const;
|
||||
bool elaborate_sig_direct_(Design*des, NetScope*scope) const;
|
||||
bool elaborate_(Design*des, NetScope*scope) const;
|
||||
bool elaborate_direct_(Design*des, NetScope*scope) const;
|
||||
|
||||
private: // not implemented
|
||||
PGenerate(const PGenerate&);
|
||||
PGenerate& operator= (const PGenerate&);
|
||||
};
|
||||
|
||||
extern std::ostream& operator << (std::ostream&, PGenerate::scheme_t);
|
||||
|
||||
#endif /* IVL_PGenerate_H */
|
||||
#endif
|
||||
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2019 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 "PModport.h"
|
||||
|
||||
PModport::PModport(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PModport::~PModport()
|
||||
{
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PModport::symbol_type() const
|
||||
{
|
||||
return MODPORT;
|
||||
}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
#ifndef IVL_PModport_H
|
||||
#define IVL_PModport_H
|
||||
/*
|
||||
* Copyright (c) 2015-2021 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 "PNamedItem.h"
|
||||
# include "PScope.h"
|
||||
# include "StringHeap.h"
|
||||
# include "netlist.h"
|
||||
# include <vector>
|
||||
|
||||
/*
|
||||
* The PModport class represents a parsed SystemVerilog modport list.
|
||||
*/
|
||||
class PModport : public PNamedItem {
|
||||
|
||||
public:
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
// of the modport, without any scope.
|
||||
explicit PModport(perm_string name);
|
||||
~PModport();
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
|
||||
typedef std::pair <NetNet::PortType,PExpr*> simple_port_t;
|
||||
std::map<perm_string,simple_port_t> simple_ports;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
|
||||
private: // not implemented
|
||||
PModport(const PModport&);
|
||||
PModport& operator= (const PModport&);
|
||||
};
|
||||
|
||||
#endif /* IVL_PModport_H */
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Martin Whitaker ([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 "PNamedItem.h"
|
||||
# include <ostream>
|
||||
|
||||
PNamedItem::PNamedItem()
|
||||
{
|
||||
}
|
||||
|
||||
PNamedItem::~PNamedItem()
|
||||
{
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PNamedItem::symbol_type() const
|
||||
{
|
||||
return ANY;
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream&o, PNamedItem::SymbolType st)
|
||||
{
|
||||
switch (st) {
|
||||
case PNamedItem::ANY:
|
||||
o << "a symbol";
|
||||
break;
|
||||
case PNamedItem::PARAM:
|
||||
o << "a parameter";
|
||||
break;
|
||||
case PNamedItem::NET:
|
||||
o << "a net";
|
||||
break;
|
||||
case PNamedItem::VAR:
|
||||
o << "a variable";
|
||||
break;
|
||||
case PNamedItem::GENVAR:
|
||||
o << "a genvar";
|
||||
break;
|
||||
case PNamedItem::EVENT:
|
||||
o << "an event";
|
||||
break;
|
||||
case PNamedItem::TYPE:
|
||||
o << "a type";
|
||||
break;
|
||||
case PNamedItem::ENUM:
|
||||
o << "an enum type or value";
|
||||
break;
|
||||
case PNamedItem::CLASS:
|
||||
o << "a class";
|
||||
break;
|
||||
case PNamedItem::FUNCTION:
|
||||
o << "a function";
|
||||
break;
|
||||
case PNamedItem::TASK:
|
||||
o << "a task";
|
||||
break;
|
||||
case PNamedItem::BLOCK:
|
||||
o << "a named block";
|
||||
break;
|
||||
case PNamedItem::GENBLOCK:
|
||||
o << "a generate block";
|
||||
break;
|
||||
case PNamedItem::MODPORT:
|
||||
o << "a modport";
|
||||
break;
|
||||
case PNamedItem::PACKAGE:
|
||||
o << "a package";
|
||||
break;
|
||||
case PNamedItem::MODULE:
|
||||
o << "a module";
|
||||
break;
|
||||
case PNamedItem::PROGRAM:
|
||||
o << "a program";
|
||||
break;
|
||||
case PNamedItem::INTERFACE:
|
||||
o << "an interface";
|
||||
break;
|
||||
case PNamedItem::PRIMITIVE:
|
||||
o << "a primitive";
|
||||
break;
|
||||
case PNamedItem::INSTANCE:
|
||||
o << "an instance name";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
PGenvar::PGenvar()
|
||||
{
|
||||
}
|
||||
|
||||
PGenvar::~PGenvar()
|
||||
{
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PGenvar::symbol_type() const
|
||||
{
|
||||
return GENVAR;
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
#ifndef IVL_PNamedItem_H
|
||||
#define IVL_PNamedItem_H
|
||||
/*
|
||||
* Copyright (c) 2019 Martin Whitaker ([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"
|
||||
|
||||
/*
|
||||
* The PNamedItem class is the base class for all items that can be added
|
||||
* to a scope's local symbol map.
|
||||
*/
|
||||
class PNamedItem : virtual public LineInfo {
|
||||
|
||||
public:
|
||||
enum SymbolType { ANY, PARAM, NET, VAR, GENVAR, EVENT, TYPE, ENUM,
|
||||
CLASS, FUNCTION, TASK, BLOCK, GENBLOCK, MODPORT,
|
||||
PACKAGE, MODULE, PROGRAM, INTERFACE, PRIMITIVE,
|
||||
INSTANCE };
|
||||
|
||||
explicit PNamedItem();
|
||||
virtual ~PNamedItem();
|
||||
|
||||
virtual SymbolType symbol_type() const;
|
||||
};
|
||||
|
||||
extern std::ostream& operator << (std::ostream&, PNamedItem::SymbolType);
|
||||
|
||||
/*
|
||||
* The PGenvar class represents a genvar. This is only used to represent
|
||||
* genvar in a scope's local symbol map.
|
||||
*/
|
||||
class PGenvar : public PNamedItem {
|
||||
|
||||
public:
|
||||
explicit PGenvar();
|
||||
virtual ~PGenvar();
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
};
|
||||
|
||||
#endif /* IVL_PNamedItem_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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2008 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,19 +14,21 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "PScope.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool LexicalScope::var_init_needs_explicit_lifetime() const
|
||||
PScope::PScope(perm_string n, PScope*p)
|
||||
: name_(n), parent_(p)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PWire* LexicalScope::wires_find(perm_string name)
|
||||
PScope::~PScope()
|
||||
{
|
||||
}
|
||||
|
||||
PWire* PScope::wires_find(perm_string name)
|
||||
{
|
||||
map<perm_string,PWire*>::const_iterator cur = wires.find(name);
|
||||
if (cur == wires.end())
|
||||
@@ -34,35 +36,3 @@ PWire* LexicalScope::wires_find(perm_string name)
|
||||
else
|
||||
return (*cur).second;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType LexicalScope::param_expr_t::symbol_type() const
|
||||
{
|
||||
return PARAM;
|
||||
}
|
||||
|
||||
PScope::PScope(perm_string n, LexicalScope*parent)
|
||||
: LexicalScope(parent), name_(n)
|
||||
{
|
||||
time_unit = 0;
|
||||
time_precision = 0;
|
||||
time_unit_is_default = true;
|
||||
time_prec_is_default = true;
|
||||
}
|
||||
|
||||
PScope::~PScope()
|
||||
{
|
||||
for(typedef_map_t::iterator it = typedefs.begin(); it != typedefs.end();
|
||||
++it)
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
|
||||
: PScope(n, parent)
|
||||
{
|
||||
time_unit_is_local = false;
|
||||
time_prec_is_local = false;
|
||||
}
|
||||
|
||||
PScopeExtra::~PScopeExtra()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PScope_H
|
||||
#define IVL_PScope_H
|
||||
#ifndef __PScope_H
|
||||
#define __PScope_H
|
||||
/*
|
||||
* Copyright (c) 2008-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2008 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,28 +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
|
||||
*/
|
||||
|
||||
# include "PNamedItem.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 Statement;
|
||||
class PCallTask;
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
@@ -47,138 +35,10 @@ class NetScope;
|
||||
* represents lexical scope. For example, a module, a function/task, a
|
||||
* named block is derived from a PScope.
|
||||
*
|
||||
* NOTE: This is not the same concept as the "scope" of an elaborated
|
||||
* NOTE: This is note the same concept as the "scope" of an elaborated
|
||||
* hierarchy. That is represented by NetScope objects after elaboration.
|
||||
*/
|
||||
|
||||
class LexicalScope {
|
||||
|
||||
public:
|
||||
enum lifetime_t { INHERITED, STATIC, AUTOMATIC };
|
||||
|
||||
explicit LexicalScope(LexicalScope*parent)
|
||||
: default_lifetime(INHERITED), has_parameter_port_list(false),
|
||||
generate_counter(0), parent_(parent) { }
|
||||
// A virtual destructor is so that dynamic_cast can work.
|
||||
virtual ~LexicalScope() { }
|
||||
|
||||
lifetime_t default_lifetime;
|
||||
|
||||
// Symbols that are defined or declared in this scope.
|
||||
std::map<perm_string,PNamedItem*>local_symbols;
|
||||
|
||||
// Symbols that are explicitly imported. Bind the imported name
|
||||
// to the package from which the name is imported.
|
||||
std::map<perm_string,PPackage*>explicit_imports;
|
||||
|
||||
// Packages that are wildcard imported. When identifiers from
|
||||
// these packages are referenced, they will be added to the
|
||||
// explicit imports (IEEE 1800-2012 26.3).
|
||||
std::list<PPackage*>potential_imports;
|
||||
|
||||
// A task or function call may reference a task or function defined
|
||||
// later in the scope. So here we stash the potential imports for
|
||||
// task and function calls. They will be added to the explicit
|
||||
// imports if we don't find a local definition.
|
||||
std::map<perm_string,PPackage*>possible_imports;
|
||||
|
||||
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 PNamedItem {
|
||||
inline param_expr_t() : data_type(0), expr(0), range(0),
|
||||
local_flag(false), overridable(true) { }
|
||||
// Type information.
|
||||
data_type_t*data_type;
|
||||
// Value expression
|
||||
PExpr*expr;
|
||||
// If there are range constraints, list them here
|
||||
range_t*range;
|
||||
// Whether it is a local parameter
|
||||
bool local_flag;
|
||||
// Whether the parameter can be overridden
|
||||
bool overridable;
|
||||
// Whether the parameter is a type parameter
|
||||
bool type_flag = false;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
};
|
||||
std::map<perm_string,param_expr_t*>parameters;
|
||||
bool has_parameter_port_list;
|
||||
|
||||
// Defined types in the scope.
|
||||
typedef std::map<perm_string,typedef_t*> typedef_map_t;
|
||||
typedef_map_t typedefs;
|
||||
|
||||
// Named events in the scope.
|
||||
std::map<perm_string,PEvent*>events;
|
||||
|
||||
// Nets and variables (wires) in the scope
|
||||
std::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.
|
||||
std::map<perm_string,LineInfo*> genvars;
|
||||
|
||||
// Variable initializations in this scope
|
||||
std::vector<Statement*> var_inits;
|
||||
|
||||
// Behaviors (processes) in this scope
|
||||
std::list<PProcess*> behaviors;
|
||||
std::list<AProcess*> analog_behaviors;
|
||||
|
||||
// The elaboration tasks in this scope
|
||||
std::list<PCallTask*> elab_tasks;
|
||||
|
||||
// Enumeration sets.
|
||||
std::vector<enum_type_t*> enum_sets;
|
||||
|
||||
// A count of the generate constructs in this scope. This is
|
||||
// used to automatically name unnamed generate blocks, as
|
||||
// specified in the LRM.
|
||||
unsigned generate_counter;
|
||||
|
||||
LexicalScope* parent_scope() const { return parent_; }
|
||||
|
||||
virtual bool var_init_needs_explicit_lifetime() const;
|
||||
|
||||
protected:
|
||||
void dump_typedefs_(std::ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_parameters_(std::ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_enumerations_(std::ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_events_(std::ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_wires_(std::ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_var_inits_(std::ostream&out, unsigned indent) const;
|
||||
|
||||
bool elaborate_var_inits_(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
LexicalScope*parent_;
|
||||
};
|
||||
|
||||
class PScope : public LexicalScope {
|
||||
class PScope {
|
||||
|
||||
public:
|
||||
// When created, a scope has a name and a parent. The name is
|
||||
@@ -189,61 +49,32 @@ class PScope : public LexicalScope {
|
||||
// modules do not nest in Verilog, the parent must be nil for
|
||||
// modules. Scopes for tasks and functions point to their
|
||||
// containing module.
|
||||
explicit PScope(perm_string name, LexicalScope*parent =0);
|
||||
PScope(perm_string name, PScope*parent);
|
||||
virtual ~PScope();
|
||||
|
||||
perm_string pscope_name() const { return name_; }
|
||||
PScope* pscope_parent() { return parent_; }
|
||||
|
||||
/* These are the timescale for this scope. The value is
|
||||
set by the `timescale directive or, in SystemVerilog,
|
||||
by timeunit and timeprecision statements. */
|
||||
int time_unit, time_precision;
|
||||
// Nets an variables (wires) in the scope
|
||||
map<perm_string,PWire*>wires;
|
||||
PWire* wires_find(perm_string name);
|
||||
|
||||
/* Flags used to support warnings about timescales. */
|
||||
bool time_unit_is_default;
|
||||
bool time_prec_is_default;
|
||||
// Named events in the scope.
|
||||
map<perm_string,PEvent*>events;
|
||||
|
||||
bool has_explicit_timescale() const {
|
||||
return !(time_unit_is_default || time_prec_is_default);
|
||||
}
|
||||
// Behaviors (processes) in this scope
|
||||
list<PProcess*> behaviors;
|
||||
|
||||
protected:
|
||||
void dump_wires_(ostream&out, unsigned indent) const;
|
||||
|
||||
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
|
||||
|
||||
bool elaborate_behaviors_(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
PScope*parent_;
|
||||
};
|
||||
|
||||
/*
|
||||
* Some scopes can carry definitions. These include Modules and PClass
|
||||
* scopes. These derive from PScopeExtra so that they hold the maps of
|
||||
* extra definitions.
|
||||
*/
|
||||
class PScopeExtra : public PScope {
|
||||
|
||||
public:
|
||||
explicit PScopeExtra(perm_string, LexicalScope*parent =0);
|
||||
~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;
|
||||
|
||||
/* Flags used to support warnings about timescales. */
|
||||
bool time_unit_is_local;
|
||||
bool time_prec_is_local;
|
||||
|
||||
protected:
|
||||
void dump_classes_(std::ostream&out, unsigned indent) const;
|
||||
void dump_tasks_(std::ostream&out, unsigned indent) const;
|
||||
void dump_funcs_(std::ostream&out, unsigned indent) const;
|
||||
};
|
||||
|
||||
#endif /* IVL_PScope_H */
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2011 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 2006 Stephen Williams <[email protected]>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,19 +14,19 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PSpec.cc,v 1.2 2007/02/12 01:52:21 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PSpec.h"
|
||||
|
||||
PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity,
|
||||
bool full_flag)
|
||||
PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt)
|
||||
: conditional(false), condition(0), edge(0),
|
||||
src(src_cnt), dst(dst_cnt),
|
||||
data_source_expression(0)
|
||||
{
|
||||
full_flag_ = full_flag;
|
||||
polarity_ = polarity;
|
||||
}
|
||||
|
||||
PSpecPath::~PSpecPath()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PSpec_H
|
||||
#define IVL_PSpec_H
|
||||
#ifndef __PSpec_H
|
||||
#define __PSpec_H
|
||||
/*
|
||||
* Copyright (c) 2006-2014 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 2006 Stephen Williams <[email protected]>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,8 +16,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PSpec.h,v 1.3 2007/04/13 02:34:35 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
@@ -46,18 +49,11 @@ class PExpr;
|
||||
*
|
||||
* If data_source_expression != nil, then the path is edge sensitive
|
||||
* and the edge might not be 0.
|
||||
*
|
||||
* The full flag is used to verify that only vectors of the same size
|
||||
* are used in a parallel connection. Icarus always creates a full
|
||||
* connection between the source and destination. The polarity is for
|
||||
* informational (display) purposes only. The polarity is either '+',
|
||||
* '-' or 0.
|
||||
*/
|
||||
class PSpecPath : public LineInfo {
|
||||
|
||||
public:
|
||||
PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity,
|
||||
bool full_flag);
|
||||
PSpecPath(unsigned src_cnt, unsigned dst_cnt);
|
||||
~PSpecPath();
|
||||
|
||||
void elaborate(class Design*des, class NetScope*scope) const;
|
||||
@@ -70,10 +66,6 @@ class PSpecPath : public LineInfo {
|
||||
class PExpr* condition;
|
||||
// Edge specification (-1==negedge, 0 = no edge, 1==posedge)
|
||||
int edge;
|
||||
// Is this a full connection.
|
||||
bool full_flag_;
|
||||
// What is the polarity of the connection.
|
||||
char polarity_;
|
||||
// Ordered set of source nodes of a path
|
||||
std::vector<perm_string> src;
|
||||
// Ordered set of destination nodes of a path
|
||||
@@ -84,4 +76,4 @@ class PSpecPath : public LineInfo {
|
||||
std::vector<class PExpr*>delays;
|
||||
};
|
||||
|
||||
#endif /* IVL_PSpec_H */
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,69 +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
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PTask.h"
|
||||
# include <cassert>
|
||||
|
||||
using namespace std;
|
||||
|
||||
PTaskFunc::PTaskFunc(perm_string n, LexicalScope*p)
|
||||
: PScope(n,p), this_type_(0), ports_(0)
|
||||
PTask::PTask(perm_string name, PScope*parent)
|
||||
: PScope(name, parent), ports_(0), statement_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PTaskFunc::~PTaskFunc()
|
||||
{
|
||||
}
|
||||
|
||||
bool PTaskFunc::var_init_needs_explicit_lifetime() const
|
||||
{
|
||||
return default_lifetime == STATIC;
|
||||
}
|
||||
|
||||
void PTaskFunc::set_ports(vector<pform_tf_port_t>*p)
|
||||
{
|
||||
assert(ports_ == 0);
|
||||
ports_ = p;
|
||||
}
|
||||
|
||||
void PTaskFunc::set_this(class_type_t*type, PWire*this_wire)
|
||||
{
|
||||
assert(this_type_ == 0);
|
||||
this_type_ = type;
|
||||
|
||||
// Push a synthesis argument that is the "this" value.
|
||||
if (ports_==0)
|
||||
ports_ = new vector<pform_tf_port_t>;
|
||||
|
||||
size_t use_size = ports_->size();
|
||||
ports_->resize(use_size + 1);
|
||||
for (size_t idx = use_size ; idx > 0 ; idx -= 1)
|
||||
ports_->at(idx) = ports_->at(idx-1);
|
||||
|
||||
ports_->at(0) = pform_tf_port_t(this_wire);
|
||||
}
|
||||
|
||||
PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__)
|
||||
: PTaskFunc(name, parent), statement_(0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PTask::symbol_type() const
|
||||
{
|
||||
return TASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PTask.cc,v $
|
||||
* Revision 1.7 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/04/19 03:04:47 steve
|
||||
* Spurious assert of empty statemnt.
|
||||
*
|
||||
* Revision 1.4 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
* Revision 1.3 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.2 1999/07/24 02:11:19 steve
|
||||
* Elaborate task input ports.
|
||||
*
|
||||
* Revision 1.1 1999/07/03 02:12:51 steve
|
||||
* Elaborate user defined tasks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PTask_H
|
||||
#define IVL_PTask_H
|
||||
#ifndef __PTask_H
|
||||
#define __PTask_H
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2008 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,71 +16,45 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "PScope.h"
|
||||
# include "PNamedItem.h"
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include <list>
|
||||
class Design;
|
||||
class NetExpr;
|
||||
class NetNet;
|
||||
class NetScope;
|
||||
class PChainConstructor;
|
||||
class PWire;
|
||||
class Statement;
|
||||
class PExpr;
|
||||
|
||||
enum PTaskFuncEnum {
|
||||
PTF_NONE,
|
||||
PTF_REG,
|
||||
PTF_REG_S,
|
||||
PTF_INTEGER,
|
||||
PTF_REAL,
|
||||
PTF_REALTIME,
|
||||
PTF_TIME
|
||||
};
|
||||
|
||||
class PTaskFunc : public PScope, public PNamedItem {
|
||||
|
||||
public:
|
||||
PTaskFunc(perm_string name, LexicalScope*parent);
|
||||
~PTaskFunc();
|
||||
|
||||
bool var_init_needs_explicit_lifetime() const;
|
||||
|
||||
void set_ports(std::vector<pform_tf_port_t>*p);
|
||||
|
||||
void set_this(class_type_t*use_type, PWire*this_wire);
|
||||
|
||||
// If this task is a method of a class, this returns a pointer
|
||||
// to the class type.
|
||||
inline class_type_t* method_of() const { return this_type_; }
|
||||
|
||||
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const =0;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const =0;
|
||||
|
||||
virtual void dump(std::ostream&, unsigned) const =0;
|
||||
|
||||
protected:
|
||||
// Elaborate the ports list. Write into the ports vector the
|
||||
// NetNet pointers for the ports, and write into the pdefs the
|
||||
// default value expressions, if any.
|
||||
void elaborate_sig_ports_(Design*des, NetScope*scope,
|
||||
std::vector<NetNet*>&ports,
|
||||
std::vector<NetExpr*>&pdefs) const;
|
||||
|
||||
void dump_ports_(std::ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
class_type_t*this_type_;
|
||||
std::vector<pform_tf_port_t>*ports_;
|
||||
struct PTaskFuncArg {
|
||||
PTaskFuncEnum type;
|
||||
svector<PExpr*>*range;
|
||||
};
|
||||
|
||||
/*
|
||||
* The PTask holds the parsed definitions of a task.
|
||||
*/
|
||||
class PTask : public PTaskFunc {
|
||||
class PTask : public PScope, public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
|
||||
explicit PTask(perm_string name, PScope*parent);
|
||||
~PTask();
|
||||
|
||||
void set_ports(svector<PWire *>*p);
|
||||
void set_statement(Statement *s);
|
||||
|
||||
// Tasks introduce scope, to need to be handled during the
|
||||
@@ -95,15 +69,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(std::ostream&, unsigned) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
svector<PWire*>*ports_;
|
||||
Statement*statement_;
|
||||
bool is_auto_;
|
||||
|
||||
private: // Not implemented
|
||||
PTask(const PTask&);
|
||||
@@ -117,26 +87,15 @@ class PTask : public PTaskFunc {
|
||||
*
|
||||
* The output value is not elaborated until elaborate_sig.
|
||||
*/
|
||||
class PFunction : public PTaskFunc {
|
||||
class PFunction : public PScope, public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
|
||||
explicit PFunction(perm_string name, PScope*parent);
|
||||
~PFunction();
|
||||
|
||||
void set_ports(svector<PWire *>*p);
|
||||
void set_statement(Statement *s);
|
||||
void set_return(data_type_t*t);
|
||||
|
||||
inline Statement* get_statement() { return statement_; }
|
||||
|
||||
// Push this statement to the front of the existing
|
||||
// definition. If the statement is a simple statement, make a
|
||||
// block to contain the statements.
|
||||
void push_statement_front(Statement*stmt);
|
||||
|
||||
// This is only used if this function is a constructor. In
|
||||
// that case, this method looks for a PChainConstructor in the
|
||||
// statement and extracts it if found.
|
||||
PChainConstructor*extract_chain_constructor();
|
||||
void set_return(PTaskFuncArg t);
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -146,43 +105,12 @@ class PFunction : public PTaskFunc {
|
||||
/* Elaborate the behavioral statement. */
|
||||
void elaborate(Design *des, NetScope*) const;
|
||||
|
||||
bool is_auto() const { return is_auto_; };
|
||||
|
||||
void dump(std::ostream&, unsigned) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
data_type_t* return_type_;
|
||||
PTaskFuncArg return_type_;
|
||||
svector<PWire *> *ports_;
|
||||
Statement *statement_;
|
||||
bool is_auto_;
|
||||
};
|
||||
|
||||
// A let is like a simple function that is expanded in the compiler
|
||||
class PLet : public PTaskFunc {
|
||||
public:
|
||||
typedef struct let_port {
|
||||
data_type_t*type_;
|
||||
perm_string name_;
|
||||
std::list<pform_range_t>*range_;
|
||||
PExpr*def_;
|
||||
|
||||
void dump(std::ostream&, unsigned) const;
|
||||
} let_port_t;
|
||||
|
||||
// FIXME: Should the port list be a vector. Check once implemented completely
|
||||
explicit PLet(perm_string name, LexicalScope*parent,
|
||||
std::list<let_port_t*>*ports, PExpr*expr);
|
||||
~PLet();
|
||||
|
||||
void elaborate_sig(Design*des, NetScope*scope) const { (void)des; (void)scope; }
|
||||
void elaborate(Design*des, NetScope*scope) const { (void)des; (void)scope; }
|
||||
|
||||
void dump(std::ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
std::list<let_port_t*>*ports_;
|
||||
PExpr*expr_;
|
||||
};
|
||||
|
||||
#endif /* IVL_PTask_H */
|
||||
#endif
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.cc,v 1.3 2004/03/08 00:47:44 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PUdp.h"
|
||||
|
||||
@@ -26,12 +29,25 @@ PUdp::PUdp(perm_string n, unsigned nports)
|
||||
|
||||
unsigned PUdp::find_port(const char*name)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
|
||||
if (ports[idx] == name)
|
||||
return idx;
|
||||
}
|
||||
|
||||
return ports.size();
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PUdp.cc,v $
|
||||
* Revision 1.3 2004/03/08 00:47:44 steve
|
||||
* primitive ports can bind bi name.
|
||||
*
|
||||
* Revision 1.2 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.1 2003/07/15 05:07:13 steve
|
||||
* Move PUdp constructor into compiled file.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PUdp_H
|
||||
#define IVL_PUdp_H
|
||||
#ifndef __PUdp_H
|
||||
#define __PUdp_H
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,20 +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
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <map>
|
||||
# include <vector>
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include "svector.h"
|
||||
# include "verinum.h"
|
||||
|
||||
class PExpr;
|
||||
|
||||
/*
|
||||
* This class represents a parsed UDP. This is a much simpler object
|
||||
* than a module or macromodule.
|
||||
* then a module or macromodule.
|
||||
*
|
||||
* - all ports are scalar,
|
||||
* - pin 0 (the first port) is always output,
|
||||
@@ -48,25 +50,25 @@ class PExpr;
|
||||
* If the UDP is sequential, the "initial" member is taken to be the
|
||||
* initial value assigned in the source, or 'x' if none is given.
|
||||
*/
|
||||
class PUdp : public LineInfo {
|
||||
class PUdp {
|
||||
|
||||
public:
|
||||
explicit PUdp(perm_string n, unsigned nports);
|
||||
|
||||
std::vector<std::string> ports;
|
||||
svector<string>ports;
|
||||
unsigned find_port(const char*name);
|
||||
|
||||
bool sequential;
|
||||
|
||||
std::vector<std::string> tinput;
|
||||
std::vector<char> tcurrent;
|
||||
std::vector<char> toutput;
|
||||
svector<string>tinput;
|
||||
svector<char> tcurrent;
|
||||
svector<char> toutput;
|
||||
|
||||
verinum::V initial;
|
||||
|
||||
std::map<std::string,PExpr*> attributes;
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
void dump(std::ostream&out) const;
|
||||
void dump(ostream&out) const;
|
||||
|
||||
perm_string name_;
|
||||
private:
|
||||
@@ -76,4 +78,53 @@ class PUdp : public LineInfo {
|
||||
PUdp& operator= (const PUdp&);
|
||||
};
|
||||
|
||||
#endif /* IVL_PUdp_H */
|
||||
/*
|
||||
* $Log: PUdp.h,v $
|
||||
* Revision 1.12 2004/03/08 00:47:44 steve
|
||||
* primitive ports can bind bi name.
|
||||
*
|
||||
* Revision 1.11 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.10 2003/07/15 05:07:13 steve
|
||||
* Move PUdp constructor into compiled file.
|
||||
*
|
||||
* Revision 1.9 2003/07/15 03:49:22 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.8 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.7 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.5 2001/04/22 23:09:45 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.4 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.3 1999/06/15 03:44:53 steve
|
||||
* Get rid of the STL vector template.
|
||||
*
|
||||
* Revision 1.2 1998/12/01 00:42:13 steve
|
||||
* Elaborate UDP devices,
|
||||
* Support UDP type attributes, and
|
||||
* pass those attributes to nodes that
|
||||
* are instantiated by elaboration,
|
||||
* Put modules into a map instead of
|
||||
* a simple list.
|
||||
*
|
||||
* Revision 1.1 1998/11/25 02:35:53 steve
|
||||
* Parse UDP primitives all the way to pform.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2007 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,36 +14,28 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
# include "ivl_assert.h"
|
||||
# include "PWire.h"
|
||||
# include "PExpr.h"
|
||||
# include <cassert>
|
||||
|
||||
using namespace std;
|
||||
# include <assert.h>
|
||||
|
||||
PWire::PWire(perm_string n,
|
||||
NetNet::Type t,
|
||||
NetNet::PortType pt,
|
||||
PWSRType rt)
|
||||
: name_(n), type_(t), port_type_(pt), signed_(false),
|
||||
port_set_(false), net_set_(false), is_scalar_(false),
|
||||
error_cnt_(0), discipline_(0)
|
||||
ivl_variable_type_t dt)
|
||||
: name_(n), type_(t), port_type_(pt), data_type_(dt),
|
||||
signed_(false), isint_(false),
|
||||
port_msb_(0), port_lsb_(0), port_set_(false),
|
||||
net_msb_(0), net_lsb_(0), net_set_(false), error_cnt_(0),
|
||||
lidx_(0), ridx_(0), discipline_(0)
|
||||
{
|
||||
switch (rt) {
|
||||
case SR_PORT:
|
||||
port_set_ = true;
|
||||
break;
|
||||
case SR_NET:
|
||||
net_set_ = true;
|
||||
break;
|
||||
case SR_BOTH:
|
||||
port_set_ = true;
|
||||
net_set_ = true;
|
||||
break;
|
||||
if (t == NetNet::INTEGER) {
|
||||
type_ = NetNet::REG;
|
||||
signed_ = true;
|
||||
isint_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,13 +58,13 @@ 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::IMPLICIT_REG) 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:
|
||||
@@ -95,10 +87,12 @@ bool PWire::set_port_type(NetNet::PortType pt)
|
||||
|
||||
switch (port_type_) {
|
||||
case NetNet::PIMPLICIT:
|
||||
case NetNet::NOT_A_PORT:
|
||||
port_type_ = pt;
|
||||
return true;
|
||||
|
||||
case NetNet::NOT_A_PORT:
|
||||
return false;
|
||||
|
||||
default:
|
||||
if (port_type_ != pt)
|
||||
return false;
|
||||
@@ -107,15 +101,28 @@ 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)
|
||||
{
|
||||
// For a non-ANSI style port declaration where the data type is
|
||||
// specified in a corresponding variable declaration, the signed
|
||||
// attribute may be attached to either the port declaration or to
|
||||
// the variable declaration (IEEE 1364-2005 section 12.3.3). The
|
||||
// signal is signed if either the port or the variable is signed.
|
||||
// Handle that here.
|
||||
signed_ = signed_ || flag;
|
||||
signed_ = flag;
|
||||
}
|
||||
|
||||
bool PWire::get_signed() const
|
||||
@@ -123,86 +130,81 @@ bool PWire::get_signed() const
|
||||
return signed_;
|
||||
}
|
||||
|
||||
void PWire::set_port(NetNet::PortType pt)
|
||||
bool PWire::get_isint() const
|
||||
{
|
||||
ivl_assert(*this, !port_set_);
|
||||
port_set_ = true;
|
||||
|
||||
bool rc = set_port_type(pt);
|
||||
ivl_assert(*this, rc);
|
||||
return isint_;
|
||||
}
|
||||
|
||||
void PWire::set_net(NetNet::Type t)
|
||||
{
|
||||
ivl_assert(*this, !net_set_);
|
||||
net_set_ = true;
|
||||
|
||||
if (t != NetNet::IMPLICIT) {
|
||||
bool rc = set_wire_type(t);
|
||||
ivl_assert(*this, rc);
|
||||
}
|
||||
}
|
||||
|
||||
void PWire::set_range(const list<pform_range_t>&rlist, PWSRType type)
|
||||
void PWire::set_range(PExpr*m, PExpr*l, PWSRType type)
|
||||
{
|
||||
switch (type) {
|
||||
case SR_PORT:
|
||||
if (!port_.empty())
|
||||
return;
|
||||
port_ = rlist;
|
||||
break;
|
||||
if (port_set_) {
|
||||
cerr << get_fileline() << ": error: Port ``" << name_
|
||||
<< "'' has already been declared a port." << endl;
|
||||
error_cnt_ += 1;
|
||||
} else {
|
||||
port_msb_ = m;
|
||||
port_lsb_ = l;
|
||||
port_set_ = true;
|
||||
}
|
||||
return;
|
||||
|
||||
case SR_NET:
|
||||
if (!net_.empty())
|
||||
return;
|
||||
net_ = rlist;
|
||||
break;
|
||||
if (net_set_) {
|
||||
cerr << get_fileline() << ": error: Net ``" << name_
|
||||
<< "'' has already been declared." << endl;
|
||||
error_cnt_ += 1;
|
||||
} else {
|
||||
net_msb_ = m;
|
||||
net_lsb_ = l;
|
||||
net_set_ = true;
|
||||
}
|
||||
return;
|
||||
|
||||
case SR_BOTH:
|
||||
if (!port_.empty() || !net_.empty())
|
||||
return;
|
||||
port_ = rlist;
|
||||
net_ = rlist;
|
||||
break;
|
||||
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_msb_ = m;
|
||||
port_lsb_ = l;
|
||||
port_set_ = true;
|
||||
net_msb_ = m;
|
||||
net_lsb_ = l;
|
||||
net_set_ = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PWire::set_unpacked_idx(const list<pform_range_t>&ranges)
|
||||
void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||
{
|
||||
if (! unpacked_.empty()) {
|
||||
if (lidx_ != 0 || ridx_ != 0) {
|
||||
cerr << get_fileline() << ": error: Array ``" << name_
|
||||
<< "'' has already been declared." << endl;
|
||||
error_cnt_ += 1;
|
||||
} else {
|
||||
unpacked_ = ranges;
|
||||
lidx_ = ldx;
|
||||
ridx_ = rdx;
|
||||
}
|
||||
}
|
||||
|
||||
void PWire::set_data_type(data_type_t*type)
|
||||
{
|
||||
if (set_data_type_.get() == type)
|
||||
return;
|
||||
|
||||
assert(!set_data_type_.get());
|
||||
set_data_type_.reset(type);
|
||||
}
|
||||
|
||||
void PWire::set_discipline(ivl_discipline_t d)
|
||||
void PWire::set_discipline(discipline_t*d)
|
||||
{
|
||||
assert(discipline_ == 0);
|
||||
discipline_ = d;
|
||||
}
|
||||
|
||||
ivl_discipline_t PWire::get_discipline(void) const
|
||||
discipline_t* PWire::get_discipline(void) const
|
||||
{
|
||||
return discipline_;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PWire::symbol_type() const
|
||||
{
|
||||
switch (type_) {
|
||||
case NetNet::IMPLICIT_REG:
|
||||
case NetNet::REG:
|
||||
return VAR;
|
||||
default:
|
||||
return NET;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PWire_H
|
||||
#define IVL_PWire_H
|
||||
#ifndef __PWire_H
|
||||
#define __PWire_H
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2007 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,24 +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
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PWire.h,v 1.21 2007/05/24 04:07:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
# include "PNamedItem.h"
|
||||
# include <list>
|
||||
# include "LineInfo.h"
|
||||
# include <map>
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
|
||||
#ifdef HAVE_IOSFWD
|
||||
# include <iosfwd>
|
||||
#else
|
||||
# include <iostream>
|
||||
class ostream;
|
||||
#endif
|
||||
|
||||
class PExpr;
|
||||
class Design;
|
||||
class netdarray_t;
|
||||
class discipline_t;
|
||||
|
||||
/*
|
||||
* The different type of PWire::set_range() calls.
|
||||
@@ -51,13 +54,13 @@ enum PWSRType {SR_PORT, SR_NET, SR_BOTH};
|
||||
* from that perspective, sub-scopes within the module are a part of
|
||||
* the wire name.
|
||||
*/
|
||||
class PWire : public PNamedItem {
|
||||
class PWire : public LineInfo {
|
||||
|
||||
public:
|
||||
PWire(perm_string name,
|
||||
NetNet::Type t,
|
||||
NetNet::PortType pt,
|
||||
PWSRType rt = SR_NET);
|
||||
ivl_variable_type_t dt);
|
||||
|
||||
// Return a hierarchical name.
|
||||
perm_string basename() const;
|
||||
@@ -70,69 +73,53 @@ class PWire : public PNamedItem {
|
||||
|
||||
void set_signed(bool flag);
|
||||
bool get_signed() const;
|
||||
bool get_isint() const;
|
||||
|
||||
void set_range(const std::list<pform_range_t>&ranges, PWSRType type);
|
||||
bool set_data_type(ivl_variable_type_t dt);
|
||||
ivl_variable_type_t get_data_type() const;
|
||||
|
||||
void set_unpacked_idx(const std::list<pform_range_t>&ranges);
|
||||
void set_range(PExpr*msb, PExpr*lsb, PWSRType type);
|
||||
|
||||
void set_data_type(data_type_t*type);
|
||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||
|
||||
void set_discipline(ivl_discipline_t);
|
||||
ivl_discipline_t get_discipline(void) const;
|
||||
void set_discipline(discipline_t*);
|
||||
discipline_t* get_discipline(void) const;
|
||||
|
||||
std::map<perm_string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
// Write myself to the specified stream.
|
||||
void dump(std::ostream&out, unsigned ind=4) const;
|
||||
void dump(ostream&out, unsigned ind=4) const;
|
||||
|
||||
NetNet* elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
bool is_net() const { return net_set_; };
|
||||
bool is_port() const { return port_set_; };
|
||||
void set_net(NetNet::Type t);
|
||||
void set_port(NetNet::PortType pt);
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
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_;
|
||||
// wire. If they do not exist, the wire is 1 bit wide.
|
||||
PExpr*port_msb_;
|
||||
PExpr*port_lsb_;
|
||||
bool port_set_;
|
||||
std::list<pform_range_t>net_;
|
||||
PExpr*net_msb_;
|
||||
PExpr*net_lsb_;
|
||||
bool net_set_;
|
||||
bool is_scalar_;
|
||||
unsigned error_cnt_;
|
||||
|
||||
// If this wire is actually a memory, these indices will give
|
||||
// me the size and address ranges of the memory.
|
||||
std::list<pform_range_t>unpacked_;
|
||||
// me the size and address range of the memory.
|
||||
PExpr*lidx_;
|
||||
PExpr*ridx_;
|
||||
|
||||
// This is the complex type of the wire. the data_type_ may
|
||||
// modify how this is interpreted.
|
||||
std::unique_ptr<data_type_t> set_data_type_;
|
||||
|
||||
ivl_discipline_t discipline_;
|
||||
discipline_t*discipline_;
|
||||
|
||||
private: // not implemented
|
||||
PWire(const PWire&);
|
||||
PWire& operator= (const PWire&);
|
||||
|
||||
ivl_type_t elaborate_type(Design*des, NetScope*scope,
|
||||
const std::vector<netrange_t>&packed_dimensions) const;
|
||||
ivl_type_t elaborate_darray_type(Design*des, NetScope*scope,
|
||||
const char *darray_type,
|
||||
const std::vector<netrange_t>&packed_dimensions)
|
||||
const;
|
||||
};
|
||||
|
||||
#endif /* IVL_PWire_H */
|
||||
#endif
|
||||
|
||||
@@ -1,514 +0,0 @@
|
||||
# The ICARUS Verilog Compilation System
|
||||
|
||||
Copyright 2000-2019 Stephen Williams
|
||||
|
||||
|
||||
## What is ICARUS Verilog?
|
||||
|
||||
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 behavioural
|
||||
constructs. For a view of the current state of Icarus Verilog, see its
|
||||
home page at http://iverilog.icarus.com/.
|
||||
|
||||
Icarus Verilog is not aimed at being a simulator in the traditional
|
||||
sense, but a compiler that generates code employed by back-end
|
||||
tools.
|
||||
|
||||
> For instructions on how to run Icarus Verilog, see the `iverilog` man page.
|
||||
|
||||
|
||||
## Building/Installing Icarus Verilog From Source
|
||||
|
||||
If you are starting from the source, the build process is designed to be
|
||||
as simple as practical. Someone basically familiar with the target
|
||||
system and C/C++ compilation should be able to build the source
|
||||
distribution with little effort. Some actual programming skills are
|
||||
not required, but helpful in case of problems.
|
||||
|
||||
> If you are building on Windows, see the mingw.txt file.
|
||||
|
||||
### Compile Time Prerequisites
|
||||
|
||||
You need the following software to compile Icarus Verilog from source
|
||||
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)
|
||||
typically have GNU make as the gmake program.
|
||||
|
||||
- ISO C++ Compiler
|
||||
The ivl and ivlpp programs are written in C++ and make use
|
||||
of templates and some of the standard C++ library. egcs and
|
||||
recent gcc compilers with the associated libstdc++ are known
|
||||
to work. MSVC++ 5 and 6 are known to definitely *not* work.
|
||||
|
||||
- bison and flex
|
||||
OSX note: bison 2.3 shipped with MacOS including Catalina generates
|
||||
broken code, but bison 3+ works. We recommend using the Fink
|
||||
project version of bison and flex (finkproject.org), brew version
|
||||
works fine either.
|
||||
|
||||
- gperf 3.0 or later
|
||||
The lexical analyzer doesn't recognize keywords directly,
|
||||
but instead matches symbols and looks them up in a hash
|
||||
table in order to get the proper lexical code. The gperf
|
||||
program generates the lookup table.
|
||||
|
||||
A version problem with this program is the most common cause
|
||||
of difficulty. See the Icarus Verilog FAQ.
|
||||
|
||||
- readline 4.2 or later
|
||||
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 or later
|
||||
This generates configure scripts from configure.ac. The 2.53
|
||||
or later versions are known to work, autoconf 2.13 is
|
||||
reported to *not* work.
|
||||
|
||||
### Compilation
|
||||
|
||||
Unpack the tar-ball and cd into the `verilog-#########` directory
|
||||
(presumably, that is how you got to this README) and compile the source
|
||||
with the commands:
|
||||
|
||||
```
|
||||
./configure
|
||||
make
|
||||
```
|
||||
|
||||
If you are building from git, you have to run the command below before
|
||||
compiling the source. This will generate the "configure" file, which is
|
||||
automatically done when building from tarball.
|
||||
|
||||
```
|
||||
sh autoconf.sh
|
||||
```
|
||||
|
||||
Normally, this command automatically figures out everything it needs
|
||||
to know. It generally works pretty well. There are a few flags to the
|
||||
configure script that modify its behaviour:
|
||||
|
||||
```
|
||||
--prefix=<root>
|
||||
The default is /usr/local, which causes the tool suite to
|
||||
be compiled for install in /usr/local/bin,
|
||||
/usr/local/share/ivl, etc.
|
||||
|
||||
I recommend that if you are configuring for precompiled
|
||||
binaries, use --prefix=/usr. On Solaris systems, it is
|
||||
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.
|
||||
|
||||
--host=<host-type>
|
||||
Compile iverilog for a different platform. You can use:
|
||||
x64_64-w64-mingw32 for building 64-bit Windows executables
|
||||
i686-w64-mingw32 for building 32-bit Windows executables
|
||||
Both options require installing the required mingw-w64 packages.
|
||||
```
|
||||
|
||||
### (Optional) Testing
|
||||
|
||||
To run a simple test before installation, execute
|
||||
|
||||
```
|
||||
make check
|
||||
```
|
||||
|
||||
The commands printed by this run might help you in running Icarus
|
||||
Verilog on your own Verilog sources before the package is installed
|
||||
by root.
|
||||
|
||||
### Installation
|
||||
|
||||
Now install the files in an appropriate place. (The makefiles by
|
||||
default install in /usr/local unless you specify a different prefix
|
||||
with the `--prefix=<path>` flag to the configure command.) You may need
|
||||
to do this as root to gain access to installation directories.
|
||||
|
||||
```
|
||||
make install
|
||||
```
|
||||
|
||||
### Uninstallation
|
||||
|
||||
The generated Makefiles also include the uninstall target. This should
|
||||
remove all the files that `make install` creates.
|
||||
|
||||
## How Icarus Verilog Works
|
||||
|
||||
This tool includes a parser which reads in Verilog (plus extensions)
|
||||
and generates an internal netlist. The netlist is passed to various
|
||||
processing steps that transform the design to more optimal/practical
|
||||
forms, then is passed to a code generator for final output. The
|
||||
processing steps and the code generator are selected by command line
|
||||
switches.
|
||||
|
||||
### Preprocessing
|
||||
|
||||
There is a separate program, ivlpp, that does the preprocessing. This
|
||||
program implements the `` `include `` and `` `define `` directives producing
|
||||
output that is equivalent but without the directives. The output is a
|
||||
single file with line number directives, so that the actual compiler
|
||||
only sees a single input file. See ivlpp/ivlpp.txt for details.
|
||||
|
||||
### 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
|
||||
(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.)
|
||||
|
||||
### Elaboration
|
||||
|
||||
This phase takes the pform and generates a netlist. The driver selects
|
||||
(by user request or lucky guess) the root module to elaborate,
|
||||
resolves references and expands the instantiations to form the design
|
||||
netlist. (See netlist.txt.) Final semantic checks are performed during
|
||||
elaboration, and some simple optimizations are performed. The netlist
|
||||
includes all the behavioural descriptions, as well as gates and wires.
|
||||
|
||||
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
|
||||
before code generation) will be dumped into the file named `<path>`.
|
||||
|
||||
Elaboration is performed in two steps: scopes and parameters
|
||||
first, followed by the structural and behavioural elaboration.
|
||||
|
||||
#### Scope 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.
|
||||
|
||||
The tail of the elaborate_scope behaviour (after the pform is
|
||||
traversed) includes a scan of the NetScope tree to locate defparam
|
||||
assignments that were collected during scope elaboration. This is when
|
||||
the defparam overrides are applied to the parameters.
|
||||
|
||||
#### Netlist Elaboration
|
||||
|
||||
After the scopes and parameters are generated and the NetScope tree
|
||||
fully formed, the elaboration runs through the pform again, this time
|
||||
generating the structural and behavioural netlist. Parameters are
|
||||
elaborated and evaluated by now so all the constants of code
|
||||
generation are now known locally, so the netlist can be generated by
|
||||
simply passing through the pform.
|
||||
|
||||
### Optimization
|
||||
|
||||
This is a collection of processing steps that perform
|
||||
optimizations that do not depend on the target technology. Examples of
|
||||
some useful transformations are
|
||||
|
||||
- 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).
|
||||
|
||||
### Code Generation
|
||||
|
||||
This step takes the design netlist and uses it to drive the code
|
||||
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
|
||||
through the design elements, calling target functions as the need arises
|
||||
to generate actual output.
|
||||
|
||||
The user selects the target code generator with the `-t` flag on the
|
||||
command line.
|
||||
|
||||
### ATTRIBUTES
|
||||
|
||||
> NOTE: The $attribute syntax will soon be deprecated in favour 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
|
||||
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
|
||||
attached to the identified object.
|
||||
|
||||
Attributes are `[<key> <value>]` pairs and are used to communicate with
|
||||
the various processing steps. See the documentation for the processing
|
||||
step for a list of the pertinent attributes.
|
||||
|
||||
Attributes can also be applied to gate types. When this is done, the
|
||||
attribute is given to every instantiation of the primitive. The syntax
|
||||
for the attribute statement is the same, except that the `<identifier>`
|
||||
names a primitive earlier in the compilation unit and the statement is
|
||||
placed in the global scope, instead of within a module. The semicolon is
|
||||
not part of a type attribute.
|
||||
|
||||
Note that attributes are also occasionally used for communication
|
||||
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.
|
||||
|
||||
## Running iverilog
|
||||
|
||||
The preferred way to invoke the compiler is with the `iverilog`(1)
|
||||
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.
|
||||
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
Example: Compiling `"hello.vl"`
|
||||
|
||||
```
|
||||
------------------------ hello.vl ----------------------------
|
||||
module main();
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hi there");
|
||||
$finish ;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
--------------------------------------------------------------
|
||||
```
|
||||
|
||||
Ensure that `iverilog` is on your search path, and the vpi library
|
||||
is available.
|
||||
|
||||
To compile the program:
|
||||
|
||||
```
|
||||
iverilog hello.vl
|
||||
```
|
||||
|
||||
(The above presumes that /usr/local/include and /usr/local/lib are
|
||||
part of the compiler search path, which is usually the case for gcc.)
|
||||
|
||||
To run the program:
|
||||
|
||||
```
|
||||
./a.out
|
||||
```
|
||||
|
||||
You can use the `-o` switch to name the output command to be generated
|
||||
by the compiler. See the `iverilog`(1) man page.
|
||||
|
||||
## Unsupported Constructs
|
||||
|
||||
Icarus Verilog is in development - as such it still only supports a
|
||||
(growing) subset of Verilog. Below is a description of some of the
|
||||
currently unsupported Verilog features. This list is not exhaustive
|
||||
and does not account for errors in the compiler. See the Icarus
|
||||
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.
|
||||
|
||||
- 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.
|
||||
|
||||
## 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 favour 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 the compilation of that file are those that it
|
||||
defines itself (or includes) or that are defined in 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 modelled 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 supports an extended 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.
|
||||
|
||||
|
||||
## 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.
|
||||
+496
@@ -0,0 +1,496 @@
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
Copyright 2000-2004 Stephen Williams
|
||||
|
||||
|
||||
1.0 What is ICARUS Verilog?
|
||||
|
||||
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://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. These back-end tools currently include a simulator engine
|
||||
called VVP, an XNF (Xilinx Netlist Format) generator and an EDIF FPGA
|
||||
netlist generator. In the future, backends are expected for EDIF/LPM,
|
||||
structural Verilog, VHDL, etc.
|
||||
|
||||
For instructions on how to run Icarus Verilog,
|
||||
see the ``iverilog'' man page.
|
||||
|
||||
|
||||
2.0 Building/Installing Icarus Verilog From Source
|
||||
|
||||
If you are starting from source, the build process is designed to be
|
||||
as simple as practical. Someone basically familiar with the target
|
||||
system and C/C++ compilation should be able to build the source
|
||||
distribution with little effort. Some actual programming skills are
|
||||
not required, but helpful in case of problems.
|
||||
|
||||
If you are building for Windows, see the mingw.txt file.
|
||||
|
||||
2.1 Compile Time Prerequisites
|
||||
|
||||
You need the following software to compile Icarus Verilog from source
|
||||
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)
|
||||
typically have GNU make as the gmake program.
|
||||
|
||||
- ISO C++ Compiler
|
||||
The ivl and ivlpp programs are written in C++ and make use
|
||||
of templates and some of the standard C++ library. egcs and
|
||||
recent gcc compilers with the associated libstdc++ are known
|
||||
to work. MSVC++ 5 and 6 are known to definitely *not* work.
|
||||
|
||||
- bison and flex
|
||||
|
||||
- gperf 2.7
|
||||
The lexical analyzer doesn't recognize keywords directly,
|
||||
but instead matches symbols and looks them up in a hash
|
||||
table in order to get the proper lexical code. The gperf
|
||||
program generates the lookup table.
|
||||
|
||||
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 CVS, 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
|
||||
(presumably that is how you got to this README) and compile the source
|
||||
with the commands:
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
Normally, this command automatically figures out everything it needs
|
||||
to know. It generally works pretty well. There are a few flags to the
|
||||
configure script that modify its behavior:
|
||||
|
||||
--without-ipal
|
||||
This turns off support for Icarus PAL, whether ipal
|
||||
libraries are installed or not.
|
||||
|
||||
--prefix=<root>
|
||||
The default is /usr/local, which causes the tool suite to
|
||||
be compiled for install in /usr/local/bin,
|
||||
/usr/local/share/ivl, etc.
|
||||
|
||||
I recommend that if you are configuring for precompiled
|
||||
binaries, use --prefix=/usr. On Solaris systems, it is
|
||||
common to use --prefix=/opt. You can configure for a non-root
|
||||
install with --prefix=$HOME.
|
||||
|
||||
--enable-vvp32 (experimental)
|
||||
If compiling on AMD64 systems, this enables the
|
||||
compilation of 32bit compatible vvp (vvp32) and the vpi
|
||||
modules that match.
|
||||
|
||||
2.2.1 Special AMD64 Instructions
|
||||
|
||||
(The Icarus Verilog RPM for x86_64 is build using these instructions.)
|
||||
|
||||
If you are building for Linux/AMD64 (a.k.a x86_64) then to get the
|
||||
most out of your install, first make sure you have both 64bit and
|
||||
32bit development libraries installed. Then configure with this
|
||||
somewhat more complicated command:
|
||||
|
||||
./configure libdir64='$(prefix)/lib64' vpidir1=vpi64 vpidir2=. --enable-vvp32
|
||||
|
||||
This reflects the convention on AMD64 systems that 64bit libraries go
|
||||
into lib64 directories. The "--enable-vvp32" also turns on 32bit
|
||||
compatibility files. A 32bit version of vvp (vvp32) will be created,
|
||||
as well as 32bit versions of the development libraries and bundled VPI
|
||||
libraries.
|
||||
|
||||
2.3 (Optional) Testing
|
||||
|
||||
To run a simple test before installation, execute
|
||||
|
||||
make check
|
||||
|
||||
The commands printed by this run might help you in running Icarus
|
||||
Verilog on your own Verilog sources before the package is installed
|
||||
by root.
|
||||
|
||||
2.4 Installation
|
||||
|
||||
Now install the files in an appropriate place. (The makefiles by
|
||||
default install in /usr/local unless you specify a different prefix
|
||||
with the --prefix=<path> flag to the configure command.) You may need
|
||||
to do this as root to gain access to installation directories.
|
||||
|
||||
make install
|
||||
|
||||
2.5 Uninstallation
|
||||
|
||||
The generated Makefiles also include the uninstall target. This should
|
||||
remove all the files that ``make install'' creates.
|
||||
|
||||
3.0 How Icarus Verilog Works
|
||||
|
||||
This tool includes a parser which reads in Verilog (plus extensions)
|
||||
and generates an internal netlist. The netlist is passed to various
|
||||
processing steps that transform the design to more optimal/practical
|
||||
forms, then is passed to a code generator for final output. The
|
||||
processing steps and the code generator are selected by command line
|
||||
switches.
|
||||
|
||||
3.1 Preprocessing
|
||||
|
||||
There is a separate program, ivlpp, that does the preprocessing. This
|
||||
program implements the `include and `define directives producing
|
||||
output that is equivalent but without the directives. The output is a
|
||||
single file with line number directives, so that the actual compiler
|
||||
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
|
||||
(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 compiler. This will cause iverilog to dump
|
||||
the pform into the file named <path>.
|
||||
|
||||
3.3 Elaboration
|
||||
|
||||
This phase takes the pform and generates a netlist. The driver selects
|
||||
(by user request or lucky guess) the root module to elaborate,
|
||||
resolves references and expands the instantiations to form the design
|
||||
netlist. (See netlist.txt.) Final semantic checks are performed during
|
||||
elaboration, and some simple optimizations are performed. The netlist
|
||||
includes all the behavioral descriptions, as well as gates and wires.
|
||||
|
||||
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
|
||||
before code generation) will be dumped into the file named <path>.
|
||||
|
||||
Elaboration is actually performed in two steps: scopes and parameters
|
||||
first, followed by the structural and behavioral elaboration.
|
||||
|
||||
3.3.1 Scope 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 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
|
||||
assignments that were collected during scope elaboration. This is when
|
||||
the defparam overrides are applied to the parameters.
|
||||
|
||||
3.3.2 Netlist Elaboration
|
||||
|
||||
After the scopes and parameters are generated and the NetScope tree
|
||||
fully formed, the elaboration runs through the pform again, this time
|
||||
generating the structural and behavioral netlist. Parameters are
|
||||
elaborated and evaluated by now so all the constants of code
|
||||
generation are now known locally, so the netlist can be generated by
|
||||
simply passing through the pform.
|
||||
|
||||
3.4 Optimization
|
||||
|
||||
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
|
||||
|
||||
- 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).
|
||||
|
||||
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
|
||||
design to suit the technology.
|
||||
|
||||
The emit() method of the Design class performs this step. It runs
|
||||
through the design elements, calling target functions as need arises
|
||||
to generate actual output.
|
||||
|
||||
The user selects the target code generator with the -t flag on the
|
||||
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 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
|
||||
attached to the identified object.
|
||||
|
||||
Attributes are [<key> <value>] pairs and are used to communicate with
|
||||
the various processing steps. See the documentation for the processing
|
||||
step for a list of the pertinent attributes.
|
||||
|
||||
Attributes can also be applied to gate types. When this is done, the
|
||||
attribute is given to every instantiation of the primitive. The syntax
|
||||
for the attribute statement is the same, except that the <identifier>
|
||||
names a primitive earlier in the compilation unit and the statement is
|
||||
placed in global scope, instead of within a module. The semicolon is
|
||||
not part of a type attribute.
|
||||
|
||||
Note that attributes are also occasionally used for communication
|
||||
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)
|
||||
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 EXAMPLES
|
||||
|
||||
Example: Compiling "hello.vl"
|
||||
|
||||
------------------------ hello.vl ----------------------------
|
||||
module main();
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hi there");
|
||||
$finish ;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
Ensure that "iverilog" is on your search path, and the vpi library
|
||||
is available.
|
||||
|
||||
To compile the program:
|
||||
|
||||
iverilog hello.vl
|
||||
|
||||
(The above presumes that /usr/local/include and /usr/local/lib are
|
||||
part of the compiler search path, which is usually the case for gcc.)
|
||||
|
||||
To run the program:
|
||||
|
||||
./a.out
|
||||
|
||||
You can use the "-o" switch to name the output command to be generated
|
||||
by the compiler. See the iverilog(1) man page.
|
||||
|
||||
5.0 Unsupported Constructs
|
||||
|
||||
Icarus Verilog is in development - as such it still only supports a
|
||||
(growing) subset of Verilog. Below is a description of some of the
|
||||
currently unsupported Verilog features. This list is not exhaustive,
|
||||
and does not account for errors in the compiler. See the Icarus
|
||||
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.
|
||||
|
||||
- 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.
|
||||
|
||||
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.
|
||||
|
||||
+80
-193
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2021 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,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
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.cc,v 1.30 2007/05/24 04:07:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Statement.h"
|
||||
# include "PExpr.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Statement::~Statement()
|
||||
{
|
||||
}
|
||||
|
||||
PAssign_::PAssign_(PExpr*lval__, PExpr*ex, bool is_constant)
|
||||
: event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(is_constant)
|
||||
PAssign_::PAssign_(PExpr*lval, PExpr*ex)
|
||||
: event_(0), lval_(lval), rval_(ex)
|
||||
{
|
||||
delay_ = 0;
|
||||
}
|
||||
|
||||
PAssign_::PAssign_(PExpr*lval__, PExpr*de, PExpr*ex)
|
||||
: event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(false)
|
||||
PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex)
|
||||
: event_(0), lval_(lval), rval_(ex)
|
||||
{
|
||||
delay_ = de;
|
||||
}
|
||||
|
||||
PAssign_::PAssign_(PExpr*lval__, PExpr*cnt, PEventStatement*ev, PExpr*ex)
|
||||
: event_(ev), count_(cnt), lval_(lval__), rval_(ex), is_constant_(false)
|
||||
PAssign_::PAssign_(PExpr*lval, PEventStatement*ev, PExpr*ex)
|
||||
: event_(ev), lval_(lval), rval_(ex)
|
||||
{
|
||||
delay_ = 0;
|
||||
}
|
||||
@@ -53,28 +53,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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -82,18 +72,13 @@ PAssign::~PAssign()
|
||||
{
|
||||
}
|
||||
|
||||
PAssignNB::PAssignNB(PExpr*lval__, PExpr*ex)
|
||||
: PAssign_(lval__, ex, false)
|
||||
PAssignNB::PAssignNB(PExpr*lval, PExpr*ex)
|
||||
: PAssign_(lval, ex)
|
||||
{
|
||||
}
|
||||
|
||||
PAssignNB::PAssignNB(PExpr*lval__, PExpr*d, PExpr*ex)
|
||||
: PAssign_(lval__, d, ex)
|
||||
{
|
||||
}
|
||||
|
||||
PAssignNB::PAssignNB(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
|
||||
: PAssign_(lval__, cnt, d, ex)
|
||||
PAssignNB::PAssignNB(PExpr*lval, PExpr*d, PExpr*ex)
|
||||
: PAssign_(lval, d, ex)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -101,101 +86,35 @@ PAssignNB::~PAssignNB()
|
||||
{
|
||||
}
|
||||
|
||||
PBlock::PBlock(perm_string n, LexicalScope*parent, BL_TYPE t)
|
||||
PBlock::PBlock(perm_string n, PScope*parent, BL_TYPE t)
|
||||
: PScope(n, parent), bl_type_(t)
|
||||
{
|
||||
}
|
||||
|
||||
PBlock::PBlock(BL_TYPE t)
|
||||
: PScope(perm_string()), bl_type_(t)
|
||||
: PScope(perm_string(),0), 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];
|
||||
}
|
||||
|
||||
bool PBlock::var_init_needs_explicit_lifetime() const
|
||||
{
|
||||
return default_lifetime == STATIC;
|
||||
}
|
||||
|
||||
PChainConstructor* PBlock::extract_chain_constructor()
|
||||
{
|
||||
if (list_.empty())
|
||||
return 0;
|
||||
|
||||
if (PChainConstructor*res = dynamic_cast<PChainConstructor*> (list_[0])) {
|
||||
for (size_t idx = 0 ; idx < list_.size()-1 ; idx += 1)
|
||||
list_[idx] = list_[idx+1];
|
||||
list_.resize(list_.size()-1);
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PBlock::set_join_type(PBlock::BL_TYPE type)
|
||||
{
|
||||
assert(bl_type_ == BL_PAR);
|
||||
assert(type==BL_PAR || type==BL_JOIN_NONE || type==BL_JOIN_ANY);
|
||||
bl_type_ = type;
|
||||
}
|
||||
|
||||
void PBlock::set_statement(const vector<Statement*>&st)
|
||||
void PBlock::set_statement(const svector<Statement*>&st)
|
||||
{
|
||||
list_ = st;
|
||||
}
|
||||
|
||||
void PBlock::push_statement_front(Statement*that)
|
||||
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
|
||||
: path_(n), parms_(p)
|
||||
{
|
||||
ivl_assert(*this, bl_type_==BL_SEQ);
|
||||
|
||||
list_.resize(list_.size()+1);
|
||||
for (size_t idx = list_.size()-1 ; idx > 0 ; idx -= 1)
|
||||
list_[idx] = list_[idx-1];
|
||||
|
||||
list_[0] = that;
|
||||
}
|
||||
|
||||
PNamedItem::SymbolType PBlock::symbol_type() const
|
||||
PCallTask::PCallTask(perm_string n, const svector<PExpr*>&p)
|
||||
: parms_(p)
|
||||
{
|
||||
return BLOCK;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -208,15 +127,15 @@ const pform_name_t& PCallTask::path() const
|
||||
return path_;
|
||||
}
|
||||
|
||||
PCase::PCase(ivl_case_quality_t q, NetCase::TYPE t, PExpr*ex, std::vector<PCase::Item*>*l)
|
||||
: quality_(q), type_(t), expr_(ex), items_(l)
|
||||
PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
|
||||
: type_(t), expr_(ex), items_(l)
|
||||
{
|
||||
}
|
||||
|
||||
PCase::~PCase()
|
||||
{
|
||||
delete expr_;
|
||||
for (unsigned idx = 0 ; idx < items_->size() ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < items_->count() ; idx += 1)
|
||||
if ((*items_)[idx]->stat) delete (*items_)[idx]->stat;
|
||||
|
||||
delete[]items_;
|
||||
@@ -233,21 +152,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)
|
||||
{
|
||||
@@ -289,32 +193,21 @@ PDisable::~PDisable()
|
||||
{
|
||||
}
|
||||
|
||||
PDoWhile::PDoWhile(PExpr*ex, Statement*st)
|
||||
: cond_(ex), statement_(st)
|
||||
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
||||
: expr_(ee), statement_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PDoWhile::~PDoWhile()
|
||||
{
|
||||
delete cond_;
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(const std::vector<PEEvent*>&ee)
|
||||
: expr_(ee), statement_(0), always_sens_(false)
|
||||
{
|
||||
assert(expr_.size() > 0);
|
||||
assert(expr_.count() > 0);
|
||||
}
|
||||
|
||||
|
||||
PEventStatement::PEventStatement(PEEvent*ee)
|
||||
: expr_(1), statement_(0), always_sens_(false)
|
||||
: expr_(1), statement_(0)
|
||||
{
|
||||
expr_[0] = ee;
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(bool always_sens)
|
||||
: statement_(0), always_sens_(always_sens)
|
||||
PEventStatement::PEventStatement(void)
|
||||
: statement_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -328,15 +221,6 @@ void PEventStatement::set_statement(Statement*st)
|
||||
statement_ = st;
|
||||
}
|
||||
|
||||
bool PEventStatement::has_aa_term(Design*des, NetScope*scope)
|
||||
{
|
||||
bool flag = false;
|
||||
for (unsigned idx = 0 ; idx < expr_.size() ; idx += 1) {
|
||||
flag = expr_[idx]->has_aa_term(des, scope) || flag;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
PForce::PForce(PExpr*l, PExpr*r)
|
||||
: lval_(l), expr_(r)
|
||||
{
|
||||
@@ -348,20 +232,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)
|
||||
{
|
||||
@@ -373,8 +243,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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -408,18 +279,8 @@ PRepeat::~PRepeat()
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PReturn::PReturn(PExpr*e)
|
||||
: expr_(e)
|
||||
{
|
||||
}
|
||||
|
||||
PReturn::~PReturn()
|
||||
{
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev)
|
||||
: package_(pkg), event_(ev)
|
||||
PTrigger::PTrigger(const pform_name_t&e)
|
||||
: event_(e)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -427,17 +288,8 @@ PTrigger::~PTrigger()
|
||||
{
|
||||
}
|
||||
|
||||
PNBTrigger::PNBTrigger(const pform_name_t&ev, PExpr*dly)
|
||||
: event_(ev), dly_(dly)
|
||||
{
|
||||
}
|
||||
|
||||
PNBTrigger::~PNBTrigger()
|
||||
{
|
||||
}
|
||||
|
||||
PWhile::PWhile(PExpr*ex, Statement*st)
|
||||
: cond_(ex), statement_(st)
|
||||
PWhile::PWhile(PExpr*e1, Statement*st)
|
||||
: cond_(e1), statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -446,3 +298,38 @@ PWhile::~PWhile()
|
||||
delete cond_;
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: Statement.cc,v $
|
||||
* Revision 1.30 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.29 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.28 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.27 2002/04/21 22:31:02 steve
|
||||
* Redo handling of assignment internal delays.
|
||||
* Leave it possible for them to be calculated
|
||||
* at run time.
|
||||
*
|
||||
* Revision 1.26 2002/04/21 04:59:07 steve
|
||||
* Add support for conbinational events by finding
|
||||
* the inputs to expressions and some statements.
|
||||
* Get case and assignment statements working.
|
||||
*
|
||||
* Revision 1.25 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.24 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.23 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*/
|
||||
|
||||
|
||||
+73
-225
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_Statement_H
|
||||
#define IVL_Statement_H
|
||||
#ifndef __Statement_H
|
||||
#define __Statement_H
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,13 +16,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include <list>
|
||||
# include "ivl_target.h"
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
@@ -30,8 +28,6 @@
|
||||
# include "HName.h"
|
||||
# include "LineInfo.h"
|
||||
class PExpr;
|
||||
class PChainConstructor;
|
||||
class PPackage;
|
||||
class Statement;
|
||||
class PEventStatement;
|
||||
class Design;
|
||||
@@ -43,29 +39,31 @@ 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_; }
|
||||
|
||||
std::map<perm_string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
ivl_process_type_t type_;
|
||||
Type type_;
|
||||
Statement*statement_;
|
||||
};
|
||||
|
||||
@@ -74,18 +72,16 @@ class PProcess : public LineInfo {
|
||||
* fact, the Statement class is abstract and represents all the
|
||||
* possible kinds of statements that exist in Verilog.
|
||||
*/
|
||||
class Statement : virtual public LineInfo {
|
||||
class Statement : public LineInfo {
|
||||
|
||||
public:
|
||||
Statement() { }
|
||||
virtual ~Statement() =0;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
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;
|
||||
|
||||
std::map<perm_string,PExpr*> attributes;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -95,55 +91,37 @@ class Statement : virtual 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,
|
||||
bool force_unsigned =false) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const;
|
||||
|
||||
NetExpr* elaborate_rval_obj_(Design*, NetScope*,
|
||||
ivl_variable_type_t type) const;
|
||||
|
||||
PExpr* delay_;
|
||||
PEventStatement*event_;
|
||||
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(std::ostream&out, unsigned ind) const;
|
||||
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_;
|
||||
};
|
||||
|
||||
class PAssignNB : public PAssign_ {
|
||||
@@ -151,10 +129,9 @@ 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(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
@@ -169,121 +146,84 @@ class PAssignNB : public PAssign_ {
|
||||
* statements before constructing this object, so it knows a priori
|
||||
* what is contained.
|
||||
*/
|
||||
class PBlock : public PScope, public Statement, public PNamedItem {
|
||||
class PBlock : public PScope, public Statement {
|
||||
|
||||
public:
|
||||
enum BL_TYPE { BL_SEQ, BL_PAR, BL_JOIN_NONE, BL_JOIN_ANY };
|
||||
enum BL_TYPE { BL_SEQ, BL_PAR };
|
||||
|
||||
// If the block has a name, it is a scope and also has a parent.
|
||||
explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t);
|
||||
explicit PBlock(perm_string n, PScope*parent, BL_TYPE t);
|
||||
// If it doesn't have a name, it's not a scope
|
||||
explicit PBlock(BL_TYPE t);
|
||||
~PBlock();
|
||||
|
||||
BL_TYPE bl_type() const { return bl_type_; }
|
||||
|
||||
bool var_init_needs_explicit_lifetime() const;
|
||||
void set_statement(const svector<Statement*>&st);
|
||||
|
||||
// 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(std::ostream&out, unsigned ind) const;
|
||||
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;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
|
||||
private:
|
||||
BL_TYPE bl_type_;
|
||||
std::vector<Statement*>list_;
|
||||
const BL_TYPE bl_type_;
|
||||
svector<Statement*>list_;
|
||||
};
|
||||
|
||||
class PCallTask : public Statement {
|
||||
|
||||
public:
|
||||
explicit PCallTask(PPackage*pkg, const pform_name_t&n, const std::list<PExpr*>&parms);
|
||||
explicit PCallTask(const pform_name_t&n, const std::list<PExpr*>&parms);
|
||||
explicit PCallTask(perm_string n, const std::list<PExpr*>&parms);
|
||||
explicit PCallTask(const pform_name_t&n, const svector<PExpr*>&parms);
|
||||
explicit PCallTask(perm_string n, const svector<PExpr*>&parms);
|
||||
~PCallTask();
|
||||
|
||||
const pform_name_t& path() const;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) 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;
|
||||
|
||||
bool elaborate_elab(Design*des, NetScope*scope) const;
|
||||
|
||||
void void_cast() { void_cast_ = true; }
|
||||
|
||||
private:
|
||||
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_void_function_(Design*des, NetScope*scope,
|
||||
NetFuncDef*def) const;
|
||||
NetProc *elaborate_non_void_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;
|
||||
NetProc*elaborate_queue_method_(Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
NetProc*elaborate_method_func_(NetScope*scope,
|
||||
NetNet*net,
|
||||
ivl_type_t type,
|
||||
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_;
|
||||
std::vector<PExpr*> parms_;
|
||||
bool void_cast_ = false;
|
||||
svector<PExpr*> parms_;
|
||||
};
|
||||
|
||||
class PCase : public Statement {
|
||||
|
||||
public:
|
||||
struct Item {
|
||||
std::list<PExpr*>expr;
|
||||
svector<PExpr*>expr;
|
||||
Statement*stat;
|
||||
};
|
||||
|
||||
PCase(ivl_case_quality_t, NetCase::TYPE, PExpr*ex, std::vector<Item*>*);
|
||||
PCase(NetCase::TYPE, PExpr*ex, svector<Item*>*);
|
||||
~PCase();
|
||||
|
||||
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(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
ivl_case_quality_t quality_;
|
||||
NetCase::TYPE type_;
|
||||
PExpr*expr_;
|
||||
|
||||
std::vector<Item*>*items_;
|
||||
svector<Item*>*items_;
|
||||
|
||||
private: // not implemented
|
||||
PCase(const PCase&);
|
||||
@@ -297,33 +237,13 @@ class PCAssign : public Statement {
|
||||
~PCAssign();
|
||||
|
||||
virtual NetCAssign* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*lval_;
|
||||
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:
|
||||
explicit PChainConstructor(const std::list<PExpr*>&parms);
|
||||
~PChainConstructor();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::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:
|
||||
@@ -333,7 +253,7 @@ 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(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
@@ -352,7 +272,7 @@ class PDeassign : public Statement {
|
||||
~PDeassign();
|
||||
|
||||
virtual NetDeassign* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*lval_;
|
||||
@@ -364,7 +284,7 @@ class PDelayStatement : public Statement {
|
||||
PDelayStatement(PExpr*d, Statement*st);
|
||||
~PDelayStatement();
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
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;
|
||||
@@ -384,29 +304,13 @@ class PDisable : public Statement {
|
||||
explicit PDisable(const pform_name_t&sc);
|
||||
~PDisable();
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
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(std::ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*cond_;
|
||||
Statement*statement_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The event statement represents the event delay in behavioral
|
||||
* code. It comes from such things as:
|
||||
@@ -419,41 +323,31 @@ class PEventStatement : public Statement {
|
||||
|
||||
public:
|
||||
|
||||
explicit PEventStatement(const std::vector<PEEvent*>&ee);
|
||||
explicit PEventStatement(const svector<PEEvent*>&ee);
|
||||
explicit PEventStatement(PEEvent*ee);
|
||||
// Make an @* statement or make a special @* version with the items
|
||||
// from functions added and outputs removed for always_comb/latch.
|
||||
explicit PEventStatement(bool always_sens = false);
|
||||
// Make an @* statement.
|
||||
explicit PEventStatement(void);
|
||||
|
||||
~PEventStatement();
|
||||
|
||||
void set_statement(Statement*st);
|
||||
|
||||
virtual void dump(std::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(std::ostream&out) const;
|
||||
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;
|
||||
|
||||
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:
|
||||
std::vector<PEEvent*>expr_;
|
||||
svector<PEEvent*>expr_;
|
||||
Statement*statement_;
|
||||
bool always_sens_;
|
||||
};
|
||||
|
||||
std::ostream& operator << (std::ostream&o, const PEventStatement&obj);
|
||||
|
||||
class PForce : public Statement {
|
||||
|
||||
public:
|
||||
@@ -461,33 +355,13 @@ class PForce : public Statement {
|
||||
~PForce();
|
||||
|
||||
virtual NetForce* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*lval_;
|
||||
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(std::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);
|
||||
@@ -496,7 +370,7 @@ 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(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
Statement*statement_;
|
||||
@@ -506,13 +380,13 @@ 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(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr* name1_;
|
||||
@@ -520,7 +394,8 @@ class PForStatement : public Statement {
|
||||
|
||||
PExpr*cond_;
|
||||
|
||||
Statement*step_;
|
||||
PExpr* name2_;
|
||||
PExpr* expr2_;
|
||||
|
||||
Statement*statement_;
|
||||
};
|
||||
@@ -540,7 +415,7 @@ 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(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
@@ -554,25 +429,12 @@ class PRelease : public Statement {
|
||||
~PRelease();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
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.
|
||||
@@ -580,44 +442,30 @@ class PReturn : public Statement {
|
||||
class PTrigger : public Statement {
|
||||
|
||||
public:
|
||||
explicit PTrigger(PPackage*pkg, const pform_name_t&ev);
|
||||
explicit PTrigger(const pform_name_t&ev);
|
||||
~PTrigger();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PPackage*package_;
|
||||
pform_name_t event_;
|
||||
};
|
||||
|
||||
class PNBTrigger : public Statement {
|
||||
public:
|
||||
explicit PNBTrigger(const pform_name_t&ev, PExpr*dly);
|
||||
~PNBTrigger();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
pform_name_t event_;
|
||||
PExpr*dly_;
|
||||
};
|
||||
|
||||
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(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*cond_;
|
||||
Statement*statement_;
|
||||
};
|
||||
|
||||
#endif /* IVL_Statement_H */
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,30 +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
|
||||
*/
|
||||
|
||||
# include "StringHeap.h"
|
||||
# include <iostream>
|
||||
# include <cstdlib>
|
||||
# include <cstring>
|
||||
# include <cassert>
|
||||
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
# include "ivl_alloc.h"
|
||||
static char **string_pool = NULL;
|
||||
static unsigned string_pool_count = 0;
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: StringHeap.cc,v 1.6 2004/02/18 17:11:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const unsigned DEFAULT_CELL_SIZE = 0x10000;
|
||||
|
||||
# include "StringHeap.h"
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
StringHeap::StringHeap()
|
||||
{
|
||||
cell_base_ = 0;
|
||||
cell_ptr_ = 0;
|
||||
cell_ptr_ = HEAPCELL;
|
||||
cell_count_ = 0;
|
||||
}
|
||||
|
||||
StringHeap::~StringHeap()
|
||||
@@ -49,53 +44,22 @@ StringHeap::~StringHeap()
|
||||
const char* StringHeap::add(const char*text)
|
||||
{
|
||||
unsigned len = strlen(text);
|
||||
unsigned rem = cell_base_==0? 0 : (DEFAULT_CELL_SIZE - cell_ptr_);
|
||||
assert((len+1) <= HEAPCELL);
|
||||
|
||||
// Special case: huge items get their own allocation.
|
||||
if ( (len+1) >= DEFAULT_CELL_SIZE ) {
|
||||
char*buf = strdup(text);
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
string_pool_count += 1;
|
||||
string_pool = (char**)realloc(string_pool,
|
||||
string_pool_count*sizeof(char**));
|
||||
string_pool[string_pool_count-1] = buf;
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
|
||||
// If the current cell that I'm working through cannot hold
|
||||
// the current string, then set it aside and get another cell
|
||||
// to put the string into.
|
||||
unsigned rem = HEAPCELL - cell_ptr_;
|
||||
if (rem < (len+1)) {
|
||||
// release any unused memory. This assumes that a
|
||||
// realloc shrink of the memory region will return the
|
||||
// same pointer.
|
||||
if (rem > 0) {
|
||||
char*old = cell_base_;
|
||||
cell_base_ = (char*)realloc(cell_base_, cell_ptr_);
|
||||
assert(cell_base_ != 0);
|
||||
assert(cell_base_ == old);
|
||||
}
|
||||
// start new cell
|
||||
cell_base_ = (char*)malloc(DEFAULT_CELL_SIZE);
|
||||
cell_ptr_ = 0;
|
||||
rem = DEFAULT_CELL_SIZE;
|
||||
cell_base_ = (char*)malloc(HEAPCELL);
|
||||
cell_ptr_ = 0;
|
||||
cell_count_ += 1;
|
||||
assert(cell_base_ != 0);
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
string_pool_count += 1;
|
||||
string_pool = (char **) realloc(string_pool,
|
||||
string_pool_count*sizeof(char **));
|
||||
string_pool[string_pool_count-1] = cell_base_;
|
||||
#endif
|
||||
}
|
||||
|
||||
assert( (len+1) <= rem );
|
||||
char*res = cell_base_ + cell_ptr_;
|
||||
memcpy(res, text, len);
|
||||
cell_ptr_ += len;
|
||||
cell_base_[cell_ptr_++] = 0;
|
||||
|
||||
assert(cell_ptr_ <= DEFAULT_CELL_SIZE);
|
||||
assert(cell_ptr_ <= HEAPCELL);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -119,22 +83,6 @@ StringHeapLex::~StringHeapLex()
|
||||
{
|
||||
}
|
||||
|
||||
void StringHeapLex::cleanup()
|
||||
{
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
for (unsigned idx = 0 ; idx < string_pool_count ; idx += 1) {
|
||||
free(string_pool[idx]);
|
||||
}
|
||||
free(string_pool);
|
||||
string_pool = NULL;
|
||||
string_pool_count = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1) {
|
||||
hash_table_[idx] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned StringHeapLex::add_hit_count() const
|
||||
{
|
||||
return hit_count_;
|
||||
@@ -231,13 +179,28 @@ bool operator < (perm_string a, perm_string b)
|
||||
return false;
|
||||
}
|
||||
|
||||
ostream& operator << (ostream&out, perm_string that)
|
||||
{
|
||||
if (that.nil())
|
||||
out << "<nil>";
|
||||
else
|
||||
out << that.str();
|
||||
return out;
|
||||
}
|
||||
/*
|
||||
* $Log: StringHeap.cc,v $
|
||||
* Revision 1.6 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.5 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*
|
||||
* Revision 1.4 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.3 2003/01/16 21:44:46 steve
|
||||
* Keep some debugging status.
|
||||
*
|
||||
* Revision 1.2 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/08/04 19:13:16 steve
|
||||
* dll uses StringHeap for named items.
|
||||
*
|
||||
*/
|
||||
|
||||
const perm_string empty_perm_string = perm_string::literal("");
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_StringHeap_H
|
||||
#define IVL_StringHeap_H
|
||||
#ifndef __StringHeap_H
|
||||
#define __StringHeap_H
|
||||
/*
|
||||
* Copyright (c) 2002-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,11 +16,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: StringHeap.h,v 1.6 2005/06/14 19:13:43 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class perm_string {
|
||||
|
||||
public:
|
||||
@@ -28,8 +34,6 @@ class perm_string {
|
||||
perm_string(const perm_string&that) : text_(that.text_) { }
|
||||
~perm_string() { }
|
||||
|
||||
inline bool nil() const { return text_ == 0; }
|
||||
|
||||
perm_string& operator = (const perm_string&that)
|
||||
{ text_ = that.text_; return *this; }
|
||||
|
||||
@@ -37,20 +41,19 @@ class perm_string {
|
||||
operator const char* () const { return str(); }
|
||||
|
||||
// This is an escape for making perm_string objects out of
|
||||
// literals. For example, perm_string::literal("Label"); Please
|
||||
// literals. For example, per_string::literal("Label"); Please
|
||||
// do *not* cheat and pass arbitrary const char* items here.
|
||||
static perm_string literal(const char*t) { return perm_string(t); }
|
||||
|
||||
private:
|
||||
friend class StringHeap;
|
||||
friend class StringHeapLex;
|
||||
explicit perm_string(const char*t) : text_(t) { };
|
||||
perm_string(const char*t) : text_(t) { };
|
||||
|
||||
private:
|
||||
const char*text_;
|
||||
};
|
||||
|
||||
extern const perm_string empty_perm_string;
|
||||
extern bool operator == (perm_string a, perm_string b);
|
||||
extern bool operator == (perm_string a, const char* b);
|
||||
extern bool operator != (perm_string a, perm_string b);
|
||||
@@ -59,7 +62,6 @@ extern bool operator > (perm_string a, perm_string b);
|
||||
extern bool operator < (perm_string a, perm_string b);
|
||||
extern bool operator >= (perm_string a, perm_string b);
|
||||
extern bool operator <= (perm_string a, perm_string b);
|
||||
extern std::ostream& operator << (std::ostream&out, perm_string that);
|
||||
|
||||
/*
|
||||
* The string heap is a way to permanently allocate strings
|
||||
@@ -76,8 +78,11 @@ class StringHeap {
|
||||
perm_string make(const char*);
|
||||
|
||||
private:
|
||||
enum { HEAPCELL = 0x10000 };
|
||||
|
||||
char*cell_base_;
|
||||
unsigned cell_ptr_;
|
||||
unsigned cell_count_;
|
||||
|
||||
private: // not implemented
|
||||
StringHeap(const StringHeap&);
|
||||
@@ -98,11 +103,10 @@ class StringHeapLex : private StringHeap {
|
||||
|
||||
const char*add(const char*);
|
||||
perm_string make(const char*);
|
||||
perm_string make(const std::string&);
|
||||
perm_string make(const string&);
|
||||
|
||||
unsigned add_count() const;
|
||||
unsigned add_hit_count() const;
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
enum { HASH_SIZE = 4096 };
|
||||
@@ -116,4 +120,28 @@ class StringHeapLex : private StringHeap {
|
||||
StringHeapLex& operator= (const StringHeapLex&);
|
||||
};
|
||||
|
||||
#endif /* IVL_StringHeap_H */
|
||||
/*
|
||||
* $Log: StringHeap.h,v $
|
||||
* Revision 1.6 2005/06/14 19:13:43 steve
|
||||
* gcc3/4 compile errors.
|
||||
*
|
||||
* Revision 1.5 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.4 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*
|
||||
* Revision 1.3 2003/01/16 21:44:46 steve
|
||||
* Keep some debugging status.
|
||||
*
|
||||
* Revision 1.2 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/08/04 19:13:16 steve
|
||||
* dll uses StringHeap for named items.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+46
-5
@@ -1,7 +1,7 @@
|
||||
#ifndef PLI_TYPES_H
|
||||
#define PLI_TYPES_H
|
||||
#ifndef PLI_TYPES
|
||||
#define PLI_TYPES
|
||||
/*
|
||||
* Copyright (c) 2003-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2003 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,8 +16,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: _pli_types.h.in,v 1.8 2007/06/05 21:32:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
# undef HAVE_INTTYPES_H
|
||||
|
||||
@@ -85,4 +88,42 @@ typedef char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
#endif
|
||||
|
||||
#endif /* PLI_TYPES_H */
|
||||
/*
|
||||
* $Log: _pli_types.h.in,v $
|
||||
* Revision 1.8 2007/06/05 21:32:30 steve
|
||||
* More standard PLI_BYTE8.
|
||||
*
|
||||
* Revision 1.7 2003/11/12 02:38:44 steve
|
||||
* Clean up manual definitions of PLI_UINT64_FMT.
|
||||
*
|
||||
* Revision 1.6 2003/11/08 20:06:21 steve
|
||||
* Spelling fixes in comments.
|
||||
*
|
||||
* Revision 1.5 2003/10/29 03:28:27 steve
|
||||
* Add the PLU_UINT64_FMT string for formatting output.
|
||||
*
|
||||
* Revision 1.4 2003/10/29 03:23:12 steve
|
||||
* Portably handle time format of VCD prints.
|
||||
*
|
||||
* Revision 1.3 2003/10/02 21:30:06 steve
|
||||
* Use configured TIME_FMT in vcd dump printf.
|
||||
*
|
||||
* Revision 1.2 2003/10/02 19:33:44 steve
|
||||
* Put libraries in libdir64.
|
||||
*
|
||||
* Revision 1.1 2003/09/30 01:33:13 steve
|
||||
* Add PLI_UINT64 to _pli_types.h.
|
||||
*
|
||||
* Revision 1.2 2003/05/26 04:39:16 steve
|
||||
* Typo type name.
|
||||
*
|
||||
* Revision 1.1 2003/02/17 06:39:47 steve
|
||||
* Add at least minimal implementations for several
|
||||
* acc_ functions. Add support for standard ACC
|
||||
* string handling.
|
||||
*
|
||||
* Add the _pli_types.h header file to carry the
|
||||
* IEEE1364-2001 standard PLI type declarations.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
+87
-7
@@ -1,7 +1,7 @@
|
||||
#ifndef ACC_USER_H
|
||||
#define ACC_USER_H
|
||||
#ifndef __acc_user_H
|
||||
#define __acc_user_H
|
||||
/*
|
||||
* Copyright (c) 2002-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,8 +16,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: acc_user.h,v 1.20 2003/12/17 15:45:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This header file contains the definitions and declarations needed
|
||||
@@ -228,9 +231,8 @@ extern PLI_INT32 acc_fetch_size(handle obj);
|
||||
|
||||
extern PLI_INT32 acc_fetch_type(handle obj);
|
||||
extern PLI_INT32 acc_fetch_fulltype(handle obj);
|
||||
extern PLI_INT32 acc_fetch_paramtype(handle obj);
|
||||
extern PLI_INT32 acc_fetch_range(handle object, int *msb, int *lsb);
|
||||
extern const char* acc_fetch_type_str(PLI_INT32 type);
|
||||
extern char* acc_fetch_type_str(PLI_INT32 type);
|
||||
|
||||
extern char* acc_fetch_value(handle obj, const char*fmt, s_acc_value*value);
|
||||
|
||||
@@ -271,4 +273,82 @@ extern char* acc_version(void);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif /* ACC_USER_H */
|
||||
/*
|
||||
* $Log: acc_user.h,v $
|
||||
* Revision 1.20 2003/12/17 15:45:07 steve
|
||||
* Add acc_set_scope function.
|
||||
*
|
||||
* Revision 1.19 2003/10/10 02:57:45 steve
|
||||
* Some PLI1 stubs.
|
||||
*
|
||||
* Revision 1.18 2003/06/13 19:23:41 steve
|
||||
* Add a bunch more PLI1 routines.
|
||||
*
|
||||
* Revision 1.17 2003/06/04 01:56:20 steve
|
||||
* 1) Adds configure logic to clean up compiler warnings
|
||||
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
|
||||
* tf_isetrealdelay, acc_handle_scope
|
||||
* 3) makes acc_next reentrant
|
||||
* 4) adds basic vpiWire type support
|
||||
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
|
||||
* 6) add vpiLeftRange/RigthRange to signals
|
||||
*
|
||||
* Revision 1.16 2003/05/30 04:18:31 steve
|
||||
* Add acc_next function.
|
||||
*
|
||||
* Revision 1.15 2003/05/29 02:35:41 steve
|
||||
* acc_fetch_type supports module.
|
||||
*
|
||||
* Revision 1.14 2003/05/29 02:21:45 steve
|
||||
* Implement acc_fetch_defname and its infrastructure in vvp.
|
||||
*
|
||||
* Revision 1.13 2003/05/24 03:02:04 steve
|
||||
* Add implementation of acc_handle_by_name.
|
||||
*
|
||||
* Revision 1.12 2003/05/18 00:16:35 steve
|
||||
* Add PLI_TRACE tracing of PLI1 modules.
|
||||
*
|
||||
* Add tf_isetdelay and friends, and add
|
||||
* callback return values for acc_vcl support.
|
||||
*
|
||||
* Revision 1.11 2003/04/24 18:57:05 steve
|
||||
* Add acc_fetch_fulltype function.
|
||||
*
|
||||
* Revision 1.10 2003/04/20 02:48:39 steve
|
||||
* Support value change callbacks.
|
||||
*
|
||||
* Revision 1.9 2003/04/12 18:57:13 steve
|
||||
* More acc_ function stubs.
|
||||
*
|
||||
* Revision 1.8 2003/03/13 04:35:09 steve
|
||||
* Add a bunch of new acc_ and tf_ functions.
|
||||
*
|
||||
* Revision 1.7 2003/02/17 06:39:47 steve
|
||||
* Add at least minimal implementations for several
|
||||
* acc_ functions. Add support for standard ACC
|
||||
* string handling.
|
||||
*
|
||||
* Add the _pli_types.h header file to carry the
|
||||
* IEEE1364-2001 standard PLI type declarations.
|
||||
*
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.5 2002/06/11 15:19:12 steve
|
||||
* Add acc_fetch_argc/argv/version (mruff)
|
||||
*
|
||||
* Revision 1.4 2002/06/07 02:58:58 steve
|
||||
* Add a bunch of acc/tf functions. (mruff)
|
||||
*
|
||||
* Revision 1.3 2002/06/02 19:03:29 steve
|
||||
* Add acc_handle_tfarg and acc_next_topmode
|
||||
*
|
||||
* Revision 1.2 2002/05/30 02:06:05 steve
|
||||
* Implement acc_product_version.
|
||||
*
|
||||
* Revision 1.1 2002/05/23 03:46:42 steve
|
||||
* Add the acc_user.h header file.
|
||||
*
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
Vendored
+46
-229
@@ -1,35 +1,39 @@
|
||||
|
||||
# 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],[AS_HELP_STRING([--enable-suffix],
|
||||
[Use/set the installation command suffix])],
|
||||
[true],[enable_suffix=no])
|
||||
if test X$enable_suffix = Xyes; then
|
||||
install_suffix='-0.10'
|
||||
elif test X$enable_suffix = Xno; then
|
||||
install_suffix=''
|
||||
else
|
||||
install_suffix="$enable_suffix"
|
||||
# AX_CPP_IDENT
|
||||
# ------------
|
||||
# Check if the C compiler supports #ident
|
||||
# Define and substitute ident_support if so.
|
||||
#
|
||||
# It would be simpler and more consistent with the rest of the autoconf
|
||||
# structure to AC_DEFINE(HAVE_CPP_IDENT) instead of
|
||||
# ident_support='-DHAVE_CVS_IDENT=1' and AC_SUBST(ident_support), but that
|
||||
# change would require all C files in the icarus top level directory to
|
||||
# put #include <config.h> before the #ifdef HAVE_CVS_IDENT (and change
|
||||
# HAVE_CVS_IDENT to HAVE_CPP_IDENT). That would also remove all special
|
||||
# ident_support handling from the Makefile. Manyana.
|
||||
#
|
||||
AC_DEFUN([AX_CPP_IDENT],
|
||||
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
|
||||
[AC_TRY_COMPILE([
|
||||
#ident "$Id: aclocal.m4,v 1.7 2007/05/16 23:59:12 steve Exp $"
|
||||
],[while (0) {}],
|
||||
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
|
||||
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
|
||||
if test $ax_cv_cpp_ident = yes; then
|
||||
ident_support='-DHAVE_CVS_IDENT=1'
|
||||
fi
|
||||
AC_SUBST(install_suffix)
|
||||
])# AX_ENABLE_SUFFIX
|
||||
AC_SUBST(ident_support)
|
||||
])# AC_CPP_IDENT
|
||||
|
||||
|
||||
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
|
||||
# ------------------------------
|
||||
# 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 or an equivalent is available, and its name
|
||||
# is defined by the $NM variable.
|
||||
# - 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_COMPILE_IFELSE([void underscore(void){}],
|
||||
[AS_IF([nm conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
|
||||
[AC_MSG_ERROR([underscore test crashed])]
|
||||
)])
|
||||
|
||||
@@ -66,24 +70,19 @@ fi
|
||||
# AX_WIN32
|
||||
# --------
|
||||
# Combined check for several flavors of Microsoft Windows so
|
||||
# their "issues" can be dealt with
|
||||
# their "issues" can be dealt with
|
||||
AC_DEFUN([AX_WIN32],
|
||||
[AC_MSG_CHECKING([for Microsoft Windows])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) []dnl
|
||||
case $host_os in
|
||||
*cygwin*) MINGW32=no; WIN32=yes;;
|
||||
|
||||
*mingw*) MINGW32=yes; WIN32=yes;;
|
||||
|
||||
*) MINGW32=no; WIN32=no;;
|
||||
esac
|
||||
[AC_CYGWIN
|
||||
AC_MINGW32
|
||||
WIN32=no
|
||||
AC_MSG_CHECKING([for Microsoft Windows])
|
||||
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
|
||||
then
|
||||
WIN32=yes
|
||||
fi
|
||||
AC_SUBST(MINGW32)
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
if test $WIN32 = yes; then
|
||||
AC_MSG_CHECKING([for MinGW])
|
||||
AC_MSG_RESULT($MINGW32)
|
||||
fi
|
||||
])# AX_WIN32
|
||||
|
||||
# AX_LD_EXTRALIBS
|
||||
@@ -114,10 +113,6 @@ case "${host}" in
|
||||
shared="-shared -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-mingw*)
|
||||
shared="-shared -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
shared="-b"
|
||||
;;
|
||||
@@ -129,13 +124,6 @@ case "${host}" in
|
||||
*-*-darwin*)
|
||||
shared="-bundle -undefined suppress -flat_namespace"
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
if test ${using_sunpro_c} = 1
|
||||
then
|
||||
shared="-G"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(shared)
|
||||
AC_MSG_RESULT($shared)
|
||||
@@ -154,20 +142,10 @@ case "${host}" in
|
||||
PICFLAG=
|
||||
;;
|
||||
|
||||
*-*-mingw*)
|
||||
PICFLAG=
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
PICFLAG=+z
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
if test ${using_sunpro_c} = 1
|
||||
then
|
||||
PICFLAG=-G
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(PICFLAG)
|
||||
AC_MSG_RESULT($PICFLAG)
|
||||
@@ -199,10 +177,6 @@ case "${host}" in
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-mingw*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
@@ -220,171 +194,14 @@ AC_SUBST(strip_dynamic)
|
||||
# AC_MSG_RESULT($strip_dynamic)
|
||||
])# AX_LD_RDYNAMIC
|
||||
|
||||
|
||||
# AX_C99_STRTOD
|
||||
# -------------
|
||||
AC_DEFUN([AX_C99_STRTOD],
|
||||
[# On MinGW we need to jump through hoops to get a C99 compliant strtod().
|
||||
# mingw-w64 doesn't need this, and the 64-bit version doesn't support it.
|
||||
# AX_CPP_PRECOMP
|
||||
# --------------
|
||||
AC_DEFUN([AX_CPP_PRECOMP],
|
||||
[# Darwin requires -no-cpp-precomp
|
||||
case "${host}" in
|
||||
x86_64-w64-mingw32)
|
||||
;;
|
||||
*-*-mingw32)
|
||||
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
|
||||
*-*-darwin*)
|
||||
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
|
||||
CFLAGS="-no-cpp-precomp $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
])# AX_C99_STRTOD
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp file name are based on the header name.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[
|
||||
_config_header=$1
|
||||
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
|
||||
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
|
||||
]) #_AC_AM_CONFIG_HEADER_HOOK
|
||||
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_PROG_CC_FOR_BUILD
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro searches for a C compiler that generates native executables,
|
||||
# that is a C compiler that surely is not a cross-compiler. This can be
|
||||
# useful if you have to generate source code at compile-time like for
|
||||
# example GCC does.
|
||||
#
|
||||
# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything
|
||||
# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD).
|
||||
# The value of these variables can be overridden by the user by specifying
|
||||
# a compiler with an environment variable (like you do for standard CC).
|
||||
#
|
||||
# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object
|
||||
# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if
|
||||
# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are
|
||||
# substituted in the Makefile.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Paolo Bonzini <[email protected]>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 18
|
||||
|
||||
AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD])
|
||||
AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
AC_REQUIRE([AC_PROG_CPP])dnl
|
||||
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
|
||||
|
||||
dnl Use the standard macros, but make them use other variable names
|
||||
dnl
|
||||
pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl
|
||||
pushdef([ac_cv_prog_cc_c89], ac_cv_build_prog_cc_c89)dnl
|
||||
pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl
|
||||
pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl
|
||||
pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl
|
||||
pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl
|
||||
pushdef([ac_cv_c_compiler_gnu], ac_cv_build_c_compiler_gnu)dnl
|
||||
pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl
|
||||
pushdef([ac_cv_objext], ac_cv_build_objext)dnl
|
||||
pushdef([ac_exeext], ac_build_exeext)dnl
|
||||
pushdef([ac_objext], ac_build_objext)dnl
|
||||
pushdef([CC], CC_FOR_BUILD)dnl
|
||||
pushdef([CPP], CPP_FOR_BUILD)dnl
|
||||
pushdef([GCC], GCC_FOR_BUILD)dnl
|
||||
pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl
|
||||
pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl
|
||||
pushdef([EXEEXT], BUILD_EXEEXT)dnl
|
||||
pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl
|
||||
pushdef([OBJEXT], BUILD_OBJEXT)dnl
|
||||
pushdef([host], build)dnl
|
||||
pushdef([host_alias], build_alias)dnl
|
||||
pushdef([host_cpu], build_cpu)dnl
|
||||
pushdef([host_vendor], build_vendor)dnl
|
||||
pushdef([host_os], build_os)dnl
|
||||
pushdef([ac_cv_host], ac_cv_build)dnl
|
||||
pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl
|
||||
pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl
|
||||
pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl
|
||||
pushdef([ac_cv_host_os], ac_cv_build_os)dnl
|
||||
pushdef([ac_tool_prefix], ac_build_tool_prefix)dnl
|
||||
pushdef([am_cv_CC_dependencies_compiler_type], am_cv_build_CC_dependencies_compiler_type)dnl
|
||||
pushdef([am_cv_prog_cc_c_o], am_cv_build_prog_cc_c_o)dnl
|
||||
pushdef([cross_compiling], cross_compiling_build)dnl
|
||||
|
||||
cross_compiling_build=no
|
||||
|
||||
ac_build_tool_prefix=
|
||||
AS_IF([test -n "$build"], [ac_build_tool_prefix="$build-"],
|
||||
[test -n "$build_alias"],[ac_build_tool_prefix="$build_alias-"])
|
||||
|
||||
AC_LANG_PUSH([C])
|
||||
AC_PROG_CC
|
||||
_AC_COMPILER_EXEEXT
|
||||
_AC_COMPILER_OBJEXT
|
||||
AC_PROG_CPP
|
||||
|
||||
dnl Restore the old definitions
|
||||
dnl
|
||||
popdef([cross_compiling])dnl
|
||||
popdef([am_cv_prog_cc_c_o])dnl
|
||||
popdef([am_cv_CC_dependencies_compiler_type])dnl
|
||||
popdef([ac_tool_prefix])dnl
|
||||
popdef([ac_cv_host_os])dnl
|
||||
popdef([ac_cv_host_vendor])dnl
|
||||
popdef([ac_cv_host_cpu])dnl
|
||||
popdef([ac_cv_host_alias])dnl
|
||||
popdef([ac_cv_host])dnl
|
||||
popdef([host_os])dnl
|
||||
popdef([host_vendor])dnl
|
||||
popdef([host_cpu])dnl
|
||||
popdef([host_alias])dnl
|
||||
popdef([host])dnl
|
||||
popdef([OBJEXT])dnl
|
||||
popdef([LDFLAGS])dnl
|
||||
popdef([EXEEXT])dnl
|
||||
popdef([CPPFLAGS])dnl
|
||||
popdef([CFLAGS])dnl
|
||||
popdef([GCC])dnl
|
||||
popdef([CPP])dnl
|
||||
popdef([CC])dnl
|
||||
popdef([ac_objext])dnl
|
||||
popdef([ac_exeext])dnl
|
||||
popdef([ac_cv_objext])dnl
|
||||
popdef([ac_cv_exeext])dnl
|
||||
popdef([ac_cv_c_compiler_gnu])dnl
|
||||
popdef([ac_cv_prog_cc_g])dnl
|
||||
popdef([ac_cv_prog_cc_cross])dnl
|
||||
popdef([ac_cv_prog_cc_works])dnl
|
||||
popdef([ac_cv_prog_cc_c89])dnl
|
||||
popdef([ac_cv_prog_gcc])dnl
|
||||
popdef([ac_cv_prog_CPP])dnl
|
||||
|
||||
dnl restore global variables ac_ext, ac_cpp, ac_compile,
|
||||
dnl ac_link, ac_compiler_gnu (dependant on the current
|
||||
dnl language after popping):
|
||||
AC_LANG_POP([C])
|
||||
|
||||
dnl Finally, set Makefile variables
|
||||
dnl
|
||||
AC_SUBST(BUILD_EXEEXT)dnl
|
||||
AC_SUBST(BUILD_OBJEXT)dnl
|
||||
AC_SUBST([CFLAGS_FOR_BUILD])dnl
|
||||
AC_SUBST([CPPFLAGS_FOR_BUILD])dnl
|
||||
AC_SUBST([LDFLAGS_FOR_BUILD])dnl
|
||||
])
|
||||
])# AX_CPP_PRECOMP
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,14 +14,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: async.cc,v 1.7 2004/01/18 23:26:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
# include <cassert>
|
||||
# include <assert.h>
|
||||
|
||||
bool NetAssign::is_asynchronous()
|
||||
{
|
||||
@@ -50,8 +53,8 @@ bool NetEvWait::is_asynchronous()
|
||||
level sensitive, but the nex_async_ method takes care of
|
||||
that test. */
|
||||
NexusSet*sense = new NexusSet;
|
||||
for (unsigned idx = 0 ; idx < events_.size() ; idx += 1) {
|
||||
NexusSet*tmp = events_[idx]->nex_async_();
|
||||
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
|
||||
NexusSet*tmp = event(idx)->nex_async_();
|
||||
if (tmp == 0) {
|
||||
delete sense;
|
||||
return false;
|
||||
@@ -82,10 +85,36 @@ bool NetProc::is_asynchronous()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetProcTop::is_asynchronous() const
|
||||
bool NetProcTop::is_asynchronous()
|
||||
{
|
||||
if (type_ == IVL_PR_INITIAL)
|
||||
if (type_ == NetProcTop::KINITIAL)
|
||||
return false;
|
||||
|
||||
return statement_->is_asynchronous();
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: async.cc,v $
|
||||
* Revision 1.7 2004/01/18 23:26:54 steve
|
||||
* The is_combinational function really need not recurse.
|
||||
*
|
||||
* Revision 1.6 2003/12/20 00:33:39 steve
|
||||
* More thorough check that NetEvWait is asynchronous.
|
||||
*
|
||||
* Revision 1.5 2003/09/04 20:28:05 steve
|
||||
* Support time0 resolution of combinational threads.
|
||||
*
|
||||
* Revision 1.4 2002/08/18 22:07:16 steve
|
||||
* Detect temporaries in sequential block synthesis.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/07/04 00:24:16 steve
|
||||
* initial statements are not asynchronous.
|
||||
*
|
||||
* Revision 1.1 2002/06/30 02:21:31 steve
|
||||
* Add structure for asynchronous logic synthesis.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+10
-7
@@ -2,15 +2,18 @@
|
||||
|
||||
#
|
||||
# This shell script exists to run autoconf on source distributions
|
||||
# that are pulled from git The configure script is not included
|
||||
# in git, so it is easiest to just run this script whenever needed
|
||||
# to generate the configure script.
|
||||
# that are pulled from CVS. The configure scripts are not included
|
||||
# in CVS, and there are several configure.in files, so it is easiest
|
||||
# to just run this script to autoconf wherever needed.
|
||||
#
|
||||
echo "Autoconf in root..."
|
||||
autoconf -f
|
||||
|
||||
echo "Precompiling lexor_keyword.gperf"
|
||||
gperf -o -i 7 -C -k 1-4,6,9,\$ -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
|
||||
for dir in vpip vpi vvp tgt-vvp tgt-fpga tgt-stub libveriuser cadpli
|
||||
do
|
||||
echo "Autoconf in $dir..."
|
||||
( cd ./$dir ; autoconf -f --include=.. )
|
||||
done
|
||||
|
||||
echo "Precompiling vhdlpp/lexor_keyword.gperf"
|
||||
(cd vhdlpp ; gperf -o -i 7 --ignore-case -C -k 1-4,6,9,\$ -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc )
|
||||
echo "Precompiling lexor_keyword.gperf"
|
||||
gperf -o -i 7 -C -k 1-4,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Makefile
|
||||
cadpli.vpl
|
||||
dep
|
||||
configure
|
||||
config.log
|
||||
config.status
|
||||
autom4te.cache
|
||||
+28
-36
@@ -12,12 +12,13 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
# Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
suffix = @install_suffix@
|
||||
VERSION = 0.9.devel
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -29,68 +30,59 @@ bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = $(prefix)/include
|
||||
|
||||
vpidir = @libdir@/ivl$(suffix)
|
||||
vpidir = @libdir@/ivl
|
||||
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
ifeq (@srcdir@,.)
|
||||
INCLUDE_PATH = -I. -I..
|
||||
else
|
||||
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = cadpli.o
|
||||
SHARED = @shared@
|
||||
|
||||
all:
|
||||
|
||||
all: dep cadpli.vpl $(ALL32)
|
||||
|
||||
# No specific check operations.
|
||||
check: all
|
||||
|
||||
clean:
|
||||
rm -rf *.o dep cadpli.vpl
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=cadpli/$@
|
||||
|
||||
dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $<
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $<
|
||||
mv $*.d dep
|
||||
|
||||
SYSTEM_VPI_LDFLAGS = -L../vpi -lvpi
|
||||
O = cadpli.o
|
||||
|
||||
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
|
||||
ifeq (@MINGW32@,yes)
|
||||
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
|
||||
endif
|
||||
|
||||
cadpli.vpl: $O ../vpi/libvpi.a ../libveriuser/libveriuser.o
|
||||
$(CC) @shared@ $(LDFLAGS) -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
|
||||
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
|
||||
$(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
install: all installdirs installfiles
|
||||
clean:
|
||||
rm -rf *.o dep cadpli.vpl bin32
|
||||
|
||||
F = ./cadpli.vpl
|
||||
distclean: clean
|
||||
rm -f Makefile config.status config.log config.cache
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
$(INSTALL_PROGRAM) ./cadpli.vpl "$(DESTDIR)$(vpidir)/cadpli.vpl"
|
||||
install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32)
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(vpidir)"
|
||||
$(vpidir)/cadpli.vpl: ./cadpli.vpl
|
||||
$(INSTALL_PROGRAM) ./cadpli.vpl $(vpidir)/cadpli.vpl
|
||||
|
||||
installdirs: ../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs $(vpidir)
|
||||
|
||||
uninstall: $(UNINSTALL32)
|
||||
rm -f "$(DESTDIR)$(vpidir)/cadpli.vpl"
|
||||
rm -f $(vpidir)/cadpli.vpl
|
||||
|
||||
uninstall32:
|
||||
|
||||
|
||||
+40
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -14,17 +14,21 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cadpli.c,v 1.7 2004/09/10 00:15:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <vpi_user.h>
|
||||
# include <veriuser.h>
|
||||
# include <stdlib.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
# include "config.h"
|
||||
# include "ivl_dlfcn.h"
|
||||
# include "ivl_alloc.h"
|
||||
|
||||
typedef void* (*funcvp)(void);
|
||||
|
||||
@@ -79,7 +83,38 @@ static void thunker_register(void)
|
||||
}
|
||||
}
|
||||
|
||||
void (*vlog_startup_routines[])(void) = {
|
||||
void (*vlog_startup_routines[])() = {
|
||||
thunker_register,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* $Log: cadpli.c,v $
|
||||
* Revision 1.7 2004/09/10 00:15:45 steve
|
||||
* Remove bad casts.
|
||||
*
|
||||
* Revision 1.6 2004/09/05 21:19:51 steve
|
||||
* Better type safety.
|
||||
*
|
||||
* Revision 1.5 2003/08/26 16:26:02 steve
|
||||
* ifdef idents correctly.
|
||||
*
|
||||
* Revision 1.4 2003/04/30 01:28:06 steve
|
||||
* Remove veriusertfs stuf.
|
||||
*
|
||||
* Revision 1.3 2003/02/22 04:04:38 steve
|
||||
* Only include malloc.h if it is present.
|
||||
*
|
||||
* Revision 1.2 2003/02/17 00:01:25 steve
|
||||
* Use a variant of ivl_dlfcn to do dynamic loading
|
||||
* from within the cadpli module.
|
||||
*
|
||||
* Change the +cadpli flag to -cadpli, to keep the
|
||||
* plusargs namespace clear.
|
||||
*
|
||||
* Revision 1.1 2003/02/16 02:23:54 steve
|
||||
* Add the cadpli interface module.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
CADENCE PLI1 MODULES
|
||||
|
||||
Copyright 2003 Stephen Williams
|
||||
$Id: cadpli.txt,v 1.2 2003/02/17 00:01:25 steve Exp $
|
||||
|
||||
With the cadpli module, Icarus Verilog is able to load PLI1
|
||||
applications that were compiled and linked to be dynamic loaded by
|
||||
@@ -33,3 +34,15 @@ the +loadpli1= argument to Verilog-XL.
|
||||
The integration from this point is seamless. The PLI application
|
||||
hardly knows that it is being invoked by Icarus Verilog instead of
|
||||
Verilog-XL, so operates as it would otherwise.
|
||||
|
||||
$Log: cadpli.txt,v $
|
||||
Revision 1.2 2003/02/17 00:01:25 steve
|
||||
Use a variant of ivl_dlfcn to do dynamic loading
|
||||
from within the cadpli module.
|
||||
|
||||
Change the +cadpli flag to -cadpli, to keep the
|
||||
plusargs namespace clear.
|
||||
|
||||
Revision 1.1 2003/02/16 02:44:47 steve
|
||||
Add the cadpli HOWTO.
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
AC_INIT(Makefile.in)
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
|
||||
AC_EXEEXT
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||
AX_WIN32
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_CHECK_HEADERS(malloc.h)
|
||||
|
||||
AC_CHECK_SIZEOF(unsigned long long)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
AC_CHECK_SIZEOF(unsigned)
|
||||
|
||||
# --
|
||||
# Look for a dl library to use. First look for the standard dlopen
|
||||
# functions, and failing that look for the HP specific shl_load function.
|
||||
|
||||
AC_CHECK_HEADERS(dlfcn.h dl.h, break)
|
||||
|
||||
DLLIB=''
|
||||
AC_CHECK_LIB(dl,dlopen,[DLLIB=-ldl])
|
||||
if test -z "$DLLIB" ; then
|
||||
AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
|
||||
fi
|
||||
AC_SUBST(DLLIB)
|
||||
|
||||
AX_CPP_PRECOMP
|
||||
|
||||
# Compiler option for position independent code, needed when making shared objects.
|
||||
AX_C_PICFLAG
|
||||
|
||||
# Linker option used when compiling the target
|
||||
AX_LD_RDYNAMIC
|
||||
|
||||
# linker options when building a shared library
|
||||
AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
AX_LD_EXTRALIBS
|
||||
|
||||
#######################
|
||||
## test for underscores. The vpi module loader in vvm needs to know this
|
||||
## in order to know the name of the start symbol for the .vpi module.
|
||||
#######################
|
||||
|
||||
AX_C_UNDERSCORES_LEADING
|
||||
AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
AX_CPP_IDENT
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
+35
-16
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_ivl_dlfcn_H
|
||||
#define IVL_ivl_dlfcn_H
|
||||
#ifndef __ivl_dlfcn_H
|
||||
#define __ivl_dlfcn_H
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,8 +16,11 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.3 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
# include <windows.h>
|
||||
@@ -32,16 +35,16 @@ typedef shl_t ivl_dll_t;
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
static __inline__ ivl_dll_t ivl_dlopen(const char *name)
|
||||
static inline ivl_dll_t ivl_dlopen(const char *name)
|
||||
{ return (void *)LoadLibrary(name); }
|
||||
|
||||
static __inline__ void *ivl_dlsym(ivl_dll_t dll, const char *nm)
|
||||
static inline void *ivl_dlsym(ivl_dll_t dll, const char *nm)
|
||||
{ return (void *)GetProcAddress((HINSTANCE)dll,nm);}
|
||||
|
||||
static __inline__ void ivl_dlclose(ivl_dll_t dll)
|
||||
static inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ (void)FreeLibrary((HINSTANCE)dll);}
|
||||
|
||||
static __inline__ const char *dlerror(void)
|
||||
static inline const char *dlerror(void)
|
||||
{
|
||||
static char msg[256];
|
||||
unsigned long err = GetLastError();
|
||||
@@ -58,10 +61,10 @@ static __inline__ const char *dlerror(void)
|
||||
}
|
||||
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
static __inline__ ivl_dll_t ivl_dlopen(const char*name)
|
||||
static inline ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return dlopen(name,RTLD_LAZY); }
|
||||
|
||||
static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{
|
||||
void*sym = dlsym(dll, nm);
|
||||
/* Not found? try without the leading _ */
|
||||
@@ -70,25 +73,41 @@ static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
return sym;
|
||||
}
|
||||
|
||||
static __inline__ void ivl_dlclose(ivl_dll_t dll)
|
||||
static inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ dlclose(dll); }
|
||||
|
||||
#elif defined(HAVE_DL_H)
|
||||
static __inline__ ivl_dll_t ivl_dlopen(const char*name)
|
||||
static inline ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return shl_load(name, BIND_IMMEDIATE, 0); }
|
||||
|
||||
static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{
|
||||
void*sym;
|
||||
int rc = shl_findsym(&dll, nm, TYPE_PROCEDURE, &sym);
|
||||
return (rc == 0) ? sym : 0;
|
||||
}
|
||||
|
||||
static __inline__ void ivl_dlclose(ivl_dll_t dll)
|
||||
static inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ shl_unload(dll); }
|
||||
|
||||
static __inline__ const char*dlerror(void)
|
||||
static inline const char*dlerror(void)
|
||||
{ return strerror( errno ); }
|
||||
#endif
|
||||
|
||||
#endif /* IVL_ivl_dlfcn_H */
|
||||
/*
|
||||
* $Log: ivl_dlfcn.h,v $
|
||||
* Revision 1.3 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.2 2003/12/12 05:43:08 steve
|
||||
* Some systems dlsym requires leading _ or not on whim.
|
||||
*
|
||||
* Revision 1.1 2003/02/17 00:01:25 steve
|
||||
* Use a variant of ivl_dlfcn to do dynamic loading
|
||||
* from within the cadpli module.
|
||||
*
|
||||
* Change the +cadpli flag to -cadpli, to keep the
|
||||
* plusargs namespace clear.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
+15
-142
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_compiler_H
|
||||
#define IVL_compiler_H
|
||||
#ifndef __compiler_H
|
||||
#define __compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include <list>
|
||||
@@ -36,17 +36,6 @@
|
||||
*/
|
||||
extern unsigned integer_width;
|
||||
|
||||
/*
|
||||
* The width_cap is the width limit for unsized expressions.
|
||||
*/
|
||||
extern unsigned width_cap;
|
||||
|
||||
/*
|
||||
* This is the maximum number of recursive module loops allowed within
|
||||
* a generate block.
|
||||
*/
|
||||
extern unsigned recursive_mod_limit;
|
||||
|
||||
/* The TIME_WIDTH is the width of time variables. */
|
||||
#ifndef TIME_WIDTH
|
||||
# define TIME_WIDTH 64
|
||||
@@ -79,10 +68,7 @@ extern unsigned recursive_mod_limit;
|
||||
|
||||
/* Implicit definitions of wires. */
|
||||
extern bool warn_implicit;
|
||||
|
||||
/* Warn if dimensions of port or var/net are implicitly taken from
|
||||
the input/output/inout declaration. */
|
||||
extern bool warn_implicit_dimensions;
|
||||
extern bool error_implicit;
|
||||
|
||||
/* inherit timescales across files. */
|
||||
extern bool warn_timescale;
|
||||
@@ -90,79 +76,33 @@ 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;
|
||||
|
||||
/* Warn about nets that are references but not driven. */
|
||||
extern bool warn_floating_nets;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Ignore errors about missing modules */
|
||||
extern bool ignore_missing_modules;
|
||||
|
||||
/* Treat each source file as a separate compilation unit (as defined
|
||||
by SystemVerilog). */
|
||||
extern bool separate_compilation;
|
||||
|
||||
/* 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. */
|
||||
extern std::list<const char*>library_suff;
|
||||
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. Note that the compiler often assumes
|
||||
this is an ordered list. */
|
||||
specific language features. */
|
||||
enum generation_t {
|
||||
GN_VER1995 = 1,
|
||||
GN_VER2001_NOCONFIG = 2,
|
||||
GN_VER2001 = 3,
|
||||
GN_VER2005 = 4,
|
||||
GN_VER2005_SV = 5,
|
||||
GN_VER2009 = 6,
|
||||
GN_VER2012 = 7,
|
||||
GN_DEFAULT = 4
|
||||
GN_VER2001 = 2,
|
||||
GN_VER2005 = 3,
|
||||
GN_DEFAULT = 3
|
||||
};
|
||||
|
||||
extern generation_t generation_flag;
|
||||
@@ -177,13 +117,6 @@ extern bool gn_icarus_misc_flag;
|
||||
is false, then skip elaboration of specify behavior. */
|
||||
extern bool gn_specify_blocks_flag;
|
||||
|
||||
/* If this flag is true, then elaborate supported assertion statements. If
|
||||
this flag is false, then stub out supported assertion statements. */
|
||||
extern bool gn_supported_assertions_flag;
|
||||
/* If this flag is true, then error on unsupported assertion statements. If
|
||||
this flag is false, then stub out unsupported assertion statements. */
|
||||
extern bool gn_unsupported_assertions_flag;
|
||||
|
||||
/* If this flag is true, then support/elaborate Verilog-AMS. */
|
||||
extern bool gn_verilog_ams_flag;
|
||||
|
||||
@@ -191,40 +124,6 @@ extern bool gn_verilog_ams_flag;
|
||||
is scalar and the net/register definition is vectored. */
|
||||
extern bool gn_io_range_error_flag;
|
||||
|
||||
/* If this flag is true, then force re-evaluation of user functions
|
||||
in a continuous assignment when any part of the expression is
|
||||
re-evaluated. */
|
||||
extern bool gn_strict_ca_eval_flag;
|
||||
|
||||
/* If this flag is true, then force strict conformance to the IEEE
|
||||
standard expression width rules. */
|
||||
extern bool gn_strict_expr_width_flag;
|
||||
|
||||
/* If this flag is true, then don't add a for-loop control variable
|
||||
to an implicit event_expression list if it is only used inside the
|
||||
loop. */
|
||||
extern bool gn_shared_loop_index_flag;
|
||||
|
||||
static inline bool gn_system_verilog(void)
|
||||
{
|
||||
if (generation_flag >= GN_VER2005_SV)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
return gn_system_verilog();
|
||||
}
|
||||
|
||||
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
|
||||
@@ -234,9 +133,6 @@ enum { GN_KEYWORDS_1364_1995 = 0x0001,
|
||||
GN_KEYWORDS_1364_2001_CONFIG = 0x0004,
|
||||
GN_KEYWORDS_1364_2005 = 0x0008,
|
||||
GN_KEYWORDS_VAMS_2_3 = 0x0010,
|
||||
GN_KEYWORDS_1800_2005 = 0x0020,
|
||||
GN_KEYWORDS_1800_2009 = 0x0040,
|
||||
GN_KEYWORDS_1800_2012 = 0x0080,
|
||||
GN_KEYWORDS_ICARUS = 0x8000
|
||||
};
|
||||
extern int lexor_keyword_mask;
|
||||
@@ -244,14 +140,14 @@ extern int lexor_keyword_mask;
|
||||
/* This is the string to use to invoke the preprocessor. */
|
||||
extern char*ivlpp_string;
|
||||
|
||||
extern std::map<perm_string,unsigned> missing_modules;
|
||||
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 std::map<perm_string,bool> library_file_map;
|
||||
extern map<perm_string,bool> library_file_map;
|
||||
|
||||
/*
|
||||
* the lex_strings are perm_strings made up of tokens from the source
|
||||
@@ -259,12 +155,7 @@ extern std::map<perm_string,bool> library_file_map;
|
||||
* much sense to use a StringHeapLex to hold them.
|
||||
*/
|
||||
extern StringHeapLex lex_strings;
|
||||
|
||||
/*
|
||||
* The ivl_target.h API in a variety of places keeps strings of
|
||||
* bits. Manage these as perm_string in a StringHeap.
|
||||
*/
|
||||
extern StringHeapLex bits_strings;
|
||||
extern StringHeap misc_strings;
|
||||
|
||||
/*
|
||||
* The filename_strings are perm_strings for file names. They are put
|
||||
@@ -286,28 +177,10 @@ struct sfunc_return_type {
|
||||
const char* name;
|
||||
ivl_variable_type_t type;
|
||||
unsigned wid;
|
||||
bool signed_flag;
|
||||
bool override_flag;
|
||||
int signed_flag;
|
||||
};
|
||||
|
||||
extern void add_sys_func(const struct sfunc_return_type&ret_type);
|
||||
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
|
||||
extern int load_sys_func_table(const char*path);
|
||||
extern void cleanup_sys_func_table();
|
||||
/*
|
||||
* This temporarily loads a VPI module, to determine the return values
|
||||
* of system functions provided by that module, and adds the return values
|
||||
* to the system function table.
|
||||
*/
|
||||
extern bool load_vpi_module(const char*path);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
extern void pre_process_failed(const char*text);
|
||||
|
||||
#endif /* IVL_compiler_H */
|
||||
#endif
|
||||
|
||||
Vendored
+675
-749
File diff suppressed because it is too large
Load Diff
+55
-17
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_config_H /* -*- c++ -*- */
|
||||
#define IVL_config_H
|
||||
#ifndef __config_H /* -*- c++ -*- */
|
||||
#define __config_H
|
||||
/*
|
||||
* Copyright (c) 2001-2021 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,19 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: config.h.in,v 1.12 2007/02/02 04:33:00 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# if !defined(__GNUC__)
|
||||
using namespace std;
|
||||
# elif (__GNUC__ == 3)
|
||||
using namespace std;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# undef NEED_LU
|
||||
# undef NEED_TU
|
||||
@@ -28,13 +39,13 @@
|
||||
# undef HAVE_GETOPT_H
|
||||
# undef HAVE_INTTYPES_H
|
||||
# undef HAVE_LIBIBERTY_H
|
||||
# undef HAVE_MALLOC_H
|
||||
# undef HAVE_DLFCN_H
|
||||
# undef HAVE_DL_H
|
||||
# undef HAVE_FCHMOD
|
||||
# undef HAVE_LIBREADLINE
|
||||
# undef HAVE_LIBZ
|
||||
# undef HAVE_LIBBZ2
|
||||
# undef HAVE_LROUND
|
||||
# undef HAVE_SYS_WAIT_H
|
||||
# undef WORDS_BIGENDIAN
|
||||
|
||||
@@ -42,17 +53,44 @@
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/* These two are needed by the lxt and lxt2 files (copied from GTKWave). */
|
||||
# undef HAVE_ALLOCA_H
|
||||
# undef HAVE_FSEEKO
|
||||
/* And this is needed by the fst files (copied from GTKWave). */
|
||||
# undef HAVE_LIBPTHREAD
|
||||
# undef HAVE_REALPATH
|
||||
|
||||
/*
|
||||
* Define this if you want to compile vvp with memory freeing and
|
||||
* special valgrind hooks for the memory pools.
|
||||
* $Log: config.h.in,v $
|
||||
* Revision 1.12 2007/02/02 04:33:00 steve
|
||||
* Use inttypes.h instead of stdint.h for portability.
|
||||
*
|
||||
* Revision 1.11 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.10 2003/08/26 16:26:01 steve
|
||||
* ifdef idents correctly.
|
||||
*
|
||||
* Revision 1.9 2003/07/03 16:29:55 steve
|
||||
* spemm WORDS_BIGENDIAN correctly.
|
||||
*
|
||||
* Revision 1.8 2003/03/07 02:44:33 steve
|
||||
* Implement $realtobits.
|
||||
*
|
||||
* Revision 1.7 2003/02/20 00:49:24 steve
|
||||
* detect -lz and -lbz2 libraries.
|
||||
*
|
||||
* Revision 1.6 2003/01/10 19:01:04 steve
|
||||
* Only use libiberty.h if available.
|
||||
*
|
||||
* Revision 1.5 2002/08/11 23:39:33 steve
|
||||
* Remove VVM option.
|
||||
*
|
||||
* Revision 1.4 2002/02/16 03:18:53 steve
|
||||
* Make vvm optional, normally off.
|
||||
*
|
||||
* Revision 1.3 2001/10/18 16:16:23 steve
|
||||
* Include HAVE_SYS_WAIT in config.h (PR#306)
|
||||
*
|
||||
* Revision 1.2 2001/09/15 18:27:04 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
* Revision 1.1 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
*/
|
||||
# undef CHECK_WITH_VALGRIND
|
||||
|
||||
#endif /* IVL_config_H */
|
||||
#endif // __config_H
|
||||
|
||||
Vendored
+138
-491
File diff suppressed because it is too large
Load Diff
-338
@@ -1,338 +0,0 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([netlist.h])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_HEADERS([_pli_types.h])
|
||||
AC_CONFIG_HEADERS([vhdlpp/vhdlpp_config.h])
|
||||
AC_CONFIG_HEADERS([vvp/config.h])
|
||||
AC_CONFIG_HEADERS([vpi/vpi_config.h])
|
||||
AC_CONFIG_HEADERS([libveriuser/config.h])
|
||||
AC_CONFIG_HEADERS([tgt-vvp/vvp_config.h])
|
||||
AC_CONFIG_HEADERS([tgt-vhdl/vhdl_config.h])
|
||||
AC_CONFIG_HEADERS([tgt-pcb/pcb_config.h])
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AX_PROG_CC_FOR_BUILD
|
||||
AC_PREREQ([2.62])
|
||||
m4_version_prereq([2.70], [], [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 ""
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(LEX,flex,none)
|
||||
if test "$LEX" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable flex found. ***"
|
||||
echo " Please install the 'flex' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(YACC,bison,none)
|
||||
if test "$YACC" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable bison found. ***"
|
||||
echo " Please install the 'bison' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "x$NM" = "x"; then
|
||||
NM=nm
|
||||
fi
|
||||
|
||||
AC_EXEEXT
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||
AX_WIN32
|
||||
|
||||
# Check to see if we are using the Sun compiler. If so then configure
|
||||
# some of the flags to match the Sun compiler syntax. This is also used
|
||||
# in the aclocal.m4 file to configure the flags used to build and link
|
||||
# dynamic libraries
|
||||
AC_CHECK_DECL(__SUNPRO_C, using_sunpro_c=1, using_sunpro_c=0)
|
||||
if test ${using_sunpro_c} = 1
|
||||
then
|
||||
AC_SUBST(DEPENDENCY_FLAG, [-xMMD])
|
||||
AC_SUBST(WARNING_FLAGS, [""])
|
||||
AC_SUBST(WARNING_FLAGS_CXX, [""])
|
||||
else
|
||||
# Check to see if -Wextra is supported.
|
||||
iverilog_temp_cflags="$CFLAGS"
|
||||
CFLAGS="-Wextra $CFLAGS"
|
||||
AC_MSG_CHECKING(if gcc supports -Wextra)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[[iverilog_wextra_flag="-Wextra";] AC_MSG_RESULT(yes)],
|
||||
[[iverilog_wextra_flag="-W";] AC_MSG_RESULT(no)])
|
||||
CFLAGS="$iverilog_temp_cflags"
|
||||
|
||||
AC_SUBST(DEPENDENCY_FLAG, [-MD])
|
||||
AC_SUBST(WARNING_FLAGS, ["-Wall $iverilog_wextra_flag -Wshadow"])
|
||||
AC_SUBST(WARNING_FLAGS_CC, ["-Wstrict-prototypes"])
|
||||
AC_SUBST(WARNING_FLAGS_CXX, [""])
|
||||
fi
|
||||
|
||||
AC_LANG(C++)
|
||||
|
||||
AC_ARG_WITH([m32], [AS_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 -std=c++11"
|
||||
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)
|
||||
AC_CHECK_SIZEOF(void *)
|
||||
|
||||
# vvp uses these...
|
||||
AC_CHECK_LIB(termcap, tputs)
|
||||
AC_CHECK_LIB(readline, readline)
|
||||
AC_CHECK_LIB(readline, add_history, NEED_LIBHISTORY=no, NEED_LIBHISTORY=yes)
|
||||
if test "$NEED_LIBHISTORY" = "yes"; then
|
||||
AC_CHECK_LIB(history, add_history)
|
||||
else
|
||||
# libreadline includes libhistory functions
|
||||
AC_DEFINE(HAVE_LIBHISTORY, 1)
|
||||
fi
|
||||
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], [AS_HELP_STRING([--with-valgrind],[Add valgrind hooks])],
|
||||
[], [check_valgrind=yes])
|
||||
|
||||
AS_IF([test "x$check_valgrind" = xyes],
|
||||
[AC_MSG_NOTICE([Not using valgrind hooks])],
|
||||
[AC_CHECK_HEADER([valgrind/memcheck.h],
|
||||
[AC_DEFINE([CHECK_WITH_VALGRIND], [1],
|
||||
[Define to one to use the valgrind hooks])],
|
||||
[AC_MSG_ERROR([Could not find <valgrind/memcheck.h>])])])
|
||||
|
||||
AC_MSG_CHECKING(for sys/times)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>
|
||||
#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.)],[do_times=no
|
||||
])
|
||||
AC_MSG_RESULT($do_times)
|
||||
|
||||
# --
|
||||
# Look for a dl library to use. First look for the standard dlopen
|
||||
# functions, and failing that look for the HP specific shl_load function.
|
||||
|
||||
AC_CHECK_HEADERS(dlfcn.h dl.h, break)
|
||||
|
||||
DLLIB=''
|
||||
AC_CHECK_LIB(dl,dlopen,[DLLIB=-ldl])
|
||||
if test -z "$DLLIB" ; then
|
||||
AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
|
||||
fi
|
||||
AC_SUBST(DLLIB)
|
||||
AC_SUBST(LDRELOCFLAGS)
|
||||
|
||||
AC_SUBST(CTARGETFLAGS)
|
||||
AC_SUBST(LDTARGETFLAGS)
|
||||
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_LANG(C)
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
# $host
|
||||
|
||||
AX_ENABLE_SUFFIX
|
||||
|
||||
AX_LD_EXTRALIBS
|
||||
|
||||
# Compiler option for position independent code, needed when making shared objects.
|
||||
# CFLAGS inherited by cadpli/Makefile?
|
||||
AX_C_PICFLAG
|
||||
|
||||
# may modify LDFLAGS
|
||||
AX_C99_STRTOD
|
||||
|
||||
# Processor specific compile flags
|
||||
case "${host}" in
|
||||
alpha*-*-linux*)
|
||||
CPPFLAGS="-mieee $CPPFLAGS"
|
||||
CFLAGS="-mieee $CFLAGS"
|
||||
;;
|
||||
*-*-mingw*)
|
||||
CXXFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CXXFLAGS"
|
||||
CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Do some more operating system specific setup. We put the file64_support
|
||||
# define in a substitution instead of simply a define because there
|
||||
# are source files (namely lxt support files) that don't include any
|
||||
# config.h header file.
|
||||
file64_support=''
|
||||
case "${host}" in
|
||||
*-*-linux*)
|
||||
AC_DEFINE([_LARGEFILE_SOURCE], [1], [Indicates LFS (i.e. the ability to create files larger than 2 GiB on 32-bit operating systems).])
|
||||
file64_support='-D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64'
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(file64_support)
|
||||
|
||||
# fstapi.c (from GTKWave) needs this define.
|
||||
AC_CHECK_FUNCS(realpath)
|
||||
|
||||
# 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.
|
||||
# autoconf >= 2.70 will enable C99 if it is available. For older autoconf
|
||||
# versions, 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
|
||||
## in order to know the name of the start symbol for the .vpi module.
|
||||
#######################
|
||||
|
||||
AX_C_UNDERSCORES_LEADING
|
||||
AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
#######################
|
||||
# Sanity check the configured results
|
||||
#######################
|
||||
|
||||
AC_MSG_CHECKING(for sanity of prefix)
|
||||
if test `echo "$prefix" | wc -w` != 1
|
||||
then
|
||||
AC_MSG_ERROR(cannot configure white space in prefix: $prefix)
|
||||
fi
|
||||
AC_MSG_RESULT(ok)
|
||||
|
||||
AC_MSG_CHECKING(for sanity of exec_prefix)
|
||||
if test `echo "$exec_prefix" | wc -w` != 1
|
||||
then
|
||||
AC_MSG_ERROR(cannot configure white space in exec_prefix: $exec_prefix)
|
||||
fi
|
||||
AC_MSG_RESULT(ok)
|
||||
|
||||
AC_MSG_CHECKING(for sanity of libdir)
|
||||
if test `echo "$libdir" | wc -w` != 1
|
||||
then
|
||||
AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
|
||||
fi
|
||||
AC_MSG_RESULT(ok)
|
||||
AC_CONFIG_FILES([Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile tgt-blif/Makefile tgt-sizer/Makefile])
|
||||
AC_OUTPUT
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user