Compare commits

..

4 Commits

Author SHA1 Message Date
Lars-Peter Clausen 4fd5291632 ci: Windows: Add gperf to dependency list
msys2 removed the gperf package from the base-devel package collection[1].

Add gperf explicitly to the dependency list, without this the Windows
CI will fail.

[1] 085698dce3

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 21:23:55 -05:00
Stephen Williams ba370285f3 ci: Windows: Replace `MINGW_INSTALLS` with `MINGW_ARCH`
Currently the Windows build generates a warning

   => WARNING: MINGW_INSTALLS is deprecated, use MINGW_ARCH instead

Make this change to the CI workflow file.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-12-26 21:22:21 -05:00
Stephen Williams 8ecb1ab15c v12: Pushes to v12-branch trigger actions 2022-12-26 13:04:33 -05:00
Stephen Williams ce20e9f769 v12: Start the v132 Stable branch 2022-12-26 12:44:58 -05:00
1930 changed files with 25479 additions and 61620 deletions

14
.github/test.sh vendored Executable file
View File

@ -0,0 +1,14 @@
#!/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

View File

@ -19,15 +19,10 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt update -qq sudo apt update -qq
sudo apt install -y make autoconf python3-venv sudo apt install -y make autoconf python3-sphinx
python3 -m venv .venv
. .venv/bin/activate
pip install --upgrade pip
pip install -r Documentation/requirements.txt
- name: Make Documentation - name: Make Documentation
run: | run: |
. .venv/bin/activate
cd Documentation cd Documentation
make html make html

View File

@ -1,27 +1,24 @@
name: test name: test
on: on:
# Every push onto the main branch triggers a retest. # Every push onto the main branch and releases triggers a retest.
push: push:
branches: branches:
- master - master
- v12-branch
# All pull_requests trigger a retest. # All pull_requests trigger a retest.
pull_request: pull_request:
workflow_dispatch:
jobs: jobs:
mac: mac:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: runs-on: macos-latest
libvvp: [true] name: '🍏 macOS'
suffix: [true]
runs-on: macos-15-intel
name: 🍏 macOS${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v2
- name: Install dependencies - name: Install dependencies
run: | run: |
@ -30,66 +27,46 @@ jobs:
- name: Build, check and install - name: Build, check and install
run: | run: |
export PATH="/usr/local/opt/bison/bin:$PATH" export PATH="/usr/local/opt/bison/bin:$PATH"
CONFIG_OPTS="--enable-libveriuser"
if [ "${{ matrix.libvvp }}" = "true" ]; then
CONFIG_OPTS="$CONFIG_OPTS --enable-libvvp"
fi
if [ "${{ matrix.suffix }}" = "true" ]; then
CONFIG_OPTS="$CONFIG_OPTS --enable-suffix"
fi
autoconf autoconf
./configure $CONFIG_OPTS ./configure
make -j$(nproc) check make check
sudo make install sudo make install
- name: Test - name: Test
run: | run: ./.github/test.sh
make check-installed
lin: lin:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: ['22.04', '24.04'] os: [
# libvvp: [false, true] '20.04',
# suffix: [false, true] '22.04'
]
runs-on: ubuntu-${{ matrix.os }} runs-on: ubuntu-${{ matrix.os }}
name: 🐧 Ubuntu ${{ matrix.os }}${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }} name: '🐧 Ubuntu ${{ matrix.os }}'
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v2
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt update -qq sudo apt update -qq
sudo apt install -y make g++ git bison flex gperf libreadline-dev libbz2-dev autoconf python3-venv sudo apt install -y make g++ git bison flex gperf libreadline-dev autoconf python3-sphinx
python3 -m venv .venv
. .venv/bin/activate
pip install --upgrade pip
pip install -r Documentation/requirements.txt
- name: Build, check and install - name: Build, check and install
run: | run: |
CONFIG_OPTS="--enable-libveriuser"
if [ "${{ matrix.libvvp }}" = "true" ]; then
CONFIG_OPTS="$CONFIG_OPTS --enable-libvvp"
fi
if [ "${{ matrix.suffix }}" = "true" ]; then
CONFIG_OPTS="$CONFIG_OPTS --enable-suffix"
fi
autoconf autoconf
./configure $CONFIG_OPTS ./configure
make -j$(nproc) check make check
sudo make install sudo make install
- name: Test - name: Test
run: run: ./.github/test.sh
make check-installed
- name: Documentation - name: Documentation
run: | run: |
. .venv/bin/activate
cd Documentation cd Documentation
make html make html
@ -98,14 +75,11 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
msystem: [MINGW64, UCRT64, CLANG64] include: [
# libvvp: [false, true] { msystem: MINGW64, arch: x86_64 },
# suffix: [false, true] { msystem: MINGW32, arch: i686 }
include: ]
- { msystem: MINGW64, env: x86_64 } name: 🟪 ${{ matrix.msystem}} · ${{ matrix.arch }}
- { msystem: UCRT64, env: ucrt-x86_64 }
- { msystem: CLANG64, env: clang-x86_64 }
name: 🟪 ${{ matrix.msystem }}${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
defaults: defaults:
run: run:
shell: msys2 {0} shell: msys2 {0}
@ -116,7 +90,7 @@ jobs:
- run: git config --global core.autocrlf input - run: git config --global core.autocrlf input
shell: bash shell: bash
- uses: actions/checkout@v6 - uses: actions/checkout@v2
- uses: msys2/setup-msys2@v2 - uses: msys2/setup-msys2@v2
with: with:
@ -125,37 +99,21 @@ jobs:
install: > install: >
git git
base-devel base-devel
python-pip gperf
mingw-w64-${{ matrix.env }}-perl mingw-w64-${{ matrix.arch }}-toolchain
- uses: actions/setup-python@v6
with:
python-version: '>=3.5'
- name: Build and check - name: Build and check
run: | run: |
cd msys2 cd msys2
CONFIG_OPTS=""
if [ ${{ matrix.msystem }} != "CLANG64" ] ; then
CONFIG_OPTS="$CONFIG_OPTS --enable-libveriuser"
fi
if [ "${{ matrix.libvvp }}" = "true" ] ; then
CONFIG_OPTS="$CONFIG_OPTS --enable-libvvp"
fi
if [ "${{ matrix.suffix }}" = "true" ]; then
CONFIG_OPTS="$CONFIG_OPTS --enable-suffix"
fi
export IVL_CONFIG_OPTIONS="$CONFIG_OPTS"
makepkg-mingw --noconfirm --noprogressbar -sCLf makepkg-mingw --noconfirm --noprogressbar -sCLf
- name: Install - name: Install
run: pacman -U --noconfirm msys2/*.zst run: pacman -U --noconfirm msys2/*.zst
- name: Test - name: Test
run: | run: ./.github/test.sh
make check-installed
- uses: actions/upload-artifact@v7 - uses: actions/upload-artifact@v2
with: with:
name: 🟪 ${{ matrix.msystem }}${{ matrix.libvvp && ' +libvvp' || '' }} name: ${{ matrix.msystem }}-${{ matrix.arch }}
path: msys2/*.zst path: msys2/*.zst

48
.gitignore vendored
View File

@ -8,10 +8,6 @@
*.swp *.swp
*~ *~
# Virtual environments
.conda/
.venv/
# Top level generic files # Top level generic files
tags tags
TAGS TAGS
@ -21,7 +17,6 @@ cscope.*
# Object files and libraries # Object files and libraries
*.[oa] *.[oa]
*.so
gmon*.out gmon*.out
gmon*.txt gmon*.txt
@ -35,19 +30,16 @@ Makefile
/_pli_types.h /_pli_types.h
config.h config.h
/tgt-pcb/pcb_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-vvp/vvp_config.h
/tgt-vhdl/vhdl_config.h /tgt-vhdl/vhdl_config.h
/vhdlpp/vhdlpp_config.h
/vpi/vpi_config.h /vpi/vpi_config.h
stamp-*-h stamp-*-h
/version.h
/version_tag.h /version_tag.h
/version_base.h
/driver-vpi/iverilog-vpi.man
/driver-vpi/res.rc
/driver/iverilog.man
/vvp/libvvp.pc
/vvp/vvp.man
# Directories # Directories
autom4te.cache autom4te.cache
@ -59,6 +51,8 @@ dep
*.vpi *.vpi
/cadpli/cadpli.vpl /cadpli/cadpli.vpl
/tgt-blif/Makefile
# lex, yacc and gperf output # lex, yacc and gperf output
/driver/cflexor.c /driver/cflexor.c
/driver/cfparse.c /driver/cfparse.c
@ -67,6 +61,14 @@ dep
/ivlpp/lexor.c /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.cc
/lexor_keyword.cc /lexor_keyword.cc
/parse.cc /parse.cc
@ -75,17 +77,6 @@ dep
/syn-rules.cc /syn-rules.cc
/syn-rules.output /syn-rules.output
/tgt-pcb/fp.cc
/tgt-pcb/fp.h
/tgt-pcb/fp.output
/tgt-pcb/fp_lex.cc
/vhdlpp/lexor.cc
/vhdlpp/lexor_keyword.cc
/vhdlpp/parse.cc
/vhdlpp/parse.h
/vhdlpp/parse.output
/vpi/sdf_lexor.c /vpi/sdf_lexor.c
/vpi/sdf_parse.c /vpi/sdf_parse.c
/vpi/sdf_parse.h /vpi/sdf_parse.h
@ -105,13 +96,17 @@ dep
# Program created files # Program created files
/vvp/tables.cc /vvp/tables.cc
/iverilog-vpi.man
/driver-vpi/res.rc
/driver/iverilog.man
/vvp/vvp.man
# The executables. # The executables.
*.exe *.exe
/driver/iverilog /driver/iverilog
/driver-vpi/iverilog-vpi /iverilog-vpi
/ivl /ivl
/ivlpp/ivlpp /ivlpp/ivlpp
/vhdlpp/vhdlpp
/vvp/vvp /vvp/vvp
/ivl.exp /ivl.exp
@ -119,4 +114,3 @@ dep
# Check output # Check output
/check.vvp /check.vvp
/driver/top.vvp

View File

@ -1,7 +1,7 @@
#ifndef IVL_AStatement_H #ifndef IVL_AStatement_H
#define IVL_AStatement_H #define IVL_AStatement_H
/* /*
* Copyright (c) 2008-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 2008-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -40,13 +40,10 @@ class AContrib : public Statement {
public: public:
AContrib(PExpr*lval, PExpr*rval); AContrib(PExpr*lval, PExpr*rval);
~AContrib() override; ~AContrib();
AContrib(const AContrib&) = delete; virtual void dump(std::ostream&out, unsigned ind) const;
AContrib& operator=(const AContrib&) = delete; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(std::ostream&out, unsigned ind) const override;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
private: private:
PExpr*lval_; PExpr*lval_;
@ -64,7 +61,7 @@ class AProcess : public LineInfo {
AProcess(ivl_process_type_t t, Statement*st) AProcess(ivl_process_type_t t, Statement*st)
: type_(t), statement_(st) { } : type_(t), statement_(st) { }
~AProcess() override; ~AProcess();
bool elaborate(Design*des, NetScope*scope) const; bool elaborate(Design*des, NetScope*scope) const;

174
BUGS.txt Normal file
View File

@ -0,0 +1,174 @@
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.)
* The Compiler Doesn't Compile
If Icarus Verilog doesn't compile, I need to know about the
compilation tools you are using. Specifically, I need to know:
- Operating system and processor type,
- Compiler w/ version,
- Versions of any libraries being linked, and
- anything else you think relevant.
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.
* The Compiler Crashes
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
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.
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.
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.
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.
* It Generates Incorrect Target Code
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.
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.
* 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
consideration. However, realize that outright errors will get more
attention than missed optimizations.
THE MAKING OF A GOOD TEST PROGRAM
If at all possible, please submit a complete source file that
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.
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
If the error occurs with the null target (``-tnull'') then a top level
module may not be needed as long as the ``-s <name>'' switch is
given.
So when you send a test case, ask yourself "Can poor overworked Steve
invoke the error without any Verilog other than what is included?" And
while we are at it, please place a copyright notice in your test
program and include a GPL license statement if you can. Your test
program may find its way into the test suite, and the notices will
make it all nice and legal. Please look at the existing tests in the
test suite <http://sourceforge.net/ivtest> for examples of good test
programs.
RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS
The URL <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 bug database supports basic keyword searches, and you can
optionally limit your search to active bugs, or fixed bugs. You may
also browse the bug database, just to get an idea what is still
broken. You may for example find a related bug that explains your
symptom.
The root page of the bug report database describes how to submit your
completed bug report.
HOW TO SEND PATCHES
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/>.
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.)
COPYRIGHT ISSUES
Icarus Verilog is Copyright (c) 1998-2018 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
be considered independently copyrightable, it's yours and I encourage
you to claim it with appropriate copyright notices. This submission
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.

View File

@ -20,7 +20,7 @@
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = 'Icarus Verilog' project = 'Icarus Verilog'
copyright = '2024-2026, Stephen Williams' copyright = '2022, Stephen Williams'
author = 'Stephen Williams' author = 'Stephen Williams'
# The short X.Y version # The short X.Y version
@ -58,7 +58,7 @@ master_doc = 'index'
# #
# This is also used if you do content translation via gettext catalogs. # This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases. # Usually you set "language" from the command line for these cases.
language = 'en' language = None
# List of patterns, relative to source directory, that match files and # List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files. # directories to ignore when looking for source files.
@ -68,40 +68,24 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use. # The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx' pygments_style = 'sphinx'
# If no language is specified, use none
highlight_language = 'none'
# -- Options for HTML output ------------------------------------------------- # -- Options for HTML output -------------------------------------------------
# A dictionary of values to pass into the template engine's context for all pages.
#
html_context = {
# Edit this page
"source_type": "github",
"source_user": "steveicarus",
"source_repo": "iverilog",
"source_version": "master",
"source_docs_path": "/Documentation/",
}
# The theme to use for HTML and HTML Help pages. See the documentation for # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # a list of builtin themes.
# #
html_theme = 'shibuya' html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme # 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 # further. For a list of options available for each theme, see the
# documentation. # documentation.
# #
html_theme_options = { # html_theme_options = {}
"github_url": "https://github.com/steveicarus/iverilog",
}
# Add any paths that contain custom static files (such as style sheets) here, # 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, # relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css". # so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static'] html_static_path = ['_static']
html_static_path = []
# Custom sidebar templates, must be a dictionary that maps document names # Custom sidebar templates, must be a dictionary that maps document names
# to template names. # to template names.
@ -113,7 +97,6 @@ html_static_path = []
# #
# html_sidebars = {} # html_sidebars = {}
html_favicon = 'favicon.ico'
# -- Options for HTMLHelp output --------------------------------------------- # -- Options for HTMLHelp output ---------------------------------------------
@ -155,7 +138,7 @@ latex_documents = [
# One entry per manual page. List of tuples # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [
(master_doc, 'iverilog-docs', 'Icarus Verilog Documentation', (master_doc, 'icarusverilog', 'Icarus Verilog Documentation',
[author], 1) [author], 1)
] ]

View File

@ -1,5 +1,5 @@
Getting Started as a Contributor Getting Started as a Contributer
================================ ================================
Icarus Verilog development is centered around the github repository at Icarus Verilog development is centered around the github repository at
@ -103,22 +103,6 @@ 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 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). V0.9 file with the V0.8 run time).
.. code-block:: none
--enable-libvvp
The vvp program is built as a small stub linked to a shared library,
libvvp.so, that may be linked with other programs so that they can host
a vvp simulation.
.. code-block:: none
--enable-libveriuser
PLI version 1 (the ACC and TF routines) were deprecated in IEEE 1364-2005.
These are supported in Icarus Verilog by the libveriuser library and cadpli
module. Starting with v13, these will only be built if this option is used.
A debug options is: A debug options is:
.. code-block:: none .. code-block:: none
@ -127,7 +111,7 @@ A debug options is:
This option adds extra memory cleanup code and pool management code to allow 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 better memory leak checking when valgrind is available. This option is not
needed when checking for basic errors with valgrind. need when checking for basic errors with valgrind.
Compiling on Linux Compiling on Linux
------------------ ------------------
@ -179,21 +163,13 @@ example:
.. code-block:: console .. code-block:: console
% cd ivtest % cd ivtest
% ./vvp_reg.pl % ./vvp_reg.pl --strict
% ./vvp_reg.py
% ./vpi_reg.pl
will run all the regression tests for the simulation engine. (This is what will run all the regression tests for the simulation engine. (This is what
most people will want to do.) You should rerun these tests before submitting 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 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 add test programs to the regression test suite to validate your new feature
(or bug fix.). The python script is the preferred method to add new tests. (or bug fix.)
All of these scripts take other options to test various configurations. What
options are supported can be found by using the ``-h/--help`` argument. There
is also a separate ``vlog95_reg.pl`` script for testing the vlog95 translation
of the original tests. This is integrated into the existing Python test script
for the new tests.
Note that pull requests will be required to pass these regression tests before Note that pull requests will be required to pass these regression tests before
being merged. being merged.
@ -242,7 +218,8 @@ first push the branch up to github:
Then go to github.com to create your pull request. `Create your pull request Then go to github.com to create your pull request. `Create your pull request
against the "master" branch of the upstream repository 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>`_, <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 request will be run 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 through continuous integration, and reviewed by one of the main
authors. Feedback may be offered to your PR, and once accepted, an approved authors. Feedback may be offered to your PR, and once accepted, an approved
individual will merge it for you. Then you are done. individual will merge it for you. Then you are done.

View File

@ -1,12 +0,0 @@
IVL - The Core Compiler
=======================
.. toctree::
:maxdepth: 1
netlist
attributes
ivl_target
lpm
t-dll

View File

@ -1,10 +0,0 @@
Miscellaneous
=============
.. toctree::
:maxdepth: 1
ieee1364-notes
swift
xilinx-hint

View File

@ -1,113 +0,0 @@
Xilinx Hint
===========
For those of you who wish to use Icarus Verilog, in combination with
the Xilinx back end (Foundation or Alliance), it can be done. I have
run some admittedly simple (2300 equivalent gates) designs through this
setup, targeting a Spartan XCS10.
Verilog:
--------
Older versions of Icarus Verilog (like 19990814) couldn't synthesize
logic buried in procedural (flip-flop) assignment. Newer versions
(like 20000120) don't have this limitation.
Procedural assignments have to be given one at a time, to be
"found" by xnfsyn. Say
::
always @ (posedge Clk) Y = newY;
always @ (posedge Clk) Z = newZ;
rather than
::
always @ (posedge Clk) begin
Y = newY;
Z = newZ;
end
Steve's xnf.txt covers most buffer and pin constructs, but I had reason
to use a global clock net not connected to an input pin. The standard
Verilog for a buffer, combined with a declaration to turn that into a
BUFG, is::
buf BUFG( your_output_here, your_input_here );
$attribute(BUFG,"XNF-LCA","BUFG:O,I")
I use post-processing on my .xnf files to add "FAST" attributes to
output pins.
Running ivl:
------------
The -F switches are important. The following order seems to robustly
generate valid XNF files, and is used by "verilog -X"::
-Fsynth -Fnodangle -Fxnfio
Generating .pcf files:
----------------------
The ngdbuild step seems to lose pin placement information that ivl
puts in the XNF file. Use xnf2pcf to extract this information to
a .pcf file, which the Xilinx place-and-route software _will_ pay
attention to. Steve says he now makes that information available
in an NCF file, with -fncf=<path>, but I haven't tested that.
Running the Xilinx back end:
You can presumably use the GUI, but that doesn't fit in Makefiles :-).
Here is the command sequence in pseudo-shell-script::
ngdbuild -p $part $1.xnf $1.ngd
map -p $part -o map.ncd $1.ngd
xnf2pcf <$1.xnf >$1.pcf # see above
par -w -ol 2 -d 0 map.ncd $1.ncd $1.pcf
bitgen_flags = -g ConfigRate:SLOW -g TdoPin:PULLNONE -g DonePin:PULLUP \
-g CRC:enable -g StartUpClk:CCLK -g SyncToDone:no \
-g DoneActive:C1 -g OutputsActive:C3 -g GSRInactive:C4 \
-g ReadClk:CCLK -g ReadCapture:enable -g ReadAbort:disable
bitgen $1.ncd -l -w $bitgen_flags
The Xilinx software has diarrhea of the temp files (14, not including
.xnf, .pcf, .ngd, .ncd, and .bit), so this sequence is best done in a
dedicated directory. Note in particular that map.ncd is a generic name.
I had reason to run this remotely (and transparently within a Makefile)
via ssh. I use the gmake rule::
%.bit : %.xnf
ssh -x -a -o 'BatchMode yes' ${ALLIANCE_HOST} \
remote_alliance ${REMOTE_DIR} $(basename $@) 2>&1 < $<
scp ${ALLIANCE_HOST}:${REMOTE_DIR}/$@ .
and the remote_alliance script (on ${ALLIANCE_HOST})::
/bin/csh
cd $1
cat >! $2.xnf
xnf2pcf <$2.xnf >! $2.pcf
./backend $2
There is now a "Xilinx on Linux HOWTO" at http://www.polybus.com/xilinx_on_linux.html
I haven't tried this yet, it looks interesting.
Downloading:
------------
I use the XESS (http://www.xess.com/) XSP-10 development board, which
uses the PC parallel (printer) port for downloading and interaction
with the host. They made an old version of their download program
public domain, posted it at http://www.xess.com/FPGA/xstools.zip ,
and now there is a Linux port at ftp://ftp.microux.com/pub/pilotscope/xstools.tar.gz .
The above hints are based on my experience with Foundation 1.5 on NT
(gack) and Alliance 2.1i on Solaris. Your mileage may vary. Good luck!
- Larry Doolittle <LRDoolittle@lbl.gov> August 19, 1999
updated February 1, 2000

View File

@ -1,9 +0,0 @@
VPI in Icarus Verilog
=====================
.. toctree::
:maxdepth: 1
vpi
va_math

View File

@ -1,13 +0,0 @@
VVP - Verilog Virtual Processor
===============================
.. toctree::
:maxdepth: 1
vvp
opcodes
vpi
vthread
debug

View File

@ -9,7 +9,5 @@ Icarus Verilog.
:maxdepth: 1 :maxdepth: 1
getting_started getting_started
regression_tests
version_stamps version_stamps
guide/index
glossary

View File

@ -1,129 +0,0 @@
The Regression Test Suite
=========================
Icarus Verilog development includes a regression test suite that is included
along with the source. The "ivtest" directory contains the regression test
suite, and this suite is used by the github actions as continuous integration
to make sure the code is always going forward.
NOTE: There are scripts written in perl to run the regression tests, but they
are being gradually replaced with a newer set of scripts. It is the newer
method that is described here.
Test Descriptions
-----------------
Regression tests are listed in the regress-vvp.list file. Each line lists the
name of the test and the path to the dest description. The list file is
therefore pretty simple, and all the description of the test is in the
description file:
.. code-block:: console
macro_str_esc vvp_tests/macro_str_esc.json
The "name" is a simple name, and the test-description-file is the path (relative
the ivtest directory) to the description file. A simple test description file
is a JSON file, like this:
.. code-block:: java
{
"type" : "normal",
"source" : "macro_str_esc.v",
"gold" : "macro_str_esc"
}
This description file contains all the information that the vvp_reg.py script
needs to run the regression test. The sections below describe the keys and
values in the description file dictionary.
source (required)
^^^^^^^^^^^^^^^^^
This specifies the name of the source file. The file is actually to be found
in the ivltests/ directory.
type (required)
^^^^^^^^^^^^^^^
This describes the kind of test to run. The valid values are:
* **normal** - Compile the source using the iverilog compiler vvp target, and if
that succeeds execute it using the vvp command. If there is no gold file
specified, then look for an output line with the "PASSED" string.
* **NI** - Mark the test as not implemented. The test will be skipped without
running or reporting an error.
* **CE** - Compile, but expect the compiler to fail. This means the compiler
command process must return an error exit.
* **EF** - Compile and run, but expect the run time to fail. This means the
run time program must return an error exit.
* **TE** - This is specific to testing the vlog95 conversion and indicates the
translated code failed to compile.
gold (optional)
^^^^^^^^^^^^^^^
If this is specified, it replaces the "Passed" condition with a comparison of
the output with a gold file. The argument is the name of the gold file set,
which will be found in the "gold/" directory. The name here is actually the
basename of the gold files, with separate actual gold files for the iverilog
and vvp stderr and stdout. For example, if a "normal" test includes a gold
file, then the program is compiled and run, and the outputs are compared with
the gold file to make sure it ran properly.
The way the regression suite works, there are 4 log files created for each
test:
* foo-iverilog-stdout.log
* foo-iverilog-stderr.log
* foo-vvp-stdout.log
* foo-vvp-stderr.log
The "gold" value is the name of the gold file set. If the gold value is "foo",
Then the actual gold files are called:
* gold/foo-iverilog-stdout.gold
* gold/foo-iverilog-stderr.gold
* gold/foo-vvp-stdout.gold
* gold/foo/vvp-stderr.gold
If any of those files is empty, then the gold file doesn't need to be
present at all. The log files and the gold files are compared byte for
byte, so if the output you are getting is correct, then copy the log to
the corresponding gold, and you're done.
If the run type is "CE" or "RE", then the gold files still work, and can
be used to check that the error message is correct. If the gold file setting
is present, the error return is required, and also the gold files must match.
iverilog-args (optional)
^^^^^^^^^^^^^^^^^^^^^^^^
If this is specified, it is a list of strings that are passed as arguments to
the iverilog command line.
vvp-args (optional)
^^^^^^^^^^^^^^^^^^^^
If this is specified, it is a list of strings that are passed as arguments to
the vvp command. These arguments go before the vvp input file that is to be
run.
vvp-args-extended (optional)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If this is specified, it is a lost of strings that are passed as arguments to
the vvp command. These are extended arguments, and are placed after the vvp
input file that is being run. This is where you place things like plusargs.
strict, force-sv or vlog95 (optional)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Any of these can be used to create overrides for the type, gold or
iverilog-args when the given test type is run.

View File

@ -9,24 +9,21 @@ These are the only files that have version information in them:
* verilog.spec -- Used to stamp RPM packages * verilog.spec -- Used to stamp RPM packages
When versions are changed, the above files need to be edited to account for When versions are changed, the above files need to be edited to account for
the new version information. The following used to have version information in the new version information. The following used to have verion information in
them, but now their version information is generated: them, but now their version information is generated:
The version_tag.h file is generated from git tag information using Replaced with version_base.h, which is edited manually, and
the "make version" target, or automatically if the version_tag.h version_tag.h which is generated from git tag information.
file doesn't exist at all. This implies that a "make version" is
something worth doing when you do a "git pull" or create commits.
The files below are now edited by the Makefile: * 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 * iverilog-vpi.man -- The .TH tag has a version string
* driver/iverilog.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 * driver-vpi/res.rc -- Used to build Windows version stamp
* vvp/vvp.man -- The .TH tag has a version string * vvp/vvp.man -- The .TH tag has a version string
This now includes version_base.h to get the version: This now includes version_base.h to get the version
* vpi/vams_simparam.c -- Hard coded result to simulatorVersion query * vpi/vams_simparam.c -- Hard coded result to simulatorVersion query
The test suite no longer has version specific files since it tracks along with
the code/branch.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -12,7 +12,6 @@ Welcome to the documentation for Icarus Verilog.
:maxdepth: 2 :maxdepth: 2
:caption: Contents: :caption: Contents:
releases/index
usage/index usage/index
targets/index targets/index
developer/index developer/index

View File

@ -1,10 +0,0 @@
Icarus Verilog Release Notes
============================
This section contains the release notes for all releases after and including
V13.0. Older release notes can be found here: `<https://iverilog.fandom.com/wiki/User_Guide>`__
.. toctree::
:maxdepth: 1
v13-0-release-note

View File

@ -1,98 +0,0 @@
🎉 Release V13.0
================
The Icarus Verilog development team is pleased to announce **Release V13** of Icarus Verilog.
Release V13 builds on the V12 series with a focus on correctness, runtime stability, improved
diagnostics, and incremental standard conformance improvements.
----
🐞 Bug Fix Summary
------------------
Release V13 resolves numerous issues reported against V12, including:
* Incorrect signed constant handling.
* Generate block naming collisions.
* Elaboration-time assertion failures.
* Runtime crashes in malformed corner cases.
* Memory management issues during elaboration and simulation.
----
🔄 Major Changes in V13
=======================
🧠 Language & Elaboration Fixes
-------------------------------
Release V13 includes multiple fixes to elaboration and expression handling:
* Resolved generate block scope resolution issues affecting nested and conditional generate constructs.
* Corrected signed arithmetic corner cases, including shift and width propagation behavior.
* Fixed constant expression evaluation inconsistencies during parameter elaboration.
* Improved handling of packed and unpacked arrays in assignments and port binding corner cases.
* Addressed elaboration-time assertion failures triggered by malformed or ambiguous constructs.
* Corrected several source-location reporting issues for elaboration errors.
These changes improve standards conformance and eliminate behavioral inconsistencies observed in the V12 series.
----
⚙️ Simulator (vvp) Improvements
-------------------------------
The `vvp` runtime engine has received internal stability and correctness updates:
* Improved event scheduling behavior in zero-delay and non-blocking assignment scenarios.
* Fixed race-condition corner cases uncovered by expanded regression testing.
* Eliminated memory leaks affecting long-running or large simulations.
* Resolved crash conditions caused by invalid internal state transitions.
* Improved robustness of `$dumpvars` handling in large hierarchical designs.
* General runtime consistency and determinism improvements.
`vvp` continues to enforce version matching between the runtime and generated bytecode. Designs
must be recompiled after upgrading.
----
🔌 VPI Updates
--------------
Fixes improve VPI reliability and conformance:
* Corrected hierarchical object lookup behavior in specific corner cases.
* Improved stability of callback registration during startup and shutdown.
* Fixed invalid handle dereference scenarios that could result in segmentation faults.
* Addressed inconsistencies in VPI object property reporting.
----
🛠 Diagnostics & Toolchain
--------------------------
* Improved clarity and consistency of error and warning messages.
* Better reporting of width mismatches and implicit net declarations.
* More accurate diagnostic source locations.
* Build system updates for compatibility with modern compiler toolchains.
* Regression suite expansion and CI validation improvements.
----
📦 Upgrade Notes
----------------
* Recompile all designs when upgrading from V12 or any other prior version.
* Review warnings carefully; improved diagnostics may expose previously silent issues.
* The only known breaking change is that wires must now be declared before use; which is required in the standard (see `gh1287 <https://github.com/steveicarus/iverilog/issues/1287>`__).
----
🙏 Acknowledgments
------------------
We thank all contributors who reported issues, submitted patches, expanded regression coverage, and
improved documentation. Release 13 reflects continued community effort toward improving correctness,
stability, and maintainability.

View File

@ -1,2 +0,0 @@
sphinx==8.1.3
shibuya==2026.1.9

View File

@ -3,21 +3,16 @@ The Icarus Verilog Targets
========================== ==========================
Icarus Verilog elaborates the design, then sends to the design to code Icarus Verilog elaborates the design, then sends to the design to code
generates (targets) for processing. New code generators can be added by generates (targets) for processing. new code generators can be added by
external packages, but these are the code generators that are bundled with 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. Icarus Verilog. The code generator is selected by the "-t" command line flag.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
tgt-vvp vvp
tgt-stub stub
tgt-null null
tgt-vhdl vhdl
tgt-vlog95 verilog95
tgt-pcb pcb
tgt-fpga
tgt-pal
tgt-sizer
tgt-verilog
tgt-blif

View File

@ -1,6 +1,6 @@
The PCB Code Generator (-tpcb) Using the PCB code generator
============================== ============================
The PCB target code generator is designed to allow a user to enter a netlist 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. in Verilog format, then generate input files for the GNU PCB layout program.

View File

@ -0,0 +1,7 @@
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.

View File

@ -1,8 +0,0 @@
The PAL Code Generator (-tpal)
==============================
.. warning::
This code generator is currently not included in Icarus Verilog.
The PAL target generates JEDEC output for a Programmable Array Logic.

View File

@ -1,49 +0,0 @@
The sizer Code Analyzer (-tsizer)
=================================
The sizer target does not generate any code. Instead it will print statistics about the Verilog code.
It is important to synthesize the Verilog code before invoking the sizer. This can be done with the `-S` flag passed to iverilog. Note, that behavioral code can not be synthesized and will generate a warning when passed to the sizer.
Example command::
% iverilog -o sizer.txt -tsizer -S -s top input.v
With this example code:
.. code-block:: verilog
module top (
input clock,
input reset,
output blink
);
reg out;
always @(posedge clock) begin
if (reset) begin
out = 1'b0;
end else begin
out <= !out;
end
end
assign blink = out;
endmodule
The resulting `sizer.txt` will contain::
**** module/scope: top
Flip-Flops : 1
Logic Gates : 3
MUX[2]: 1 slices
LOG[13]: 1 unaccounted
LOG[14]: 1 unaccounted
**** TOTALS
Flip-Flops : 1
Logic Gates : 3
MUX[2]: 1 slices
LOG[13]: 1 unaccounted
LOG[14]: 1 unaccounted

View File

@ -1,30 +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.
Example command::
% iverilog -o stub.txt -tstub -s top input.v
With this example code:
.. code-block:: verilog
module top;
initial $display("Hello World!");
endmodule
The resulting `stub.txt` will contain::
root module = top
scope: top (0 parameters, 0 signals, 0 logic) module top time units = 1e0
time precision = 1e0
end scope top
# There are 0 constants detected
initial
Call $display(1 parameters); /* hello_world.v:2 */
<string="Hello World!", width=96, type=bool>

View File

@ -1,6 +0,0 @@
The Verilog Code Generator (-tverilog)
======================================
.. warning::
This code generator is currently not included in Icarus Verilog.

View File

@ -1,63 +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.
Example command::
% iverilog -o top.vvp -s top hello_world.v
Equivalent command::
% iverilog -o top.vvp -tvvp -s top hello_world.v
With this example code in `hello_world.v`:
.. code-block:: verilog
module top;
initial $display("Hello World!");
endmodule
The resulting `top.vvp` will contain something similar to::
#! /usr/local/bin/vvp
:ivl_version "13.0 (devel)" "(s20221226-119-g8cb2e1a05-dirty)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision + 0;
:vpi_module "/usr/local/lib/ivl/system.vpi";
:vpi_module "/usr/local/lib/ivl/vhdl_sys.vpi";
:vpi_module "/usr/local/lib/ivl/vhdl_textio.vpi";
:vpi_module "/usr/local/lib/ivl/v2005_math.vpi";
:vpi_module "/usr/local/lib/ivl/va_math.vpi";
S_0x563c3c5d1540 .scope module, "top" "top" 2 1;
.timescale 0 0;
.scope S_0x563c3c5d1540;
T_0 ;
%vpi_call 2 2 "$display", "Hello World!" {0 0 0};
%end;
.thread T_0;
# The file index is used to find the file name in the following table.
:file_names 3;
"N/A";
"<interactive>";
"hello_world.v";
The first line contains the shebang. If this file is executed, the shebang tells the shell to use vvp for the execution of this file.
To run the simulation, execute::
% ./top.vvp
Or you can call vvp directly::
% vvp top.vvp
Next are some directives. The first one, `:ivl_version` specifies which version of iverilog this file was created with. Next is the delay selection with "min:typical:max" values and the time precision, which we did not set specifically, so the default value is used. The next lines tell vvp which VPI modules to load and in which order. The next lines tell vvp which VPI modules to load and in what order. Next, a new scope is created with the `.scope` directive and the timescale is set with `.timescale`. A thread `T_0` is created that contains two instructions: `%vpi_call` executes the VPI function `$display` with the specified arguments, and `%end` terminates the simulation.
Opcodes
-------
The various available opcodes can be seen in :doc:`Opcodes <../developer/guide/vvp/opcodes>`

View File

@ -1,6 +1,6 @@
The Verilog '95 Code Generator (-tvlog95) Using The Verilog '95 Code Generator
========================================= ====================================
Icarus Verilog contains a code generator to emit 1995 compliant Verilog from 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 the input Verilog netlist. This allows Icarus Verilog to function as a Verilog

View File

@ -0,0 +1,6 @@
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.

View File

@ -68,16 +68,6 @@ These flags affect the general behavior of the compiler.
This flag enables the IEEE1800-2012 standard, which includes This flag enables the IEEE1800-2012 standard, which includes
SystemVerilog. SystemVerilog.
* 2017
This flag enables the IEEE1800-2017 standard, which includes
SystemVerilog.
* 2023
This flag enables the IEEE1800-2023 standard, which includes
SystemVerilog.
* verilog-ams * verilog-ams
This flag enables Verilog-AMS features that are supported by Icarus This flag enables Verilog-AMS features that are supported by Icarus
@ -141,18 +131,6 @@ These flags affect the general behavior of the compiler.
containing an unsized constant number, and unsized constant numbers are containing an unsized constant number, and unsized constant numbers are
not truncated to integer width. not truncated to integer width.
* strict-declaration/no-strict-declaration
* strict-net-var-declaration/no-strict-net-var-declaration
* strict-parameter-declaration/no-strict-parameter-declaration
The standards require that nets, variables, and parameters must be
declared lexically before they are used. Using -gno-strict-declaration
will allow using a data object before declaration, with a warning. The
warning can be suppressed with -Wno-declaration-after-use. The option
can be applied for nets and variables and for parameters separately.
* shared-loop-index/no-shared-loop-index * shared-loop-index/no-shared-loop-index
Enable or disable the exclusion of for-loop control variables from Enable or disable the exclusion of for-loop control variables from
@ -282,7 +260,6 @@ These flags affect the general behavior of the compiler.
-Wanachronisms -Wanachronisms
-Wimplicit -Wimplicit
-Wimplicit-dimensions -Wimplicit-dimensions
-Wdeclaration-after-use
-Wmacro-replacement -Wmacro-replacement
-Wportbind -Wportbind
-Wselect-range -Wselect-range
@ -311,15 +288,6 @@ These flags affect the general behavior of the compiler.
This flag is supported in release 10.1 or master branch snapshots after This flag is supported in release 10.1 or master branch snapshots after
2016-02-06. 2016-02-06.
* declaration-after-use
This enables warnings for declarations after use, when those are not
flagged as errors (enabled by default). Use no-declaration-after-use
to disable this.
This flag was added in version 14.0 or later (and is in the master branch
as of 2026-03-21).
* macro-redefinition * macro-redefinition
This enables warnings when a macro is redefined, even if the macro text This enables warnings when a macro is redefined, even if the macro text

View File

@ -65,21 +65,21 @@ example, the counter model in counter.v
.. code-block:: verilog .. code-block:: verilog
module counter(out, clk, reset); module counter(output, clk, reset);
parameter WIDTH = 8; parameter WIDTH = 8;
output [WIDTH-1 : 0] out; output [WIDTH-1 : 0] output;
input clk, reset; input clk, reset;
reg [WIDTH-1 : 0] out; reg [WIDTH-1 : 0] out;
wire clk, reset; wire clk, reset;
always @(posedge clk or posedge reset) always @(posedge clk or posedge reset)
if (reset) if (reset)
out <= 0; output <= 0;
else else
out <= out + 1; output <= output + 1;
endmodule // counter endmodule // counter

View File

@ -1,32 +1,22 @@
Viewing Waveforms
=================
To view waveforms, either GTKWave or Surfer can be used. Waveforms With GTKWave
======================
GTKWave is a waveform viewer based on the GTK library. This viewer supports GTKWave is a VCD waveform viewer based on the GTK library. This viewer support
VCD, FST, LXT, and LXT2 formats for waveform dumps. GTKWave is available on GitHub VCD and LXT formats for signal dumps. GTKWAVE is available on github
`here <https://github.com/gtkwave/gtkwave>`__. Most Linux distributions already `here <https://github.com/gtkwave/gtkwave>`_. Most Linux distributions already
include gtkwave prepackaged and there are binaries for Windows available. include gtkwave prepackaged.
.. image:: GTKWave_Example2.png .. image:: GTKWave_Example2.png
Surfer is a waveform viewer based on the Rust egui library. This viewer supports Generating VCD/FST files for GTKWAVE ------------------------------------
VCD and FST formats for waveform dumps. Surfer is available on GitLab
`here <https://gitlab.com/surfer-project/surfer>`__. It runs on Windows, Linux,
and MacOS, but can also run in a `web browser <https://app.surfer-project.org/>`__
and there is a VS Code
`extension <https://marketplace.visualstudio.com/items?itemName=surfer-project.surfer>`__.
Generating waveform dump files for viewing
------------------------------------------
Waveform dumps are written by the Icarus Verilog runtime program vvp. The user 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 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 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 specified by the $dumpfile system task. If the $dumpfile call is absent, the
compiler will choose the file name dump.vcd, dump.lxt, dump.lxt2, or dump.fst, compiler will choose the file name dump.vcd or dump.lxt or dump.fst, depending
depending on runtime flags. The example below dumps everything in and below on runtime flags. The example below dumps everything in and below the test
the test module: module:
.. code-block:: verilog .. code-block:: verilog
@ -40,9 +30,9 @@ the test module:
By default, the vvp runtime will generate VCD dump output. This is the default 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 because it is the most portable. However, when using gtkwave, the FST output
format is faster and most compact. Use the "-fst", "-lxt", or "-lxt2" extended format is faster and most compact. Use the "-fst" extended argument to
argument to activate FST, LXT, or LXT2 output, respectively. For example, if activate LXT output. For example, if your compiled output is written into the
your compiled output is written into the file "foo.vvp", the command: file "foo.vvp", the command:
.. code-block:: console .. code-block:: console
@ -50,7 +40,7 @@ your compiled output is written into the file "foo.vvp", the command:
will cause the dumpfile output to be written in FST format. Absent any 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 specific $dumpfile command, this file will be called dump.fst, which can be
viewed with GTKWave using the command: viewed with the command:
.. code-block:: console .. code-block:: console
@ -115,7 +105,7 @@ Then the simulation file:
$time, value, value); $time, value, value);
endmodule // test endmodule // test
Compile, run, and view waveforms with GTKWave using these commands: Compile, run, and view waveforms with these commands:
.. code-block:: console .. code-block:: console
@ -123,6 +113,6 @@ Compile, run, and view waveforms with GTKWave using these commands:
% vvp dsn % vvp dsn
% gtkwave test.vcd & % gtkwave test.vcd &
Click on the 'test', then 'c1' in the top left box of GTKWave, then drag the 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, signals to the Signals box. You will be able to add signals to display,
scanning by scope. scanning by scope.

View File

@ -1,173 +0,0 @@
Icarus Verilog Extensions
=========================
Icarus Verilog supports certain extensions to the baseline IEEE 1364
standard. Some of these are picked from extended variants of the
language, such as SystemVerilog, and some are expressions of internal
behavior of Icarus Verilog, made available as a tool debugging aid.
Don't use any of these extensions if you want to keep your code portable
across other Verilog compilers.
System Functions
----------------
``$is_signed(<expr>)``
^^^^^^^^^^^^^^^^^^^^^^
This function returns 1 if the expression contained is signed, or 0 otherwise.
This is mostly of use for compiler regression tests.
``$bits(<expr>)``, ``$sizeof(<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`` system function is deprecated in favour of ``$bits``, which is
the same thing, but included in the SystemVerilog definition.
``$simtime()``
^^^^^^^^^^^^^^
This returns as a 64bit value the simulation time, unscaled by the time units
of the 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 IEEE 1364 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``.
System Tasks
------------
``$readmempath``
^^^^^^^^^^^^^^^^
The ``$readmemb`` and ``$readmemh`` system tasks read text files that contain
data values to populate memories. Normally, those files are found in a current
working directory. The ``$readmempath()`` system task can be used to create a
search path for those files. For example:
.. code-block:: verilog
reg [7:0] mem [0:7];
initial begin
$readmemh("datafile.txt", mem);
end
This assumes that "datafile.txt" is in the current working directory where
the ``vvp`` command is running. But with the ``$readmempath``, one can specify
a search path:
.. code-block:: verilog
reg [7:0] mem [0:7];
initial begin
$readmempath(".:alternative:/global/defaults");
$readmemh("datafile.txt", mem);
end
In this example, "datafile.txt" is searched for in each of the directories
in the above list (separated by ":" characters). The first located instance
is the one that is used. So for example, if "./datafile.txt" exists, then it
is read instead of "/global/defaults/datafile.txt" even if the latter exists.
``$finish_and_return(code)``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This task operates the same as the ``$finish`` system task, but adds the
feature of specifying an exit code for the interpreter. This can be useful in
automated test environments to indicate whether the simulation finished with
or without errors.
Extended Verilog Data Types
---------------------------
This feature is turned on by the generation flag "-gxtypes" and turned
off by the generation flag "-gno-xtypes". It is turned on by default.
Icarus Verilog adds support for extended data types. This extended
type syntax is based on a proposal by Cadence Design Systems,
originally as an update to the IEEE 1364 standard. Icarus Verilog
currently only takes the new primitive types from the proposal.
SystemVerilog provides the same functionality using somewhat different
syntax. This extension is maintained for backwards compatibility.
- Types
Extended data types separates the concept of net/variable from the
data type. Both nets and variables can declared with any data
type. The primitive types available are::
logic - The familiar 0, 1, x and z, optionally with strength.
bool - Limited to only 0 and 1
real - 64-bit real values
Nets with logic type may have multiple drivers with strength, and the
value is resolved the usual way. Only logic values may be driven to
logic nets, so bool values driven onto logic nets are implicitly
converted to logic.
Nets with any other type may not have multiple drivers. The compiler
should detect the multiple drivers and report an error.
- Declarations
The declaration of a net is extended to include the type of the wire,
with the syntax::
wire <type> <wire-assignment-list>... ;
The <type>, if omitted, is taken to be logic. The "wire" can be any of
the net keywords. Wires can be logic, bool, real, or vectors of logic
or bool. Some valid examples::
wire real foo = 1.0;
tri logic bus[31:0];
wire bool addr[23:0];
... and so on.
The declarations of variables is similar. The "reg" keyword is used to
specify that this is a variable. Variables can have the same data
types as nets.
- Ports
Module and task ports in standard Verilog are restricted to logic
types. This extension removes that restriction, allowing any of
the above types to pass through the port consistent with the
continuous assignment connectivity that is implied by the type.
- Expressions
Expressions in the face of real values is covered by the baseline
Verilog standard.
The bool type supports the same operators as the logic type, with the
obvious differences imposed by the limited domain.
Comparison operators (not case compare) return logic if either of
their operands is logic. If both are bool or real (including mix of
bool and real) then the result is bool. This is because comparison of
bools and reals always return exactly true or false.
Case comparison returns bool. This differs from baseline Verilog,
which strictly speaking returns a logic, but only 0 or 1 values.
Arithmetic operators return real if either of their operands is real,
otherwise they return logic if either of their operands is logic. If
both operands are bool, they return bool.

View File

@ -1,438 +0,0 @@
Icarus Verilog Quirks
=====================
This is a list of known quirks that are presented by Icarus Verilog. The idea
of this chapter is to call out ways that Icarus Verilog differs from the
standard, or from other implementations.
This is NOT AN EXHAUSTIVE LIST. If something is missing from this list, let us
know and we can add documentation.
Unsized Numeric Constants are Not Limited to 32 Bits
----------------------------------------------------
The Verilog standard allows Verilog implementations to limit the size of
unsized constants to a bit width of at least 32. That means that a constant
17179869183 (``36'h3_ffff_ffff``) may overflow some compilers. In fact, it
is common to limit these values to 32 bits. However, a compiler may just as
easily choose another width limit, for example 64 bits. That value is
equally good.
However, it is not required that an implementation truncate at 32 bits, and
in fact Icarus Verilog does not truncate at all. It will make the unsized
constant as big as it needs to be to hold the value accurately. This is
especially useful in situations like this;
.. code-block:: verilog
reg [width-1:0] foo = 17179869183;
The programmer wants the constant to take on the width of the reg, which in
this example is parameterized. Since constant sizes cannot be parameterized,
the programmer ideally gives an unsized constant, which the compiler then
expands/contracts to match the l-value.
Also, by choosing to not ever truncate, Icarus Verilog can handle code written
for a 64 bit compiler as easily as for a 32 bit compiler. In particular, any
constants that the user does not expect to be arbitrarily truncated by their
compiler will also not be truncated by Icarus Verilog, no matter what that
other compiler chooses as a truncation point.
Unsized Expressions
-------------------
Icarus Verilog classes any expression containing an unsized numeric constant
or unsized parameter value that is not part of a self-determined operand as
an unsized expression. When calculating the bit width of an unsized expression,
it extends the width of the expression to avoid arithmetic overflow or
underflow; in other words, the expression width will be made large enough to
represent any possible arithmetic result of the expression. If the expression
contains operations that do not follow the normal rules of arithmetic (e.g. an
explicit or implicit cast between signed and unsigned values), the expression
width will be extended to at least the width of an integer.
An exception to the above is made if the expression contains a shift or power
operator with a right hand operand that is a non-constant unsized expression.
In this case any expansion of the expression width due to that operation is
limited to the width of an integer, to avoid excessive expression widths
(without this, an expression such as ``2**(i-1)``, where ``i`` is an integer,
would be expanded to 2\**33 bits).
The above behaviour is a deviation from the Verilog standard, which states
that when calculating an expression width, the width of an unsized constant
number is the same as the width of an integer. If you need strict standard
compliance (for compatibility with other EDA tools), then the compiler has
a command line option, ``-gstrict-expr-width``, which disables the special
treatment of unsized expressions. With this option, the compiler will output
a warning message if an unsized numeric constant is encountered that cannot
be represented in integer-width bits and will truncate the value.
If you are simulating synthesisable code, it is recommended that the
``-gstrict-expr-width`` option is used, as this eliminates a potential
source of synthesis vs. simulation mismatches.
Unsized Parameters
------------------
Icarus Verilog classes any parameter declaration that has no explicit or
implicit range specification as an unsized parameter declaration. When
calculating the bit width of the final value expression for the parameter,
it follows the same rules as it does for unsized expressions, regardless of
whether or not the expression contains any unsized numeric constants.
If the final value expression for an unsized parameter is an unsized
expression (i.e. does contain unsized numeric constants), any subsequent use
of that parameter will be treated as if it was an unsized numeric constant.
If not, it will be treated as if it was a numeric constant of the appropriate
size. For example, with the declarations:
.. code-block:: verilog
localparam Value1 = 'd3 + 'd2;
localparam Value2 = 2'd3 + 2'd2;
any subsequent use of ``Value1`` will be treated as if the programmer had
written ``'d5`` and any subsequent use of ``Value2`` will be treated as if
the programmer had written ``3'd5``. In particular, note that ``Value2`` can
be used as a concatenation operand, but ``Value1`` cannot.
The above behaviour is a deviation from the Verilog standard. As for
unsized expressions, if you need strict standard compliance. use the
``-gstrict-expr-width`` compiler option.
Unsized Expressions as Arguments to Concatenation
-------------------------------------------------
The Verilog standard clearly states in 4.1.14:
"Unsized constant numbers shall not be allowed in concatenations. This
is because the size of each operand in the concatenation is needed to
calculate the complete size of the concatenation."
So for example the expression ``{1'b0, 16}`` is clearly illegal. It also stands
to reason that ``{1'b0, 15+1}`` is illegal, for exactly the same justification.
What is the size of the expression (15+1)? Furthermore, it is reasonable to
expect that (16) and (15+1) are exactly the same so far as the compiler is
concerned.
Unfortunately, Cadence seems to feel otherwise. In particular, it has been
reported that although ``{1'b0, 16}`` causes an error, ``{1'b0, 15+1}`` is
accepted. Further testing shows that any expression other than a simple
unsized constant is accepted there, even if all the operands of all the
operators that make up the expression are unsized integers.
This is a semantic problem. Icarus Verilog doesn't limit the size of integer
constants. This is valid as stated in 2.5.1 Note 3:
"The number of bits that make up an unsized number (which is a simple
decimal number or a number without the size specification) shall be
**at least** 32." [emphasis added]
Icarus Verilog will hold any integer constant, so the size will be as large as
it needs to be, whether that is 64 bits, 128 bits, or more. With this in mind,
what is the value of these expressions?
.. code-block:: verilog
{'h1_00_00_00_00}
{'h1 << 32}
{'h0_00_00_00_01 << 32}
{'h5_00_00_00_00 + 1}
These examples show that the standard is justified in requiring that the
operands of concatenation have size. The dispute is what it takes to cause
an expression to have a size, and what that size is. Verilog-XL claims that
(16) does not have a size, but (15+1) does. The size of the expression (15+1)
is the size of the adder that is created, but how wide is the adder when
adding unsized constants?
One might note that the quote from section 4.1.14 says "Unsized constant
numbers shall not be allowed." It does not say "Unsized expressions...", so
arguably accepting (15+1) or even (16+0) as an operand to a concatenation is
not a violation of the letter of the law. However, the very next sentence of
the quote expresses the intent, and accepting (15+1) as having a more defined
size then (16) seems to be a violation of that intent.
Whatever a compiler decides the size is, the user has no way to predict it,
and the compiler should not have the right to treat (15+1) any differently
then (16). Therefore, Icarus Verilog takes the position that such expressions
are unsized and are not allowed as operands to concatenations. Icarus Verilog
will in general assume that operations on unsized numbers produce unsized
results. There are exceptions when the operator itself does define a size,
such as the comparison operators or the reduction operators. Icarus Verilog
will generate appropriate error messages.
Scope of Macro Defines Doesn't Extend into Libraries
----------------------------------------------------
Icarus Verilog does preprocess modules that are loaded from libraries via the
``-y`` mechanism to substitute macros and load includes. However, the only
macros defined during compilation of an automatically loaded library module
file are those that it defines itself (or includes) or that are defined on the
command line or in the command file. Specifically, macros defined in the non-
library source files are not remembered when the library module is loaded, and
macros defined in a library module do not escape into the rest of the design.
This is intentional. If it were otherwise, then compilation results might vary
depending on the order that libraries are loaded, and that is unacceptable.
For example, given sample library module ``a.v``:
.. code-block:: verilog
`define MACRO_A 1
module a(input x);
always @(x) $display("x=",x);
endmodule
and sample library module ``b.v``:
.. code-block:: verilog
module b(input y);
`ifdef MACRO_A
always @(y) $display("MACRO_A is defined",,y);
`else
always @(y) $display("MACRO_A is NOT defined",,y);
`endif
endmodule
If a program instantiates both of these modules, there is no way to know
which will be loaded first by the compiler, so if the definition of
``MACRO_A`` in ``a.v`` were to escape, then there is no way to predict or
control whether ``MACRO_A`` is defined when ``b.v`` is processed. So the
preprocessor processes automatic library module files as if they are in
their own compilation unit, and you can know that ``MACRO_A`` will not be
defined in ``b.v`` unless it is defined on the command line (a ``-D`` flag)
or in the command file (a ``+define+`` record.)
Of course if ``a.v`` and ``b.v`` were listed in the command file or on the
command line, then the situation is different; the order is clear. The files
are processed as if they were concatenated in the order that they are listed
on the command line. The non-library modules are all together in a main
compilation unit, and they are all processed before any library modules are
loaded.
It is said that some commercial compilers do allow macro definitions to span
library modules. That's just plain weird. However, there is a special case
that Icarus Verilog does handle. Preprocessor definitions that are made in
files explicitly listed on the command line or in the command file, do pass
into implicitly loaded library files. For example, given the source file
``x.v``:
.. code-block:: verilog
module main;
reg foo;
b dut(foo);
endmodule
`define MACRO_A
and the library module file ``b.v`` described above, the situation is well
defined, assuming the ``x.v`` file is listed on the command line or in the
command file. The library module will receive the ``MACRO_A`` definition
from the last explicitly loaded source file. The position of the define of
``MACRO_A`` in the explicitly loaded source files does not matter, as all
explicitly loaded source files are preprocessed before any library files
are loaded.
Continuous Assign L-Values Can Implicit-Define Wires
----------------------------------------------------
The IEEE 1364-2001 standard, Section 3.5, lists the cases where nets may be
implicitly created. These include:
- identifier is a module port
- identifier is passed as a port to a primitive or module
This does not seem to include continuous assignment l-values (or r-values)
so the standard does not justify allowing implicit declarations of nets by
continuous assignment.
However, it has been reported that many Verilog compilers, including the big
name tools, do allow this. So, Icarus Verilog will allow it as well, as an
extension. If ``-gxtypes`` (the default) is used, this extension is enabled.
To turn off this behavior, use the ``-gno-xtypes`` flag.
Dumping Array Words (``$dumpvars``)
-----------------------------------
Icarus has the ability to dump individual array words. They are only dumped
when explicitly passed to $dumpvars. They are not dumped by default. For
example given the following:
.. code-block:: verilog
module top;
reg [7:0] array [2:0];
initial begin
$dumpvars(0, array[0], array[1]);
...
end
endmodule
``array[0]`` and ``array[1]`` will be dumped whenever they change value. They
will be displayed as an escaped identifier and GTKWave fully supports this.
Note that this is an implicitly created escaped identifier that could conflict
with an explicitly created escaped identifier. You can automate adding the
array word by adding an index definition
.. code-block:: verilog
integer idx;
and replacing the previous $dumpvars statement with
.. code-block:: verilog
for (idx = 0; idx < 2; idx = idx + 1) $dumpvars(0, array[idx]);
This will produce the same results as the previous example, but it is much
easier to specify/change which elements are to be dumped. One important note
regarding this syntax. Most system tasks/functions keep the variable selection
(for this case it is a variable array word selection) context. If ``$dumpvars``
did this then all callback created would point to this element and would use
the same index which for the example above would have the value 2. This is
certainly not what is desired and for this special case when ``$dumpvars``
executes it uses the current index value to create a constant array selection
and that is monitored instead of the original variable selection.
Referencing Declarations Within an Unnamed Generate Block
---------------------------------------------------------
The IEEE 1364-2005 standard permits generate blocks to be unnamed, but states:
"If the generate block selected for instantiation is not named, it still
creates a scope; but the declarations within it cannot be referenced using
hierarchical names other than from within the hierarchy instantiated by the
generate block itself."
The standard later defines a scheme for automatically naming the unnamed
scopes for use with external interfaces.
Icarus Verilog implements the defined automatic naming scheme, but does not
prevent the automatically generated names being used in a hierarchical
reference. This behaviour is harmless - the automatically generated names are
guaranteed to be unique within the enclosing scope, so there is no possibility
of confusion with explicit scope names. However, to maintain code portability,
it is recommended that this behavior is not exploited.
``%g/%G`` Format Specifiers
---------------------------
In the IEEE 1364-2001 standard there is a general statement that the real
number format specifiers will use the full formatting capabilities of C.
This is then followed by an example that describes ``%10.3g``. The example
description would be correct for the ``%e`` format specifier which should
always have three fractional digits, but the ``%g`` format specifier does
not work that way. For it the ``.3`` specifies that there will be three
significant digits. What this means is that ``%g`` will always produce one
less significant digit than ``%e`` and will only match the output from ``%f``
for certain values. For example:
.. code-block:: verilog
module top_level;
real rval;
initial begin
rval = 1234567890;
$display("This is g and e: %10.3g, %10.3e.", rval, rval);
rval = 0.1234567890;
$display("This is g and f: %10.3g, %10.3f.", rval, rval);
rval = 1.234567890;
$display("This is more g and f: %10.3g, %10.3f.", rval, rval);
end
endmodule // top_level
will produce the following output:
.. code-block:: verilog
This is g and e: 1.23e+09, 1.235e+09.
This is g and f: 0.123, 0.123.
This is more g and f: 1.23, 1.235.
``%t`` Time Format Specifier Can Specify Width
----------------------------------------------
Standard Verilog does not allow width fields in the ``%t`` formats of display
strings. For example, this is illegal:
.. code-block:: verilog
$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.
``%v`` Format Specifier Can Display Vectors
-------------------------------------------
The IEEE 1364-2005 standard limits the ``%v`` specifier in display strings to
work only with a single bit. Icarus Verilog extends that to support displaying
the strength of vectors. The output is a strength specifier for each bit of the
vector, with underscore characters separating each bit, e.g. ``St0_St1_Pu1_HiZ``.
Most other tools will just print the strength of the least significant bit of
a vector, so this may give different output results for code that otherwise
works fine.
Assign/Deassign and Force/Release of Bit/Part Selects
-----------------------------------------------------
Icarus Verilog allows as an extension the assign/deassign and force/release
of variable bit and part selects in certain cases. This allows the Verilog
test bench writer to assign/deassign for example single bits of a variable
(register, etc.). Other tools will report this as an error.
``repeat`` Statement is Sign Aware
----------------------------------
The standard does not specify what to do for this case, but it does say what
a repeat event control should do. In Icarus Verilog the ``repeat`` statement
is consistent with the repeat event control definition. If the argument is
signed and is a negative value this will be treated the same as an argument
value of 0.
Built-in System Functions May Be Evaluated at Compile Time
----------------------------------------------------------
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.
``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* that 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.

View File

@ -2,7 +2,8 @@
Icarus Verilog Usage Icarus Verilog Usage
==================== ====================
This section contains documents to help support Icarus Verilog users. This section contains documents to help support developers who contribute to
Icarus Verilog.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
@ -13,13 +14,9 @@ This section contains documents to help support Icarus Verilog users.
command_line_flags command_line_flags
command_files command_files
verilog_attributes verilog_attributes
ivlpp_flags
vvp_flags vvp_flags
gtkwave
vvp_debug vvp_debug
vvp_library
vhdlpp_flags
waveform_viewer
vpi vpi
icarus_verilog_extensions ivl_target
icarus_verilog_quirks
reporting_issues reporting_issues

View File

@ -2,26 +2,24 @@
Installation Guide Installation Guide
================== ==================
Icarus Verilog may be installed from source code (either from ``git`` or a Icarus Verilog may be installed from source code, or from pre-packaged binary
released `tar/zip` file), or from pre-packaged binary distributions. If you distributions. If you don't have need for the very latest, and prepackaged
don't have a need for the very latest, and prepackaged binaries are available, binaries are available, that would be the best place to start.
that is the easiest place to start.
Installation From Source Installation From Source
------------------------ ------------------------
Icarus is developed for Unix-like environments but can also be compiled on Icarus is developed for Unix-like environments but can also be compiled on
Windows systems using the `Cygwin/MSYS2` environments or `MinGW` compilers. The Windows systems using the Cygwin environment or MinGW compilers. The following
following instructions are the common steps for obtaining the Icarus Verilog instructions are the common steps for obtaining the Icarus Verilog source,
source code, compiling, installing, and checking the compiled code is working compiling and installing. Note that there are precompiled and/or prepackaged
properly. Note that there are pre-compiled and/or prepackaged versions for a versions for a variety of systems, so if you find an appropriate packaged
variety of systems, so if you find an appropriate packaged version, then that version, then that is the easiest way to install.
is the easiest way to install.
The source code for Icarus is stored under the `git` source code control 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 system. You can use git to get the latest development head or the latest of a
a specific branch. Stable releases are placed on branches, and in particular V12 specific branch. Stable releases are placed on branches, and in particular v11
stable releases are on the branch "v12-branch" To get the development version stable releases are on the branch "v11-branch" To get the development version
of the code follow these steps:: of the code follow these steps::
% git config --global user.name "Your Name Goes Here" % git config --global user.name "Your Name Goes Here"
@ -31,7 +29,7 @@ of the code follow these steps::
The first two lines are optional and are used to tell git who you are. This 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 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 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 a directory, named iverilog, containing the source tree, and will populate
that directory with the most current source from the HEAD of the repository. that directory with the most current source from the HEAD of the repository.
Change into this directory using:: Change into this directory using::
@ -39,26 +37,19 @@ Change into this directory using::
% cd iverilog % cd iverilog
Normally, this is enough as you are now pointing at the most current Normally, this is enough as you are now pointing at the most current
development code, and you have implicitly created a branch `master` that development code, and you have implicitly created a branch "master" that
tracks the development head. However, If you want to actually be working on tracks the development head. However, If you want to actually be working on
the `v12-branch` (the branch where the latest V12 patches are) then you the v11-branch (the branch where the latest v11 patches are) then you checkout
checkout that branch with the command:: that branch with the command::
% git checkout --track -b v12-branch origin/v12-branch % git checkout --track -b v11-branch origin/v11-branch
This creates a local branch that tracks the `v12-branch` in the repository, and This creates a local branch that tracks the v11-branch in the repository, and
switches you over to your new `v12-branch`. The tracking is important as it 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 causes pulls from the repository to re-merge your local branch with the remote
`v12-branch`. You always work on a local branch, then merge only when you v11-branch. You always work on a local branch, then merge only when you
push/pull from the remote repository. push/pull from the remote repository.
The choice between the development branch and the latest released branch
depends on your stability requirements. The released branch will only get bug
fixes. It will not get any enhancements or changes in the compiler output
format. Unlike many project the development branch is fairly stable with only
occasional periods of instability. We do most of our big changes in side
branches and only merge them into the development branch when they are clean.
Now that you've cloned the repository and optionally selected the branch you 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 want to work on, your local source tree may later be synced up with the
development source by using the git command:: development source by using the git command::
@ -68,33 +59,22 @@ development source by using the git command::
The git system remembers the repository that it was cloned from, so you don't The git system remembers the repository that it was cloned from, so you don't
need to re-enter it when you pull. need to re-enter it when you pull.
To build the `configure` script and hash files you need to run the Finally, configuration files are built by the extra step::
following::
% sh autoconf.sh % sh autoconf.sh
% cd ..
This is not need for the released `tar/zip` files since they already contain The source is then compiled as appropriate for your system. See the specific
these files. You only need to run this once after cloning. If you are missing build instructions below for your operation system for what to do next.
``autoconf`` or ``gperf`` then the script will fail::
You will need autoconf and gperf installed in order for the script to work.
If you get errors such as::
Autoconf in root... Autoconf in root...
autoconf.sh: 10: autoconf: not found autoconf.sh: 10: autoconf: not found
Precompiling lexor_keyword.gperf Precompiling lexor_keyword.gperf
autoconf.sh: 13: gperf: not found. autoconf.sh: 13: gperf: not found.
You will need to install the ``autoconf`` and ``gperf`` tools before you can You will need to install download and install the autoconf and gperf tools.
continue.
The other way to get the source code is to download a released `tar/zip` file::
% tar -xvzf v13_0.tar.gz
or
% unzip v13_0.zip
See the build instructions for your operation system below to know what to do
next. Though first determine if there are any extra configuration option you
may need.
Icarus Specific Configuration Options Icarus Specific Configuration Options
------------------------------------- -------------------------------------
@ -113,215 +93,37 @@ 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 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 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 a compatible version e.g.(you can not run a V0.9 file with the V0.8 run
time).:: time). ::
--with-valgrind --with-valgrind
This option adds extra memory cleanup code and pool management code to allow 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 better memory leak checking when valgrind is available. This option is not
needed when checking for basic errors with valgrind and should not be used if need when checking for basic errors with valgrind.
you just intend to use ``iverilog`` as a simulator. ::
--enable-libvvp
The vvp program is built as a small stub linked to a shared library,
libvvp.so, that may be linked with other programs so that they can host
a vvp simulation. ::
--enable-libveriuser
PLI version 1 (the ACC and TF routines) were deprecated in IEEE 1364-2005.
These are supported in Icarus Verilog by the libveriuser library and cadpli
module. Starting with V13, these will only be built if this option is used.
Compiling on Linux/Unix Compiling on Linux/Unix
----------------------- -----------------------
Note: For a gcc compile you will need to install ``bison``, ``flex``, ``g++``, (Note: You will need to install bison, flex, g++ and gcc) This is probably the
``gcc`` and preferably `bz2`, `zlib` and `readline` development packages. The easiest case. Given that you have the source tree from the above instructions,
`bz2` and `zlib` development packages are required for the non-VCD waveform the compile and install is generally as simple as::
dumpers and the `readline` development package is needed to enable better
terminal control in the ``vvp`` interactive mode.
If you are only compiling one variant then you can compile directly in the % ./configure
source tree. If you need multiple variants (optimized, debugging, multiple % make
compilers) then it is recommended you compile each in their own directory. (su to root)
# make install
For multiple variants create a directory for each of the variants you intend The "make install" typically needs to be done as root so that it can install
to create and in each run the following steps, adjusting the options in the in directories such as "/usr/local/bin" etc. You can change where you want to
configure stage to get the functionality you want. For a single build you can install by passing a prefix to the "configure" command::
either build it with the source or in a separate build directory.
The following is from a Ubuntu 22.04 machine using gcc (version 11.4):: % ./configure --prefix=/my/special/directory
% mkdir gcc This will configure the source for eventual installation in the directory that
% cd gcc you specify. Note that "rpm" packages of binaries for Linux are typically
or configured with "--prefix=/usr" per the Linux File System Standard.
% cd iverilog
You can also use ``clang/clang++``. I usual build optimized version for Make sure you have the latest version of flex otherwise you will get an error
normal use and reserve debugging options for a valgrind or a separate
debugging build. Make sure you have `sudo` permission if you are using a
system prefix area, otherwise you need to use some place you have
permission to install (e.g. ~/).::
% env CFLAGS=-O2 CXXFLAGS=-O2 LDFLAGS=-s CC=gcc CXX=g++ ../iverilog/configure --enable-suffix=-gcc --prefix=/usr/local
This will generate the following (with some inline comments)::
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking for gcc... gcc
checking whether the C compiler works... yes
...
checking for gperf... gperf # required for git builds
checking for man... man # you likely want manual pages
checking for ps2pdf... ps2pdf
checking for groff... groff
checking for git... git # required for git builds
checking for flex... flex # required
checking for bison... bison # required
...
checking for tputs in -ltermcap... yes
checking for readline in -lreadline... yes
checking for add_history in -lreadline... yes
checking for readline/readline.h... yes
checking for readline/history.h... yes # you likely want this
...
checking for pthread_create in -lpthread... yes
checking for gzwrite in -lz... yes
checking for gzwrite in -lz... (cached) yes
checking for BZ2_bzdopen in -lbz2... yes
checking for BZ2_bzdopen in -lbz2... (cached) yes # you want these for fst dumping
...
<Create all the parameterized Makefile and header files>
Usually if ``configure`` fails there is some required dependency missing. I
usually review all the output to make sure it makes sense (e.g. I requested
``gcc`` and that's what is being used, other things match my expectation). If
all the waveform dumpers are not enabled there could be a few test failures.
Next we need to compile the code. Note: make sure you are using GNU make.
It may be named gmake (e.g. GhostBSD)::
% make check >& make.log
This is for a tcsh/csh shell. Bash/fish/zsh use ``&>`` instead of ``>&``.
Once this has completed check the make.log for any errors. There should not
be any! I also check for warnings. There are often some related to the
output from bison. For example::
From: ./parse.cc
parse.cc:9462:18: warning: missing initializer for member vlltype::lexical_pos [-Wmissing-field-initializers]
9462 | = { 1, 1, 1, 1 }
| ^
parse.cc:9462:18: warning: missing initializer for member vlltype::text [-Wmissing-field-initializers]
and::
From: ./vvp/parse.cc
parse.cc:3242: warning: suspicious sequence in the output: m4_type [-Wother]
parse.cc:3248: warning: suspicious sequence in the output: m4_type [-Wother]
Are common, but benign warnings. Different compilers or compiler versions may
have other warnings.
The expected last few lines of the make.log file and these indicate everything
should be working as expected are::
...
driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp ../iverilog/examples/hello.vl
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
Hello, World
If everything is good to this point and you are installing into a system
prefix; install using ``sudo`` as shown below. If you are installing into a
personal location skip the ``sudo``::
% sudo make install
Now you should verify the regression test suite is working as expected::
% cd ../iverilog/ivtest
% ./vvp_reg.pl --suffix=-gcc
This is the original test script and should give no failures::
Running compiler/VVP tests for Icarus Verilog version: 13, suffix: -gcc.
----------------------------------------------------------------------------
macro_with_args: Passed.
mcl1: Passed.
pr622: Passed.
pr639: Passed.
...
ssetclr2: Passed.
ssetclr3: Passed.
synth_if_no_else: Passed.
ufuncsynth1: Passed.
============================================================================
Test results:
Total=3018, Passed=3013, Failed=0, Not Implemented=2, Expected Fail=3
Next run the new test script::
% ./vvp_reg.py --suffix=-gcc
This should also give no failures::
Running compiler/VVP tests for Icarus Verilog version: 13, suffix: -gcc
Using list(s): regress-vvp.list
----------------------------------------------------------------------------
always4A: Passed - CE.
always4B: Passed - CE.
analog1: Not Implemented.
analog2: Not Implemented.
...
vvp_quiet_mode: Passed.
warn_opt_sys_tf: Passed - EF.
wreal: Passed.
writemem-invalid: Passed - EF.
============================================================================
Test results: Ran 284, Failed 0.
Finally you can check that the VPI is working properly using::
% ./vpi_reg.pl --suffix=-gcc
The output for this should have no failures::
Running VPI tests for Icarus Verilog version: 13, suffix: -gcc.
----------------------------------------------------------------------------
br_gh59: Passed.
br_gh73a: Passed.
br_gh73b: Passed.
br_gh117: Passed.
...
value_change_cb2: Passed.
value_change_cb3: Passed.
value_change_cb4: Passed.
vpi_control: Passed.
============================================================================
Test results: Total=77, Passed=77, Failed=0, Not Implemented=0
You can uninstall everything using the following. If needed skip the ``sudo``
as described in the install description above.::
% sudo make uninstall
You can cleanup the compile directory using::
% make clean
or
% make distclean
The first just cleans up just the compiled files, etc. The later cleans up
the compiled file along with all the files generated in the ``configure``
phase.
Note that "rpm" packages of binaries for Linux are typically configured with
"--prefix=/usr" per the Linux File System Standard.
Make sure you have a recent version of flex otherwise you will get an error
when parsing lexor.lex. when parsing lexor.lex.
Compiling on Macintosh OS X Compiling on Macintosh OS X
@ -342,36 +144,3 @@ be updated to version 3. ::
Icarus Verilog is also available through the Homebrew package manager: "brew Icarus Verilog is also available through the Homebrew package manager: "brew
install icarus-verilog". install icarus-verilog".
Cross-Compiling for Windows
---------------------------
The `Cygwin` and `MSYS2` environments can compile Icarus Verilog as described
above for `Linux/Unix`. There is a `MSYS2` build recipe which can be found in
the `msys2/` directory. The accompanying README file provides further details.
`MSYS2` is typically preferred over `Cygwin` since ``GTKWave`` and Icarus
Verilog are both provided as pre-compiled packages.
What follows are older instructions for building Icarus Verilog binaries for
Windows using mingw cross compiler tools on Linux.
To start with, you need the mingw64-cross-* packages for your linux
distribution, which gives you the x86_64-w64-mingw32-* commands
installed on your system. Installing the cross environment is outside
the scope of this writeup.
First, configure with this command::
$ ./configure --host=x86_64-w64-mingw32
This generates the Makefiles needed to cross compile everything with
the mingw32 compiler. The configure script will generate the command
name paths, so long as commands line x86_64-w64-mingw32-gcc
et. al. are in your path.
Next, compile with the command::
$ make
The configure generated the cross compiler flags. The
configure script should have gotten all that right.

View File

@ -1,6 +1,6 @@
Loadable Target API (ivl_target) Loadable Target API (ivl_target.h)
================================ ==================================
In addition to the standard VPI API, Icarus Verilog supports a non-standard 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 loadable target module API. This API helps C programmers write modules that
@ -104,28 +104,3 @@ Installing the Target Module
Finally, the "empty.conf", the "empty-s.conf" and the "empty.tgt" files need 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 to be installed. Where they go depends on your system, but in Linux they are
normally installed in "/usr/lib/ivl". normally installed in "/usr/lib/ivl".
LPM Devices
-----------
All LPM devices support a small set of common LPM functions, as
described in the ivl_target header file. The ivl_lpm_t object has a
type enumerated by ivl_lpm_type_t, and that type is accessible via the
ivl_lpm_type function.
The following are type specific aspects of LPM devices.
* IVL_LPM_UFUNC
This LPM represents a user defined function. It is a way to connect
behavioral code into a structural network. The UFUNC device has a
vector output and a set of inputs. The ivl_lpm_define function returns
the definition as an ivl_scope_t object.
The output vector is accessible through the ivl_lpm_q, and the output
has the width defined by ivl_lpm_width. This similar to most every
other LPM device with outputs.
There are ivl_lpm_size() input ports, each with the width
ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2().

View File

@ -2,43 +2,25 @@
Reporting Issues Reporting Issues
================ ================
The developers of and contributors to Icarus Verilog use github to track 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 issues and to create patches for the product. If you believe you have found a
problem, use the Issues tracker at the problem, use the Issues tracker at the
`Icarus Verilog github page <https://github.com/steveicarus/iverilog>`__. `Icarus Verilog github page <https://github.com/steveicarus/iverilog>`_.
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.
On the main page, you will find a row of selections near the top. Click the 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 `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 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 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 issue, and to write a detailed description of your issue. Please include
enough information that anyone who sees your issue can understand and enough information that anyone who sees your issue can understand and
reproduce it. reproduce it.
Good Issue Reporting
--------------------
Before an error can be fixed, one needs 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.
One key characteristic of a well reported issue is a small sample program that 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 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 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 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. issue will be far more likely to be addressed.
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
Be prepared to have a conversation about your issue. More often then you would 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 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, looking into your issue may point out a bug in your code. You learn something,
@ -53,24 +35,3 @@ 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 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. of grief, and again you increase the odds that your issue will be addressed.
How To Create A Pull Request
----------------------------
Bug reports with patches/PRs are very welcome. Please also add a new test case in the regression test suite to prevent the bug from reappearing.
If you are editing the source, you should be using the latest
version from git. Please see the developer documentation for more
detailed instructions -- :doc:`Getting Started as a Contributor <getting_started>` .
COPYRIGHT ISSUES
Icarus Verilog is Copyright (c) 1998-2024 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
be considered independently copyrightable, it's yours and I encourage
you to claim it with appropriate copyright notices. This submission
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.

View File

@ -42,7 +42,7 @@ 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 each of the functions in the table in order. The following simple C definition
defines a sample table:: defines a sample table::
void (*vlog_startup_routines[])(void) = { void (*vlog_startup_routines[])() = {
hello_register, hello_register,
0 0
}; };
@ -89,18 +89,16 @@ file hello.c::
static int hello_compiletf(char*user_data) static int hello_compiletf(char*user_data)
{ {
(void)user_data; // Avoid a warning since user_data is not used.
return 0; return 0;
} }
static int hello_calltf(char*user_data) static int hello_calltf(char*user_data)
{ {
(void)user_data; // Avoid a warning since user_data is not used.
vpi_printf("Hello, World!\n"); vpi_printf("Hello, World!\n");
return 0; return 0;
} }
void hello_register(void) void hello_register()
{ {
s_vpi_systf_data tf_data; s_vpi_systf_data tf_data;
@ -113,7 +111,7 @@ file hello.c::
vpi_register_systf(&tf_data); vpi_register_systf(&tf_data);
} }
void (*vlog_startup_routines[])(void) = { void (*vlog_startup_routines[])() = {
hello_register, hello_register,
0 0
}; };

View File

@ -1,4 +1,4 @@
VVP Interactive Mode Vvp Interactive Mode
==================== ====================
The vvp command has an interactive debug mode, where you can stop the The vvp command has an interactive debug mode, where you can stop the

View File

@ -14,10 +14,6 @@ These options/flags go before the path to the vvp-executable program. They
effect behavior of the vvp runtime engine, including preparation for effect behavior of the vvp runtime engine, including preparation for
simulation. simulation.
* -i
This flag causes all output to <stdout> to be unbuffered.
* -l<logfile> * -l<logfile>
This flag specifies a logfile where all MCI <stdlog> output goes. Specify This flag specifies a logfile where all MCI <stdlog> output goes. Specify
@ -45,25 +41,6 @@ simulation.
determine the return types of user-defined system functions. If specified at determine the return types of user-defined system functions. If specified at
compile-time, there is no need to specify them again here. compile-time, there is no need to specify them again here.
* -n
This flag makes $stop or a <Control\-C> a synonym for $finish. It can be
used to give the program a more meaningful interface when running in a
non-interactive environment.
* -N
This flag does the same thing as "-n", but results in an exit code of 1
if the stimulation calls $stop. It can be used to indicate a simulation
failure when running a testbench.
* -q
Enable quiet mode. This suppresses all output to <stdout> sent via MCD
bit 0 (e.g. all output from $display and friends). It does not affect
output to the log file, nor does it affect output to <stdout> sent via
the STDOUT file descriptor.
* -s * -s
$stop right away, in the beginning of the simulation. This kicks the $stop right away, in the beginning of the simulation. This kicks the
@ -74,10 +51,6 @@ simulation.
Show verbose progress while setting up or cleaning up the runtime Show verbose progress while setting up or cleaning up the runtime
engine. This also displays some performance information. engine. This also displays some performance information.
* -V
Print the version of the runtime, and exit.
Extended Arguments Extended Arguments
------------------ ------------------
@ -86,9 +59,6 @@ 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 start with a "+" character are left for use by the user via the $plus$flag and
$plus$value functions. $plus$value functions.
NOTE: The extended arguments must appear *after* the input file name on the
command line.
VCD/FST/LXT Arguments VCD/FST/LXT Arguments
^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
@ -105,20 +75,13 @@ behavior.
* -fst * -fst
Generate FST format outputs instead of VCD format waveform dumps. This is Generate FST format outputs instead of VCD format waveform dumps. This is
the preferred output format if using GTKWave or Surfer for viewing waveforms. the preferred output format if using GTKWave for viewing waveforms.
* -lxt/-lxt2 * -lxt/-lxt2
Generate LXT or LXT2format instead of VCD format waveform dumps. The LXT2 Generate LXT or LXT2format instead of VCD format waveform dumps. The LXT2
format is more advanced. format is more advanced.
* -dumpfile=<name>
Set the default dumpfile. If unspecified, the default is "dump". This
command line flag allows you do change it. If no suffix is specified,
then the suffix will be chosen based on the dump type. In any case, the
$dumpfile system task overrides this flag.
SDF Support SDF Support
^^^^^^^^^^^ ^^^^^^^^^^^
@ -143,3 +106,4 @@ Environment Variables
The vvp program pays attention to certain environment variables. The vvp program pays attention to certain environment variables.
* IVERILOG_DUMPER * IVERILOG_DUMPER

View File

@ -1,29 +0,0 @@
VVP as a library
================
If configured with ::
--enable-libvvp
the vvp program will be built as a small stub that
depends on a shared library, libvvp.so.
The library may also be used to include a vvp simulation
in a larger program. Typically, the simulation communicates
with its host program using VPI, but since
almost all the functions of vvp are included in the library
it may be possible to use text output and interactive mode.
The accessible functions of the library are defined and documented
in the header file, vvp/libvvp.h. Although vvp is a C++ program, the
header file presents a C interface.
Note that the vvp software was not designed to be used this way
and the library is a straightforward recompilation of the program code.
That imposes some restrictions, mostly arising from the use
of static variables: only a single run of a single simulation instance
can be expected to work without special actions.
To mitigate these restrictions, the library may by loaded dynamically
and unloaded at the end of each simulation run.
Parallel simulation should be possible by making multiple copies
of the library with different names.

180
INSTALL
View File

@ -1,59 +1,52 @@
Basic Installation Basic Installation
================== ==================
These are generic installation instructions, with minor updates These are generic installation instructions.
for the `iverilog` project.
Instructions in the `README` are more concise for this project. The `configure' shell script attempts to guess correct values for
The `configure` shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses various system-dependent variables used during compilation. It uses
those values to create a `Makefile` in each directory of the package. those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h` files containing system-dependent It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status` that definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file you can run in the future to recreate the current configuration, a file
`config.cache` that saves the results of its tests to speed up `config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log` containing compiler output reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure`). (useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try If you need to do unusual things to compile the package, please try
to figure out how `configure` could check whether to do them, and mail to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README` so they can 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` 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. 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 The file `configure.ac' is used to create `configure' by a program
called `autoconf`. You only need `configure.ac` if you want to change called `autoconf'. You only need `configure.ac' if you want to change
it or regenerate `configure` using a newer version of `autoconf`. it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is: The simplest way to compile this package is:
1. `cd` to the directory containing the package's source code. 1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
2. Run `sh autoconf.sh`, if building from source (and not a release). Running `configure' takes awhile. While running, it prints some
If you're building from a release, skip this step.
3. Run `./configure` to configure the package for your system. If you're
using `csh` on an old version of System V, you might need to type
`sh ./configure` instead to prevent `csh` from trying to execute
`configure` itself.
Running `configure` takes awhile. While running, it prints some
messages telling which features it is checking for. messages telling which features it is checking for.
4. Type `make` to compile the package. 2. Type `make' to compile the package.
5. Optionally, type `make check` to run any self-tests that come with 3. Optionally, type `make check' to run any self-tests that come with
the package. the package.
6. Type `make install` to install the programs and any data files and 4. Type `make install' to install the programs and any data files and
documentation. You may need to use `sudo`. documentation.
7. You can remove the program binaries and object files from the 5. You can remove the program binaries and object files from the
source code directory by typing `make clean`. To also remove the source code directory by typing `make clean'. To also remove the
files that `configure` created (so you can compile the package for files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean`. There is a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean` target, but that is intended mainly also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came all sorts of other programs in order to regenerate files that came
with the distribution. with the distribution.
@ -62,131 +55,126 @@ Compilers and Options
===================== =====================
Some systems require unusual options for compilation or linking that Some systems require unusual options for compilation or linking that
the `configure` script does not know about. You can give `configure` the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like a Bourne-compatible shell, you can do that on the command line like
this: this:
```bash
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
```
Or on systems that have the `env` program, you can do it like this: Or on systems that have the `env' program, you can do it like this:
```bash
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
```
Compiling For Multiple Architectures Compiling For Multiple Architectures
==================================== ====================================
You can compile the package for more than one kind of computer at the You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make` that own directory. To do this, you must use a version of `make' that
supports the `VPATH` variable, such as GNU `make`. `cd` to the supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run directory where you want the object files and executables to go and run
the `configure` script. `configure` automatically checks for the the `configure' script. `configure' automatically checks for the
source code in the directory that `configure` is in and in `..`. source code in the directory that `configure' is in and in `..'.
If you have to use a `make` that does not supports the `VPATH` If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for in the source code directory. After you have installed the package for
one architecture, use `make distclean` before reconfiguring for another one architecture, use `make distclean' before reconfiguring for another
architecture. architecture.
Installation Names Installation Names
================== ==================
By default, `make install` will install the package's files in By default, `make install' will install the package's files in
`/usr/local/bin`, `/usr/local/man`, etc. You can specify an `/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local` by giving `configure` the installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH`. option `--prefix=PATH'.
You can specify separate installation prefixes for You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you architecture-specific files and architecture-independent files. If you
give `configure` the option `--exec-prefix=PATH`, the package will use give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries. PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix. Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH` to specify different values for particular options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help` for a list of the directories kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure` the with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX` or `--program-suffix=SUFFIX`. option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features Optional Features
================= =================
Some packages pay attention to `--enable-FEATURE` options to Some packages pay attention to `--enable-FEATURE' options to
`configure`, where FEATURE indicates an optional part of the package. `configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE` options, where PACKAGE They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as` or `x` (for the X Window System). The is something like `gnu-as' or `x' (for the X Window System). The
`README` should mention any `--enable-` and `--with-` options that the `README' should mention any `--enable-' and `--with-' options that the
package recognizes. package recognizes.
For packages that use the X Window System, `configure` can usually For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't, find the X include and library files automatically, but if it doesn't,
you can use the `configure` options `--x-includes=DIR` and you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR` to specify their locations. `--x-libraries=DIR' to specify their locations.
Specifying the System Type Specifying the System Type
========================== ==========================
There may be some features `configure` can not figure out There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package automatically, but needs to determine by the type of host the package
will run on. Usually `configure` can figure that out, but if it prints will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the a message saying it can not guess the host type, give it the
`--host=TYPE` option. TYPE can either be a short name for the system `--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4`, or a canonical name with three fields: type, such as `sun4', or a canonical name with three fields:
`CPU-COMPANY-SYSTEM` CPU-COMPANY-SYSTEM
See the file `config.sub` for the possible values of each field. If See the file `config.sub' for the possible values of each field. If
`config.sub` isn't included in this package, then this package doesn't `config.sub' isn't included in this package, then this package doesn't
need to know the host type. need to know the host type.
If you are building compiler tools for cross-compiling, you can also If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE` option to select the type of system they will use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE` option to select the type of produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package. system on which you are compiling the package.
Sharing Defaults Sharing Defaults
================ ================
If you want to set default values for `configure` scripts to share, If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site` that gives you can create a site shell script called `config.site' that gives
default values for variables like `CC`, `cache_file`, and `prefix`. default values for variables like `CC', `cache_file', and `prefix'.
`configure` looks for `PREFIX/share/config.site` if it exists, then `configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site` if it exists. Or, you can set the `PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE` environment variable to the location of the site script. `CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure` scripts look for a site script. A warning: not all `configure' scripts look for a site script.
Operation Controls Operation Controls
================== ==================
`configure` recognizes the following options to control how it `configure' recognizes the following options to control how it
operates. operates.
`--cache-file=FILE` `--cache-file=FILE'
Use and save the results of the tests in FILE instead of Use and save the results of the tests in FILE instead of
`./config.cache`. Set FILE to `/dev/null` to disable caching, for `./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure`. debugging `configure'.
`--help` `--help'
Print a summary of the options to `configure`, and exit. Print a summary of the options to `configure', and exit.
`--quiet` `--quiet'
`--silent` `--silent'
`-q` `-q'
Do not print messages saying which checks are being made. Do not print messages saying which checks are being made.
`--srcdir=DIR` `--srcdir=DIR'
Look for the package's source code in directory DIR. Usually Look for the package's source code in directory DIR. Usually
`configure` can determine that directory automatically. `configure' can determine that directory automatically.
`--version` `--version'
Print the version of Autoconf used to generate the `configure` Print the version of Autoconf used to generate the `configure'
script, and exit. script, and exit.
`configure` also accepts some other, not widely useful, options. `configure' also accepts some other, not widely useful, options.

View File

@ -36,22 +36,17 @@ prefix = @prefix@
exec_prefix = @exec_prefix@ exec_prefix = @exec_prefix@
srcdir = @srcdir@ srcdir = @srcdir@
datarootdir = @datarootdir@ datarootdir = @datarootdir@
VERSION_MAJOR = @VERSION_MAJOR@
VERSION_MINOR = @VERSION_MINOR@
SUBDIRS = ivlpp vhdlpp vvp vpi tgt-null tgt-stub tgt-vvp \ SUBDIRS = ivlpp vhdlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver \ tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver
ivtest
# Only run distclean for these directories. # Only run distclean for these directories.
NOTUSED = tgt-fpga tgt-pal tgt-verilog NOTUSED = tgt-fpga tgt-pal tgt-verilog
ifeq (@LIBVERIUSER@,yes) ifeq (@MINGW32@,yes)
SUBDIRS += libveriuser cadpli
else
NOTUSED += libveriuser cadpli
endif
SUBDIRS += driver-vpi SUBDIRS += driver-vpi
else
NOTUSED += driver-vpi
endif
# To get the version headers to build correctly we only want to look # 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 # for C++ files in the source directory. All other files will require
@ -66,7 +61,8 @@ bindir = @bindir@
libdir = @libdir@ libdir = @libdir@
# This is actually the directory where we install our own header files. # This is actually the directory where we install our own header files.
# It is a little different from the generic includedir. # It is a little different from the generic includedir.
ivl_includedir = @includedir@/iverilog$(suffix) includedir = @includedir@/iverilog$(suffix)
mandir = @mandir@
dllib=@DLLIB@ dllib=@DLLIB@
@ -76,19 +72,16 @@ HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
BUILDCC = @CC_FOR_BUILD@ BUILDCC = @CC_FOR_BUILD@
BUILDEXT = @BUILD_EXEEXT@ BUILDEXT = @BUILD_EXEEXT@
CC = @CC@
CXX = @CXX@ CXX = @CXX@
ENV_VVP=@ENV_VVP@ DLLTOOL = @DLLTOOL@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
LEX = @LEX@ LEX = @LEX@
YACC = @YACC@ YACC = @YACC@
YACC_CONFLICT_FLAGS = -Werror=conflicts-sr -Werror=conflicts-rr
MAN = @MAN@ MAN = @MAN@
PS2PDF = @PS2PDF@ PS2PDF = @PS2PDF@
GROFF = @GROFF@
GIT = @GIT@ GIT = @GIT@
ifeq (@srcdir@,.) ifeq (@srcdir@,.)
@ -121,16 +114,15 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
net_event.o net_expr.o net_func.o \ net_event.o net_expr.o net_func.o \
net_func_eval.o net_link.o net_modulo.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_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
net_udp.o map_named_args.o \ net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.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_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
pform_types.o \ pform_types.o \
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o vpi_modules.o target.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 \ 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 PTimingCheck.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) PTask.o PUdp.o PWire.o Statement.o AStatement.o $M $(FF) $(TT)
all: dep config.h _pli_types.h version_tag.h version_base.h ivl@EXEEXT@ all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
# In the windows world, the installer will need a dosify program to # In the windows world, the installer will need a dosify program to
@ -138,29 +130,37 @@ all: dep config.h _pli_types.h version_tag.h version_base.h ivl@EXEEXT@
ifeq (@MINGW32@,yes) ifeq (@MINGW32@,yes)
all: dosify$(BUILDEXT) all: dosify$(BUILDEXT)
dosify$(BUILDEXT): $(srcdir)/dosify.c dosify$(BUILDEXT): $(srcdir)/dosify.c
$(BUILDCC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c $(BUILDCC) $(CFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c
endif endif
# This rule runs the compiler using the trivial hello.vl program to make sure # This rule rules the compiler in the trivial hello.vl program to make
# the base programs are compiled properly. # sure the basics were compiled properly.
check: all check: all
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
rm -f check.vvp
test -r check.conf || cp $(srcdir)/check.conf . test -r check.conf || cp $(srcdir)/check.conf .
driver/iverilog@EXEEXT@ -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl && \ driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
$(ENV_VVP) vvp/vvp$(suffix)@EXEEXT@ -M- -M./vpi ./check.vvp | grep 'Hello, World' ifeq (@WIN32@,yes)
ifeq (@install_suffix@,)
check-installed check-installed-vpi check-installed-vvp check-installed-vvp-py: vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
$(MAKE) -C ivtest $@ 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: clean:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
rm -f *.o parse.cc parse.h lexor.cc rm -f *.o parse.cc parse.h lexor.cc
rm -f ivl.exp rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps
rm -f iverilog_man.ps iverilog_man.pdf iverilog_man_$(VERSION_MAJOR)_$(VERSION_MINOR).pdf
rm -f parse.output syn-rules.output dosify$(BUILDEXT) ivl@EXEEXT@ check.vvp rm -f parse.output syn-rules.output dosify$(BUILDEXT) ivl@EXEEXT@ check.vvp
rm -f lexor_keyword.cc libivl.a libvpi.a syn-rules.cc rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
rm -rf dep rm -rf dep
rm -f version.exe
distclean: clean distclean: clean
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@ -168,17 +168,14 @@ distclean: clean
rm -f Makefile config.status config.log config.cache rm -f Makefile config.status config.log config.cache
rm -f stamp-config-h config.h rm -f stamp-config-h config.h
rm -f stamp-_pli_types-h _pli_types.h rm -f stamp-_pli_types-h _pli_types.h
rm -f stamp-version_base-h version_base.h
ifneq (@srcdir@,.) ifneq (@srcdir@,.)
rm -f version_tag.h check.conf rm -f version_tag.h check.conf
rmdir $(SUBDIRS) $(NOTUSED) rmdir $(SUBDIRS) $(NOTUSED)
endif endif
rm -rf autom4te.cache rm -rf autom4te.cache
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c
cppcheck --enable=all --std=c99 --std=c++11 -f \ cppcheck --enable=all --std=c99 --std=c++03 -f \
--check-level=exhaustive \
--suppressions-list=$(srcdir)/cppcheck-global.sup \
--suppressions-list=$(srcdir)/cppcheck.sup \ --suppressions-list=$(srcdir)/cppcheck.sup \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \ -UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \ -UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
@ -206,11 +203,6 @@ stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
./config.status _pli_types.h ./config.status _pli_types.h
_pli_types.h: stamp-_pli_types-h _pli_types.h: stamp-_pli_types-h
stamp-version_base-h: $(srcdir)/version_base.h.in config.status
@rm -f $@
./config.status version_base.h
version_base.h: stamp-version_base-h
$(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/aclocal.m4 $(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/aclocal.m4
cd $(srcdir) && autoconf cd $(srcdir) && autoconf
@ -219,17 +211,40 @@ config.status: $(srcdir)/configure
./config.status ./config.status
ifeq (@WIN32@,yes) ifeq (@WIN32@,yes)
# Under Windows we need to create an import library to allow the target code # Under Windows (mingw) I need to make the ivl.exe in two steps.
# generators to access the items exported by ivl.exe. The .def file controls # The first step makes an ivl.exe that dlltool can use to make an
# what is visible in the import library. # export and import library, and the last link makes a, ivl.exe
# that really exports the things that the import library imports.
ivl@EXEEXT@: $O $(srcdir)/ivl.def ivl@EXEEXT@: $O $(srcdir)/ivl.def
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ -Wl,--out-implib=libivl.a $(srcdir)/ivl.def $O $(dllib) @EXTRALIBS@ $(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
$(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 else
ivl@EXEEXT@: $O ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib) $(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif endif
%.o: %.cc config.h | dep ifeq (@MINGW32@,no)
all: iverilog-vpi
iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@SUFFIX@;$(suffix);' \
-e 's;@IVCC@;$(CC);' \
-e 's;@IVCXX@;$(CXX);' \
-e 's;@IVCFLAGS@;$(CFLAGS);' \
-e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \
-e 's;@IVCTARGETFLAGS@;$(CTARGETFLAGS);' \
-e 's;@INCLUDEDIR@;$(includedir);' \
-e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
$(BUILDCC) $(CFLAGS) -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
%.o: %.cc config.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep/$*.d mv $*.d dep/$*.d
@ -242,10 +257,10 @@ parse.o: parse.cc
# Use pattern rules to avoid parallel build issues (see pr3462585) # Use pattern rules to avoid parallel build issues (see pr3462585)
parse%cc parse%h: $(srcdir)/parse%y parse%cc parse%h: $(srcdir)/parse%y
$(YACC) --verbose $(YACC_CONFLICT_FLAGS) -t -p VL --defines=parse.h -o parse.cc $< $(YACC) --verbose -t -p VL --defines=parse.h -o parse.cc $<
syn-rules.cc: $(srcdir)/syn-rules.y syn-rules.cc: $(srcdir)/syn-rules.y
$(YACC) --verbose $(YACC_CONFLICT_FLAGS) -t -p syn_ -o $@ $< $(YACC) --verbose -t -p syn_ -o $@ $<
lexor.cc: $(srcdir)/lexor.lex lexor.cc: $(srcdir)/lexor.lex
$(LEX) -s -t $< > $@ $(LEX) -s -t $< > $@
@ -253,17 +268,20 @@ lexor.cc: $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc parse.h lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
gperf -o -i 7 -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $< > $@ || (rm -f $@ ; false) 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)
iverilog_man.ps: driver/iverilog.man vvp/vvp.man driver-vpi/iverilog-vpi.man iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
$(GROFF) -man -rC1 -rD1 -T ps $^ > $@ ./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@
tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@
iverilog_man.pdf: iverilog_man.ps iverilog-vpi.ps: iverilog-vpi.man
$(PS2PDF) $< $@ $(MAN) -t ./iverilog-vpi.man > iverilog-vpi.ps
cp $@ iverilog_man_$(VERSION_MAJOR)_$(VERSION_MINOR).pdf
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 # For VERSION_TAG in driver/main.c, first try git-describe, then look for a
# release_tag.h file in the source tree (included in snapshots and releases), # version_tag.h file in the source tree (included in snapshots and releases),
# and finally use nothing. # and finally use nothing.
# "true" and "false" in the next few lines are Unix shell command names # "true" and "false" in the next few lines are Unix shell command names
@ -278,14 +296,37 @@ version_tag.h version:
tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \ tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \ | sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \ echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
elif test -r $(srcdir)/release_tag.h; then \ elif test -r $(srcdir)/version_tag.h; then \
echo "Using $(srcdir)/release_tag.h for VERSION_TAG"; \ echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \
diff $(srcdir)/release_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/release_tag.h version_tag.h; \ diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \
else \ else \
echo "Using empty VERSION_TAG"; \ echo "Using empty VERSION_TAG"; \
echo '#define VERSION_TAG ""' > version_tag.h; \ echo '#define VERSION_TAG ""' > version_tag.h; \
fi fi
ifeq (@MINGW32@,yes)
ifeq ($(MAN),none)
INSTALL_DOC = installman
else
ifeq ($(PS2PDF),none)
INSTALL_DOC = installman
else
INSTALL_DOC = installpdf installman
all: dep iverilog-vpi.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = installman
INSTALL_DOCDIR = $(mandir)/man1
endif
ifeq (@MINGW32@,yes)
WIN32_INSTALL =
else
WIN32_INSTALL = installwin32
endif
install: all installdirs installfiles install: all installdirs installfiles
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@ -297,24 +338,37 @@ F = ./ivl@EXEEXT@ \
$(srcdir)/sv_vpi_user.h \ $(srcdir)/sv_vpi_user.h \
$(srcdir)/vpi_user.h \ $(srcdir)/vpi_user.h \
$(srcdir)/acc_user.h \ $(srcdir)/acc_user.h \
$(srcdir)/veriuser.h $(srcdir)/veriuser.h \
$(INSTALL_DOC) \
$(WIN32_INSTALL)
installwin32: ./iverilog-vpi installdirs
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
installman: iverilog-vpi.man installdirs
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
installpdf: iverilog-vpi.pdf installdirs
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
installfiles: $(F) | installdirs installfiles: $(F) | installdirs
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@" $(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)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams" $(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(ivl_includedir)/ivl_target.h" $(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h"
$(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(ivl_includedir)/_pli_types.h" $(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(includedir)/_pli_types.h"
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(ivl_includedir)/sv_vpi_user.h" $(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(includedir)/sv_vpi_user.h"
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(ivl_includedir)/vpi_user.h" $(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h"
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(ivl_includedir)/acc_user.h" $(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h"
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(ivl_includedir)/veriuser.h" $(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
installdirs: $(srcdir)/mkinstalldirs installdirs: $(srcdir)/mkinstalldirs
$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \ $(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(ivl_includedir)" \ "$(DESTDIR)$(includedir)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)" \ "$(DESTDIR)$(libdir)/ivl$(suffix)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)/include" "$(DESTDIR)$(libdir)/ivl$(suffix)/include" \
"$(DESTDIR)$(mandir)" \
"$(DESTDIR)$(mandir)/man1"
uninstall: uninstall:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
@ -322,13 +376,12 @@ uninstall:
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include" -rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)" -rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)"
for f in verilog$(suffix) gverilog$(suffix)@EXEEXT@; \ for f in verilog$(suffix) iverilog-vpi$(suffix) gverilog$(suffix)@EXEEXT@; \
do rm -f "$(DESTDIR)$(bindir)/$$f"; done 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; \ 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)$(ivl_includedir)/$$f"; done do rm -f "$(DESTDIR)$(includedir)/$$f"; done
-test X$(suffix) = X || rmdir "$(DESTDIR)$(ivl_includedir)" -test X$(suffix) = X || rmdir "$(DESTDIR)$(includedir)"
rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf"
-include $(patsubst %.o, dep/%.d, $O) -include $(patsubst %.o, dep/%.d, $O)
.PHONY: check-installed check-installed-vpi check-installed-vvp check-installed-vvp-py

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,65 +21,13 @@
# include "Module.h" # include "Module.h"
# include "PGate.h" # include "PGate.h"
# include "PModport.h"
# include "PWire.h" # include "PWire.h"
# include "parse_api.h" # include <cassert>
# include "ivl_assert.h"
# include <iostream>
using namespace std; using namespace std;
list<Module::named_expr_t> Module::user_defparms; list<Module::named_expr_t> Module::user_defparms;
Module::port_t::port_t()
: port_kind(P_SIGNAL), default_value(0), interface_unpacked_dimensions(0), lexical_pos(0)
{
}
bool resolve_interface_formal_port(const LineInfo*li, Design*des,
const Module::port_t*port,
interface_formal_port_t&res,
bool emit_errors)
{
ivl_assert(*li, port);
ivl_assert(*li, port->is_interface_port());
res = interface_formal_port_t();
map<perm_string,Module*>::const_iterator mod =
pform_modules.find(port->interface_type);
if (mod == pform_modules.end() || !mod->second->is_interface) {
if (emit_errors) {
cerr << li->get_fileline() << ": error: Interface port "
<< port->name << " uses unknown interface type `"
<< port->interface_type << "'." << endl;
des->errors += 1;
}
return false;
}
res.module = mod->second;
if (port->modport_name.str()) {
map<perm_string,PModport*>::const_iterator mp =
mod->second->modports.find(port->modport_name);
if (mp == mod->second->modports.end()) {
if (emit_errors) {
cerr << li->get_fileline() << ": error: Interface port "
<< port->name << " uses unknown modport `"
<< port->modport_name << "' of interface `"
<< port->interface_type << "'." << endl;
des->errors += 1;
}
return false;
}
res.modport = mp->second;
}
return true;
}
/* n is a permallocated string. */ /* n is a permallocated string. */
Module::Module(LexicalScope*parent, perm_string n) Module::Module(LexicalScope*parent, perm_string n)
: PScopeExtra(n, parent) : PScopeExtra(n, parent)
@ -112,24 +60,18 @@ unsigned Module::port_count() const
*/ */
const vector<PEIdent*>& Module::get_port(unsigned idx) const const vector<PEIdent*>& Module::get_port(unsigned idx) const
{ {
ivl_assert(*this, idx < ports.size()); assert(idx < ports.size());
static const vector<PEIdent*> zero; static const vector<PEIdent*> zero;
if (ports[idx] && !ports[idx]->is_interface_port()) if (ports[idx])
return ports[idx]->expr; return ports[idx]->expr;
else else
return zero; return zero;
} }
const Module::port_t* Module::get_port_info(unsigned idx) const
{
ivl_assert(*this, idx < ports.size());
return ports[idx];
}
unsigned Module::find_port(const char*name) const unsigned Module::find_port(const char*name) const
{ {
ivl_assert(*this, name != 0); assert(name != 0);
for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) { for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) {
if (ports[idx] == 0) { if (ports[idx] == 0) {
/* It is possible to have undeclared ports. These /* It is possible to have undeclared ports. These
@ -139,7 +81,7 @@ unsigned Module::find_port(const char*name) const
inaccessible to binding by name. */ inaccessible to binding by name. */
continue; continue;
} }
ivl_assert(*this, ports[idx]); assert(ports[idx]);
if (ports[idx]->name == name) if (ports[idx]->name == name)
return idx; return idx;
} }
@ -150,7 +92,7 @@ unsigned Module::find_port(const char*name) const
perm_string Module::get_port_name(unsigned idx) const perm_string Module::get_port_name(unsigned idx) const
{ {
ivl_assert(*this, idx < ports.size()); assert(idx < ports.size());
if (ports[idx] == 0 || ports[idx]->name.str() == 0) { if (ports[idx] == 0 || ports[idx]->name.str() == 0) {
/* It is possible to have undeclared ports. These /* It is possible to have undeclared ports. These
are ports that are skipped in the declaration, are ports that are skipped in the declaration,
@ -166,7 +108,7 @@ perm_string Module::get_port_name(unsigned idx) const
PExpr* Module::get_port_default_value(unsigned idx) const PExpr* Module::get_port_default_value(unsigned idx) const
{ {
ivl_assert(*this, idx < ports.size()); assert(idx < ports.size());
return ports[idx] ? ports[idx]->default_value : 0; return ports[idx] ? ports[idx]->default_value : 0;
} }
@ -206,7 +148,7 @@ bool Module::can_be_toplevel() const
// Don't choose modules with parameters without default value // Don't choose modules with parameters without default value
for (std::map<perm_string,param_expr_t*>::const_iterator cur = for (std::map<perm_string,param_expr_t*>::const_iterator cur =
parameters.begin(); cur != parameters.end(); ++cur) { parameters.begin(); cur != parameters.end(); cur++) {
if (cur->second->expr == 0) if (cur->second->expr == 0)
return false; return false;
} }

View File

@ -1,7 +1,7 @@
#ifndef IVL_Module_H #ifndef IVL_Module_H
#define IVL_Module_H #define IVL_Module_H
/* /*
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -37,13 +37,11 @@ class PGate;
class PGenerate; class PGenerate;
class PModport; class PModport;
class PSpecPath; class PSpecPath;
class PTimingCheck;
class PTask; class PTask;
class PFunction; class PFunction;
class PWire; class PWire;
class PProcess; class PProcess;
class Design; class Design;
class LineInfo;
class NetScope; class NetScope;
/* /*
@ -66,32 +64,16 @@ class Module : public PScopeExtra, public PNamedItem {
default value. */ default value. */
public: public:
struct port_t { struct port_t {
enum port_kind_t { P_SIGNAL, P_INTERFACE };
port_t();
port_kind_t port_kind;
perm_string name; perm_string name;
std::vector<PEIdent*> expr; std::vector<PEIdent*> expr;
PExpr*default_value; PExpr*default_value;
/* Interface formal port metadata. For signal ports these
fields are empty/zero. The modport name is optional in the
representation, although the parser initially only accepts
the explicit interface_type.modport form. */
perm_string interface_type;
perm_string modport_name;
std::list<pform_range_t>*interface_unpacked_dimensions;
unsigned lexical_pos;
bool is_interface_port() const { return port_kind == P_INTERFACE; }
}; };
public: public:
/* The name passed here is the module name, not the instance /* The name passed here is the module name, not the instance
name. This name must be a permallocated string. */ name. This name must be a permallocated string. */
explicit Module(LexicalScope*parent, perm_string name); explicit Module(LexicalScope*parent, perm_string name);
~Module() override; ~Module();
/* Initially false. This is set to true if the module has been /* Initially false. This is set to true if the module has been
declared as a library module. This makes the module declared as a library module. This makes the module
@ -154,9 +136,7 @@ class Module : public PScopeExtra, public PNamedItem {
program blocks. */ program blocks. */
std::map<perm_string,PModport*> modports; std::map<perm_string,PModport*> modports;
/* List for specify paths and timing checks */
std::list<PSpecPath*> specify_paths; std::list<PSpecPath*> specify_paths;
std::list<PTimingCheck*> timing_checks;
// The mod_name() is the name of the module type. // The mod_name() is the name of the module type.
perm_string mod_name() const { return pscope_name(); } perm_string mod_name() const { return pscope_name(); }
@ -165,7 +145,6 @@ class Module : public PScopeExtra, public PNamedItem {
unsigned port_count() const; unsigned port_count() const;
const std::vector<PEIdent*>& get_port(unsigned idx) const; const std::vector<PEIdent*>& get_port(unsigned idx) const;
const port_t* get_port_info(unsigned idx) const;
unsigned find_port(const char*name) const; unsigned find_port(const char*name) const;
// Return port name ("" for undeclared port) // Return port name ("" for undeclared port)
@ -185,13 +164,12 @@ class Module : public PScopeExtra, public PNamedItem {
bool elaborate_sig(Design*, NetScope*scope) const; bool elaborate_sig(Design*, NetScope*scope) const;
SymbolType symbol_type() const override; SymbolType symbol_type() const;
bool can_be_toplevel() const; bool can_be_toplevel() const;
private: private:
void dump_specparams_(std::ostream&out, unsigned indent) const; void dump_specparams_(std::ostream&out, unsigned indent) const;
void dump_timingchecks_(std::ostream&out, unsigned indent) const;
std::list<PGate*> gates_; std::list<PGate*> gates_;
private: // Not implemented private: // Not implemented
@ -199,16 +177,4 @@ class Module : public PScopeExtra, public PNamedItem {
Module& operator= (const Module&); Module& operator= (const Module&);
}; };
struct interface_formal_port_t {
interface_formal_port_t() : module(0), modport(0) { }
const Module*module;
const PModport*modport;
};
extern bool resolve_interface_formal_port(const LineInfo*li, Design*des,
const Module::port_t*port,
interface_formal_port_t&res,
bool emit_errors);
#endif /* IVL_Module_H */ #endif /* IVL_Module_H */

View File

@ -1,7 +1,7 @@
#ifndef IVL_PClass_H #ifndef IVL_PClass_H
#define IVL_PClass_H #define IVL_PClass_H
/* /*
* Copyright (c) 2012-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2019 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -36,11 +36,11 @@ class PClass : public PScopeExtra, public PNamedItem {
public: public:
explicit PClass (perm_string name, LexicalScope*parent); explicit PClass (perm_string name, LexicalScope*parent);
~PClass() override; ~PClass();
void dump(std::ostream&out, unsigned indent) const; void dump(std::ostream&out, unsigned indent) const;
SymbolType symbol_type() const override; SymbolType symbol_type() const;
public: public:
class_type_t*type; class_type_t*type;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -130,11 +130,10 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
return expr; return expr;
} }
static const NetExpr *calc_decay_time(const NetExpr *rise, static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
const NetExpr *fall)
{ {
const NetEConst *c_rise = dynamic_cast<const NetEConst*>(rise); NetEConst *c_rise = dynamic_cast<NetEConst*>(rise);
const NetEConst *c_fall = dynamic_cast<const NetEConst*>(fall); NetEConst *c_fall = dynamic_cast<NetEConst*>(fall);
if (c_rise && c_fall) { if (c_rise && c_fall) {
if (c_rise->value() < c_fall->value()) return rise; if (c_rise->value() < c_fall->value()) return rise;
else return fall; else return fall;
@ -143,43 +142,44 @@ static const NetExpr *calc_decay_time(const NetExpr *rise,
return 0; return 0;
} }
void PDelays::eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays, void PDelays::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_nets_flag) const bool as_nets_flag) const
{ {
assert(scope); assert(scope);
if (delay_[0]) { if (delay_[0]) {
NetExpr *rise = calculate_val(des, scope, delay_[0]); rise_time = calculate_val(des, scope, delay_[0]);
if (as_nets_flag) if (as_nets_flag)
rise = make_delay_nets(des, scope, rise); rise_time = make_delay_nets(des, scope, rise_time);
delays.rise = rise;
if (delay_[1]) { if (delay_[1]) {
NetExpr *fall = calculate_val(des, scope, delay_[1]); fall_time = calculate_val(des, scope, delay_[1]);
if (as_nets_flag) if (as_nets_flag)
fall = make_delay_nets(des, scope, fall); fall_time = make_delay_nets(des, scope, fall_time);
delays.fall = fall;
if (delay_[2]) { if (delay_[2]) {
NetExpr *decay = calculate_val(des, scope, delay_[2]); decay_time = calculate_val(des, scope, delay_[2]);
if (as_nets_flag) if (as_nets_flag)
decay = make_delay_nets(des, scope, decay); decay_time = make_delay_nets(des, scope,
delays.decay = decay; decay_time);
} else { } else {
// If this is zero then we need to do the min() // If this is zero then we need to do the min()
// at run time. // at run time.
delays.decay = calc_decay_time(delays.rise, decay_time = calc_decay_time(rise_time, fall_time);
delays.fall);
} }
} else { } else {
assert(delay_[2] == 0); assert(delay_[2] == 0);
delays.fall = delays.rise; fall_time = rise_time;
delays.decay = delays.rise; decay_time = rise_time;
} }
} else { } else {
delays.rise = nullptr; rise_time = 0;
delays.fall = nullptr; fall_time = 0;
delays.decay = nullptr; decay_time = 0;
} }
} }

View File

@ -1,7 +1,7 @@
#ifndef IVL_PDelays_H #ifndef IVL_PDelays_H
#define IVL_PDelays_H #define IVL_PDelays_H
/* /*
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -27,7 +27,6 @@ class Design;
class NetScope; class NetScope;
class NetExpr; class NetExpr;
class PExpr; class PExpr;
struct delay_exprs_t;
/* /*
* Various PForm objects can carry delays. These delays include rise, * Various PForm objects can carry delays. These delays include rise,
@ -47,7 +46,10 @@ class PDelays {
unsigned delay_count() const; unsigned delay_count() const;
void eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays, void eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_nets_flag =false) const; bool as_nets_flag =false) const;
void dump_delays(std::ostream&out) const; void dump_delays(std::ostream&out) const;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004-2024 Stephen Williams (steve@icarus.com) * Copyright (c) 2004-2019 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,8 +21,8 @@
# include "PEvent.h" # include "PEvent.h"
PEvent::PEvent(perm_string n, unsigned lexical_pos) PEvent::PEvent(perm_string n)
: name_(n), lexical_pos_(lexical_pos) : name_(n)
{ {
} }

View File

@ -1,7 +1,7 @@
#ifndef IVL_PEvent_H #ifndef IVL_PEvent_H
#define IVL_PEvent_H #define IVL_PEvent_H
/* /*
* Copyright (c) 2000-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2019 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -36,20 +36,17 @@ class PEvent : public PNamedItem {
public: public:
// The name is a perm-allocated string. It is the simple name // The name is a perm-allocated string. It is the simple name
// of the event, without any scope. // of the event, without any scope.
explicit PEvent(perm_string name, unsigned lexical_pos); explicit PEvent(perm_string name);
~PEvent() override; ~PEvent();
perm_string name() const; perm_string name() const;
unsigned lexical_pos() const { return lexical_pos_; }
void elaborate_scope(Design*des, NetScope*scope) const; void elaborate_scope(Design*des, NetScope*scope) const;
SymbolType symbol_type() const override; SymbolType symbol_type() const;
private: private:
perm_string name_; perm_string name_;
unsigned lexical_pos_;
private: // not implemented private: // not implemented
PEvent(const PEvent&); PEvent(const PEvent&);

173
PExpr.cc
View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2026 Stephen Williams <steve@icarus.com> * Copyright (c) 1998-2021 Stephen Williams <steve@icarus.com>
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -20,14 +20,12 @@
# include "config.h" # include "config.h"
# include <algorithm>
# include <iostream> # include <iostream>
# include "compiler.h" # include "compiler.h"
# include "PExpr.h" # include "PExpr.h"
# include "PWire.h" # include "PWire.h"
# include "Module.h" # include "Module.h"
# include "ivl_assert.h"
# include "netmisc.h" # include "netmisc.h"
# include "util.h" # include "util.h"
# include <typeinfo> # include <typeinfo>
@ -55,7 +53,7 @@ bool PExpr::has_aa_term(Design*, NetScope*) const
return false; return false;
} }
NetNet* PExpr::elaborate_lnet(Design*, NetScope*, bool) const NetNet* PExpr::elaborate_lnet(Design*, NetScope*) const
{ {
cerr << get_fileline() << ": error: " cerr << get_fileline() << ": error: "
<< "expression not valid in assign l-value: " << "expression not valid in assign l-value: "
@ -63,7 +61,7 @@ NetNet* PExpr::elaborate_lnet(Design*, NetScope*, bool) const
return 0; return 0;
} }
NetNet* PExpr::elaborate_bi_net(Design*, NetScope*, bool) const NetNet* PExpr::elaborate_bi_net(Design*, NetScope*) const
{ {
cerr << get_fileline() << ": error: " cerr << get_fileline() << ": error: "
<< "expression not valid as argument to inout port: " << "expression not valid as argument to inout port: "
@ -100,24 +98,20 @@ PEAssignPattern::PEAssignPattern()
} }
PEAssignPattern::PEAssignPattern(const list<PExpr*>&p) PEAssignPattern::PEAssignPattern(const list<PExpr*>&p)
: parms_(p.begin(), p.end()) : 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() PEAssignPattern::~PEAssignPattern()
{ {
} }
bool PEAssignPattern::has_aa_term(Design*des, NetScope*scope) const
{
bool flag = false;
for (const auto *parm : parms_) {
if (parm)
flag = parm->has_aa_term(des, scope) || flag;
}
return flag;
}
PEBinary::PEBinary(char op, PExpr*l, PExpr*r) PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
: op_(op), left_(l), right_(r) : op_(op), left_(l), right_(r)
{ {
@ -135,7 +129,7 @@ void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
{ {
ivl_assert(*this, left_ && right_); assert(left_ && right_);
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope); return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
} }
@ -156,7 +150,6 @@ bool PECastSize::has_aa_term(Design *des, NetScope *scope) const
PECastType::PECastType(data_type_t*t, PExpr*b) PECastType::PECastType(data_type_t*t, PExpr*b)
: target_(t), base_(b) : target_(t), base_(b)
{ {
target_type_ = nullptr;
} }
PECastType::~PECastType() PECastType::~PECastType()
@ -193,7 +186,7 @@ PEBComp::~PEBComp()
PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r) PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r) : PEBinary(op, l, r)
{ {
ivl_assert(*this, op == 'a' || op == 'o' || op == 'q' || op == 'Q'); assert(op == 'a' || op == 'o' || op == 'q' || op == 'Q');
} }
PEBLogic::~PEBLogic() PEBLogic::~PEBLogic()
@ -227,13 +220,13 @@ PEBShift::~PEBShift()
{ {
} }
PECallFunction::PECallFunction(const pform_name_t &n, const vector<named_pexpr_t> &parms) PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
: path_(n), parms_(parms), is_overridden_(false) : package_(0), path_(n), parms_(parms), is_overridden_(false)
{ {
} }
PECallFunction::PECallFunction(PPackage *pkg, const pform_name_t &n, const vector<named_pexpr_t> &parms) PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector<PExpr *> &parms)
: path_(pkg, n), parms_(parms), is_overridden_(false) : package_(pkg), path_(n), parms_(parms), is_overridden_(false)
{ {
} }
@ -245,78 +238,76 @@ static pform_name_t pn_from_ps(perm_string n)
return tmp; return tmp;
} }
PECallFunction::PECallFunction(PPackage *pkg, const pform_name_t &n, const list<named_pexpr_t> &parms) PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *> &parms)
: path_(pkg, n), parms_(parms.begin(), parms.end()), is_overridden_(false) : 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<named_pexpr_t> &parms) PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(parms), is_overridden_(false) : package_(0), path_(pn_from_ps(n)), parms_(parms), is_overridden_(false)
{ {
} }
PECallFunction::PECallFunction(perm_string n) PECallFunction::PECallFunction(perm_string n)
: path_(pn_from_ps(n)), is_overridden_(false) : package_(0), path_(pn_from_ps(n)), is_overridden_(false)
{ {
} }
// NOTE: Anachronism. Try to work all use of svector out. // NOTE: Anachronism. Try to work all use of svector out.
PECallFunction::PECallFunction(const pform_name_t &n, const list<named_pexpr_t> &parms) PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
: path_(n), parms_(parms.begin(), parms.end()), is_overridden_(false) : 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<named_pexpr_t> &parms) PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms)
: path_(pn_from_ps(n)), parms_(parms.begin(), parms.end()), is_overridden_(false) : package_(0), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false)
{
}
PECallFunction::PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
const vector<named_pexpr_t> &parms)
: path_(method), parms_(parms), chain_prefix_(chain_prefix), is_overridden_(false)
{
}
PECallFunction::PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
const list<named_pexpr_t> &parms)
: path_(method), parms_(parms.begin(), parms.end()),
chain_prefix_(chain_prefix), 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() PECallFunction::~PECallFunction()
{ {
delete chain_prefix_;
} }
void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{ {
if (chain_prefix_) { for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
chain_prefix_->declare_implicit_nets(scope, type); parms_[idx]->declare_implicit_nets(scope, type);
}
for (const auto &parm : parms_) {
if (parm.parm) {
parm.parm->declare_implicit_nets(scope, type);
}
} }
} }
bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
{ {
if (chain_prefix_ && chain_prefix_->has_aa_term(des, scope)) { bool flag = false;
return true; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
} flag = parms_[idx]->has_aa_term(des, scope) || flag;
for (const auto &parm : parms_) {
if (parm.parm && parm.parm->has_aa_term(des, scope)) {
return true;
}
} }
return false; return flag;
} }
PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r) PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r)
: parms_(p.begin(), p.end()), width_modes_(SIZED, p.size()), repeat_(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; tested_scope_ = 0;
repeat_count_ = 1; repeat_count_ = 1;
} }
@ -361,7 +352,7 @@ PEEvent::edge_t PEEvent::type() const
bool PEEvent::has_aa_term(Design*des, NetScope*scope) const bool PEEvent::has_aa_term(Design*des, NetScope*scope) const
{ {
ivl_assert(*this, expr_); assert(expr_);
return expr_->has_aa_term(des, scope); return expr_->has_aa_term(des, scope);
} }
@ -393,19 +384,19 @@ const verireal& PEFNumber::value() const
return *value_; return *value_;
} }
PEIdent::PEIdent(const pform_name_t&that, unsigned lexical_pos) PEIdent::PEIdent(const pform_name_t&that)
: path_(that), lexical_pos_(lexical_pos), no_implicit_sig_(false) : package_(0), path_(that), no_implicit_sig_(false)
{ {
} }
PEIdent::PEIdent(perm_string s, unsigned lexical_pos, bool no_implicit_sig) PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
: lexical_pos_(lexical_pos), no_implicit_sig_(no_implicit_sig) : package_(0), no_implicit_sig_(no_implicit_sig)
{ {
path_.name.push_back(name_component_t(s)); path_.push_back(name_component_t(s));
} }
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that, unsigned lexical_pos) PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
: path_(pkg, that), lexical_pos_(lexical_pos), no_implicit_sig_(true) : package_(pkg), path_(that), no_implicit_sig_(true)
{ {
} }
@ -415,11 +406,14 @@ PEIdent::~PEIdent()
static bool find_enum_constant(LexicalScope*scope, perm_string name) static bool find_enum_constant(LexicalScope*scope, perm_string name)
{ {
return std::any_of(scope->enum_sets.cbegin(), scope->enum_sets.cend(), for (vector<enum_type_t*>::const_iterator cur = scope->enum_sets.begin() ;
[name](const enum_type_t *cur) { cur != scope->enum_sets.end() ; ++ cur) {
return std::any_of(cur->names->cbegin(), cur->names->cend(), for (list<named_pexpr_t>::const_iterator idx = (*cur)->names->begin() ;
[name](const named_pexpr_t&idx){return idx.name == name;}); idx != (*cur)->names->end() ; ++ idx) {
}); if (idx->name == name) return true;
}
}
return false;
} }
void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
@ -431,10 +425,8 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
- this is not an implicit named port connection */ - this is not an implicit named port connection */
if (no_implicit_sig_) if (no_implicit_sig_)
return; return;
if (path_.package) if ((path_.size() == 1) && (path_.front().index.size() == 0)) {
return; perm_string name = path_.front().name;
if (path_.name.size() == 1 && path_.name.front().index.empty()) {
perm_string name = path_.name.front().name;
LexicalScope*ss = scope; LexicalScope*ss = scope;
while (ss) { while (ss) {
if (ss->wires.find(name) != ss->wires.end()) if (ss->wires.find(name) != ss->wires.end())
@ -456,7 +448,7 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
ss = ss->parent_scope(); ss = ss->parent_scope();
} }
PWire*net = new PWire(name, lexical_pos_, type, NetNet::NOT_A_PORT); PWire*net = new PWire(name, type, NetNet::NOT_A_PORT);
net->set_file(get_file()); net->set_file(get_file());
net->set_lineno(get_lineno()); net->set_lineno(get_lineno());
scope->wires[name] = net; scope->wires[name] = net;
@ -470,7 +462,7 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
{ {
symbol_search_results sr; symbol_search_results sr;
if (!symbol_search(this, des, scope, path_, lexical_pos_, &sr)) if (!symbol_search(this, des, scope, path_, &sr))
return false; return false;
// Class properties are not considered automatic since a non-blocking // Class properties are not considered automatic since a non-blocking
@ -496,9 +488,14 @@ PENewClass::PENewClass(void)
{ {
} }
PENewClass::PENewClass(const list<named_pexpr_t> &p, data_type_t *class_type) PENewClass::PENewClass(const list<PExpr*>&p, data_type_t *class_type)
: parms_(p.begin(), p.end()), class_type_(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() PENewClass::~PENewClass()
@ -517,7 +514,7 @@ PENewCopy::~PENewCopy()
PENumber::PENumber(verinum*vp) PENumber::PENumber(verinum*vp)
: value_(vp) : value_(vp)
{ {
ivl_assert(*this, vp); assert(vp);
} }
PENumber::~PENumber() PENumber::~PENumber()
@ -556,7 +553,7 @@ PETernary::~PETernary()
void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{ {
ivl_assert(*this, expr_ && tru_ && fal_); assert(expr_ && tru_ && fal_);
expr_->declare_implicit_nets(scope, type); expr_->declare_implicit_nets(scope, type);
tru_->declare_implicit_nets(scope, type); tru_->declare_implicit_nets(scope, type);
fal_->declare_implicit_nets(scope, type); fal_->declare_implicit_nets(scope, type);
@ -564,7 +561,7 @@ void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
bool PETernary::has_aa_term(Design*des, NetScope*scope) const bool PETernary::has_aa_term(Design*des, NetScope*scope) const
{ {
ivl_assert(*this, expr_ && tru_ && fal_); assert(expr_ && tru_ && fal_);
return expr_->has_aa_term(des, scope) return expr_->has_aa_term(des, scope)
|| tru_->has_aa_term(des, scope) || tru_->has_aa_term(des, scope)
|| fal_->has_aa_term(des, scope); || fal_->has_aa_term(des, scope);
@ -590,13 +587,13 @@ PEUnary::~PEUnary()
void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{ {
ivl_assert(*this, expr_); assert(expr_);
expr_->declare_implicit_nets(scope, type); expr_->declare_implicit_nets(scope, type);
} }
bool PEUnary::has_aa_term(Design*des, NetScope*scope) const bool PEUnary::has_aa_term(Design*des, NetScope*scope) const
{ {
ivl_assert(*this, expr_); assert(expr_);
return expr_->has_aa_term(des, scope); return expr_->has_aa_term(des, scope);
} }

454
PExpr.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PExpr_H #ifndef IVL_PExpr_H
#define IVL_PExpr_H #define IVL_PExpr_H
/* /*
* Copyright (c) 1998-2026 Stephen Williams <steve@icarus.com> * Copyright (c) 1998-2021 Stephen Williams <steve@icarus.com>
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -37,7 +37,6 @@ class NetExpr;
class NetScope; class NetScope;
class PPackage; class PPackage;
struct symbol_search_results; struct symbol_search_results;
class netclass_t;
/* /*
* The PExpr class hierarchy supports the description of * The PExpr class hierarchy supports the description of
@ -61,7 +60,7 @@ class PExpr : public LineInfo {
static const char*width_mode_name(width_mode_t mode); static const char*width_mode_name(width_mode_t mode);
PExpr(); PExpr();
virtual ~PExpr() override; virtual ~PExpr();
virtual void dump(std::ostream&) const; virtual void dump(std::ostream&) const;
@ -157,15 +156,13 @@ class PExpr : public LineInfo {
// This method elaborates the expression as gates, but // This method elaborates the expression as gates, but
// restricted for use as l-values of continuous assignments. // restricted for use as l-values of continuous assignments.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope, virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
bool var_allowed_in_sv) const;
// This is similar to elaborate_lnet, except that the // This is similar to elaborate_lnet, except that the
// expression is evaluated to be bi-directional. This is // expression is evaluated to be bi-directional. This is
// useful for arguments to inout ports of module instances and // useful for arguments to inout ports of module instances and
// ports of tran primitives. // ports of tran primitives.
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope, virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
bool var_allowed_in_sv) const;
// Expressions that can be in the l-value of procedural // Expressions that can be in the l-value of procedural
// assignments can be elaborated with this method. If the // assignments can be elaborated with this method. If the
@ -175,8 +172,7 @@ class PExpr : public LineInfo {
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
bool is_cassign, bool is_cassign,
bool is_force, bool is_force) const;
bool is_init = false) const;
// This method returns true if the expression represents a // This method returns true if the expression represents a
// structural net that can have multiple drivers. This is // structural net that can have multiple drivers. This is
@ -205,37 +201,20 @@ class PEAssignPattern : public PExpr {
public: public:
explicit PEAssignPattern(); explicit PEAssignPattern();
explicit PEAssignPattern(const std::list<PExpr*>&p); explicit PEAssignPattern(const std::list<PExpr*>&p);
~PEAssignPattern() override; ~PEAssignPattern();
void dump(std::ostream&) const override; void dump(std::ostream&) const;
virtual bool has_aa_term(Design*des, NetScope*scope) const override; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode);
virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode) override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
private: private:
NetExpr* elaborate_expr_packed_(Design *des, NetScope *scope, NetExpr* elaborate_expr_darray_(Design*des, NetScope*scope,
ivl_variable_type_t base_type, ivl_type_t type, unsigned flags) const;
unsigned int width,
const netranges_t &dims,
unsigned int cur_dim,
bool need_const) const;
NetExpr* elaborate_expr_struct_(Design *des, NetScope *scope,
const netstruct_t *struct_type,
bool need_const) const;
NetExpr* elaborate_expr_array_(Design *des, NetScope *scope,
const netarray_t *array_type,
bool need_const, bool up) const;
NetExpr* elaborate_expr_uarray_(Design *des, NetScope *scope,
const netuarray_t *uarray_type,
const netranges_t &dims,
unsigned int cur_dim,
bool need_const) const;
private: private:
std::vector<PExpr*>parms_; std::vector<PExpr*>parms_;
@ -245,39 +224,35 @@ class PEConcat : public PExpr {
public: public:
explicit PEConcat(const std::list<PExpr*>&p, PExpr*r =0); explicit PEConcat(const std::list<PExpr*>&p, PExpr*r =0);
~PEConcat() override; ~PEConcat();
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const override; virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope, virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
bool var_allowed_in_sv) const override; virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope,
bool var_allowed_in_sv) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
bool is_cassign, bool is_cassign,
bool is_force, bool is_force) const;
bool is_init = false) const override;
virtual bool is_collapsible_net(Design*des, NetScope*scope, virtual bool is_collapsible_net(Design*des, NetScope*scope,
NetNet::PortType port_type) const override; NetNet::PortType port_type) const;
private: private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag, bool bidirectional_flag) const;
bool var_allowed_in_sv) const;
private: private:
std::vector<PExpr*>parms_; std::vector<PExpr*>parms_;
std::valarray<width_mode_t>width_modes_; std::valarray<width_mode_t>width_modes_;
@ -302,14 +277,14 @@ class PEEvent : public PExpr {
// Use this constructor to create events based on edges or levels. // Use this constructor to create events based on edges or levels.
PEEvent(edge_t t, PExpr*e); PEEvent(edge_t t, PExpr*e);
~PEEvent() override; ~PEEvent();
edge_t type() const; edge_t type() const;
PExpr* expr() const; PExpr* expr() const;
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
virtual bool has_aa_term(Design*des, NetScope*scope) const override; virtual bool has_aa_term(Design*des, NetScope*scope) const;
private: private:
edge_t type_; edge_t type_;
@ -323,19 +298,19 @@ class PEFNumber : public PExpr {
public: public:
explicit PEFNumber(verireal*vp); explicit PEFNumber(verireal*vp);
~PEFNumber() override; ~PEFNumber();
const verireal& value() const; const verireal& value() const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
private: private:
verireal*value_; verireal*value_;
@ -344,41 +319,40 @@ class PEFNumber : public PExpr {
class PEIdent : public PExpr { class PEIdent : public PExpr {
public: public:
explicit PEIdent(perm_string, unsigned lexical_pos, bool no_implicit_sig=false); explicit PEIdent(perm_string, bool no_implicit_sig=false);
explicit PEIdent(PPackage*pkg, const pform_name_t&name, unsigned lexical_pos); explicit PEIdent(PPackage*pkg, const pform_name_t&name);
explicit PEIdent(const pform_name_t&, unsigned lexical_pos); explicit PEIdent(const pform_name_t&);
~PEIdent() override; ~PEIdent();
// Add another name to the string of hierarchy that is the // Add another name to the string of hierarchy that is the
// current identifier. // current identifier.
void append_name(perm_string); void append_name(perm_string);
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const override; virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
// Identifiers are allowed (with restrictions) is assign l-values. // Identifiers are allowed (with restrictions) is assign l-values.
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope, bool var_allowed_in_sv) const override; virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope, bool var_allowed_in_sv) const override; virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
// Identifiers are also allowed as procedural assignment l-values. // Identifiers are also allowed as procedural assignment l-values.
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
bool is_cassign, bool is_cassign,
bool is_force, bool is_force) const;
bool is_init = false) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
// Elaborate the PEIdent as a port to a module. This method // Elaborate the PEIdent as a port to a module. This method
// only applies to Ident expressions. // only applies to Ident expressions.
@ -390,15 +364,15 @@ class PEIdent : public PExpr {
NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const; NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const;
virtual bool is_collapsible_net(Design*des, NetScope*scope, virtual bool is_collapsible_net(Design*des, NetScope*scope,
NetNet::PortType port_type) const override; NetNet::PortType port_type) const;
const pform_scoped_name_t& path() const { return path_; } const PPackage* package() const { return package_; }
unsigned lexical_pos() const { return lexical_pos_; } const pform_name_t& path() const { return path_; }
private: private:
pform_scoped_name_t path_; PPackage*package_;
unsigned lexical_pos_; pform_name_t path_;
bool no_implicit_sig_; bool no_implicit_sig_;
private: private:
@ -415,7 +389,7 @@ class PEIdent : public PExpr {
// the values written to the msb/lsb arguments. If there are // the values written to the msb/lsb arguments. If there are
// invalid bits (xz) in either expression, then the defined // invalid bits (xz) in either expression, then the defined
// flag is set to *false*. // flag is set to *false*.
void calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const; bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const; NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const;
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const; bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
@ -429,37 +403,28 @@ class PEIdent : public PExpr {
// [2:0][x] - BAD // [2:0][x] - BAD
// [y][x] - BAD // [y][x] - BAD
// Leave the last index for special handling. // Leave the last index for special handling.
bool calculate_packed_indices_(Design*des, NetScope*scope, const NetNet*net, bool calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net,
std::list<long>&prefix_indices) const; std::list<long>&prefix_indices) const;
private: private:
NetAssign_*elaborate_lval_method_class_member_(Design*, NetScope*) const;
void report_mixed_assignment_conflict_(const char*category) const;
NetAssign_ *elaborate_lval_array_(Design *des, NetScope *scope,
bool is_force, NetNet *reg) const;
NetAssign_ *elaborate_lval_var_(Design *des, NetScope *scope,
bool is_force, bool is_cassign,
NetNet *reg, ivl_type_t data_type,
pform_name_t tail_path) const;
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*, NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*,
bool need_const_idx, bool is_force) const; bool need_const_idx) const;
bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*, bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*,
bool need_const_idx, bool is_force) const; bool need_const_idx) const;
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*, bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
bool is_force) const;
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*, bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
index_component_t::ctype_t, index_component_t::ctype_t,
bool need_const_idx, bool is_force) const; bool need_const_idx) const;
NetAssign_*elaborate_lval_net_class_member_(Design*, NetScope*, NetAssign_*elaborate_lval_net_class_member_(Design*, NetScope*,
const netclass_t *class_type, const netclass_t *class_type,
NetNet*, NetNet*,
pform_name_t) const; pform_name_t) const;
bool elaborate_lval_net_packed_member_(Design*, NetScope*, bool elaborate_lval_net_packed_member_(Design*, NetScope*,
NetAssign_*, NetAssign_*,
pform_name_t member_path, bool is_force) const; pform_name_t member_path) const;
bool elaborate_lval_darray_bit_(Design*, NetScope*, bool elaborate_lval_darray_bit_(Design*, NetScope*,
NetAssign_*, bool is_force) const; NetAssign_*) const;
private: private:
NetExpr* elaborate_expr_(Design *des, NetScope *scope, NetExpr* elaborate_expr_(Design *des, NetScope *scope,
@ -491,12 +456,18 @@ class PEIdent : public PExpr {
const NetScope*found_in, const NetScope*found_in,
ivl_type_t par_type, ivl_type_t par_type,
unsigned expr_wid) const; unsigned expr_wid) const;
NetExpr*elaborate_expr_param_idx_up_do_(Design*des, NetExpr*elaborate_expr_param_idx_up_(Design*des,
NetScope*scope, NetScope*scope,
const NetExpr*par, const NetExpr*par,
const NetScope*found_in, const NetScope*found_in,
ivl_type_t par_type, ivl_type_t par_type,
bool up, bool need_const) const; bool need_const) const;
NetExpr*elaborate_expr_param_idx_do_(Design*des,
NetScope*scope,
const NetExpr*par,
const NetScope*found_in,
ivl_type_t par_type,
bool need_const) const;
NetExpr*elaborate_expr_net(Design*des, NetExpr*elaborate_expr_net(Design*des,
NetScope*scope, NetScope*scope,
NetNet*net, NetNet*net,
@ -514,11 +485,16 @@ class PEIdent : public PExpr {
NetESignal*net, NetESignal*net,
NetScope*found, NetScope*found,
unsigned expr_wid) const; unsigned expr_wid) const;
NetExpr*elaborate_expr_net_idx_up_do_(Design*des, NetExpr*elaborate_expr_net_idx_up_(Design*des,
NetScope*scope, NetScope*scope,
NetESignal*net, NetESignal*net,
NetScope*found, NetScope*found,
bool up, bool need_const) const; bool need_const) const;
NetExpr*elaborate_expr_net_idx_do_(Design*des,
NetScope*scope,
NetESignal*net,
NetScope*found,
bool need_const) const;
NetExpr*elaborate_expr_net_bit_(Design*des, NetExpr*elaborate_expr_net_bit_(Design*des,
NetScope*scope, NetScope*scope,
NetESignal*net, NetESignal*net,
@ -530,23 +506,26 @@ class PEIdent : public PExpr {
NetScope*found, NetScope*found,
bool need_const) const; bool need_const) const;
NetExpr*elaborate_expr_class_member_(Design*des,
NetScope*scope,
unsigned expr_wid,
unsigned flags) const;
NetExpr *elaborate_expr_class_field_(Design*des, NetScope*scope, NetExpr *elaborate_expr_class_field_(Design*des, NetScope*scope,
const symbol_search_results &sr, const symbol_search_results &sr,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const; unsigned flags) const;
unsigned test_width_parameter_(const NetExpr *par, width_mode_t&mode); unsigned test_width_method_(Design*des, NetScope*scope, width_mode_t&mode);
ivl_type_t resolve_type_(Design *des, const symbol_search_results &sr, unsigned test_width_parameter_(const NetExpr *par, width_mode_t&mode);
unsigned int &index_depth) const;
private: private:
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
bool bidirectional_flag, bool bidirectional_flag) const;
bool var_allowed_in_sv) const;
bool eval_part_select_(Design*des, NetScope*scope, const NetNet*sig, bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
long&midx, long&lidx) const; long&midx, long&lidx) const;
}; };
@ -554,16 +533,16 @@ class PENewArray : public PExpr {
public: public:
explicit PENewArray (PExpr*s, PExpr*i); explicit PENewArray (PExpr*s, PExpr*i);
~PENewArray() override; ~PENewArray();
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
private: private:
PExpr*size_; PExpr*size_;
@ -576,21 +555,21 @@ class PENewClass : public PExpr {
// New without (or with default) constructor // New without (or with default) constructor
explicit PENewClass (); explicit PENewClass ();
// New with constructor arguments // New with constructor arguments
explicit PENewClass (const std::list<named_pexpr_t> &p, explicit PENewClass (const std::list<PExpr*>&p,
data_type_t *class_type = nullptr); data_type_t *class_type = nullptr);
~PENewClass() override; ~PENewClass();
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
// Class objects don't have a useful width, but the expression // Class objects don't have a useful width, but the expression
// is IVL_VT_CLASS. // is IVL_VT_CLASS.
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
// Note that class (new) expressions only appear in context // Note that class (new) expressions only appear in context
// that uses this form of the elaborate_expr method. In fact, // that uses this form of the elaborate_expr method. In fact,
// the type argument is going to be a netclass_t object. // the type argument is going to be a netclass_t object.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
private: private:
NetExpr* elaborate_expr_constructor_(Design*des, NetScope*scope, NetExpr* elaborate_expr_constructor_(Design*des, NetScope*scope,
@ -598,25 +577,25 @@ class PENewClass : public PExpr {
NetExpr*obj, unsigned flags) const; NetExpr*obj, unsigned flags) const;
private: private:
std::vector<named_pexpr_t> parms_; std::vector<PExpr*>parms_;
data_type_t *class_type_; data_type_t *class_type_;
}; };
class PENewCopy : public PExpr { class PENewCopy : public PExpr {
public: public:
explicit PENewCopy(PExpr*src); explicit PENewCopy(PExpr*src);
~PENewCopy() override; ~PENewCopy();
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
// Class objects don't have a useful width, but the expression // Class objects don't have a useful width, but the expression
// is IVL_VT_CLASS. // is IVL_VT_CLASS.
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
// Note that class (new) expressions only appear in context // Note that class (new) expressions only appear in context
// that uses this form of the elaborate_expr method. In fact, // that uses this form of the elaborate_expr method. In fact,
// the type argument is going to be a netclass_t object. // the type argument is going to be a netclass_t object.
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
private: private:
PExpr*src_; PExpr*src_;
@ -625,39 +604,38 @@ class PENewCopy : public PExpr {
class PENull : public PExpr { class PENull : public PExpr {
public: public:
explicit PENull(); explicit PENull();
~PENull() override; ~PENull();
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
}; };
class PENumber : public PExpr { class PENumber : public PExpr {
public: public:
explicit PENumber(verinum*vp); explicit PENumber(verinum*vp);
~PENumber() override; ~PENumber();
const verinum& value() const; const verinum& value() const;
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetExpr *elaborate_expr(Design*des, NetScope*scope, virtual NetExpr *elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*, virtual NetEConst*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned) const override; unsigned expr_wid, unsigned) const;
virtual NetAssign_* elaborate_lval(Design*des, virtual NetAssign_* elaborate_lval(Design*des,
NetScope*scope, NetScope*scope,
bool is_cassign, bool is_cassign,
bool is_force, bool is_force) const;
bool is_init = false) const override;
private: private:
verinum*const value_; verinum*const value_;
@ -674,24 +652,20 @@ class PEString : public PExpr {
public: public:
explicit PEString(char*s); explicit PEString(char*s);
~PEString() override; ~PEString();
std::string value() const; std::string value() const;
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetEConst*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
virtual NetEConst*elaborate_expr(Design*des, NetScope*, virtual NetEConst*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned) const override; unsigned expr_wid, unsigned) const;
NetExpr *elaborate_expr_uarray_(Design *des, NetScope *scope,
const netuarray_t *uarray_type,
const std::vector<netrange_t> &dims,
unsigned int cur_dim) const;
private: private:
char*text_; char*text_;
}; };
@ -699,13 +673,13 @@ class PEString : public PExpr {
class PETypename : public PExpr { class PETypename : public PExpr {
public: public:
explicit PETypename(data_type_t*data_type); explicit PETypename(data_type_t*data_type);
~PETypename() override; ~PETypename();
virtual void dump(std::ostream&) const override; virtual void dump(std::ostream&) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
inline data_type_t* get_type() const { return data_type_; } inline data_type_t* get_type() const { return data_type_; }
@ -717,20 +691,20 @@ class PEUnary : public PExpr {
public: public:
explicit PEUnary(char op, PExpr*ex); explicit PEUnary(char op, PExpr*ex);
~PEUnary() override; ~PEUnary();
virtual void dump(std::ostream&out) const override; virtual void dump(std::ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const override; virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
public: public:
inline char get_op() const { return op_; } inline char get_op() const { return op_; }
@ -748,20 +722,20 @@ class PEBinary : public PExpr {
public: public:
explicit PEBinary(char op, PExpr*l, PExpr*r); explicit PEBinary(char op, PExpr*l, PExpr*r);
~PEBinary() override; ~PEBinary();
virtual void dump(std::ostream&out) const override; virtual void dump(std::ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const override; virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
protected: protected:
char op_; char op_;
@ -792,13 +766,13 @@ class PEBComp : public PEBinary {
public: public:
explicit PEBComp(char op, PExpr*l, PExpr*r); explicit PEBComp(char op, PExpr*l, PExpr*r);
~PEBComp() override; ~PEBComp();
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
NetExpr* elaborate_expr(Design*des, NetScope*scope, NetExpr* elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const override; unsigned expr_wid, unsigned flags) const;
private: private:
unsigned l_width_; unsigned l_width_;
@ -812,13 +786,13 @@ class PEBLogic : public PEBinary {
public: public:
explicit PEBLogic(char op, PExpr*l, PExpr*r); explicit PEBLogic(char op, PExpr*l, PExpr*r);
~PEBLogic() override; ~PEBLogic();
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
NetExpr* elaborate_expr(Design*des, NetScope*scope, NetExpr* elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const override; unsigned expr_wid, unsigned flags) const;
}; };
/* /*
@ -830,38 +804,38 @@ class PEBLeftWidth : public PEBinary {
public: public:
explicit PEBLeftWidth(char op, PExpr*l, PExpr*r); explicit PEBLeftWidth(char op, PExpr*l, PExpr*r);
~PEBLeftWidth() override =0; ~PEBLeftWidth() =0;
virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const =0; unsigned expr_wid) const =0;
protected: protected:
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
}; };
class PEBPower : public PEBLeftWidth { class PEBPower : public PEBLeftWidth {
public: public:
explicit PEBPower(char op, PExpr*l, PExpr*r); explicit PEBPower(char op, PExpr*l, PExpr*r);
~PEBPower() override; ~PEBPower();
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const override; unsigned expr_wid) const;
}; };
class PEBShift : public PEBLeftWidth { class PEBShift : public PEBLeftWidth {
public: public:
explicit PEBShift(char op, PExpr*l, PExpr*r); explicit PEBShift(char op, PExpr*l, PExpr*r);
~PEBShift() override; ~PEBShift();
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
unsigned expr_wid) const override; unsigned expr_wid) const;
}; };
/* /*
@ -872,20 +846,20 @@ class PETernary : public PExpr {
public: public:
explicit PETernary(PExpr*e, PExpr*t, PExpr*f); explicit PETernary(PExpr*e, PExpr*t, PExpr*f);
~PETernary() override; ~PETernary();
virtual void dump(std::ostream&out) const override; virtual void dump(std::ostream&out) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
virtual bool has_aa_term(Design*des, NetScope*scope) const override; virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*, virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
private: private:
NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope, NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope,
@ -905,53 +879,43 @@ class PETernary : public PExpr {
*/ */
class PECallFunction : public PExpr { class PECallFunction : public PExpr {
public: public:
explicit PECallFunction(const pform_name_t &n, const std::vector<named_pexpr_t> &parms); explicit PECallFunction(const pform_name_t&n, const std::vector<PExpr *> &parms);
// Call function defined in package. // Call function defined in package.
explicit PECallFunction(PPackage *pkg, const pform_name_t &n, const std::list<named_pexpr_t> &parms); explicit PECallFunction(PPackage*pkg, perm_string n, const std::vector<PExpr *> &parms);
explicit PECallFunction(PPackage*pkg, perm_string n, const std::list<PExpr *> &parms);
// Used to convert a user function called as a task // Used to convert a user function called as a task
explicit PECallFunction(PPackage *pkg, const pform_name_t &n, const std::vector<named_pexpr_t> &parms); explicit PECallFunction(PPackage*pkg, const pform_name_t&n, const std::vector<PExpr *> &parms);
// Call of system function (name is not hierarchical) // Call of system function (name is not hierarchical)
explicit PECallFunction(perm_string n, const std::vector<named_pexpr_t> &parms); explicit PECallFunction(perm_string n, const std::vector<PExpr *> &parms);
explicit PECallFunction(perm_string n); explicit PECallFunction(perm_string n);
// std::list versions. Should be removed! // std::list versions. Should be removed!
explicit PECallFunction(const pform_name_t &n, const std::list<named_pexpr_t> &parms); explicit PECallFunction(const pform_name_t&n, const std::list<PExpr *> &parms);
explicit PECallFunction(perm_string n, const std::list<named_pexpr_t> &parms); explicit PECallFunction(perm_string n, const std::list<PExpr *> &parms);
// SystemVerilog: prefix().method(args) — prefix elaborates to a class handle. ~PECallFunction();
explicit PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
const std::vector<named_pexpr_t> &parms);
explicit PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
const std::list<named_pexpr_t> &parms);
~PECallFunction() override; virtual void dump(std::ostream &) const;
// For chained-call resolution (path is only the final method name). virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
const pform_scoped_name_t& peek_path(void) const { return path_; }
const PExpr* peek_chain_prefix(void) const { return chain_prefix_; }
virtual void dump(std::ostream &) const override; virtual bool has_aa_term(Design*des, NetScope*scope) const;
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const override; unsigned expr_wid, unsigned flags) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
private: private:
pform_scoped_name_t path_; PPackage*package_;
std::vector<named_pexpr_t> parms_; pform_name_t path_;
// If non-null, this call is prefix().tail_name(...) (SV method chain). std::vector<PExpr *> parms_;
PExpr* chain_prefix_ = nullptr;
// For system functions. // For system functions.
bool is_overridden_; bool is_overridden_;
@ -964,11 +928,14 @@ class PECallFunction : public PExpr {
NetExpr* elaborate_expr_(Design *des, NetScope *scope, NetExpr* elaborate_expr_(Design *des, NetScope *scope,
unsigned flags) const; unsigned flags) const;
NetExpr*elaborate_expr_pkg_(Design*des, NetScope*scope,
unsigned flags)const;
NetExpr* elaborate_expr_method_(Design*des, NetScope*scope, NetExpr* elaborate_expr_method_(Design*des, NetScope*scope,
symbol_search_results&search_results) symbol_search_results&search_results)
const; const;
NetExpr* elaborate_expr_method_par_(Design*des, const NetScope*scope, NetExpr* elaborate_expr_method_par_(Design*des, NetScope*scope,
const symbol_search_results&search_results) symbol_search_results&search_results)
const; const;
@ -980,35 +947,16 @@ class PECallFunction : public PExpr {
unsigned test_width_sfunc_(Design*des, NetScope*scope, unsigned test_width_sfunc_(Design*des, NetScope*scope,
width_mode_t&mode); width_mode_t&mode);
unsigned test_width_method_(Design*des, NetScope*scope, unsigned test_width_method_(Design*des, NetScope*scope,
const symbol_search_results&search_results, symbol_search_results&search_results,
width_mode_t&mode); width_mode_t&mode);
NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope, NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
unsigned flags) const; unsigned flags) const;
unsigned elaborate_arguments_(Design*des, NetScope*scope, unsigned elaborate_arguments_(Design*des, NetScope*scope,
const NetFuncDef*def, bool need_const, NetFuncDef*def, bool need_const,
std::vector<NetExpr*>&parms, std::vector<NetExpr*>&parms,
unsigned parm_off, unsigned parm_off) const;
const std::vector<named_pexpr_t>*src_parms = nullptr) const;
NetExpr* elaborate_class_method_net_(Design*des, NetScope*scope,
NetNet*net, const netclass_t*class_type,
perm_string method_name,
const std::vector<named_pexpr_t>*src_parms) const;
NetExpr* elaborate_class_method_net_this_(Design*des, NetScope*scope,
NetExpr* this_expr,
const netclass_t*class_type,
perm_string method_name,
const std::vector<named_pexpr_t>*src_parms) const;
NetExpr* elaborate_expr_method_chained_(Design*des, NetScope*scope,
symbol_search_results&search_results) const;
NetExpr* elaborate_expr_chain_(Design*des, NetScope*scope, unsigned flags) const;
unsigned test_width_chain_(Design*des, NetScope*scope, width_mode_t&mode);
}; };
/* /*
@ -1018,18 +966,18 @@ class PECastSize : public PExpr {
public: public:
explicit PECastSize(PExpr*size, PExpr*base); explicit PECastSize(PExpr*size, PExpr*base);
~PECastSize() override; ~PECastSize();
void dump(std::ostream &out) const override; void dump(std::ostream &out) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
virtual bool has_aa_term(Design *des, NetScope *scope) const override; virtual bool has_aa_term(Design *des, NetScope *scope) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
private: private:
PExpr* size_; PExpr* size_;
@ -1043,20 +991,20 @@ class PECastType : public PExpr {
public: public:
explicit PECastType(data_type_t*target, PExpr*base); explicit PECastType(data_type_t*target, PExpr*base);
~PECastType() override; ~PECastType();
void dump(std::ostream &out) const override; void dump(std::ostream &out) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const override; ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned flags) const override; unsigned expr_wid, unsigned flags) const;
virtual bool has_aa_term(Design *des, NetScope *scope) const override; virtual bool has_aa_term(Design *des, NetScope *scope) const;
virtual unsigned test_width(Design*des, NetScope*scope, virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode) override; width_mode_t&mode);
private: private:
data_type_t* target_; data_type_t* target_;
@ -1071,16 +1019,16 @@ class PECastSign : public PExpr {
public: public:
explicit PECastSign(bool signed_flag, PExpr *base); explicit PECastSign(bool signed_flag, PExpr *base);
~PECastSign() override = default; ~PECastSign() = default;
void dump(std::ostream &out) const override; void dump(std::ostream &out) const;
NetExpr* elaborate_expr(Design *des, NetScope *scope, NetExpr* elaborate_expr(Design *des, NetScope *scope,
unsigned expr_wid, unsigned flags) const override; unsigned expr_wid, unsigned flags) const;
virtual bool has_aa_term(Design *des, NetScope *scope) const override; virtual bool has_aa_term(Design *des, NetScope *scope) const;
unsigned test_width(Design *des, NetScope *scope, width_mode_t &mode) override; unsigned test_width(Design *des, NetScope *scope, width_mode_t &mode);
private: private:
std::unique_ptr<PExpr> base_; std::unique_ptr<PExpr> base_;
@ -1094,11 +1042,11 @@ class PEVoid : public PExpr {
public: public:
explicit PEVoid(); explicit PEVoid();
~PEVoid() override; ~PEVoid();
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
unsigned expr_wid, unsigned expr_wid,
unsigned flags) const override; unsigned flags) const;
}; };
#endif /* IVL_PExpr_H */ #endif /* IVL_PExpr_H */

View File

@ -20,6 +20,7 @@
# include "config.h" # include "config.h"
# include "PTask.h" # include "PTask.h"
# include "Statement.h" # include "Statement.h"
# include <cassert>
# include "ivl_assert.h" # include "ivl_assert.h"
using namespace std; using namespace std;
@ -37,8 +38,8 @@ PFunction::~PFunction()
void PFunction::set_statement(Statement*s) void PFunction::set_statement(Statement*s)
{ {
ivl_assert(*this, s != 0); assert(s != 0);
ivl_assert(*this, statement_ == 0); assert(statement_ == 0);
statement_ = s; statement_ = s;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -22,42 +22,48 @@
# include "PGate.h" # include "PGate.h"
# include "PExpr.h" # include "PExpr.h"
# include "verinum.h" # include "verinum.h"
# include "ivl_assert.h" # include <cassert>
using namespace std; using namespace std;
void PGate::set_pins_(list<PExpr*>*pins) void PGate::set_pins_(list<PExpr*>*pins)
{ {
ivl_assert(*this, pins); assert(pins);
ivl_assert(*this, pins->size() == pins_.size()); assert(pins->size() == pins_.size());
for (size_t idx = 0 ; idx < pins_.size() ; idx += 1) { for (size_t idx = 0 ; idx < pins_.size() ; idx += 1) {
pins_[idx] = pins->front(); pins_[idx] = pins->front();
pins->pop_front(); pins->pop_front();
} }
ivl_assert(*this, pins->empty()); assert(pins->empty());
delete pins; delete pins;
} }
PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del) PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr) : name_(name), pins_(pins? pins->size() : 0), ranges_(0)
{ {
if (pins) set_pins_(pins); if (pins) set_pins_(pins);
if (del) delay_.set_delays(del); if (del) delay_.set_delays(del);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
} }
PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del) PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del)
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr) : name_(name), pins_(pins? pins->size() : 0), ranges_(0)
{ {
if (pins) set_pins_(pins); if (pins) set_pins_(pins);
if (del) delay_.set_delay(del); if (del) delay_.set_delay(del);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
} }
PGate::PGate(perm_string name, list<PExpr*>*pins) PGate::PGate(perm_string name, list<PExpr*>*pins)
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr) : name_(name), pins_(pins? pins->size() : 0), ranges_(0)
{ {
if (pins) set_pins_(pins); if (pins) set_pins_(pins);
str0_ = IVL_DR_STRONG;
str1_ = IVL_DR_STRONG;
} }
PGate::~PGate() PGate::~PGate()
@ -66,18 +72,28 @@ PGate::~PGate()
void PGate::set_ranges(list<pform_range_t>*ranges) void PGate::set_ranges(list<pform_range_t>*ranges)
{ {
ivl_assert(*this, ranges_ == 0); assert(ranges_ == 0);
ranges_ = ranges; ranges_ = ranges;
} }
drive_strength_t PGate::strength() const ivl_drive_t PGate::strength0() const
{ {
return strength_; return str0_;
} }
void PGate::strength(const drive_strength_t &str) void PGate::strength0(ivl_drive_t s)
{ {
strength_ = str; str0_ = s;
}
ivl_drive_t PGate::strength1() const
{
return str1_;
}
void PGate::strength1(ivl_drive_t s)
{
str1_ = s;
} }
void PGate::elaborate_scope(Design*, NetScope*) const void PGate::elaborate_scope(Design*, NetScope*) const
@ -93,10 +109,15 @@ void PGate::elaborate_scope(Design*, NetScope*) const
* numbers of expressions. * numbers of expressions.
*/ */
void PGate::eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays, void PGate::eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_expr,
NetExpr*&fall_expr,
NetExpr*&decay_expr,
bool as_net_flag) const bool as_net_flag) const
{ {
delay_.eval_delays(des, scope, delays, as_net_flag); delay_.eval_delays(des, scope,
rise_expr, fall_expr, decay_expr,
as_net_flag);
} }
unsigned PGate::delay_count() const unsigned PGate::delay_count() const
@ -112,13 +133,13 @@ PNamedItem::SymbolType PGate::symbol_type() const
PGAssign::PGAssign(list<PExpr*>*pins) PGAssign::PGAssign(list<PExpr*>*pins)
: PGate(perm_string(), pins) : PGate(perm_string(), pins)
{ {
ivl_assert(*this, pin_count() == 2); assert(pin_count() == 2);
} }
PGAssign::PGAssign(list<PExpr*>*pins, list<PExpr*>*dels) PGAssign::PGAssign(list<PExpr*>*pins, list<PExpr*>*dels)
: PGate(perm_string(), pins, dels) : PGate(perm_string(), pins, dels)
{ {
ivl_assert(*this, pin_count() == 2); assert(pin_count() == 2);
} }
PGAssign::~PGAssign() PGAssign::~PGAssign()
@ -127,7 +148,7 @@ PGAssign::~PGAssign()
PGBuiltin::PGBuiltin(Type t, perm_string name, PGBuiltin::PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins, list<PExpr*>*pins,
const list<PExpr*>*del) list<PExpr*>*del)
: PGate(name, pins, del), type_(t) : PGate(name, pins, del), type_(t)
{ {
} }
@ -249,7 +270,7 @@ PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
} }
PGModule::PGModule(perm_string type, perm_string name, PGModule::PGModule(perm_string type, perm_string name,
named_pexpr_t *pins, unsigned npins) named<PExpr*>*pins, unsigned npins)
: PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins), : PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0) npins_(npins), parms_(0), nparms_(0)
{ {
@ -267,14 +288,14 @@ PGModule::~PGModule()
void PGModule::set_parameters(list<PExpr*>*o) void PGModule::set_parameters(list<PExpr*>*o)
{ {
ivl_assert(*this, overrides_ == 0); assert(overrides_ == 0);
overrides_ = o; overrides_ = o;
} }
void PGModule::set_parameters(named_pexpr_t *pa, unsigned npa) void PGModule::set_parameters(named<PExpr*>*pa, unsigned npa)
{ {
ivl_assert(*this, parms_ == 0); assert(parms_ == 0);
ivl_assert(*this, overrides_ == 0); assert(overrides_ == 0);
parms_ = pa; parms_ = pa;
nparms_ = npa; nparms_ = npa;
} }

74
PGate.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PGate_H #ifndef IVL_PGate_H
#define IVL_PGate_H #define IVL_PGate_H
/* /*
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -31,8 +31,6 @@
class PExpr; class PExpr;
class PUdp; class PUdp;
class Module; class Module;
struct delay_exprs_t;
struct drive_strength_t;
/* /*
* A PGate represents a Verilog gate. The gate has a name and other * A PGate represents a Verilog gate. The gate has a name and other
@ -59,7 +57,7 @@ class PGate : public PNamedItem {
explicit PGate(perm_string name, std::list<PExpr*>*pins); explicit PGate(perm_string name, std::list<PExpr*>*pins);
virtual ~PGate() override; virtual ~PGate();
void set_ranges(std::list<pform_range_t>*ranges); void set_ranges(std::list<pform_range_t>*ranges);
bool is_array() const { return ranges_ != 0; } bool is_array() const { return ranges_ != 0; }
@ -68,7 +66,10 @@ class PGate : public PNamedItem {
// This evaluates the delays as far as possible, but returns // This evaluates the delays as far as possible, but returns
// an expression, and do not signal errors. // an expression, and do not signal errors.
void eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays, void eval_delays(Design*des, NetScope*scope,
NetExpr*&rise_time,
NetExpr*&fall_time,
NetExpr*&decay_time,
bool as_net_flag =false) const; bool as_net_flag =false) const;
unsigned delay_count() const; unsigned delay_count() const;
@ -76,9 +77,11 @@ class PGate : public PNamedItem {
unsigned pin_count() const { return pins_.size(); } unsigned pin_count() const { return pins_.size(); }
PExpr*pin(unsigned idx) const { return pins_[idx]; } PExpr*pin(unsigned idx) const { return pins_[idx]; }
drive_strength_t strength() const; ivl_drive_t strength0() const;
ivl_drive_t strength1() const;
void strength(const drive_strength_t &str); void strength0(ivl_drive_t);
void strength1(ivl_drive_t);
std::map<perm_string,PExpr*> attributes; std::map<perm_string,PExpr*> attributes;
@ -87,7 +90,7 @@ class PGate : public PNamedItem {
virtual void elaborate_scope(Design*des, NetScope*sc) const; virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const; virtual bool elaborate_sig(Design*des, NetScope*scope) const;
SymbolType symbol_type() const override; SymbolType symbol_type() const;
protected: protected:
const std::vector<PExpr*>& get_pins() const { return pins_; } const std::vector<PExpr*>& get_pins() const { return pins_; }
@ -106,7 +109,7 @@ class PGate : public PNamedItem {
std::list<pform_range_t>*ranges_; std::list<pform_range_t>*ranges_;
drive_strength_t strength_; ivl_drive_t str0_, str1_;
void set_pins_(std::list<PExpr*>*pins); void set_pins_(std::list<PExpr*>*pins);
@ -124,15 +127,14 @@ class PGAssign : public PGate {
public: public:
explicit PGAssign(std::list<PExpr*>*pins); explicit PGAssign(std::list<PExpr*>*pins);
explicit PGAssign(std::list<PExpr*>*pins, std::list<PExpr*>*dels); explicit PGAssign(std::list<PExpr*>*pins, std::list<PExpr*>*dels);
~PGAssign() override; ~PGAssign();
void dump(std::ostream&out, unsigned ind =4) const override; void dump(std::ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*des, NetScope*scope) const override; virtual void elaborate(Design*des, NetScope*scope) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private: private:
void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval, void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const;
const drive_strength_t &drive,
const delay_exprs_t &delays) const;
}; };
@ -157,17 +159,18 @@ class PGBuiltin : public PGate {
public: public:
explicit PGBuiltin(Type t, perm_string name, explicit PGBuiltin(Type t, perm_string name,
std::list<PExpr*>*pins, std::list<PExpr*>*pins,
const std::list<PExpr*>*del); std::list<PExpr*>*del);
explicit PGBuiltin(Type t, perm_string name, explicit PGBuiltin(Type t, perm_string name,
std::list<PExpr*>*pins, std::list<PExpr*>*pins,
PExpr*del); PExpr*del);
~PGBuiltin() override; ~PGBuiltin();
Type type() const { return type_; } Type type() const { return type_; }
const char * gate_name() const; const char * gate_name() const;
virtual void dump(std::ostream&out, unsigned ind =4) const override; virtual void dump(std::ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*, NetScope*scope) const override; virtual void elaborate(Design*, NetScope*scope) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
private: private:
void calculate_gate_and_lval_count_(unsigned&gate_count, void calculate_gate_and_lval_count_(unsigned&gate_count,
@ -201,23 +204,25 @@ class PGModule : public PGate {
// If the binding of ports is by name, this constructor takes // If the binding of ports is by name, this constructor takes
// the bindings and stores them for later elaboration. // the bindings and stores them for later elaboration.
explicit PGModule(perm_string type, perm_string name, explicit PGModule(perm_string type, perm_string name,
named_pexpr_t *pins, unsigned npins); named<PExpr*>*pins, unsigned npins);
// If the module type is known by design, then use this // If the module type is known by design, then use this
// constructor. // constructor.
explicit PGModule(Module*type, perm_string name); explicit PGModule(Module*type, perm_string name);
~PGModule() override; ~PGModule();
// Parameter overrides can come as an ordered list, or a set // Parameter overrides can come as an ordered list, or a set
// of named expressions. // of named expressions.
void set_parameters(std::list<PExpr*>*o); void set_parameters(std::list<PExpr*>*o);
void set_parameters(named_pexpr_t *pa, unsigned npa); void set_parameters(named<PExpr*>*pa, unsigned npa);
virtual void dump(std::ostream&out, unsigned ind =4) const override; std::map<perm_string,PExpr*> attributes;
virtual void elaborate(Design*, NetScope*scope) const override;
virtual void elaborate_scope(Design*des, NetScope*sc) const override; virtual void dump(std::ostream&out, unsigned ind =4) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const override; 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 // This returns the module name of this module. It is a
// permallocated string. // permallocated string.
@ -227,28 +232,19 @@ class PGModule : public PGate {
Module*bound_type_; Module*bound_type_;
perm_string type_; perm_string type_;
std::list<PExpr*>*overrides_; std::list<PExpr*>*overrides_;
named_pexpr_t *pins_; named<PExpr*>*pins_;
unsigned npins_; unsigned npins_;
// These members support parameter override by name // These members support parameter override by name
named_pexpr_t *parms_; named<PExpr*>*parms_;
unsigned nparms_; unsigned nparms_;
friend class delayed_elaborate_scope_mod_instances; friend class delayed_elaborate_scope_mod_instances;
void elaborate_mod_(Design*, const Module*mod, NetScope*scope) const; void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
void elaborate_udp_(Design*, PUdp *udp, 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_(Design*des, Module*mod, NetScope*sc) const;
void elaborate_scope_mod_instances_(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, const Module*mod) const; bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
bool bind_interface_ports_(Design*des, const Module*mod,
NetScope*parent_scope, NetScope*instance_scope,
const std::vector<PExpr*>&pins,
const std::vector<bool>&pins_fromwc) const;
bool match_module_ports_(Design*des, const Module*mod,
NetScope*scope,
std::vector<PExpr*>&pins,
std::vector<bool>&pins_fromwc,
std::vector<bool>&pins_is_explicitly_not_connected) const;
// Not currently used. // Not currently used.
#if 0 #if 0
bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const; bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const;

View File

@ -1,7 +1,7 @@
#ifndef IVL_PGenerate_H #ifndef IVL_PGenerate_H
#define IVL_PGenerate_H #define IVL_PGenerate_H
/* /*
* Copyright (c) 2006-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 2006-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -26,12 +26,10 @@
# include <list> # include <list>
# include <map> # include <map>
# include <valarray> # include <valarray>
# include <vector>
# include "pform_types.h" # include "pform_types.h"
class Design; class Design;
class NetScope; class NetScope;
class PClass;
class PExpr; class PExpr;
class PFunction; class PFunction;
class PProcess; class PProcess;
@ -56,7 +54,7 @@ class PGenerate : public PNamedItem, public LexicalScope {
public: public:
explicit PGenerate(LexicalScope*parent, unsigned id_number); explicit PGenerate(LexicalScope*parent, unsigned id_number);
~PGenerate() override; ~PGenerate();
// Generate schemes have an ID number, for when the scope is // Generate schemes have an ID number, for when the scope is
// implicit. // implicit.
@ -94,11 +92,9 @@ class PGenerate : public PNamedItem, public LexicalScope {
std::list<PGate*> gates; std::list<PGate*> gates;
void add_gate(PGate*); void add_gate(PGate*);
// Definitions instantiated within this scheme. // Tasks instantiated within this scheme.
std::map<perm_string,PTask*> tasks; std::map<perm_string,PTask*> tasks;
std::map<perm_string,PFunction*>funcs; std::map<perm_string,PFunction*>funcs;
std::map<perm_string,PClass*> classes;
std::vector<PClass*> classes_lexical;
// Generate schemes can contain further generate schemes. // Generate schemes can contain further generate schemes.
std::list<PGenerate*> generate_schemes; std::list<PGenerate*> generate_schemes;
@ -116,7 +112,7 @@ class PGenerate : public PNamedItem, public LexicalScope {
void dump(std::ostream&out, unsigned indent) const; void dump(std::ostream&out, unsigned indent) const;
SymbolType symbol_type() const override; SymbolType symbol_type() const;
private: private:
void check_for_valid_genvar_value_(long value); void check_for_valid_genvar_value_(long value);

View File

@ -1,7 +1,7 @@
#ifndef IVL_PModport_H #ifndef IVL_PModport_H
#define IVL_PModport_H #define IVL_PModport_H
/* /*
* Copyright (c) 2015-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 2015-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -34,14 +34,14 @@ class PModport : public PNamedItem {
// The name is a perm-allocated string. It is the simple name // The name is a perm-allocated string. It is the simple name
// of the modport, without any scope. // of the modport, without any scope.
explicit PModport(perm_string name); explicit PModport(perm_string name);
~PModport() override; ~PModport();
perm_string name() const { return name_; } perm_string name() const { return name_; }
typedef std::pair <NetNet::PortType,PExpr*> simple_port_t; typedef std::pair <NetNet::PortType,PExpr*> simple_port_t;
std::map<perm_string,simple_port_t> simple_ports; std::map<perm_string,simple_port_t> simple_ports;
SymbolType symbol_type() const override; SymbolType symbol_type() const;
private: private:
perm_string name_; perm_string name_;

View File

@ -1,7 +1,7 @@
#ifndef IVL_PNamedItem_H #ifndef IVL_PNamedItem_H
#define IVL_PNamedItem_H #define IVL_PNamedItem_H
/* /*
* Copyright (c) 2019-2025 Martin Whitaker (icarus@martin-whitaker.me.uk) * Copyright (c) 2019 Martin Whitaker (icarus@martin-whitaker.me.uk)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -34,7 +34,7 @@ class PNamedItem : virtual public LineInfo {
INSTANCE }; INSTANCE };
explicit PNamedItem(); explicit PNamedItem();
virtual ~PNamedItem() override; virtual ~PNamedItem();
virtual SymbolType symbol_type() const; virtual SymbolType symbol_type() const;
}; };
@ -49,9 +49,9 @@ class PGenvar : public PNamedItem {
public: public:
explicit PGenvar(); explicit PGenvar();
virtual ~PGenvar() override; virtual ~PGenvar();
SymbolType symbol_type() const override; SymbolType symbol_type() const;
}; };
#endif /* IVL_PNamedItem_H */ #endif /* IVL_PNamedItem_H */

View File

@ -1,7 +1,7 @@
#ifndef IVL_PPackage_H #ifndef IVL_PPackage_H
#define IVL_PPackage_H #define IVL_PPackage_H
/* /*
* Copyright (c) 2012-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -24,7 +24,6 @@
# include "LineInfo.h" # include "LineInfo.h"
# include "StringHeap.h" # include "StringHeap.h"
# include <iostream> # include <iostream>
# include <vector>
/* /*
* SystemVerilog supports class declarations with their own lexical * SystemVerilog supports class declarations with their own lexical
@ -36,20 +35,13 @@ class PPackage : public PScopeExtra, public LineInfo {
public: public:
explicit PPackage (perm_string name, LexicalScope*parent); explicit PPackage (perm_string name, LexicalScope*parent);
~PPackage() override; ~PPackage();
bool elaborate_scope(Design*des, NetScope*scope); bool elaborate_scope(Design*des, NetScope*scope);
bool elaborate_sig(Design*des, NetScope*scope) const; bool elaborate_sig(Design*des, NetScope*scope) const;
bool elaborate(Design*des, NetScope*scope) const; bool elaborate(Design*des, NetScope*scope) const;
void pform_dump(std::ostream&out) const; void pform_dump(std::ostream&out) const;
struct export_t {
PPackage *pkg;
perm_string name;
};
std::vector<export_t> exports;
}; };
#endif /* IVL_PPackage_H */ #endif /* IVL_PPackage_H */

View File

@ -1,7 +1,7 @@
#ifndef IVL_PScope_H #ifndef IVL_PScope_H
#define IVL_PScope_H #define IVL_PScope_H
/* /*
* Copyright (c) 2008-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 2008-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -25,7 +25,6 @@
# include "ivl_target.h" # include "ivl_target.h"
# include <map> # include <map>
# include <set> # include <set>
# include <unordered_set>
# include <vector> # include <vector>
class PEvent; class PEvent;
@ -68,14 +67,9 @@ class LexicalScope {
// Symbols that are defined or declared in this scope. // Symbols that are defined or declared in this scope.
std::map<perm_string,PNamedItem*>local_symbols; std::map<perm_string,PNamedItem*>local_symbols;
// Symbols that are explicitly imported. This contains the package where // Symbols that are explicitly imported. Bind the imported name
// the symbol has been decelared. When using exports, this might not be // to the package from which the name is imported.
// the same as the package where it has been imported from.
std::map<perm_string,PPackage*>explicit_imports; std::map<perm_string,PPackage*>explicit_imports;
// Symbols that are explicitly imported. This contains the set of
// packages from which the symbol has been imported. When using exports
// the same identifier can be imported via multiple packages.
std::map<perm_string,std::unordered_set<PPackage*>> explicit_imports_from;
// Packages that are wildcard imported. When identifiers from // Packages that are wildcard imported. When identifiers from
// these packages are referenced, they will be added to the // these packages are referenced, they will be added to the
@ -121,10 +115,6 @@ class LexicalScope {
bool overridable; bool overridable;
// Whether the parameter is a type parameter // Whether the parameter is a type parameter
bool type_flag = false; bool type_flag = false;
// Type restriction for a type parameter
type_restrict_t type_restrict;
// The lexical position of the declaration
unsigned lexical_pos = 0;
SymbolType symbol_type() const; SymbolType symbol_type() const;
}; };
@ -200,7 +190,7 @@ class PScope : public LexicalScope {
// modules. Scopes for tasks and functions point to their // modules. Scopes for tasks and functions point to their
// containing module. // containing module.
explicit PScope(perm_string name, LexicalScope*parent =0); explicit PScope(perm_string name, LexicalScope*parent =0);
virtual ~PScope() override; virtual ~PScope();
perm_string pscope_name() const { return name_; } perm_string pscope_name() const { return name_; }
@ -235,7 +225,7 @@ class PScopeExtra : public PScope {
public: public:
explicit PScopeExtra(perm_string, LexicalScope*parent =0); explicit PScopeExtra(perm_string, LexicalScope*parent =0);
~PScopeExtra() override; ~PScopeExtra();
/* Task definitions within this module */ /* Task definitions within this module */
std::map<perm_string,PTask*> tasks; std::map<perm_string,PTask*> tasks;

View File

@ -19,11 +19,10 @@
# include "PSpec.h" # include "PSpec.h"
PSpecPath::PSpecPath(const std::list<perm_string> &src_list, PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity,
const std::list<perm_string> &dst_list, bool full_flag)
char polarity, bool full_flag)
: conditional(false), condition(0), edge(0), : conditional(false), condition(0), edge(0),
src(src_list.begin(), src_list.end()), dst(dst_list.begin(), dst_list.end()), src(src_cnt), dst(dst_cnt),
data_source_expression(0) data_source_expression(0)
{ {
full_flag_ = full_flag; full_flag_ = full_flag;

10
PSpec.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PSpec_H #ifndef IVL_PSpec_H
#define IVL_PSpec_H #define IVL_PSpec_H
/* /*
* Copyright (c) 2006-2025 Stephen Williams <steve@icarus.com> * Copyright (c) 2006-2014 Stephen Williams <steve@icarus.com>
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -22,7 +22,6 @@
# include "LineInfo.h" # include "LineInfo.h"
# include "StringHeap.h" # include "StringHeap.h"
# include <vector> # include <vector>
# include <list>
class PExpr; class PExpr;
@ -57,10 +56,9 @@ class PExpr;
class PSpecPath : public LineInfo { class PSpecPath : public LineInfo {
public: public:
PSpecPath(const std::list<perm_string> &src_list, PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity,
const std::list<perm_string> &dst_list, bool full_flag);
char polarity, bool full_flag); ~PSpecPath();
~PSpecPath() override;
void elaborate(class Design*des, class NetScope*scope) const; void elaborate(class Design*des, class NetScope*scope) const;

View File

@ -18,8 +18,8 @@
*/ */
# include "config.h" # include "config.h"
# include "PTask.h" # include "PTask.h"
# include "ivl_assert.h" # include <cassert>
using namespace std; using namespace std;
@ -39,13 +39,13 @@ bool PTaskFunc::var_init_needs_explicit_lifetime() const
void PTaskFunc::set_ports(vector<pform_tf_port_t>*p) void PTaskFunc::set_ports(vector<pform_tf_port_t>*p)
{ {
ivl_assert(*this, ports_ == 0); assert(ports_ == 0);
ports_ = p; ports_ = p;
} }
void PTaskFunc::set_this(class_type_t*type, PWire*this_wire) void PTaskFunc::set_this(class_type_t*type, PWire*this_wire)
{ {
ivl_assert(*this, this_type_ == 0); assert(this_type_ == 0);
this_type_ = type; this_type_ = type;
// Push a synthesis argument that is the "this" value. // Push a synthesis argument that is the "this" value.
@ -72,7 +72,7 @@ PTask::~PTask()
void PTask::set_statement(Statement*s) void PTask::set_statement(Statement*s)
{ {
ivl_assert(*this, statement_ == 0); assert(statement_ == 0);
statement_ = s; statement_ = s;
} }

37
PTask.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PTask_H #ifndef IVL_PTask_H
#define IVL_PTask_H #define IVL_PTask_H
/* /*
* Copyright (c) 1999-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -39,9 +39,9 @@ class PTaskFunc : public PScope, public PNamedItem {
public: public:
PTaskFunc(perm_string name, LexicalScope*parent); PTaskFunc(perm_string name, LexicalScope*parent);
~PTaskFunc() override; ~PTaskFunc();
bool var_init_needs_explicit_lifetime() const override; bool var_init_needs_explicit_lifetime() const;
void set_ports(std::vector<pform_tf_port_t>*p); void set_ports(std::vector<pform_tf_port_t>*p);
@ -63,8 +63,7 @@ class PTaskFunc : public PScope, public PNamedItem {
// default value expressions, if any. // default value expressions, if any.
void elaborate_sig_ports_(Design*des, NetScope*scope, void elaborate_sig_ports_(Design*des, NetScope*scope,
std::vector<NetNet*>&ports, std::vector<NetNet*>&ports,
std::vector<NetExpr*> &pdefs, std::vector<NetExpr*>&pdefs) const;
std::vector<perm_string> &port_names) const;
void dump_ports_(std::ostream&out, unsigned ind) const; void dump_ports_(std::ostream&out, unsigned ind) const;
@ -80,7 +79,7 @@ class PTask : public PTaskFunc {
public: public:
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto); explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
~PTask() override; ~PTask();
void set_statement(Statement *s); void set_statement(Statement *s);
@ -91,16 +90,16 @@ class PTask : public PTaskFunc {
void elaborate_scope(Design*des, NetScope*scope) const; void elaborate_scope(Design*des, NetScope*scope) const;
// Bind the ports to the regs that are the ports. // Bind the ports to the regs that are the ports.
void elaborate_sig(Design*des, NetScope*scope) const override; void elaborate_sig(Design*des, NetScope*scope) const;
// Elaborate the statement to finish off the task definition. // Elaborate the statement to finish off the task definition.
void elaborate(Design*des, NetScope*scope) const override; void elaborate(Design*des, NetScope*scope) const;
bool is_auto() const { return is_auto_; }; bool is_auto() const { return is_auto_; };
void dump(std::ostream&, unsigned) const override; void dump(std::ostream&, unsigned) const;
SymbolType symbol_type() const override; SymbolType symbol_type() const;
private: private:
Statement*statement_; Statement*statement_;
@ -122,7 +121,7 @@ class PFunction : public PTaskFunc {
public: public:
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto); explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
~PFunction() override; ~PFunction();
void set_statement(Statement *s); void set_statement(Statement *s);
void set_return(data_type_t*t); void set_return(data_type_t*t);
@ -142,16 +141,16 @@ class PFunction : public PTaskFunc {
void elaborate_scope(Design*des, NetScope*scope) const; void elaborate_scope(Design*des, NetScope*scope) const;
/* elaborate the ports and return value. */ /* elaborate the ports and return value. */
void elaborate_sig(Design *des, NetScope*) const override; void elaborate_sig(Design *des, NetScope*) const;
/* Elaborate the behavioral statement. */ /* Elaborate the behavioral statement. */
void elaborate(Design *des, NetScope*) const override; void elaborate(Design *des, NetScope*) const;
bool is_auto() const { return is_auto_; }; bool is_auto() const { return is_auto_; };
void dump(std::ostream&, unsigned) const override; void dump(std::ostream&, unsigned) const;
SymbolType symbol_type() const override; SymbolType symbol_type() const;
private: private:
data_type_t* return_type_; data_type_t* return_type_;
@ -174,12 +173,12 @@ class PLet : public PTaskFunc {
// FIXME: Should the port list be a vector. Check once implemented completely // FIXME: Should the port list be a vector. Check once implemented completely
explicit PLet(perm_string name, LexicalScope*parent, explicit PLet(perm_string name, LexicalScope*parent,
std::list<let_port_t*>*ports, PExpr*expr); std::list<let_port_t*>*ports, PExpr*expr);
~PLet() override; ~PLet();
void elaborate_sig(Design*des, NetScope*scope) const override { (void)des; (void)scope; } void elaborate_sig(Design*des, NetScope*scope) const { (void)des; (void)scope; }
void elaborate(Design*des, NetScope*scope) const override { (void)des; (void)scope; } void elaborate(Design*des, NetScope*scope) const { (void)des; (void)scope; }
void dump(std::ostream&, unsigned) const override; void dump(std::ostream&, unsigned) const;
private: private:
std::list<let_port_t*>*ports_; std::list<let_port_t*>*ports_;

View File

@ -1,72 +0,0 @@
/*
* Copyright (c) 2006-2023 Stephen Williams <steve@icarus.com>
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "PTimingCheck.h"
PRecRem::PRecRem(event_t* reference_event,
event_t* data_event,
PExpr* setup_limit,
PExpr* hold_limit,
pform_name_t* notifier,
PExpr* timestamp_cond,
PExpr* timecheck_cond,
pform_name_t* delayed_reference,
pform_name_t* delayed_data)
:
reference_event_ (reference_event),
data_event_ (data_event),
setup_limit_ (setup_limit),
hold_limit_ (hold_limit),
notifier_ (notifier),
timestamp_cond_ (timestamp_cond),
timecheck_cond_ (timecheck_cond),
delayed_reference_ (delayed_reference),
delayed_data_ (delayed_data)
{
}
PRecRem::~PRecRem()
{
}
PSetupHold::PSetupHold(event_t* reference_event,
event_t* data_event,
PExpr* setup_limit,
PExpr* hold_limit,
pform_name_t* notifier,
PExpr* timestamp_cond,
PExpr* timecheck_cond,
pform_name_t* delayed_reference,
pform_name_t* delayed_data)
:
reference_event_ (reference_event),
data_event_ (data_event),
setup_limit_ (setup_limit),
hold_limit_ (hold_limit),
notifier_ (notifier),
timestamp_cond_ (timestamp_cond),
timecheck_cond_ (timecheck_cond),
delayed_reference_ (delayed_reference),
delayed_data_ (delayed_data)
{
}
PSetupHold::~PSetupHold()
{
}

View File

@ -1,139 +0,0 @@
#ifndef IVL_PTimingCheck_H
#define IVL_PTimingCheck_H
/*
* Copyright (c) 2006-2025 Stephen Williams <steve@icarus.com>
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "LineInfo.h"
# include "PExpr.h"
# include "pform_types.h"
# include <memory>
/*
* The PTimingCheck is the base class for all timing checks
*/
class PTimingCheck : public LineInfo {
public:
enum EdgeType {EDGE_01, EDGE_0X, EDGE_10, EDGE_1X, EDGE_X0, EDGE_X1};
struct event_t {
pform_name_t name;
bool posedge;
bool negedge;
std::vector<EdgeType> edges;
std::unique_ptr<PExpr> condition;
};
// This struct is used to parse the optional arguments
struct optional_args_t {
pform_name_t* notifier = nullptr;
PExpr* timestamp_cond = nullptr;
PExpr* timecheck_cond = nullptr;
pform_name_t* delayed_reference = nullptr;
pform_name_t* delayed_data = nullptr;
PExpr* event_based_flag = nullptr;
PExpr* remain_active_flag = nullptr;
};
PTimingCheck() { }
virtual ~PTimingCheck() override { }
virtual void elaborate(class Design*des, class NetScope*scope) const = 0;
virtual void dump(std::ostream&out, unsigned ind) const = 0;
};
/*
* The PRecRem is the parse of a $recrem timing check
*/
class PRecRem : public PTimingCheck {
public:
PRecRem(event_t* reference_event,
event_t* data_event,
PExpr* setup_limit,
PExpr* hold_limit,
pform_name_t* notifier,
PExpr* timestamp_cond,
PExpr* timecheck_cond,
pform_name_t* delayed_reference,
pform_name_t* delayed_data);
~PRecRem() override;
void elaborate(class Design*des, class NetScope*scope) const override;
void dump(std::ostream&out, unsigned ind) const override;
private:
std::unique_ptr<event_t> reference_event_;
std::unique_ptr<event_t> data_event_;
std::unique_ptr<PExpr> setup_limit_;
std::unique_ptr<PExpr> hold_limit_;
std::unique_ptr<pform_name_t> notifier_;
std::unique_ptr<PExpr> timestamp_cond_;
std::unique_ptr<PExpr> timecheck_cond_;
std::unique_ptr<pform_name_t> delayed_reference_;
std::unique_ptr<pform_name_t> delayed_data_;
};
/*
* The PSetupHold is the parse of a $setuphold timing check
*/
class PSetupHold : public PTimingCheck {
public:
PSetupHold(event_t* reference_event,
event_t* data_event,
PExpr* setup_limit,
PExpr* hold_limit,
pform_name_t* notifier,
PExpr* timestamp_cond,
PExpr* timecheck_cond,
pform_name_t* delayed_reference,
pform_name_t* delayed_data);
~PSetupHold() override;
void elaborate(class Design*des, class NetScope*scope) const override;
void dump(std::ostream&out, unsigned ind) const override;
private:
std::unique_ptr<event_t> reference_event_;
std::unique_ptr<event_t> data_event_;
std::unique_ptr<PExpr> setup_limit_;
std::unique_ptr<PExpr> hold_limit_;
std::unique_ptr<pform_name_t> notifier_;
std::unique_ptr<PExpr> timestamp_cond_;
std::unique_ptr<PExpr> timecheck_cond_;
std::unique_ptr<pform_name_t> delayed_reference_;
std::unique_ptr<pform_name_t> delayed_data_;
};
#endif /* IVL_PTimingCheck_H */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2024 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,15 +21,15 @@
# include "ivl_assert.h" # include "ivl_assert.h"
# include "PWire.h" # include "PWire.h"
# include "PExpr.h" # include "PExpr.h"
# include <cassert>
using namespace std; using namespace std;
PWire::PWire(perm_string n, PWire::PWire(perm_string n,
unsigned lp,
NetNet::Type t, NetNet::Type t,
NetNet::PortType pt, NetNet::PortType pt,
PWSRType rt) PWSRType rt)
: name_(n), lexical_pos_(lp), type_(t), port_type_(pt), signed_(false), : name_(n), type_(t), port_type_(pt), signed_(false),
port_set_(false), net_set_(false), is_scalar_(false), port_set_(false), net_set_(false), is_scalar_(false),
error_cnt_(0), discipline_(0) error_cnt_(0), discipline_(0)
{ {
@ -59,7 +59,7 @@ perm_string PWire::basename() const
bool PWire::set_wire_type(NetNet::Type t) bool PWire::set_wire_type(NetNet::Type t)
{ {
ivl_assert(*this, t != NetNet::IMPLICIT); assert(t != NetNet::IMPLICIT);
switch (type_) { switch (type_) {
case NetNet::IMPLICIT: case NetNet::IMPLICIT:
@ -90,8 +90,8 @@ NetNet::PortType PWire::get_port_type() const
bool PWire::set_port_type(NetNet::PortType pt) bool PWire::set_port_type(NetNet::PortType pt)
{ {
ivl_assert(*this, pt != NetNet::NOT_A_PORT); assert(pt != NetNet::NOT_A_PORT);
ivl_assert(*this, pt != NetNet::PIMPLICIT); assert(pt != NetNet::PIMPLICIT);
switch (port_type_) { switch (port_type_) {
case NetNet::PIMPLICIT: case NetNet::PIMPLICIT:
@ -181,13 +181,13 @@ void PWire::set_data_type(data_type_t*type)
if (set_data_type_.get() == type) if (set_data_type_.get() == type)
return; return;
ivl_assert(*this, !set_data_type_.get()); assert(!set_data_type_.get());
set_data_type_.reset(type); set_data_type_.reset(type);
} }
void PWire::set_discipline(ivl_discipline_t d) void PWire::set_discipline(ivl_discipline_t d)
{ {
ivl_assert(*this, discipline_ == 0); assert(discipline_ == 0);
discipline_ = d; discipline_ = d;
} }

22
PWire.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PWire_H #ifndef IVL_PWire_H
#define IVL_PWire_H #define IVL_PWire_H
/* /*
* Copyright (c) 1998-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -55,7 +55,6 @@ class PWire : public PNamedItem {
public: public:
PWire(perm_string name, PWire(perm_string name,
unsigned lexical_pos,
NetNet::Type t, NetNet::Type t,
NetNet::PortType pt, NetNet::PortType pt,
PWSRType rt = SR_NET); PWSRType rt = SR_NET);
@ -63,17 +62,12 @@ class PWire : public PNamedItem {
// Return a hierarchical name. // Return a hierarchical name.
perm_string basename() const; perm_string basename() const;
unsigned lexical_pos() const { return lexical_pos_; }
NetNet::Type get_wire_type() const; NetNet::Type get_wire_type() const;
bool set_wire_type(NetNet::Type); bool set_wire_type(NetNet::Type);
NetNet::PortType get_port_type() const; NetNet::PortType get_port_type() const;
bool set_port_type(NetNet::PortType); bool set_port_type(NetNet::PortType);
void set_const(bool is_const) { is_const_ = is_const; };
bool get_const() const { return is_const_; };
void set_signed(bool flag); void set_signed(bool flag);
bool get_signed() const; bool get_signed() const;
@ -91,9 +85,9 @@ class PWire : public PNamedItem {
// Write myself to the specified stream. // Write myself to the specified stream.
void dump(std::ostream&out, unsigned ind=4) const; void dump(std::ostream&out, unsigned ind=4) const;
NetNet* elaborate_sig(Design*, NetScope*scope); NetNet* elaborate_sig(Design*, NetScope*scope) const;
SymbolType symbol_type() const override; SymbolType symbol_type() const;
bool is_net() const { return net_set_; }; bool is_net() const { return net_set_; };
bool is_port() const { return port_set_; }; bool is_port() const { return port_set_; };
@ -102,16 +96,10 @@ class PWire : public PNamedItem {
private: private:
perm_string name_; perm_string name_;
unsigned lexical_pos_;
NetNet::Type type_; NetNet::Type type_;
NetNet::PortType port_type_; NetNet::PortType port_type_;
bool signed_; bool signed_;
// Whether the wire is variable declared with the const keyword.
bool is_const_ = false;
bool is_elaborating_ = false;
// These members hold expressions for the bit width of the // These members hold expressions for the bit width of the
// wire. If they do not exist, the wire is 1 bit wide. If they // wire. If they do not exist, the wire is 1 bit wide. If they
// do exist, they represent the packed dimensions of the // do exist, they represent the packed dimensions of the
@ -140,10 +128,10 @@ class PWire : public PNamedItem {
PWire& operator= (const PWire&); PWire& operator= (const PWire&);
ivl_type_t elaborate_type(Design*des, NetScope*scope, ivl_type_t elaborate_type(Design*des, NetScope*scope,
const netranges_t &packed_dimensions) const; const std::vector<netrange_t>&packed_dimensions) const;
ivl_type_t elaborate_darray_type(Design*des, NetScope*scope, ivl_type_t elaborate_darray_type(Design*des, NetScope*scope,
const char *darray_type, const char *darray_type,
const netranges_t &packed_dimensions) const std::vector<netrange_t>&packed_dimensions)
const; const;
}; };

83
QUICK_START.txt Normal file
View File

@ -0,0 +1,83 @@
* Getting Started with Icarus Verilog
Icarus Verilog is a Verilog compiler. It is suitable for use as a
simulator, and, to some degree, synthesizer. Icarus Verilog runs under
Linux and a variety of UNIX systems, as well as Windows as a command
line tool, so the instructions are generally applicable to all
environments. Note that this is only a quick start. For more detailed
documentation, see the manual page for the iverilog command.
* Hello, World!
The first thing you want to do as a user 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:
module main;
initial
begin
$display("Hello, World");
$finish ;
end
endmodule
By a text editor (or copy hello.vl from the Icarus Verilog examples
directory) arrange for this program to be in a text file, "hello.vl".
Next, compile this program with a command like this:
% iverilog -o hello hello.vl
The results of this compile are placed into the file "hello", as 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 form is the VVP
format, which is actually run by the "vvp" command.
The "iverilog" and "vvp" commands are the only commands that users
use to invoke Icarus Verilog. What the compiler actually does is
controlled by command line switches. In our little example, we asked
the compiler to compile the source program to the default vvp form,
which is in turn executed by the vvp program.
* Windows Install
The easiest way to install under Windows is to get a precompiled
installer for the version you wish to install. Icarus Verilog is
distributed for Windows users as a self-installing .exe. Just execute
the installer and follow the instructions. During the install, take
note of the directory where the program is installed: for example,
C:\iverilog is a good place to install.
Once the binary is installed, you need to add the bin directory to
your execution path. The executables you need are in C:\iverilog\bin,
where the "C:\iverilog" part is actually the root of where you
installed the package. The programs are in the bin subdirectory. Put
this directory in your PATH environment variable, and the above
commands become accessible to you at the command line prompt, or even
in batch files.
* Linux Install
Under Linux, the install is even easier. For RedHat and Mandrake based
systems, there is the appropriate RPM file. Just install the package
with the "rpm -U <file>" command. Debian users should get Icarus
Verilog packages from the main Debian software site.
* Install From Source
In this case, see README.txt and other documentation that comes with
the source.

268
README.md
View File

@ -1,45 +1,15 @@
# The ICARUS Verilog Compilation System # The ICARUS Verilog Compilation System
Copyright 2000-2026 Stephen Williams Copyright 2000-2019 Stephen Williams
<details>
<summary><h2>Table of Contents</h2></summary>
1. [What is ICARUS Verilog?](#what-is-icarus-verilog)
2. [Building/Installing Icarus Verilog From Source](#buildinginstalling-icarus-verilog-from-source)
- [Compile Time Prerequisites](#compile-time-prerequisites)
- [Compilation](#compilation)
- [(Optional) Testing](#optional-testing)
- [Installation](#installation)
3. [How Icarus Verilog Works](#how-icarus-verilog-works)
- [Preprocessing](#preprocessing)
- [Parse](#parse)
- [Elaboration](#elaboration)
- [Optimization](#optimization)
- [Code Generation](#code-generation)
- [Attributes](#attributes)
4. [Running iverilog](#running-iverilog)
- [Examples](#examples)
5. [Unsupported Constructs](#unsupported-constructs)
6. [Nonstandard Constructs or Behaviors](#nonstandard-constructs-or-behaviors)
- [Builtin system functions](#builtin-system-functions)
- [Preprocessing Library Modules](#preprocessing-library-modules)
- [Width in %t Time Formats](#width-in-t-time-formats)
- [vpiScope iterator on vpiScope objects](#vpiscope-iterator-on-vpiscope-objects)
- [Time 0 Race Resolution](#time-0-race-resolution)
- [Nets with Types](#nets-with-types)
7. [Credits](#credits)
</details>
## What is ICARUS Verilog? ## What is ICARUS Verilog?
Icarus Verilog is intended to compile ALL of the Verilog HDL, as 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 described in the IEEE-1364 standard. Of course, it's not quite there
yet. It also compiles a (slowly growing) subset of the SystemVerilog yet. It does currently handle a mix of structural and behavioural
language, as described in the IEEE 1800 standard. For a view of the constructs. For a view of the current state of Icarus Verilog, see its
current state of Icarus Verilog, see its home page at home page at http://iverilog.icarus.com/.
https://steveicarus.github.io/iverilog/.
Icarus Verilog is not aimed at being a simulator in the traditional Icarus Verilog is not aimed at being a simulator in the traditional
sense, but a compiler that generates code employed by back-end sense, but a compiler that generates code employed by back-end
@ -48,7 +18,7 @@ tools.
> For instructions on how to run Icarus Verilog, see the `iverilog` man page. > For instructions on how to run Icarus Verilog, see the `iverilog` man page.
## Building/Installing Icarus Verilog from Source ## Building/Installing Icarus Verilog From Source
If you are starting from the source, the build process is designed to be If you are starting from the source, the build process is designed to be
as simple as practical. Someone basically familiar with the target as simple as practical. Someone basically familiar with the target
@ -56,12 +26,9 @@ system and C/C++ compilation should be able to build the source
distribution with little effort. Some actual programming skills are distribution with little effort. Some actual programming skills are
not required, but helpful in case of problems. not required, but helpful in case of problems.
### Compile Time Prerequisites > If you are building on Windows, see the mingw.txt file.
You can use: ### Compile Time Prerequisites
```bash
apt install -y autoconf gperf make gcc g++ bison flex
```
You need the following software to compile Icarus Verilog from source You need the following software to compile Icarus Verilog from source
on a UNIX-like system: on a UNIX-like system:
@ -82,7 +49,7 @@ on a UNIX-like system:
OSX note: bison 2.3 shipped with MacOS including Catalina generates OSX note: bison 2.3 shipped with MacOS including Catalina generates
broken code, but bison 3+ works. We recommend using the Fink broken code, but bison 3+ works. We recommend using the Fink
project version of bison and flex (finkproject.org), brew version project version of bison and flex (finkproject.org), brew version
works fine too. works fine either.
- gperf 3.0 or later - gperf 3.0 or later
The lexical analyzer doesn't recognize keywords directly, The lexical analyzer doesn't recognize keywords directly,
@ -110,29 +77,21 @@ on a UNIX-like system:
### Compilation ### Compilation
<details> Unpack the tar-ball and cd into the `verilog-#########` directory
<summary><h4><a href="https://github.com/steveicarus/iverilog/releases">Compiling From Release</a></h4></summary> (presumably, that is how you got to this README) and compile the source
with the commands:
Unpack the tar-ball, `cd` into the `verilog-#########` directory, ```
and compile the source with the commands:
```bash
./configure ./configure
make make
``` ```
</details>
<details>
<summary><h4>Compiling From GitHub</h4></summary>
If you are building from git, you have to run the command below before 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 compiling the source. This will generate the "configure" file, which is
automatically done when building from tarball. automatically done when building from tarball.
```bash ```
sh autoconf.sh sh autoconf.sh
./configure
make
``` ```
Normally, this command automatically figures out everything it needs Normally, this command automatically figures out everything it needs
@ -167,13 +126,12 @@ configure script that modify its behaviour:
i686-w64-mingw32 for building 32-bit Windows executables i686-w64-mingw32 for building 32-bit Windows executables
Both options require installing the required mingw-w64 packages. Both options require installing the required mingw-w64 packages.
``` ```
</details>
### (Optional) Testing ### (Optional) Testing
To run a simple test before installation, execute To run a simple test before installation, execute
```bash ```
make check make check
``` ```
@ -188,7 +146,7 @@ default install in /usr/local unless you specify a different prefix
with the `--prefix=<path>` flag to the configure command.) You may need with the `--prefix=<path>` flag to the configure command.) You may need
to do this as root to gain access to installation directories. to do this as root to gain access to installation directories.
```bash ```
make install make install
``` ```
@ -208,11 +166,11 @@ switches.
### Preprocessing ### Preprocessing
There is a separate program, `ivlpp`, that does the preprocessing. This There is a separate program, ivlpp, that does the preprocessing. This
program implements the `` `include `` and `` `define `` directives producing program implements the `` `include `` and `` `define `` directives producing
output that is equivalent but without the directives. The output is a output that is equivalent but without the directives. The output is a
single file with line number directives, so that the actual compiler single file with line number directives, so that the actual compiler
only sees a single input file. See `ivlpp/ivlpp.txt` for details. only sees a single input file. See ivlpp/ivlpp.txt for details.
### Parse ### Parse
@ -293,7 +251,7 @@ to generate actual output.
The user selects the target code generator with the `-t` flag on the The user selects the target code generator with the `-t` flag on the
command line. command line.
### Attributes ### ATTRIBUTES
> NOTE: The $attribute syntax will soon be deprecated in favour of the Verilog-2001 attribute syntax, which is cleaner and standardized. > NOTE: The $attribute syntax will soon be deprecated in favour of the Verilog-2001 attribute syntax, which is cleaner and standardized.
@ -332,32 +290,31 @@ attributes. They have the same general meaning as with the $attribute
syntax, but they are attached to objects by position instead of by syntax, but they are attached to objects by position instead of by
name. Also, the key is a Verilog identifier instead of a string. name. Also, the key is a Verilog identifier instead of a string.
## Running `iverilog` ## Running iverilog
The preferred way to invoke the compiler is with the `iverilog`(1) The preferred way to invoke the compiler is with the `iverilog`(1)
command. This program invokes the preprocessor (`ivlpp`) and the command. This program invokes the preprocessor (ivlpp) and the
compiler (`ivl`) with the proper command line options to get the job 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. done in a friendly way. See the `iverilog`(1) man page for usage details.
### EXAMPLE: Hello World ## EXAMPLES
Example: Compiling `"hello.vl"` Example: Compiling `"hello.vl"`
```verilog ```
// ------------------------ hello.vl ---------------------------- ------------------------ hello.vl ----------------------------
module main(); module main();
initial initial
begin begin
$display("Hello World"); $display("Hi there");
$finish ; $finish ;
end end
endmodule endmodule
// -------------------------------------------------------------- --------------------------------------------------------------
``` ```
Ensure that `iverilog` is on your search path, and the vpi library Ensure that `iverilog` is on your search path, and the vpi library
@ -365,16 +322,16 @@ is available.
To compile the program: To compile the program:
```bash ```
iverilog hello.vl iverilog hello.vl
``` ```
(The above presumes that `/usr/local/include` and `/usr/local/lib` are (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`.) part of the compiler search path, which is usually the case for gcc.)
To run the generated program: To run the program:
```bash ```
./a.out ./a.out
``` ```
@ -391,30 +348,165 @@ Verilog web page for the current state of support for Verilog, and in
particular, browse the bug report database for reported unsupported particular, browse the bug report database for reported unsupported
constructs. constructs.
- Specify blocks are parsed but ignored by default. When enabled - System functions are supported, but the return value is a little
by the `-gspecify` compiler option, a subset of specify block tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page.
constructs are supported.
- Specify blocks are parsed but ignored in general.
- `trireg` is not supported. `tri0` and `tri1` are supported. - `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 - Net delays, of the form `wire #N foo;` do not work. Delays in
every other context do work properly, including the V2001 form every other context do work properly, including the V2001 form
`wire #5 foo = bar;` `wire #5 foo = bar;`
The list of unsupported SystemVerilog constructs is too large to - Event controls inside non-blocking assignments are not supported.
enumerate here. i.e.: `a <= @(posedge clk) b;`
## Nonstandard Constructs and Behaviors - Macro arguments are not supported. `` `define `` macros are supported,
but they cannot take arguments.
Icarus Verilog includes some features that are not part of the IEEE 1364 ## Nonstandard Constructs or Behaviors
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 "Icarus Verilog Extensions" and "Icarus Verilog Quirks" sections at
https://steveicarus.github.io/iverilog/ for more details.
## Credits 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.
Except where otherwise noted, Icarus Verilog, ivl, and ivlpp are * `$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 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, file. However, I have early on received aid in the form of fixes,
Verilog guidance, and especially testing from many people. Testers, in Verilog guidance, and especially testing from many people. Testers, in

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2024 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -29,9 +29,8 @@ Statement::~Statement()
{ {
} }
PAssign_::PAssign_(PExpr*lval__, PExpr*ex, bool is_constant, bool is_init) PAssign_::PAssign_(PExpr*lval__, PExpr*ex, bool is_constant)
: event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(is_constant), : event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(is_constant)
is_init_(is_init)
{ {
delay_ = 0; delay_ = 0;
} }
@ -74,8 +73,8 @@ PAssign::PAssign(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
{ {
} }
PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant, bool is_init) PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant)
: PAssign_(lval__, ex, is_constant, is_init), op_(0) : PAssign_(lval__, ex, is_constant), op_(0)
{ {
} }
@ -140,8 +139,8 @@ PChainConstructor* PBlock::extract_chain_constructor()
void PBlock::set_join_type(PBlock::BL_TYPE type) void PBlock::set_join_type(PBlock::BL_TYPE type)
{ {
ivl_assert(*this, bl_type_ == BL_PAR); assert(bl_type_ == BL_PAR);
ivl_assert(*this, type==BL_PAR || type==BL_JOIN_NONE || type==BL_JOIN_ANY); assert(type==BL_PAR || type==BL_JOIN_NONE || type==BL_JOIN_ANY);
bl_type_ = type; bl_type_ = type;
} }
@ -166,19 +165,37 @@ PNamedItem::SymbolType PBlock::symbol_type() const
return BLOCK; return BLOCK;
} }
PCallTask::PCallTask(const pform_name_t &n, const list<named_pexpr_t> &p) PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
: package_(0), path_(n), parms_(p.begin(), p.end()) : 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<named_pexpr_t> &p) PCallTask::PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&p)
: package_(pkg), path_(n), parms_(p.begin(), p.end()) : 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<named_pexpr_t> &p) PCallTask::PCallTask(perm_string n, const list<PExpr*>&p)
: package_(0), parms_(p.begin(), p.end()) : 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)); path_.push_back(name_component_t(n));
} }
@ -216,14 +233,15 @@ PCAssign::~PCAssign()
delete expr_; delete expr_;
} }
PChainConstructor::PChainConstructor(const list<named_pexpr_t> &parms) PChainConstructor::PChainConstructor(const list<PExpr*>&parms)
: parms_(parms.begin(), parms.end()) : parms_(parms.size())
{
}
PChainConstructor::PChainConstructor(const vector<named_pexpr_t> &parms)
: parms_(parms)
{ {
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() PChainConstructor::~PChainConstructor()
@ -285,7 +303,7 @@ PDoWhile::~PDoWhile()
PEventStatement::PEventStatement(const std::vector<PEEvent*>&ee) PEventStatement::PEventStatement(const std::vector<PEEvent*>&ee)
: expr_(ee), statement_(0), always_sens_(false) : expr_(ee), statement_(0), always_sens_(false)
{ {
ivl_assert(*this, expr_.size() > 0); assert(expr_.size() > 0);
} }
@ -331,8 +349,12 @@ PForce::~PForce()
} }
PForeach::PForeach(perm_string av, const list<perm_string>&ix, Statement*s) PForeach::PForeach(perm_string av, const list<perm_string>&ix, Statement*s)
: array_var_(av), index_vars_(ix.begin(), ix.end()), 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() PForeach::~PForeach()
@ -396,8 +418,8 @@ PReturn::~PReturn()
delete expr_; delete expr_;
} }
PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev, unsigned lexical_pos) PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev)
: event_(pkg, ev), lexical_pos_(lexical_pos) : package_(pkg), event_(ev)
{ {
} }
@ -405,8 +427,8 @@ PTrigger::~PTrigger()
{ {
} }
PNBTrigger::PNBTrigger(const pform_name_t&ev, unsigned lexical_pos, PExpr*dly) PNBTrigger::PNBTrigger(const pform_name_t&ev, PExpr*dly)
: event_(ev), lexical_pos_(lexical_pos), dly_(dly) : event_(ev), dly_(dly)
{ {
} }

View File

@ -1,7 +1,7 @@
#ifndef IVL_Statement_H #ifndef IVL_Statement_H
#define IVL_Statement_H #define IVL_Statement_H
/* /*
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -40,8 +40,6 @@ class NetCAssign;
class NetDeassign; class NetDeassign;
class NetForce; class NetForce;
class NetScope; class NetScope;
class NetNet;
class netdarray_t;
/* /*
* The PProcess is the root of a behavioral process. Each process gets * The PProcess is the root of a behavioral process. Each process gets
@ -55,10 +53,7 @@ class PProcess : public LineInfo {
PProcess(ivl_process_type_t t, Statement*st) PProcess(ivl_process_type_t t, Statement*st)
: type_(t), statement_(st) { } : type_(t), statement_(st) { }
virtual ~PProcess() override; virtual ~PProcess();
PProcess(const PProcess&) = delete;
PProcess& operator=(const PProcess&) = delete;
bool elaborate(Design*des, NetScope*scope) const; bool elaborate(Design*des, NetScope*scope) const;
@ -83,7 +78,7 @@ class Statement : virtual public LineInfo {
public: public:
Statement() { } Statement() { }
virtual ~Statement() override =0; virtual ~Statement() =0;
virtual void dump(std::ostream&out, unsigned ind) const; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
@ -100,14 +95,10 @@ class Statement : virtual public LineInfo {
*/ */
class PAssign_ : public Statement { class PAssign_ : public Statement {
public: public:
explicit PAssign_(PExpr*lval, PExpr*ex, bool is_constant, explicit PAssign_(PExpr*lval, PExpr*ex, bool is_constant);
bool is_init = false);
explicit PAssign_(PExpr*lval, PExpr*de, 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*cnt, PEventStatement*de, PExpr*ex);
virtual ~PAssign_() override =0; virtual ~PAssign_() =0;
PAssign_(const PAssign_&) = delete;
PAssign_& operator=(const PAssign_&) = delete;
const PExpr* lval() const { return lval_; } const PExpr* lval() const { return lval_; }
PExpr* rval() const { return rval_; } PExpr* rval() const { return rval_; }
@ -131,8 +122,6 @@ class PAssign_ : public Statement {
PExpr* lval_; PExpr* lval_;
PExpr* rval_; PExpr* rval_;
bool is_constant_; bool is_constant_;
// Whether the assignment is a variable initializer expression
bool is_init_ = false;
}; };
class PAssign : public PAssign_ { class PAssign : public PAssign_ {
@ -146,11 +135,11 @@ class PAssign : public PAssign_ {
explicit PAssign(PExpr*lval, char op, PExpr*ex); explicit PAssign(PExpr*lval, char op, PExpr*ex);
explicit PAssign(PExpr*lval, PExpr*de, 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*cnt, PEventStatement*de, PExpr*ex);
explicit PAssign(PExpr*lval, PExpr*ex, bool is_constant, bool is_init); explicit PAssign(PExpr*lval, PExpr*ex, bool is_constant);
~PAssign() override; ~PAssign();
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private: private:
NetProc* elaborate_compressed_(Design*des, NetScope*scope) const; NetProc* elaborate_compressed_(Design*des, NetScope*scope) const;
@ -163,10 +152,10 @@ class PAssignNB : public PAssign_ {
explicit PAssignNB(PExpr*lval, PExpr*ex); explicit PAssignNB(PExpr*lval, PExpr*ex);
explicit PAssignNB(PExpr*lval, PExpr*de, PExpr*ex); explicit PAssignNB(PExpr*lval, PExpr*de, PExpr*ex);
explicit PAssignNB(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex); explicit PAssignNB(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex);
~PAssignNB() override; ~PAssignNB();
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private: private:
NetProc*assign_to_memory_(class NetMemory*, PExpr*, NetProc*assign_to_memory_(class NetMemory*, PExpr*,
@ -189,11 +178,11 @@ class PBlock : public PScope, public Statement, public PNamedItem {
explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t); explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t);
// If it doesn't have a name, it's not a scope // If it doesn't have a name, it's not a scope
explicit PBlock(BL_TYPE t); explicit PBlock(BL_TYPE t);
~PBlock() override; ~PBlock();
BL_TYPE bl_type() const { return bl_type_; } BL_TYPE bl_type() const { return bl_type_; }
bool var_init_needs_explicit_lifetime() const override; bool var_init_needs_explicit_lifetime() const;
// This is only used if this block is the statement list for a // This is only used if this block is the statement list for a
// constructor. We look for a PChainConstructor as the first // constructor. We look for a PChainConstructor as the first
@ -210,36 +199,30 @@ class PBlock : public PScope, public Statement, public PNamedItem {
// block. // block.
void push_statement_front(Statement*that); void push_statement_front(Statement*that);
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const override; virtual void elaborate_sig(Design*des, NetScope*scope) const;
SymbolType symbol_type() const override; SymbolType symbol_type() const;
private: private:
BL_TYPE bl_type_; BL_TYPE bl_type_;
std::vector<Statement*>list_; std::vector<Statement*>list_;
}; };
class PBreak : public Statement {
public:
void dump(std::ostream&out, unsigned ind) const override;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
};
class PCallTask : public Statement { class PCallTask : public Statement {
public: public:
explicit PCallTask(PPackage *pkg, const pform_name_t &n, const std::list<named_pexpr_t> &parms); explicit PCallTask(PPackage*pkg, const pform_name_t&n, const std::list<PExpr*>&parms);
explicit PCallTask(const pform_name_t &n, const std::list<named_pexpr_t> &parms); explicit PCallTask(const pform_name_t&n, const std::list<PExpr*>&parms);
explicit PCallTask(perm_string n, const std::list<named_pexpr_t> &parms); explicit PCallTask(perm_string n, const std::list<PExpr*>&parms);
~PCallTask() override; ~PCallTask();
const pform_name_t& path() const; const pform_name_t& path() const;
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
bool elaborate_elab(Design*des, NetScope*scope) const; bool elaborate_elab(Design*des, NetScope*scope) const;
@ -261,49 +244,21 @@ class PCallTask : public Statement {
NetProc*elaborate_sys_task_method_(Design*des, NetScope*scope, NetProc*elaborate_sys_task_method_(Design*des, NetScope*scope,
NetNet*net, NetNet*net,
perm_string method_name, perm_string method_name,
const char *sys_task_name, const char*sys_task_name) const;
const std::vector<perm_string> &parm_names = {}) const;
NetProc*elaborate_sys_task_property_method_(Design*des, NetScope*scope,
NetNet*net, int property_idx,
perm_string method_name,
const char *sys_task_name,
const std::vector<perm_string> &parm_names = {}) const;
NetProc*elaborate_queue_method_(Design*des, NetScope*scope, NetProc*elaborate_queue_method_(Design*des, NetScope*scope,
NetNet*net, NetNet*net,
perm_string method_name, perm_string method_name,
const char *sys_task_name, const char*sys_task_name) const;
const std::vector<perm_string> &parm_names) const;
NetProc*elaborate_queue_property_method_(Design*des, NetScope*scope,
NetNet*net, int property_idx,
perm_string method_name,
const char *sys_task_name,
const std::vector<perm_string> &parm_names) const;
NetProc*elaborate_method_func_(NetScope*scope, NetProc*elaborate_method_func_(NetScope*scope,
NetNet*net, NetNet*net,
ivl_type_t type, ivl_type_t type,
perm_string method_name, perm_string method_name,
const char*sys_task_name) const; const char*sys_task_name) const;
NetProc*elaborate_method_property_func_(NetScope*scope, bool test_task_calls_ok_(Design*des, NetScope*scope) const;
NetNet*net, int property_idx,
ivl_type_t type,
perm_string method_name,
const char*sys_task_name) const;
NetProc*elaborate_queue_method_expr_(Design*des, NetScope*scope,
NetExpr*queue_base,
const netdarray_t*use_darray,
perm_string method_name,
const char *sys_task_name,
const std::vector<perm_string> &parm_names) const;
NetProc*elaborate_method_func_expr_(NetScope*scope,
NetExpr*queue_base,
ivl_type_t type,
perm_string method_name,
const char*sys_task_name) const;
bool test_task_calls_ok_(Design*des, const NetScope*scope) const;
PPackage*package_; PPackage*package_;
pform_name_t path_; pform_name_t path_;
std::vector<named_pexpr_t> parms_; std::vector<PExpr*> parms_;
bool void_cast_ = false; bool void_cast_ = false;
}; };
@ -316,12 +271,12 @@ class PCase : public Statement {
}; };
PCase(ivl_case_quality_t, NetCase::TYPE, PExpr*ex, std::vector<Item*>*); PCase(ivl_case_quality_t, NetCase::TYPE, PExpr*ex, std::vector<Item*>*);
~PCase() override; ~PCase();
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const override; virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
private: private:
ivl_case_quality_t quality_; ivl_case_quality_t quality_;
@ -339,13 +294,10 @@ class PCAssign : public Statement {
public: public:
explicit PCAssign(PExpr*l, PExpr*r); explicit PCAssign(PExpr*l, PExpr*r);
~PCAssign() override; ~PCAssign();
PCAssign(const PCAssign&) = delete; virtual NetCAssign* elaborate(Design*des, NetScope*scope) const;
PCAssign& operator=(const PCAssign&) = delete; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetCAssign* elaborate(Design*des, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind) const override;
private: private:
PExpr*lval_; PExpr*lval_;
@ -359,30 +311,29 @@ class PCAssign : public Statement {
*/ */
class PChainConstructor : public Statement { class PChainConstructor : public Statement {
public: public:
explicit PChainConstructor(const std::list<named_pexpr_t> &parms); explicit PChainConstructor(const std::list<PExpr*>&parms);
explicit PChainConstructor(const std::vector<named_pexpr_t> &parms); ~PChainConstructor();
~PChainConstructor() override;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
inline const std::vector<named_pexpr_t>& chain_args(void) const inline const std::vector<PExpr*>& chain_args(void) const
{ return parms_; } { return parms_; }
private: private:
std::vector<named_pexpr_t> parms_; std::vector<PExpr*> parms_;
}; };
class PCondit : public Statement { class PCondit : public Statement {
public: public:
PCondit(PExpr*ex, Statement*i, Statement*e); PCondit(PExpr*ex, Statement*i, Statement*e);
~PCondit() override; ~PCondit();
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const override; virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
private: private:
PExpr*expr_; PExpr*expr_;
@ -394,24 +345,14 @@ class PCondit : public Statement {
PCondit& operator= (const PCondit&); PCondit& operator= (const PCondit&);
}; };
class PContinue : public Statement {
public:
virtual void dump(std::ostream&out, unsigned ind) const override;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
};
class PDeassign : public Statement { class PDeassign : public Statement {
public: public:
explicit PDeassign(PExpr*l); explicit PDeassign(PExpr*l);
~PDeassign() override; ~PDeassign();
PDeassign(const PDeassign&) = delete; virtual NetDeassign* elaborate(Design*des, NetScope*scope) const;
PDeassign& operator=(const PDeassign&) = delete; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetDeassign* elaborate(Design*des, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind) const override;
private: private:
PExpr*lval_; PExpr*lval_;
@ -421,12 +362,12 @@ class PDelayStatement : public Statement {
public: public:
PDelayStatement(PExpr*d, Statement*st); PDelayStatement(PExpr*d, Statement*st);
~PDelayStatement() override; ~PDelayStatement();
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const override; virtual void elaborate_sig(Design*des, NetScope*scope) const;
private: private:
PExpr*delay_; PExpr*delay_;
@ -441,10 +382,10 @@ class PDisable : public Statement {
public: public:
explicit PDisable(const pform_name_t&sc); explicit PDisable(const pform_name_t&sc);
~PDisable() override; ~PDisable();
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private: private:
pform_name_t scope_; pform_name_t scope_;
@ -454,15 +395,12 @@ class PDoWhile : public Statement {
public: public:
PDoWhile(PExpr*ex, Statement*st); PDoWhile(PExpr*ex, Statement*st);
~PDoWhile() override; ~PDoWhile();
PDoWhile(const PDoWhile&) = delete; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
PDoWhile& operator=(const PDoWhile&) = delete; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind) const override;
private: private:
PExpr*cond_; PExpr*cond_;
@ -487,17 +425,17 @@ class PEventStatement : public Statement {
// from functions added and outputs removed for always_comb/latch. // from functions added and outputs removed for always_comb/latch.
explicit PEventStatement(bool always_sens = false); explicit PEventStatement(bool always_sens = false);
~PEventStatement() override; ~PEventStatement();
void set_statement(Statement*st); void set_statement(Statement*st);
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
// Call this with a NULL statement only. It is used to print // Call this with a NULL statement only. It is used to print
// the event expression for inter-assignment event controls. // the event expression for inter-assignment event controls.
virtual void dump_inline(std::ostream&out) const; virtual void dump_inline(std::ostream&out) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const override; virtual void elaborate_sig(Design*des, NetScope*scope) const;
bool has_aa_term(Design*des, NetScope*scope); bool has_aa_term(Design*des, NetScope*scope);
@ -506,7 +444,7 @@ class PEventStatement : public Statement {
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const; NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
NetProc* elaborate_wait(Design*des, NetScope*scope, NetProc*st) const; NetProc* elaborate_wait(Design*des, NetScope*scope, NetProc*st) const;
NetProc* elaborate_wait_fork(Design*des, const NetScope*scope) const; NetProc* elaborate_wait_fork(Design*des, NetScope*scope) const;
private: private:
std::vector<PEEvent*>expr_; std::vector<PEEvent*>expr_;
@ -520,13 +458,10 @@ class PForce : public Statement {
public: public:
explicit PForce(PExpr*l, PExpr*r); explicit PForce(PExpr*l, PExpr*r);
~PForce() override; ~PForce();
PForce(const PForce&) = delete; virtual NetForce* elaborate(Design*des, NetScope*scope) const;
PForce& operator=(const PForce&) = delete; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetForce* elaborate(Design*des, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind) const override;
private: private:
PExpr*lval_; PExpr*lval_;
@ -536,19 +471,16 @@ class PForce : public Statement {
class PForeach : public Statement { class PForeach : public Statement {
public: public:
explicit PForeach(perm_string var, const std::list<perm_string>&ix, Statement*stmt); explicit PForeach(perm_string var, const std::list<perm_string>&ix, Statement*stmt);
~PForeach() override; ~PForeach();
PForeach(const PForeach&) = delete; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
PForeach& operator=(const PForeach&) = delete; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind) const override;
private: private:
NetProc* elaborate_static_array_(Design*des, NetScope*scope, NetProc* elaborate_static_array_(Design*des, NetScope*scope,
const netranges_t&dims) const; const std::vector<netrange_t>&dims) const;
private: private:
perm_string array_var_; perm_string array_var_;
@ -559,15 +491,12 @@ class PForeach : public Statement {
class PForever : public Statement { class PForever : public Statement {
public: public:
explicit PForever(Statement*s); explicit PForever(Statement*s);
~PForever() override; ~PForever();
PForever(const PForever&) = delete; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
PForever& operator=(const PForever&) = delete; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind) const override;
private: private:
Statement*statement_; Statement*statement_;
@ -578,12 +507,12 @@ class PForStatement : public Statement {
public: public:
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond, PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
Statement*step, Statement*body); Statement*step, Statement*body);
~PForStatement() override; ~PForStatement();
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const override; virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
private: private:
PExpr* name1_; PExpr* name1_;
@ -600,21 +529,18 @@ class PNoop : public Statement {
public: public:
PNoop() { } PNoop() { }
~PNoop() override { } ~PNoop() { }
}; };
class PRepeat : public Statement { class PRepeat : public Statement {
public: public:
explicit PRepeat(PExpr*expr, Statement*s); explicit PRepeat(PExpr*expr, Statement*s);
~PRepeat() override; ~PRepeat();
PRepeat(const PRepeat&) = delete; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
PRepeat& operator=(const PRepeat&) = delete; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind) const override;
private: private:
PExpr*expr_; PExpr*expr_;
@ -625,13 +551,10 @@ class PRelease : public Statement {
public: public:
explicit PRelease(PExpr*l); explicit PRelease(PExpr*l);
~PRelease() override; ~PRelease();
PRelease(const PRelease&) = delete; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
PRelease& operator=(const PRelease&) = delete; virtual void dump(std::ostream&out, unsigned ind) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind) const override;
private: private:
PExpr*lval_; PExpr*lval_;
@ -641,13 +564,10 @@ class PReturn : public Statement {
public: public:
explicit PReturn(PExpr*e); explicit PReturn(PExpr*e);
~PReturn() override; ~PReturn();
PReturn(const PReturn&) = delete; NetProc* elaborate(Design*des, NetScope*scope) const;
PReturn& operator=(const PReturn&) = delete; virtual void dump(std::ostream&out, unsigned ind) const;
NetProc* elaborate(Design*des, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind) const override;
private: private:
PExpr*expr_; PExpr*expr_;
@ -660,28 +580,27 @@ class PReturn : public Statement {
class PTrigger : public Statement { class PTrigger : public Statement {
public: public:
explicit PTrigger(PPackage*pkg, const pform_name_t&ev, unsigned lexical_pos); explicit PTrigger(PPackage*pkg, const pform_name_t&ev);
~PTrigger() override; ~PTrigger();
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
private: private:
pform_scoped_name_t event_; PPackage*package_;
unsigned lexical_pos_; pform_name_t event_;
}; };
class PNBTrigger : public Statement { class PNBTrigger : public Statement {
public: public:
explicit PNBTrigger(const pform_name_t&ev, unsigned lexical_pos, PExpr*dly); explicit PNBTrigger(const pform_name_t&ev, PExpr*dly);
~PNBTrigger() override; ~PNBTrigger();
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
virtual void dump(std::ostream&out, unsigned ind) const override; virtual void dump(std::ostream&out, unsigned ind) const;
private: private:
pform_name_t event_; pform_name_t event_;
unsigned lexical_pos_;
PExpr*dly_; PExpr*dly_;
}; };
@ -689,15 +608,12 @@ class PWhile : public Statement {
public: public:
PWhile(PExpr*ex, Statement*st); PWhile(PExpr*ex, Statement*st);
~PWhile() override; ~PWhile();
PWhile(const PWhile&) = delete; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
PWhile& operator=(const PWhile&) = delete; virtual void elaborate_scope(Design*des, NetScope*scope) const;
virtual void elaborate_sig(Design*des, NetScope*scope) const;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override; virtual void dump(std::ostream&out, unsigned ind) const;
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
virtual void dump(std::ostream&out, unsigned ind) const override;
private: private:
PExpr*cond_; PExpr*cond_;

409
aclocal.m4 vendored
View File

@ -1,27 +1,390 @@
# generated automatically by aclocal 1.18.1 -*- Autoconf -*-
# Copyright (C) 1996-2025 Free Software Foundation, Inc. # 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"
fi
AC_SUBST(install_suffix)
])# AX_ENABLE_SUFFIX
# This file is free software; the Free Software Foundation # _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
# gives unlimited permission to copy and/or distribute it, # ------------------------------
# with or without modifications, as long as this notice is preserved. # 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.
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF],
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([void underscore(void){}])],
[AS_IF([$NM conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
[AC_MSG_ERROR([underscore test crashed])]
)])
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) # AX_C_UNDERSCORES_LEADING
m4_include([m4/_ac_am_config_header_hook.m4]) # ---------------------------------
m4_include([m4/_ax_c_underscores_match_if.m4]) # Check if symbol names in object files produced by C compiler have
m4_include([m4/ax_c99_strtod.m4]) # leading underscores. Define NEED_LU if so.
m4_include([m4/ax_c_picflag.m4]) AC_DEFUN([AX_C_UNDERSCORES_LEADING],
m4_include([m4/ax_c_underscores_leading.m4]) [AC_CACHE_CHECK([for leading underscores], ax_cv_c_underscores_leading,
m4_include([m4/ax_c_underscores_trailing.m4]) [_AX_C_UNDERSCORES_MATCH_IF([_underscore],
m4_include([m4/ax_cxx_compile_stdcxx.m4]) [AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
m4_include([m4/ax_enable_suffix.m4]) [AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
m4_include([m4/ax_ld_extralibs.m4]) if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
m4_include([m4/ax_ld_rdynamic.m4]) AC_DEFINE([NEED_LU], [1], [Symbol names in object files produced by C compiler have leading underscores.])
m4_include([m4/ax_ld_sharedlib_opts.m4]) fi
m4_include([m4/ax_prog_cc_for_build.m4]) ])# AX_C_UNDERSCORES_LEADING
m4_include([m4/ax_win32.m4])
# AX_C_UNDERSCORES_TRAILING
# ---------------------------------
# Check if symbol names in object files produced by C compiler have
# trailing underscores. Define NEED_TU if so.
AC_DEFUN([AX_C_UNDERSCORES_TRAILING],
[AC_CACHE_CHECK([for trailing underscores], ax_cv_c_underscores_trailing,
[_AX_C_UNDERSCORES_MATCH_IF([underscore_],
[AS_VAR_SET(ax_cv_c_underscores_trailing, yes)],
[AS_VAR_SET(ax_cv_c_underscores_trailing, no)])])
if test $ax_cv_c_underscores_trailing = yes; then
AC_DEFINE([NEED_TU], [1], [Symbol names in object files produced by C compiler have trailing underscores.])
fi
])# AX_C_UNDERSCORES_TRAILING
# AX_WIN32
# --------
# Combined check for several flavors of Microsoft Windows so
# their "issues" can be dealt with
AC_DEFUN([AX_WIN32],
[AC_MSG_CHECKING([for Microsoft Windows])
AC_REQUIRE([AC_CANONICAL_HOST]) []dnl
case $host_os in
*cygwin*) MINGW32=no; WIN32=yes;;
*mingw*) MINGW32=yes; WIN32=yes;;
*) MINGW32=no; WIN32=no;;
esac
AC_SUBST(MINGW32)
AC_SUBST(WIN32)
AC_MSG_RESULT($WIN32)
if test $WIN32 = yes; then
AC_MSG_CHECKING([for MinGW])
AC_MSG_RESULT($MINGW32)
fi
])# AX_WIN32
# AX_LD_EXTRALIBS
# ---------------
# mingw needs to link with libiberty.a, but cygwin alone can't tolerate it
AC_DEFUN([AX_LD_EXTRALIBS],
[AC_MSG_CHECKING([for extra libs needed])
EXTRALIBS=
case "${host}" in
*-*-cygwin* )
if test "$MINGW32" = "yes"; then
EXTRALIBS="-liberty"
fi
;;
esac
AC_SUBST(EXTRALIBS)
AC_MSG_RESULT($EXTRALIBS)
])# AX_LD_EXTRALIBS
# AX_LD_SHAREDLIB_OPTS
# --------------------
# linker options when building a shared library
AC_DEFUN([AX_LD_SHAREDLIB_OPTS],
[AC_MSG_CHECKING([for shared library link flag])
shared=-shared
case "${host}" in
*-*-cygwin*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-mingw*)
shared="-shared -Wl,--enable-auto-image-base"
;;
*-*-hpux*)
shared="-b"
;;
*-*-darwin1.[0123])
shared="-bundle -undefined suppress"
;;
*-*-darwin*)
shared="-bundle -undefined suppress -flat_namespace"
;;
*-*-solaris*)
if test ${using_sunpro_c} = 1
then
shared="-G"
fi
;;
esac
AC_SUBST(shared)
AC_MSG_RESULT($shared)
])# AX_LD_SHAREDLIB_OPTS
# AX_C_PICFLAG
# ------------
# The -fPIC flag is used to tell the compiler to make position
# independent code. It is needed when making shared objects.
AC_DEFUN([AX_C_PICFLAG],
[AC_MSG_CHECKING([for flag to make position independent code])
PICFLAG=-fPIC
case "${host}" in
*-*-cygwin*)
PICFLAG=
;;
*-*-mingw*)
PICFLAG=
;;
*-*-hpux*)
PICFLAG=+z
;;
*-*-solaris*)
if test ${using_sunpro_c} = 1
then
PICFLAG=-G
fi
;;
esac
AC_SUBST(PICFLAG)
AC_MSG_RESULT($PICFLAG)
])# AX_C_PICFLAG
# AX_LD_RDYNAMIC
# --------------
# The -rdynamic flag is used by iverilog when compiling the target,
# to know how to export symbols of the main program to loadable modules
# that are brought in by -ldl
AC_DEFUN([AX_LD_RDYNAMIC],
[AC_MSG_CHECKING([for -rdynamic compiler flag])
rdynamic=-rdynamic
case "${host}" in
*-*-netbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-openbsd*)
rdynamic="-Wl,--export-dynamic"
;;
*-*-solaris*)
rdynamic=""
;;
*-*-cygwin*)
rdynamic=""
;;
*-*-mingw*)
rdynamic=""
;;
*-*-hpux*)
rdynamic="-E"
;;
*-*-darwin*)
rdynamic="-Wl,-all_load"
strip_dynamic="-SX"
;;
esac
AC_SUBST(rdynamic)
AC_MSG_RESULT($rdynamic)
AC_SUBST(strip_dynamic)
# since we didn't tell them we're "checking", no good place to tell the answer
# AC_MSG_RESULT($strip_dynamic)
])# AX_LD_RDYNAMIC
# AX_C99_STRTOD
# -------------
AC_DEFUN([AX_C99_STRTOD],
[# On MinGW we need to jump through hoops to get a C99 compliant strtod().
# mingw-w64 doesn't need this, and the 64-bit version doesn't support it.
case "${host}" in
x86_64-w64-mingw32)
;;
*-*-mingw32)
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
;;
esac
])# AX_C99_STRTOD
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp file name are based on the header name.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[
_config_header=$1
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
]) #_AC_AM_CONFIG_HEADER_HOOK
# ===========================================================================
# 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 <bonzini@gnu.org>
#
# 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
])

View File

@ -28,6 +28,11 @@ bool NetAssign::is_asynchronous()
return true; return true;
} }
bool NetCondit::is_asynchronous()
{
return false;
}
/* /*
* NetEvWait statements come from statements of the form @(...) in the * NetEvWait statements come from statements of the form @(...) in the
* Verilog source. These event waits are considered asynchronous if * Verilog source. These event waits are considered asynchronous if

View File

@ -1,19 +1,14 @@
Icarus Verilog Attributes ATTRIBUTE NAMING CONVENTIONS
=========================
Attribute Naming Conventions
----------------------------
Attributes that are specific to Icarus Verilog, and are intended to be Attributes that are specific to Icarus Verilog, and are intended to be
of use to programmers, start with the prefix "ivl\_". of use to programmers, start with the prefix "ivl_".
Attributes with the "_ivl_" prefix are set aside for internal Attributes with the "_ivl_" prefix are set aside for internal
use. They may be generated internally by the compiler. They need not use. They may be generated internally by the compiler. They need not
be documented here. be documented here.
Attributes To Control Synthesis ATTRIBUTES TO CONTROL SYNTHESIS
-------------------------------
The following is a summary of Verilog attributes that Icarus Verilog The following is a summary of Verilog attributes that Icarus Verilog
understands within Verilog source files to control synthesis understands within Verilog source files to control synthesis
@ -28,7 +23,7 @@ warning.)
* Attributes for "always" and "initial" statements * Attributes for "always" and "initial" statements
(\* ivl_combinational \*) (* ivl_combinational *)
This attribute tells the compiler that the statement models This attribute tells the compiler that the statement models
combinational logic. If the compiler finds that it cannot make combinational logic. If the compiler finds that it cannot make
@ -39,14 +34,14 @@ warning.)
latches or flip-flops where the user intended combinational latches or flip-flops where the user intended combinational
logic. logic.
(\* ivl_synthesis_on \*) (* ivl_synthesis_on *)
This attribute tells the compiler that the marked always statement This attribute tells the compiler that the marked always statement
is synthesizable. The compiler will attempt to synthesize the is synthesizable. The compiler will attempt to synthesize the
code in the marked "always" statement. If it cannot in any way code in the marked "always" statement. If it cannot in any way
synthesize it, then it will report an error. synthesize it, then it will report an error.
(\* ivl_synthesis_off \*) (* ivl_synthesis_off *)
If this value is attached to an "always" statement, then the If this value is attached to an "always" statement, then the
compiler will *not* synthesize the "always" statement. This can be compiler will *not* synthesize the "always" statement. This can be
@ -55,7 +50,7 @@ warning.)
* Attributes for modules * Attributes for modules
(\* ivl_synthesis_cell \*) (* ivl_synthesis_cell *)
If this value is attached to a module during synthesis, that If this value is attached to a module during synthesis, that
module will be considered a target architecture primitive, and module will be considered a target architecture primitive, and
@ -65,7 +60,7 @@ warning.)
* Attributes for signals (wire/reg/integer/tri/etc.) * Attributes for signals (wire/reg/integer/tri/etc.)
(\* PAD = "<pad assignment list>" \*) (* PAD = "<pad assignment list>" *)
If this attribute is attached to a signal that happens to be a If this attribute is attached to a signal that happens to be a
root module port, then targets that support it will use the string root module port, then targets that support it will use the string
@ -78,10 +73,9 @@ warning.)
[ none defined yet ] [ none defined yet ]
Misc MISC
----
(\* _ivl_schedule_push \*) (* _ivl_schedule_push *)
If this attribute is attached to a thread object (always or If this attribute is attached to a thread object (always or
initial statement) then the vvp code generator will generate code initial statement) then the vvp code generator will generate code

View File

@ -6,8 +6,6 @@
# in git, so it is easiest to just run this script whenever needed # in git, so it is easiest to just run this script whenever needed
# to generate the configure script. # to generate the configure script.
# #
# wget -O config.guess 'https://git.savannah.gnu.org/cgit/config.git/plain/config.guess'
# wget -O config.sub 'https://git.savannah.gnu.org/cgit/config.git/plain/config.sub'
echo "Autoconf in root..." echo "Autoconf in root..."
autoconf -f autoconf -f

View File

@ -59,11 +59,7 @@ distclean: clean
rm -f Makefile config.log rm -f Makefile config.log
cppcheck: $(O:.o=.c) cppcheck: $(O:.o=.c)
cppcheck --enable=all --std=c99 --std=c++11 -f \ cppcheck --enable=all --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^
--check-level=exhaustive \
--suppressions-list=$(srcdir)/../cppcheck-global.sup \
--suppressions-list=$(srcdir)/cppcheck.sup \
$(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=cadpli/$@ cd ..; ./config.status --file=cadpli/$@
@ -71,7 +67,7 @@ Makefile: $(srcdir)/Makefile.in ../config.status
dep: dep:
mkdir dep mkdir dep
%.o: %.c | dep %.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $<
mv $*.d dep mv $*.d dep

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -53,7 +53,7 @@ static void thunker_register(void)
strncpy(module, cp, bp-cp); strncpy(module, cp, bp-cp);
module[bp-cp] = 0; module[bp-cp] = 0;
mod = ivl_dlopen(module, false); mod = ivl_dlopen(module);
if (mod == 0) { if (mod == 0) {
vpi_printf("%s link: %s\n", vlog_info.argv[idx], dlerror()); vpi_printf("%s link: %s\n", vlog_info.argv[idx], dlerror());
free(module); free(module);

View File

@ -1,6 +1,7 @@
Cadence PLI1 Modules CADENCE PLI1 MODULES
====================
Copyright 2003 Stephen Williams
With the cadpli module, Icarus Verilog is able to load PLI1 With the cadpli module, Icarus Verilog is able to load PLI1
applications that were compiled and linked to be dynamic loaded by applications that were compiled and linked to be dynamic loaded by
@ -16,7 +17,7 @@ is invoked by the usual -m flag to iverilog or vvp. This module in
turn scans the extended arguments, looking for +cadpli= arguments. The turn scans the extended arguments, looking for +cadpli= arguments. The
latter specify the share object and bootstrap function for running the latter specify the share object and bootstrap function for running the
module. For example, to run the module product.so, that has the module. For example, to run the module product.so, that has the
bootstrap function "my_boot":: bootstrap function "my_boot":
vvp -mcadpli a.out -cadpli=./product.so:my_boot vvp -mcadpli a.out -cadpli=./product.so:my_boot

View File

@ -1,7 +0,0 @@
// We use guarded memory allocation routines, but cppcheck is not
// noticing this so it is complaining we could return a NULL value.
nullPointerOutOfMemory:cadpli.c:53
nullPointerOutOfMemory:cadpli.c:54
// Unused function
unusedFunction:ivl_dlfcn.h:87

94
cadpli/ivl_dlfcn.h Normal file
View File

@ -0,0 +1,94 @@
#ifndef IVL_ivl_dlfcn_H
#define IVL_ivl_dlfcn_H
/*
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#if defined(__MINGW32__)
# include <windows.h>
# include <stdio.h>
typedef void * ivl_dll_t;
#elif defined(HAVE_DLFCN_H)
# include <dlfcn.h>
typedef void* ivl_dll_t;
#elif defined(HAVE_DL_H)
# include <dl.h>
typedef shl_t ivl_dll_t;
#endif
#if defined(__MINGW32__)
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)
{ return (void *)GetProcAddress((HINSTANCE)dll,nm);}
static __inline__ void ivl_dlclose(ivl_dll_t dll)
{ (void)FreeLibrary((HINSTANCE)dll);}
static __inline__ const char *dlerror(void)
{
static char msg[256];
unsigned long err = GetLastError();
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &msg,
sizeof(msg) - 1,
NULL
);
return msg;
}
#elif defined(HAVE_DLFCN_H)
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)
{
void*sym = dlsym(dll, nm);
/* Not found? try without the leading _ */
if (sym == 0 && nm[0] == '_')
sym = dlsym(dll, nm+1);
return sym;
}
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)
{ return shl_load(name, BIND_IMMEDIATE, 0); }
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)
{ shl_unload(dll); }
static __inline__ const char*dlerror(void)
{ return strerror( errno ); }
#endif
#endif /* IVL_ivl_dlfcn_H */

View File

@ -1,7 +1,7 @@
#ifndef IVL_compiler_H #ifndef IVL_compiler_H
#define IVL_compiler_H #define IVL_compiler_H
/* /*
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -104,9 +104,6 @@ extern bool warn_sens_entire_arr;
/* Warn about level-appropriate anachronisms. */ /* Warn about level-appropriate anachronisms. */
extern bool warn_anachronisms; extern bool warn_anachronisms;
/* Warn about declaration after use (unless flaged as errors). */
extern bool warn_decl_after_use;
/* Warn about nets that are references but not driven. */ /* Warn about nets that are references but not driven. */
extern bool warn_floating_nets; extern bool warn_floating_nets;
@ -165,8 +162,6 @@ enum generation_t {
GN_VER2005_SV = 5, GN_VER2005_SV = 5,
GN_VER2009 = 6, GN_VER2009 = 6,
GN_VER2012 = 7, GN_VER2012 = 7,
GN_VER2017 = 8,
GN_VER2023 = 9,
GN_DEFAULT = 4 GN_DEFAULT = 4
}; };
@ -182,11 +177,6 @@ extern bool gn_icarus_misc_flag;
is false, then skip elaboration of specify behavior. */ is false, then skip elaboration of specify behavior. */
extern bool gn_specify_blocks_flag; extern bool gn_specify_blocks_flag;
/* If this flag is true, then add input/output buffers to modules so that
VVP can insert intermodpaths inbetween. If this flag
is false, then no input/output buffers are inserted if not needed. */
extern bool gn_interconnect_flag;
/* If this flag is true, then elaborate supported assertion statements. If /* If this flag is true, then elaborate supported assertion statements. If
this flag is false, then stub out supported assertion statements. */ this flag is false, then stub out supported assertion statements. */
extern bool gn_supported_assertions_flag; extern bool gn_supported_assertions_flag;
@ -215,20 +205,6 @@ extern bool gn_strict_expr_width_flag;
loop. */ loop. */
extern bool gn_shared_loop_index_flag; extern bool gn_shared_loop_index_flag;
/* If this flag is true (default), then parameters must be declared before
use. `-gno-strict[-parameter]-declaration` allows to use parameters before
declaration, as prior to version 13.
A warning is emited with -Wdeclaration-after-use (default).
*/
extern bool gn_strict_parameter_declaration;
/* If this flag is true (default), then nets and variablesmust be declared
before use. `-gno-strict[-net-var]-declaration` allows to use nets and
variables before declaration, as prior to version 13.
A warning is emited with -Wdeclaration-after-use (default).
*/
extern bool gn_strict_net_var_declaration;
static inline bool gn_system_verilog(void) static inline bool gn_system_verilog(void)
{ {
if (generation_flag >= GN_VER2005_SV) if (generation_flag >= GN_VER2005_SV)

1783
config.guess vendored Normal file → Executable file

File diff suppressed because it is too large Load Diff

3397
config.sub vendored Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +1,6 @@
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_INIT
AC_CONFIG_MACRO_DIRS([m4])
dnl Define project version
m4_define([VER_MAJOR], [14])
m4_define([VER_MINOR], [0])
m4_define([VER_EXTRA], [devel])
dnl define libvvp ABI version
m4_define([LIBVVP_SOVERSION], [1])
AC_INIT([iverilog], [VER_MAJOR.VER_MINOR (VER_EXTRA)])
AC_SUBST([VERSION_MAJOR], [VER_MAJOR])
AC_SUBST([VERSION_MINOR], [VER_MINOR])
AC_SUBST([VERSION_EXTRA], [" (VER_EXTRA)"])
AC_SUBST([VERSION], ["VER_MAJOR.VER_MINOR (VER_EXTRA)"])
# used in res.rc
AC_SUBST([PRODUCTVERSION], ["VER_MAJOR,VER_MINOR,0,0"])
# setup libvvp soversion, which depends on abi not package version
AC_SUBST([LIBVVP_SOVERSION], [LIBVVP_SOVERSION])
# setup libvvp version
AC_SUBST([LIBVVP_VERSION], [LIBVVP_SOVERSION.VER_MAJOR.VER_MINOR])
AC_CONFIG_SRCDIR([netlist.h]) AC_CONFIG_SRCDIR([netlist.h])
# Need a stamp file like the other header files
AC_CONFIG_FILES([version_base.h],[
_config_header=version_base.h
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_HEADERS([_pli_types.h]) AC_CONFIG_HEADERS([_pli_types.h])
AC_CONFIG_HEADERS([vhdlpp/vhdlpp_config.h]) AC_CONFIG_HEADERS([vhdlpp/vhdlpp_config.h])
@ -47,19 +18,15 @@ AX_PROG_CC_FOR_BUILD
AC_PREREQ([2.62]) AC_PREREQ([2.62])
m4_version_prereq([2.70], [], [AC_PROG_CC_C99]) m4_version_prereq([2.70], [], [AC_PROG_CC_C99])
AC_PROG_CXX AC_PROG_CXX
# Require C++11 (avoid newer defaults like C++23 from newer toolchains)
AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
AC_PROG_RANLIB AC_PROG_RANLIB
AC_CHECK_TOOL(LD, ld, false) AC_CHECK_TOOL(LD, ld, false)
AC_CHECK_TOOL(AR, ar, false) AC_CHECK_TOOL(AR, ar, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(STRIP, strip, true) AC_CHECK_TOOL(STRIP, strip, true)
AC_CHECK_TOOL(WINDRES,windres,false) AC_CHECK_TOOL(WINDRES,windres,false)
AC_CHECK_PROGS(XGPERF,gperf,none) AC_CHECK_PROGS(XGPERF,gperf,none)
AC_CHECK_PROGS(MAN,man,none) AC_CHECK_PROGS(MAN,man,none)
AC_CHECK_PROGS(PS2PDF,ps2pdf,none) AC_CHECK_PROGS(PS2PDF,ps2pdf,none)
AC_CHECK_PROGS(GROFF,groff,none)
AC_CHECK_PROGS(GIT,git,none) AC_CHECK_PROGS(GIT,git,none)
if test "$XGPERF" = "none" if test "$XGPERF" = "none"
then then
@ -98,20 +65,6 @@ AC_SUBST(EXEEXT)
# Combined check for Microsoft-related bogosities; sets WIN32 if found # Combined check for Microsoft-related bogosities; sets WIN32 if found
AX_WIN32 AX_WIN32
# Detect which directory/file separator to use
AC_MSG_CHECKING([for directory/file separator])
AS_CASE([$host_os:$MSYSTEM],
[*mingw*:UCRT64|*mingw*:MINGW64|*mingw*:MINGW32|*mingw*:CLANG64|*mingw*:CLANGARM64], [
PATH_SEP=\\\\
],
[
PATH_SEP=/
]
)
AC_MSG_RESULT([$PATH_SEP])
AC_SUBST([PATH_SEP])
# Check to see if we are using the Sun compiler. If so then configure # 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 # 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 # in the aclocal.m4 file to configure the flags used to build and link
@ -151,15 +104,7 @@ AS_IF( [test "x$with_m32" = xyes],
[]) [])
CFLAGS="$CTARGETFLAGS $CFLAGS" CFLAGS="$CTARGETFLAGS $CFLAGS"
# Cygwin does not declare strdup() for C++ 11 by default so use gnu++11 CXXFLAGS="$CTARGETFLAGS $CXXFLAGS -std=c++11"
# to expose the declaration.
decl_cxx_std="-std=c++11"
case "${host}" in
*-*-cygwin*)
decl_cxx_std="-std=gnu++11"
;;
esac
CXXFLAGS="$CTARGETFLAGS $CXXFLAGS $decl_cxx_std"
LDFLAGS="$CTARGETFLAGS $LDFLAGS" LDFLAGS="$CTARGETFLAGS $LDFLAGS"
# Check that we are using either the GNU compilers or the Sun compilers # Check that we are using either the GNU compilers or the Sun compilers
@ -225,29 +170,6 @@ AC_SUBST(HAVE_LIBBZ2)
AC_FUNC_ALLOCA AC_FUNC_ALLOCA
AC_FUNC_FSEEKO AC_FUNC_FSEEKO
# Feature Options
# ---------------
# Build VVP as a library and stub
AC_ARG_ENABLE([libvvp],
[AS_HELP_STRING([--enable-libvvp], [build VVP as a shared library])],
[enable_libvvp=yes],
[enable_libvvp=no])
AC_SUBST([LIBVVP], [$enable_libvvp])
AS_IF([test "x$enable_libvvp" = "xyes"],
[AC_MSG_NOTICE([Building with libvvp support enabled])],
[AC_MSG_NOTICE([Building with libvvp support disabled])])
AC_ARG_ENABLE([libveriuser],
[AS_HELP_STRING([--enable-libveriuser], [include support for PLI 1 (deprecated)])],
[AC_SUBST(LIBVERIUSER, yes)],
[AC_SUBST(LIBVERIUSER, no)])
# Package Options
# ---------------
# valgrind checks # valgrind checks
AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind],[Add valgrind hooks])], AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind],[Add valgrind hooks])],
[], [check_valgrind=yes]) [], [check_valgrind=yes])
@ -310,40 +232,11 @@ case "${host}" in
CFLAGS="-mieee $CFLAGS" CFLAGS="-mieee $CFLAGS"
;; ;;
*-*-mingw*) *-*-mingw*)
# The MINGW64/32 environments link to MSVCRT which has stdio issues CXXFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CXXFLAGS"
# so use the slower, but functional mingw versions for this case. CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CFLAGS"
case "${MSYSTEM}" in
MINGW*)
CXXFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CXXFLAGS"
CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CFLAGS"
AC_MSG_NOTICE([${MSYSTEM} needs -D__USE_MINGW_ANSI_STDIO=1])
;;
esac
;; ;;
esac esac
# Setup test environment for running vvp from build directory
VVP_BUILDDIR="$(pwd)/vvp"
case "$host_os" in
linux*)
ENV_VVP="LD_LIBRARY_PATH=$VVP_BUILDDIR"
;;
*bsd*)
ENV_VVP="LD_LIBRARY_PATH=$VVP_BUILDDIR"
;;
darwin*)
ENV_VVP="DYLD_LIBRARY_PATH=$VVP_BUILDDIR"
;;
*)
# Since the libvvp DLL is located in the same directory as the
# vvp executable, no action is required here
ENV_VVP=""
;;
esac
AC_SUBST([ENV_VVP])
# Do some more operating system specific setup. We put the file64_support # Do some more operating system specific setup. We put the file64_support
# define in a substitution instead of simply a define because there # define in a substitution instead of simply a define because there
# are source files (namely lxt support files) that don't include any # are source files (namely lxt support files) that don't include any
@ -441,32 +334,5 @@ then
AC_MSG_ERROR(cannot configure white space in libdir: $libdir) AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
fi fi
AC_MSG_RESULT(ok) AC_MSG_RESULT(ok)
AC_CONFIG_FILES([ 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])
Makefile
cadpli/Makefile
driver-vpi/Makefile
driver-vpi/iverilog-vpi.man
driver-vpi/res.rc
driver/Makefile
driver/iverilog.man
ivlpp/Makefile
ivtest/Makefile
libveriuser/Makefile
tgt-blif/Makefile
tgt-fpga/Makefile
tgt-null/Makefile
tgt-pal/Makefile
tgt-pcb/Makefile
tgt-sizer/Makefile
tgt-stub/Makefile
tgt-verilog/Makefile
tgt-vhdl/Makefile
tgt-vlog95/Makefile
tgt-vvp/Makefile
vhdlpp/Makefile
vpi/Makefile
vvp/Makefile
vvp/libvvp.pc
vvp/vvp.man
])
AC_OUTPUT AC_OUTPUT

View File

@ -1,4 +0,0 @@
// Skip all messages about missing system include files
missingIncludeSystem
// Skip the active checker report message
checkersReport

View File

@ -1,97 +1,20 @@
// Skip the use STL messages
useStlAlgorithm
// Skip all memory issues since they should be handled by ivl_alloc.h
ctunullpointerOutOfMemory
nullPointerArithmeticOutOfMemory
nullPointerOutOfMemory
// valgrind does not find any issues so cppcheck is wrong
ctuuninitvar:parse_misc.cc:61
// Skip strdup() not constant.
constVariablePointer:main.cc:421
constVariablePointer:main.cc:425
constVariablePointer:main.cc:675
// const auto should be const
constVariablePointer:elab_expr.cc:344
constVariablePointer:elab_expr.cc:347
constVariablePointer:elab_expr.cc:416
// The reference cannot be const since it is updated in the calling function.
constParameterReference:net_udp.cc:37
// These cannot be static since they access object data
functionStatic:net_link.cc:178
functionStatic:net_link.cc:184
functionStatic:net_link.cc:189
functionStatic:net_link.cc:194
// This cannot be static when checking with valgrind
functionStatic:libmisc/StringHeap.cc
// Skip not initialized in the constructor for target scope
uninitMemberVar:t-dll.cc:41
uninitMemberVar:t-dll.cc:109
// By convention we put statics at the top scope.
variableScope:pform.cc:3499
// These are correct and are used to find the base (zero) pin. // These are correct and are used to find the base (zero) pin.
thisSubtraction:netlist.h:5376 thisSubtraction:netlist.h:5213
thisSubtraction:netlist.h:5385 thisSubtraction:netlist.h:5222
// This is used when running a debugger // This is used when running a debugger
// debugger_release // debugger_release
knownConditionTrueFalse:main.cc:955 knownConditionTrueFalse:main.cc:919
// These should be checked, but are not real issues
knownConditionTrueFalse:elaborate.cc:7970
knownConditionTrueFalse:elab_sig.cc:272
knownConditionTrueFalse:elab_sig.cc:345
// Yes, it's a duplicate
duplicateCondition:elaborate.cc:8021
// To complicated to use std::find_if()
useStlAlgorithm:map_named_args.cc:38
// The condition is always true at least once based on the previous assertion
derefInvalidIterator:netmisc.cc:420
// By convention we put statics at the top scope.
variableScope:t-dll.cc:2309
// We check memory allocation with valgrind
unsafeClassCanLeak:libmisc/StringHeap.h:79
// We only use a StringHeap or a StringHepLex
duplInheritedMember:libmisc/StringHeap.h:99
duplInheritedMember:libmisc/StringHeap.h:100
duplInheritedMember:libmisc/StringHeap.cc:160
duplInheritedMember:libmisc/StringHeap.cc:182
// cppcheck is wrong this is correct usage
redundantAssignment:syn-rules.y:230
redundantAssignment:syn-rules.y:234
redundantAssignment:syn-rules.y:243
redundantAssignment:syn-rules.y:271
redundantAssignment:syn-rules.y:274
redundantAssignment:syn-rules.y:294
// Cannot define a constructor sine this is in the parser union
noConstructor:property_qual.h:22
// This are just stubs // This are just stubs
// vpi_control() // vpi_control()
unusedFunction:vpi_modules.cc:109 unusedFunction:vpi_modules.cc:107
// vpi_mcd_printf() // vpi_mcd_printf()
unusedFunction:vpi_modules.cc:86 unusedFunction:vpi_modules.cc:84
// vpi_printf() // vpi_printf()
unusedFunction:vpi_modules.cc:90 unusedFunction:vpi_modules.cc:88
// vpi_sim_control() // vpi_sim_control()
unusedFunction:vpi_modules.cc:110 unusedFunction:vpi_modules.cc:108
// These are the functions that the compiler exports to the targets. // These are the functions that the compiler exports to the targets.
//ivl_branch_island() //ivl_branch_island()
@ -713,71 +636,3 @@ unusedFunction:t-dll-api.cc:1007
unusedFunction:t-dll-api.cc:1016 unusedFunction:t-dll-api.cc:1016
// ivl_udp_sequ() // ivl_udp_sequ()
unusedFunction:t-dll-api.cc:980 unusedFunction:t-dll-api.cc:980
// Unused routines
// has_compat_attributes()
unusedFunction:Attrib.cc:72
// bl_type()
unusedFunction:Statement.h:192
// chain_args()
unusedFunction:Statement.h:341
// gn_modules_nest()
unusedFunction:compiler.h:247
// driven_mask()
unusedFunction:link_const.cc:275
// find_root_scope()
unusedFunction:net_design.cc:121
// assign_lval()
unusedFunction:net_link.cc:283
// intersect()
unusedFunction:net_link.cc:687
// get_def_fileline()
unusedFunction:net_scope.cc:201
// get_module_port_info()
unusedFunction:net_scope.cc:600
// find_link_signal()
unusedFunction:netlist.cc:113
// find_link()
unusedFunction:netlist.cc:304
// set_module_port_index()
unusedFunction:netlist.cc:658
// width_a()
unusedFunction:netlist.cc:1685
// width_b()
unusedFunction:netlist.cc:1690
// result_sig()
unusedFunction:netlist.cc:2191
// soft_union()
unusedFunction:netstruct.h:93
// test_protected()
unusedFunction:property_qual.h:50
// test_rand()
unusedFunction:property_qual.h:52
// test_randc()
unusedFunction:property_qual.h:53
// sub_off_from_expr_()
unusedFunction:t-dll-expr.cc:55
// mul_expr_by_const_()
unusedFunction:t-dll-expr.cc:91
// net_assign()
unusedFunction:t-dll.cc:2300
// is_before()
unusedFunction:verinum.cc:588
// Errors/limitations in the generated yacc and lex files
constVariablePointer:<stdout>
cstyleCast:<stdout>
duplicateBreak:<stdout>
nullPointer:<stdout>
redundantInitialization:<stdout>
syntaxError:<stdout>
unusedFunction:<stdout>
duplicateBreak:lexor.lex
allocaCalled:parse.cc
constParameterPointer:parse.cc
constVariablePointer:parse.cc
knownConditionTrueFalse:parse.cc
allocaCalled:syn-rules.cc
constParameterPointer:syn-rules.cc
knownConditionTrueFalse:syn-rules.cc
constVariablePointer:syn-rules.cc

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -41,16 +41,16 @@ struct cprop_functor : public functor_t {
unsigned count; unsigned count;
virtual void signal(Design*des, NetNet*obj) override; virtual void signal(Design*des, NetNet*obj);
virtual void lpm_add_sub(Design*des, NetAddSub*obj) override; virtual void lpm_add_sub(Design*des, NetAddSub*obj);
virtual void lpm_compare(Design*des, const NetCompare*obj) override; virtual void lpm_compare(Design*des, const NetCompare*obj);
virtual void lpm_concat(Design*des, NetConcat*obj) override; virtual void lpm_concat(Design*des, NetConcat*obj);
virtual void lpm_ff(Design*des, NetFF*obj) override; virtual void lpm_ff(Design*des, NetFF*obj);
virtual void lpm_logic(Design*des, NetLogic*obj) override; virtual void lpm_logic(Design*des, NetLogic*obj);
virtual void lpm_mux(Design*des, NetMux*obj) override; virtual void lpm_mux(Design*des, NetMux*obj);
virtual void lpm_part_select(Design*des, NetPartSelect*obj) override; virtual void lpm_part_select(Design*des, NetPartSelect*obj);
static void lpm_compare_eq_(Design*des, const NetCompare*obj); void lpm_compare_eq_(Design*des, const NetCompare*obj);
}; };
void cprop_functor::signal(Design*, NetNet*) void cprop_functor::signal(Design*, NetNet*)
@ -90,7 +90,7 @@ void cprop_functor::lpm_concat(Design*des, NetConcat*obj)
unsigned off = 0; unsigned off = 0;
for (unsigned idx = 1 ; idx < obj->pin_count() ; idx += 1) { for (unsigned idx = 1 ; idx < obj->pin_count() ; idx += 1) {
const Nexus*nex = obj->pin(idx).nexus(); Nexus*nex = obj->pin(idx).nexus();
// If there are non-constant drivers, then give up. // If there are non-constant drivers, then give up.
if (! nex->drivers_constant()) if (! nex->drivers_constant())
return; return;
@ -156,7 +156,7 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
if (obj->sel_width() != 1) if (obj->sel_width() != 1)
return; return;
const Nexus*sel_nex = obj->pin_Sel().nexus(); Nexus*sel_nex = obj->pin_Sel().nexus();
/* If the select input is constant, then replace with a BUFZ */ /* If the select input is constant, then replace with a BUFZ */
@ -180,7 +180,9 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
<< "Replace binary MUX with constant select=" << sel_val << "Replace binary MUX with constant select=" << sel_val
<< " with a BUFZ to the selected input." << endl; << " with a BUFZ to the selected input." << endl;
tmp->delay_times(obj->delay_times()); tmp->rise_time(obj->rise_time());
tmp->fall_time(obj->fall_time());
tmp->decay_time(obj->decay_time());
connect(tmp->pin(0), obj->pin_Result()); connect(tmp->pin(0), obj->pin_Result());
if (sel_val == verinum::V1) if (sel_val == verinum::V1)
@ -192,7 +194,7 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
count += 1; count += 1;
} }
static bool compare_base(const NetPartSelect*a, const NetPartSelect*b) static bool compare_base(NetPartSelect*a, NetPartSelect*b)
{ {
return a->base() < b->base(); return a->base() < b->base();
} }
@ -217,23 +219,15 @@ void cprop_functor::lpm_part_select(Design*des, NetPartSelect*obj)
Nexus*nex = obj->pin(1).nexus(); Nexus*nex = obj->pin(1).nexus();
vector<NetPartSelect*> obj_set; vector<NetPartSelect*> obj_set;
bool output_2_state = false;
for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) { for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) {
NetPins*tmp_obj = cur->get_obj();
// Record if we are driving a 2-state net.
const NetNet*net_obj = dynamic_cast<NetNet*> (tmp_obj);
if (net_obj && (net_obj->data_type() == IVL_VT_BOOL))
output_2_state = true;
// If this is an input (or passive) then ignore it. // If this is an input (or passive) then ignore it.
if (cur->get_dir() != Link::OUTPUT) if (cur->get_dir() != Link::OUTPUT)
continue; continue;
// Check to see if this is the output of a // Check to see if this is the output of a
// NetPartSelect::PV. If not, then give up on the blend. // NetPartSelect::PV. If not, then give up on the blend.
NetPins*tmp_obj = cur->get_obj();
unsigned tmp_pin = cur->get_pin(); unsigned tmp_pin = cur->get_pin();
NetPartSelect*cur_obj = dynamic_cast<NetPartSelect*> (tmp_obj); NetPartSelect*cur_obj = dynamic_cast<NetPartSelect*> (tmp_obj);
@ -249,12 +243,7 @@ void cprop_functor::lpm_part_select(Design*des, NetPartSelect*obj)
obj_set.push_back(cur_obj); obj_set.push_back(cur_obj);
} }
// When driving a 4-state signal, we only want to create a if (obj_set.size() < 2)
// concatenation if we have more than one part select. But
// when driving a 2-state signal, create a concatenation
// even if there's only one part select, which forces the
// undriven bits to zero without needing an explicit cast.
if ((obj_set.size() == 0) || ((obj_set.size() == 1) && !output_2_state))
return; return;
if (debug_optimizer) if (debug_optimizer)
@ -318,10 +307,8 @@ void cprop_functor::lpm_part_select(Design*des, NetPartSelect*obj)
for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) { for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) {
NetPartSelect*cobj = obj_set[idx]; NetPartSelect*cobj = obj_set[idx];
if (cobj->base() > off) { if (cobj->base() > off) {
NetNet*val = output_2_state NetNet*zzz = make_const_z(des, scope, cobj->base()-off);
? make_const_0(des, scope, cobj->base()-off) connect(cncat->pin(concat_pin), zzz->pin(0));
: make_const_z(des, scope, cobj->base()-off);
connect(cncat->pin(concat_pin), val->pin(0));
concat_pin += 1; concat_pin += 1;
off = cobj->base(); off = cobj->base();
} }
@ -330,10 +317,8 @@ void cprop_functor::lpm_part_select(Design*des, NetPartSelect*obj)
off += cobj->width(); off += cobj->width();
} }
if (off < sig_width) { if (off < sig_width) {
NetNet*val = output_2_state NetNet*zzz = make_const_z(des, scope, sig_width-off);
? make_const_0(des, scope, sig_width-off) connect(cncat->pin(concat_pin), zzz->pin(0));
: make_const_z(des, scope, sig_width-off);
connect(cncat->pin(concat_pin), val->pin(0));
concat_pin += 1; concat_pin += 1;
} }
ivl_assert(*obj, concat_pin == cncat->pin_count()); ivl_assert(*obj, concat_pin == cncat->pin_count());
@ -353,7 +338,7 @@ void cprop_functor::lpm_part_select(Design*des, NetPartSelect*obj)
*/ */
struct cprop_dc_functor : public functor_t { struct cprop_dc_functor : public functor_t {
virtual void lpm_const(Design*des, NetConst*obj) override; virtual void lpm_const(Design*des, NetConst*obj);
}; };
struct nexus_info_s { struct nexus_info_s {

35
cygwin.txt Normal file
View File

@ -0,0 +1,35 @@
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
----------------------------------------------------------------------------
Note: Icarus Verilog also compiles to native Windows binaries if you
use the instructions in the mingw.txt file. Some people prefer cygwin
binaries, and these instructions apply.
To build using cygwin:
Prerequisites:
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
Procedure:
o Get the source code - see the main Icarus Verilog page for how to
do this
o cd to the verilog directory
o autoconf.sh
o ./configure
o make
o make install
That's all that's needed.
To build your own extensions - just include vpi_user.h and link with
a command like this:
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
- Venkat Iyer <venkat@comit.com>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -90,30 +90,6 @@ ostream& operator << (ostream&o, ivl_drive_t str)
return o; return o;
} }
ostream &operator << (ostream &o, const drive_strength_t &strength)
{
o << strength.drive0 << "0 " << strength.drive1 << "1";
return o;
}
static void dump_delay_expr(ostream &o, const NetExpr *expr)
{
if (expr)
o << *expr;
else
o << "0";
}
ostream &operator << (ostream &o, const delay_exprs_t &delays)
{
dump_delay_expr(o, delays.rise);
o << ",";
dump_delay_expr(o, delays.fall);
o << ",";
dump_delay_expr(o, delays.decay);
return o;
}
ostream& operator << (ostream&o, ivl_variable_type_t val) ostream& operator << (ostream&o, ivl_variable_type_t val)
{ {
switch (val) { switch (val) {
@ -230,18 +206,6 @@ ostream& operator << (ostream&fd, NetCaseCmp::kind_t that)
return fd; return fd;
} }
static std::ostream& operator << (std::ostream &out, const std::vector<NetExpr*> &exprs)
{
for (size_t idx = 0; idx < exprs.size(); idx++) {
if (idx != 0)
out << ", ";
if (exprs[idx])
out << *exprs[idx];
}
return out;
}
ostream& ivl_type_s::debug_dump(ostream&o) const ostream& ivl_type_s::debug_dump(ostream&o) const
{ {
o << typeid(*this).name(); o << typeid(*this).name();
@ -433,9 +397,18 @@ static inline ostream&operator<<(ostream&out, const netrange_t&that)
return out; return out;
} }
ostream&operator<<(ostream&out, const netranges_t&rlist) ostream&operator<<(ostream&out, const list<netrange_t>&rlist)
{ {
for (netranges_t::const_iterator cur = rlist.begin() for (list<netrange_t>::const_iterator cur = rlist.begin()
; cur != rlist.end() ; ++cur) {
out << *cur;
}
return out;
}
ostream&operator<<(ostream&out, const vector<netrange_t>&rlist)
{
for (vector<netrange_t>::const_iterator cur = rlist.begin()
; cur != rlist.end() ; ++cur) { ; cur != rlist.end() ; ++cur) {
out << *cur; out << *cur;
} }
@ -478,7 +451,8 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")"; o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
if (scope()) if (scope())
o << " scope=" << scope_path(scope()); o << " scope=" << scope_path(scope());
o << " #(" << delay_times() << ") vector_width=" << vector_width() o << " #(" << rise_time() << "," << fall_time() << ","
<< decay_time() << ") vector_width=" << vector_width()
<< " pin_count=" << pin_count(); << " pin_count=" << pin_count();
if (pins_are_virtual()) { if (pins_are_virtual()) {
o << " pins_are_virtual" << endl; o << " pins_are_virtual" << endl;
@ -509,7 +483,8 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
void NetNode::dump_node(ostream&o, unsigned ind) const void NetNode::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "node: "; o << setw(ind) << "" << "node: ";
o << typeid(*this).name() << " #(" << delay_times() << ") " << name() o << typeid(*this).name() << " #(" << rise_time()
<< "," << fall_time() << "," << decay_time() << ") " << name()
<< endl; << endl;
dump_node_pins(o, ind+4); dump_node_pins(o, ind+4);
@ -540,7 +515,8 @@ void NetPins::dump_node_pins(ostream&o, unsigned ind, const char**pin_names) con
break; break;
} }
o << " (" << pin(idx).drive() << "): "; o << " (" << pin(idx).drive0() << "0 "
<< pin(idx).drive1() << "1): ";
if (pin(idx).is_linked()) { if (pin(idx).is_linked()) {
const Nexus*nex = pin(idx).nexus(); const Nexus*nex = pin(idx).nexus();
@ -643,7 +619,11 @@ void NetConcat::dump_node(ostream&o, unsigned ind) const
o << setw(ind) << "" << "NetConcat: "; o << setw(ind) << "" << "NetConcat: ";
o << name(); o << name();
o << " #(" << delay_times() << ")"; if (rise_time())
o << " #(" << *rise_time()
<< "," << *fall_time() << "," << *decay_time() << ")";
else
o << " #(0,0,0)";
o << " scope=" << scope_path(scope()) o << " scope=" << scope_path(scope())
<< " width=" << width_ << endl; << " width=" << width_ << endl;
dump_node_pins(o, ind+4); dump_node_pins(o, ind+4);
@ -668,7 +648,14 @@ void NetPow::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "LPM_POW (NetPow): " << name() o << setw(ind) << "" << "LPM_POW (NetPow): " << name()
<< " scope=" << scope_path(scope()) << " scope=" << scope_path(scope())
<< " delay=(" << delay_times() << ")" << endl; << " delay=(";
if (rise_time())
o << *rise_time() << "," << *fall_time() << ","
<< *decay_time();
else
o << "0,0,0";
o << ")" << endl;
dump_node_pins(o, ind+4); dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4); dump_obj_attr(o, ind+4);
} }
@ -686,7 +673,8 @@ void NetBUFZ::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "NetBUFZ: " << name() o << setw(ind) << "" << "NetBUFZ: " << name()
<< " scope=" << scope_path(scope()) << " scope=" << scope_path(scope())
<< " delay=(" << delay_times() << ") width=" << width() << " delay=(" << rise_time() << "," << fall_time() << "," <<
decay_time() << ") width=" << width()
<< (transparent()? " " : " non-") << "transparent" << endl; << (transparent()? " " : " non-") << "transparent" << endl;
dump_node_pins(o, ind+4); dump_node_pins(o, ind+4);
} }
@ -702,8 +690,10 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "constant " << value_; o << setw(ind) << "" << "constant " << value_;
o << ": " << name(); o << ": " << name();
if (delay_times().has_delay()) if (rise_time())
o << " #(" << delay_times() << ")"; o << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
else else
o << " #(.,.,.)"; o << " #(.,.,.)";
o << endl; o << endl;
@ -736,8 +726,10 @@ void NetLiteral::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "constant real " << real_ o << setw(ind) << "" << "constant real " << real_
<< ": " << name(); << ": " << name();
if (delay_times().has_delay()) if (rise_time())
o << " #(" << delay_times() << ")"; o << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
else else
o << " #(.,.,.)"; o << " #(.,.,.)";
o << endl; o << endl;
@ -815,7 +807,8 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
o << "xor"; o << "xor";
break; break;
} }
o << " #(" << delay_times() << ") " << name() o << " #(" << rise_time()
<< "," << fall_time() << "," << decay_time() << ") " << name()
<< " scope=" << scope_path(scope()) << " scope=" << scope_path(scope())
<< endl; << endl;
@ -843,8 +836,10 @@ void NetPartSelect::dump_node(ostream&o, unsigned ind) const
} }
o << setw(ind) << "" << "NetPartSelect(" << pt << "): " o << setw(ind) << "" << "NetPartSelect(" << pt << "): "
<< name(); << name();
if (delay_times().has_delay()) if (rise_time())
o << " #(" << delay_times() << ")"; o << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
else else
o << " #(.,.,.)"; o << " #(.,.,.)";
o << " off=" << off_ << " wid=" << wid_ <<endl; o << " off=" << off_ << " wid=" << wid_ <<endl;
@ -856,8 +851,10 @@ void NetSubstitute::dump_node(ostream&fd, unsigned ind) const
{ {
fd << setw(ind) << "" << "NetSubstitute: " fd << setw(ind) << "" << "NetSubstitute: "
<< name(); << name();
if (delay_times().has_delay()) if (rise_time())
fd << " #(" << delay_times() << ")"; fd << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
else else
fd << " #(.,.,.)"; fd << " #(.,.,.)";
fd << " width=" << wid_ << " base=" << off_ <<endl; fd << " width=" << wid_ << " base=" << off_ <<endl;
@ -877,8 +874,10 @@ void NetReplicate::dump_node(ostream&o, unsigned ind) const
void NetSignExtend::dump_node(ostream&o, unsigned ind) const void NetSignExtend::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "NetSignExtend: " << name(); o << setw(ind) << "" << "NetSignExtend: " << name();
if (delay_times().has_delay()) if (rise_time())
o << " #(" << delay_times() << ")"; o << " #(" << *rise_time()
<< "," << *fall_time()
<< "," << *decay_time() << ")";
else else
o << " #(.,.,.)"; o << " #(.,.,.)";
o << " output width=" << width_ << endl; o << " output width=" << width_ << endl;
@ -912,7 +911,8 @@ void NetUReduce::dump_node(ostream&o, unsigned ind) const
o << "xnor"; o << "xnor";
break; break;
} }
o << " #(" << delay_times() << ") " << name() o << " #(" << rise_time()
<< "," << fall_time() << "," << decay_time() << ") " << name()
<< " scope=" << scope_path(scope()) << " scope=" << scope_path(scope())
<< endl; << endl;
@ -932,8 +932,10 @@ void NetUserFunc::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "USER FUNC: " o << setw(ind) << "" << "USER FUNC: "
<< scope_path(def_); << scope_path(def_);
if (delay_times().has_delay()) if (rise_time())
o << " #(" << delay_times() << ")"; o << " #(" <<*rise_time()
<<","<<*fall_time()
<< "," <<*decay_time() << ")";
o << endl; o << endl;
dump_node_pins(o, ind+4); dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4); dump_obj_attr(o, ind+4);
@ -981,7 +983,14 @@ void NetTran::dump_node(ostream&o, unsigned ind) const
<< " part=" << part_width() << " part=" << part_width()
<< " offset=" << part_offset(); << " offset=" << part_offset();
} }
o << " delay=(" << delay_times() << ")" << endl; o << " delay=(";
if (rise_time())
o << *rise_time() << "," << *fall_time() << ","
<< *decay_time();
else
o << "0,0,0";
o << ")" << endl;
dump_node_pins(o, ind+4); dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4); dump_obj_attr(o, ind+4);
} }
@ -989,7 +998,8 @@ void NetTran::dump_node(ostream&o, unsigned ind) const
void NetUDP::dump_node(ostream&o, unsigned ind) const void NetUDP::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "UDP (" << udp_name() << "): "; o << setw(ind) << "" << "UDP (" << udp_name() << "): ";
o << " #(" << delay_times() << ") " << name() << endl; o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
") " << name() << endl;
dump_node_pins(o, ind+4); dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4); dump_obj_attr(o, ind+4);
@ -1138,7 +1148,7 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
if (rval()) if (rval())
o << *rval() << ";" << endl; o << *rval() << ";" << endl;
else else
o << "<rval elaboration error>;" << endl; o << "rval elaboration error>;" << endl;
} }
@ -1170,11 +1180,6 @@ void NetBlock::dump(ostream&o, unsigned ind) const
o << setw(ind) << "" << "end" << endl; o << setw(ind) << "" << "end" << endl;
} }
void NetBreak::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "break;" << endl;
}
void NetCase::dump(ostream&o, unsigned ind) const void NetCase::dump(ostream&o, unsigned ind) const
{ {
o << setw(ind) << ""; o << setw(ind) << "";
@ -1243,11 +1248,6 @@ void NetCondit::dump(ostream&o, unsigned ind) const
} }
} }
void NetContinue::dump(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "continue;" << endl;
}
void NetContribution::dump(ostream&o, unsigned ind) const void NetContribution::dump(ostream&o, unsigned ind) const
{ {
o << setw(ind) << ""; o << setw(ind) << "";
@ -1386,26 +1386,10 @@ void NetForLoop::dump(ostream&fd, unsigned ind) const
fd << index_->name(); fd << index_->name();
else else
fd << "<nil>"; fd << "<nil>";
fd << ", init_expr=";
if (init_expr_)
fd << *init_expr_;
else
fd << "<nil>";
fd << ", condition=";
if (condition_)
fd << *condition_;
else
fd << "<nil>";
fd << endl; fd << endl;
fd << setw(ind+4) << "" << "Init Statement {" << endl;
if (init_statement_)
init_statement_->dump(fd, ind+8);
fd << setw(ind+4) << "" << "}" << endl;
statement_->dump(fd, ind+4); statement_->dump(fd, ind+4);
fd << setw(ind+4) << "" << "Step Statement {" << endl;
if (step_statement_) if (step_statement_)
step_statement_->dump(fd, ind+8); step_statement_->dump(fd, ind+4);
fd << setw(ind+4) << "" << "}" << endl;
} }
void NetFree::dump(ostream&o, unsigned ind) const void NetFree::dump(ostream&o, unsigned ind) const
@ -1640,7 +1624,17 @@ void NetSTask::dump(ostream&o, unsigned ind) const
o << setw(ind) << "" << name_; o << setw(ind) << "" << name_;
if (! parms_.empty()) { if (! parms_.empty()) {
o << "(" << parms_ << ")"; o << "(";
if (parms_[0])
parms_[0]->dump(o);
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
o << ", ";
if (parms_[idx])
parms_[idx]->dump(o);
}
o << ")";
} }
o << ";" << endl; o << ";" << endl;
} }
@ -1682,7 +1676,15 @@ void NetEAccess::dump(ostream&o) const
void NetEArrayPattern::dump(ostream&fd) const void NetEArrayPattern::dump(ostream&fd) const
{ {
fd << "'{" << items_ << "}"; fd << "'{";
if (items_.size() >= 1) {
if (items_[0]) fd << *items_[0];
}
for (size_t idx = 1 ; idx < items_.size() ; idx += 1) {
fd << ", ";
if (items_[idx]) fd << *items_[idx];
}
fd << "}";
} }
void NetEBinary::dump(ostream&o) const void NetEBinary::dump(ostream&o) const
@ -1786,7 +1788,18 @@ void NetEConcat::dump(ostream&o) const
if (repeat_ != 1) if (repeat_ != 1)
o << repeat_; o << repeat_;
o << "{" << parms_ << "}"; if (parms_[0])
o << "{" << *parms_[0];
else
o << "{";
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
if (parms_[idx])
o << ", " << *parms_[idx];
else
o << ", ";
}
o << "}";
} }
void NetEConst::dump(ostream&o) const void NetEConst::dump(ostream&o) const
@ -1914,7 +1927,8 @@ void NetESignal::dump(ostream&o) const
o << "+"; o << "+";
o << name(); o << name();
if (word_) o << "[word=" << *word_ << "]"; if (word_) o << "[word=" << *word_ << "]";
o << net_->net_type()->slice_dimensions(); vector<netrange_t>tmp = net_->net_type()->slice_dimensions();
o << tmp;
} }
void NetETernary::dump(ostream&o) const void NetETernary::dump(ostream&o) const
@ -1925,7 +1939,15 @@ void NetETernary::dump(ostream&o) const
void NetEUFunc::dump(ostream&o) const void NetEUFunc::dump(ostream&o) const
{ {
o << scope_path(func_) << "(" << parms_ << ")"; o << scope_path(func_) << "(";
if (! parms_.empty()) {
parms_[0]->dump(o);
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
o << ", ";
parms_[idx]->dump(o);
}
}
o << ")";
} }
void NetEUnary::dump(ostream&o) const void NetEUnary::dump(ostream&o) const

View File

@ -1,24 +1,21 @@
Developer Guide Developer Quick Start for Icarus Verilog
===============
The developer guide is intended to give you a gross structure of the The documentation for getting, building and installing Icarus Verilog
is kept and maintained at the iverilog documentation wiki at
<http://iverilog.wikia.com>. See the Installation Guide for getting
the current source from the git repository (and how to use the git
repository) and see the Developer Guide for instructions on
participating in the Icarus Verilog development process. That
information will not be repeated here.
What this documentation *will* cover is the gross structure of the
Icarus Verilog compiler source. This will help orient you to the Icarus Verilog compiler source. This will help orient you to the
source code itself, so that you can find the global parts where you source code itself, so that you can find the global parts where you
can look for even better detail. can look for even better detail.
The documentation for getting, building and installing Icarus Verilog
is kept and maintained at :doc:`Getting Started as a Contributor <../getting_started>`
See the Installation Guide for getting the current source from the git * Compiler Components
repository (and how to use the git repository) and see the Developer Guide
for instructions on participating in the Icarus Verilog development process.
That information will not be repeated here.
Scroll down to a listing with further readings.
Compiler Components
-------------------
- The compiler driver (driver/) - The compiler driver (driver/)
@ -29,29 +26,28 @@ subcommands to perform the steps of compilation.
- The preprocessor (ivlpp/) - The preprocessor (ivlpp/)
This implements the Verilog pre-processor. In Icarus Verilog, the This implements the Verilog pre-processor. In Icarus Verilog, the
compiler directives \`define, \`include, \`ifdef and etc. are implemented compiler directives `define, `include, `ifdef and etc. are implemented
in an external program. The ivlpp/ directory contains the source for in an external program. The ivlpp/ directory contains the source for
this program. this program.
- The core compiler (root directory) - The core compiler (this directory)
The "ivl" program is the core that does all the Verilog compiler The "ivl" program is the core that does all the Verilog compiler
processing that is not handled elsewhere. This is the main core of the processing that is not handled elsewhere. This is the main core of the
Icarus Verilog compiler, not the runtime. See below for more details Icarus Verilog compiler, not the runtime. See below for more details
on the core itself. on the core itself.
- The loadable code generators (tgt-\*/) - The loadable code generators (tgt-*/)
This core compiler, after it is finished with parsing and semantic This core compiler, after it is finished with parsing and semantic
analysis, uses loadable code generators to emit code for supported analysis, uses loadable code generators to emit code for supported
targets. The tgt-\*/ directories contains the source for the target targets. The tgt-*/ directories contains the source for the target
code generators that are bundled with Icarus Verilog. The tgt-vvp/ code generators that are bundled with Icarus Verilog. The tgt-vvp/
directory in particular contains the code generator for the vvp directory in particular contains the code generator for the vvp
runtime. runtime.
Runtime Components * Runtime Components
------------------
- The vvp runtime (vvp/) - The vvp runtime (vvp/)
@ -79,8 +75,7 @@ PLI-1 code written for Verilog-XL. This directory contains the source
for the module that provides the Cadence PLI interface. for the module that provides the Cadence PLI interface.
The Core Compiler * The Core Compiler
-----------------
The "ivl" binary is the core compiler that does the heavy lifting of The "ivl" binary is the core compiler that does the heavy lifting of
compiling the Verilog source (including libraries) and generating the compiling the Verilog source (including libraries) and generating the
@ -152,18 +147,3 @@ parameters must be intermingled with the elaboration of scopes because
the exact values of parameters may impact the scopes created (imagine the exact values of parameters may impact the scopes created (imagine
generate schemes and instance arrays) and the created scopes in turn generate schemes and instance arrays) and the created scopes in turn
create new parameters that need override and evaluation. create new parameters that need override and evaluation.
Further Reading
---------------
For further information on the individual parts of Icarus Verilog, see this listing:
.. toctree::
:maxdepth: 2
ivl/index
vvp/index
tgt-vvp/tgt-vvp
vpi/index
cadpli/cadpli
misc/index

View File

@ -1,7 +1,7 @@
#ifndef IVL_discipline_H #ifndef IVL_discipline_H
#define IVL_discipline_H #define IVL_discipline_H
/* /*
* Copyright (c) 2008-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 2008-2021 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -36,7 +36,7 @@ extern std::ostream& operator << (std::ostream&, ivl_dis_domain_t);
class ivl_nature_s : public LineInfo { class ivl_nature_s : public LineInfo {
public: public:
explicit ivl_nature_s(perm_string name, perm_string access); explicit ivl_nature_s(perm_string name, perm_string access);
~ivl_nature_s() override; ~ivl_nature_s();
perm_string name() const { return name_; } perm_string name() const { return name_; }
// Identifier for the access function for this nature // Identifier for the access function for this nature
@ -51,12 +51,12 @@ class ivl_discipline_s : public LineInfo {
public: public:
explicit ivl_discipline_s (perm_string name, ivl_dis_domain_t dom, explicit ivl_discipline_s (perm_string name, ivl_dis_domain_t dom,
ivl_nature_t pot, ivl_nature_t flow); ivl_nature_t pot, ivl_nature_t flow);
~ivl_discipline_s() override; ~ivl_discipline_s();
perm_string name() const { return name_; } perm_string name() const { return name_; }
ivl_dis_domain_t domain() const { return domain_; } ivl_dis_domain_t domain() const { return domain_; }
ivl_nature_t potential() const { return potential_; } ivl_nature_t potential() const { return potential_; }
ivl_nature_t flow() const { return flow_; } ivl_nature_t flow() const { return flow_; }
private: private:
perm_string name_; perm_string name_;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -28,7 +28,7 @@
# include <stdio.h> # include <stdio.h>
int main(int argc, const char*argv[]) int main(int argc, char*argv[])
{ {
FILE*ifile; FILE*ifile;
FILE*ofile; FILE*ofile;

View File

@ -31,11 +31,7 @@ suffix = @install_suffix@
bindir = $(exec_prefix)/bin bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib libdir = $(exec_prefix)/lib
includedir = $(prefix)/include includedir = $(prefix)/include
# This is actually the directory where we install our own header files. mandir = @mandir@
# It is a little different from the generic includedir.
ivl_includedir = @includedir@/iverilog$(suffix)
man1dir = @mandir@/man1
docdir = @docdir@
dllib=@DLLIB@ dllib=@DLLIB@
@ -43,11 +39,8 @@ CC = @CC@
HOSTCC := @CC@ HOSTCC := @CC@
WINDRES = @WINDRES@ WINDRES = @WINDRES@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
MAN = @MAN@
PS2PDF = @PS2PDF@
ifeq (@srcdir@,.) ifeq (@srcdir@,.)
INCLUDE_PATH = -I. -I.. INCLUDE_PATH = -I. -I..
@ -55,68 +48,31 @@ else
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
endif endif
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@ CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
PICFLAGS = @PICFLAG@ LDFLAGS = @LDFLAGS@
LDFLAGS = @rdynamic@ @LDFLAGS@
O = main.o res.o O = main.o res.o
ifeq (@MINGW32@,yes)
all: iverilog-vpi@EXEEXT@ all: iverilog-vpi@EXEEXT@
else
all: iverilog-vpi
endif
INSTALL_DOC =
ifneq ($(MAN),none)
INSTALL_DOC += installman
ifneq ($(PS2PDF),none)
ifeq (@MINGW32@,yes)
INSTALL_DOC += installpdf
all: iverilog-vpi.pdf
endif
endif
endif
check: all check: all
clean: clean:
rm -f *.o config.h iverilog-vpi@EXEEXT@ iverilog-vpi \ rm -f *.o config.h iverilog-vpi@EXEEXT@ res.rc
iverilog-vpi.man iverilog-vpi.ps iverilog-vpi.pdf res.rc
distclean: clean distclean: clean
rm -f Makefile config.log rm -f Makefile config.log
cppcheck: main.c config.h cppcheck: main.c
cppcheck --enable=all --std=c99 --std=c++11 -f \ cppcheck --enable=all --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^
--check-level=exhaustive \
--suppressions-list=$(srcdir)/../cppcheck-global.sup \
--suppressions-list=$(srcdir)/cppcheck.sup \
$(INCLUDE_PATH) $^
Makefile: $(srcdir)/Makefile.in ../config.status Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; ./config.status --file=driver-vpi/$@ cd ..; ./config.status --file=driver-vpi/$@
ifeq (@MINGW32@,yes)
iverilog-vpi@EXEEXT@: $O iverilog-vpi@EXEEXT@: $O
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@ $(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
endif
ifeq (@MINGW32@,no)
iverilog-vpi: $(srcdir)/iverilog-vpi.sh ../config.status
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@ENABLE_PLI1@;@LIBVERIUSER@;' \
-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@;$(ivl_includedir);' \
-e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
main.o: $(srcdir)/main.c config.h main.o: $(srcdir)/main.c config.h
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c $(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
@ -128,46 +84,22 @@ config.h: $(srcdir)/config.h.in Makefile
-e 's;@IVLCFLAGS@;$(CFLAGS);' \ -e 's;@IVLCFLAGS@;$(CFLAGS);' \
-e 's;@IVLCXXFLAGS@;$(CXXFLAGS);' \ -e 's;@IVLCXXFLAGS@;$(CXXFLAGS);' \
-e 's;@SHARED@;@shared@;' $< > $@ -e 's;@SHARED@;@shared@;' $< > $@
ifeq (@LIBVERIUSER@,yes)
sed -i 's;@VPILIBS@;-lveriuser$(suffix) -lvpi$(suffix);' $@
else
sed -i 's;@VPILIBS@;-lvpi$(suffix);' $@
endif
# Windows specific... # Windows specific...
res.rc: $(srcdir)/res.rc.in ../config.status res.rc: $(srcdir)/res.rc.in ../version.exe
cd ..; ./config.status --file=driver-vpi/$@ sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%n,0,0'`';' \
$(srcdir)/res.rc.in > $@
res.o: res.rc res.o: res.rc
$(WINDRES) -i res.rc -o res.o $(WINDRES) -i res.rc -o res.o
# #
iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in ../config.status
cd ..; ./config.status --file=driver-vpi/$@
iverilog-vpi.ps: iverilog-vpi.man
$(MAN) -t ./$< > $@
iverilog-vpi.pdf: iverilog-vpi.ps
$(PS2PDF) $< $@
install: all installdirs installfiles install: all installdirs installfiles
F = $(INSTALL_DOC) F = ./iverilog-vpi@EXEEXT@
ifeq (@MINGW32@,yes)
F += ./iverilog-vpi@EXEEXT@
endif
ifeq (@MINGW32@,no)
F += ./iverilog-vpi
endif
installfiles: $(F) | installdirs installfiles: $(F) | installdirs
ifeq (@MINGW32@,yes)
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@" $(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@"
endif
ifeq (@MINGW32@,no)
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
endif
ifeq (@WIN32@,yes) ifeq (@WIN32@,yes)
ifneq ($(HOSTCC),$(CC)) ifneq ($(HOSTCC),$(CC))
$(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libwinpthread-1.dll) "$(DESTDIR)$(bindir)" $(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libwinpthread-1.dll) "$(DESTDIR)$(bindir)"
@ -176,24 +108,8 @@ ifneq ($(HOSTCC),$(CC))
endif endif
endif endif
installman: iverilog-vpi.man installdirs
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(man1dir)/iverilog-vpi$(suffix).1"
installpdf: iverilog-vpi.pdf installdirs
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(docdir)/iverilog-vpi$(suffix).pdf"
installdirs: $(srcdir)/../mkinstalldirs installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs \ $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)"
"$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(docdir)" \
"$(DESTDIR)$(man1dir)"
uninstall: uninstall:
ifeq (@MINGW32@,yes)
rm -f $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@ rm -f $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@
endif
ifeq (@MINGW32@,no)
rm -f $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)
endif
rm -f "$(DESTDIR)$(man1dir)/iverilog-vpi$(suffix).1" \
"$(DESTDIR)$(docdir)/iverilog-vpi$(suffix).pdf"

View File

@ -6,5 +6,5 @@
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@" #define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@"
#define IVERILOG_VPI_CXXFLAGS " @IVLCXXFLAGS@" #define IVERILOG_VPI_CXXFLAGS " @IVLCXXFLAGS@"
#define IVERILOG_VPI_LDFLAGS "@SHARED@" #define IVERILOG_VPI_LDFLAGS "@SHARED@"
#define IVERILOG_VPI_LDLIBS "@VPILIBS@" #define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@"
#define IVERILOG_SUFFIX "@SUFFIX@" #define IVERILOG_SUFFIX "@SUFFIX@"

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