Compare commits

..

152 Commits

Author SHA1 Message Date
steve 1b551aaf94 Update to v0.8.4 release. 2007-03-23 23:26:51 +00:00
steve a3dda80fb2 Properly support signed task/function arguments. 2007-03-23 23:22:57 +00:00
steve 9e9d5ccfdd Fix compile time eval of <= comparison. 2007-03-23 23:02:31 +00:00
steve 07daee9438 Fix compile time evaluation of < operator. 2007-03-23 20:59:25 +00:00
steve 82808d8b5d Parse attribute attached to block items. 2007-03-23 19:31:22 +00:00
steve c045f51a7f Spelling fixes (larry doolittle) 2007-02-26 19:51:38 +00:00
steve d72eadb885 Get page size from sysconf. 2007-02-16 23:29:17 +00:00
steve e99f0a8f51 Comment about 10.3. 2007-02-09 05:30:22 +00:00
steve ed2cb380cd fix lexical handling of slashes in strings. 2007-02-09 05:29:24 +00:00
steve dc8e941260 Fix parse of bit select in notifier expression, 2006-12-03 04:58:20 +00:00
steve d486b81f23 Fix crash handling constant true conditional. 2006-11-27 01:47:14 +00:00
steve 59c2f16a5f Fix evaluate of constant condition expressions. 2006-11-27 01:32:24 +00:00
steve 1470a061fd Add synthesis of user defined functions. 2006-11-26 01:54:05 +00:00
steve c1333a21ef Prevent constant mux outputs from confusing itself. 2006-11-12 01:20:45 +00:00
steve 04ef0b7d80 Fix async blocks to take accumulated input. 2006-11-11 23:10:20 +00:00
steve 2fc9413d1f More detailed BuildRequires settings. 2006-11-11 21:21:50 +00:00
steve c94bdbcdb0 Make signal lookup use extended names. 2006-11-11 21:21:21 +00:00
steve 1820cd0244 Fix compile on Mac OS X 2006-11-02 17:47:52 +00:00
steve aa3cbbdf99 Error message for condit expression not synthesized. 2006-11-02 02:13:15 +00:00
steve 0a9b6f34ae Detect and synthesize enables using condit false. 2006-10-30 02:03:30 +00:00
steve 5c2c5453ac Fix code generation for signed numbers in real expressions. 2006-10-11 00:19:04 +00:00
steve 0c6bb476ea Get rounding of conversion correct. 2006-10-11 00:17:35 +00:00
steve 568924dcb5 Version stamp update 2006-10-04 17:08:59 +00:00
steve 33b3f7bdda Detect delay precision overflow. 2006-10-04 00:37:03 +00:00
steve 3a04e0a051 Fix a dangling reference to NetEParam objects in defparams. 2006-10-04 00:34:45 +00:00
steve 66ae377801 Snapshot v0.8.3 2006-10-03 21:34:40 +00:00
steve 898db57405 Describe the preconfigure steps. 2006-09-28 23:42:14 +00:00
steve 0fe45b5046 Fix host type detection in some configure scripts. 2006-09-22 03:29:02 +00:00
steve 20cfe99457 Fix left shift of small unsized constants. 2006-09-20 20:27:02 +00:00
steve 4ec8b38a5c Special handling of exploded memory arguments. 2006-09-15 23:56:05 +00:00
steve 79add47002 Build instruction typos and minor corrections. 2006-09-15 23:53:24 +00:00
steve c429f4c9a7 missing sig diagnostics. 2006-08-23 04:09:14 +00:00
steve 7f6a0b652a Do not count self as signifincant in nodangle. 2006-08-23 04:08:55 +00:00
steve 9f3f9154eb Fix missing sig on certain mux outputs.
Ignore condit statements (for synthesis) with no outputs.
2006-08-23 04:08:19 +00:00
steve 498fd06412 Add synthesis for casez statements. 2006-08-22 04:22:45 +00:00
steve 6d3b780791 Improve performance of unlink of heavily connected nexa. 2006-08-15 03:41:24 +00:00
steve a0ec981c50 Improved nexus management performance. 2006-08-08 02:17:48 +00:00
steve 930cd598a0 Typo clearing an event cell. 2006-08-06 18:09:42 +00:00
steve 77adab0f33 Remove excess PEString:: prefix for stubborn compilers. 2006-07-28 16:26:17 +00:00
steve 0e3768f829 Handle statement output override better in blocks. 2006-07-23 19:42:33 +00:00
steve 22884f2e64 Add support for full_case attribute. 2006-07-10 00:21:49 +00:00
steve 62da6aca28 Root dir variable does not include lib/ivl components. 2006-07-07 21:31:50 +00:00
steve 525ebddb0c Properly synthesize casex statements. 2006-07-02 00:50:15 +00:00
steve 521750c007 Fix ambiguity warnings. 2006-06-27 01:47:25 +00:00
steve 85d2833a62 Fix const/non-const warnings. 2006-06-27 01:37:14 +00:00
steve e2cc258283 Cure exit from main warning. 2006-06-27 01:33:17 +00:00
steve f09cf85c76 Fix unused var warning for mingw32 build. 2006-06-27 01:30:20 +00:00
steve c32de1dba0 Handle case where case output appears to be internal. 2006-06-26 00:05:46 +00:00
steve 628b866c36 Change Copyright tag to License. 2006-06-24 05:22:55 +00:00
steve 08dbe801c1 synthesis of NetCondit handles partial resets. 2006-06-23 03:49:46 +00:00
steve 101810df21 Handle simple memory addressing in expression synthesis. 2006-06-15 01:57:26 +00:00
steve 3877b636df synthesis for NetEBitSel. 2006-06-14 03:02:54 +00:00
steve 9d028a63f2 Remove redundant call to get_root_dir. 2006-06-14 03:01:49 +00:00
steve 35e5cea9df Add support for -Wunused warnings. 2006-06-12 00:16:50 +00:00
steve ec510071f1 Fix partial use of NetMux in sync condit statements. 2006-06-07 03:17:39 +00:00
steve 7413c533f6 Compilation warnings. 2006-06-02 23:42:48 +00:00
steve dde69cebb6 Handle condit clauses with unassigned outputs. 2006-06-01 03:01:48 +00:00
steve f942657ad5 NetESignal input is only selected bits. 2006-05-21 21:58:46 +00:00
steve fad1620828 Replace assertions with error messages. 2006-05-20 16:06:48 +00:00
steve a9931e7a58 Fix synthesis of l-value bit select in block. 2006-05-18 01:47:12 +00:00
steve 6cd4adb135 Fix synthesis of expressions with land of vectors. 2006-05-15 03:55:22 +00:00
steve 9643b86ab3 Update to use only Mingw for build. 2006-05-08 04:33:35 +00:00
steve 452eaeaea8 Handle memory assignments out of range during synthesis 2006-05-05 01:56:36 +00:00
steve 3a6e2df958 Fix uninitialized mem_lref_ member. 2006-05-02 02:00:15 +00:00
steve e73b7e2656 parse.cc and parse.h are made by the same steps. 2006-05-01 20:11:56 +00:00
steve 469ec11190 Merge fixes from devel tree. 2006-04-25 05:11:14 +00:00
steve e0bbfa512c Constant propagate addresses through NetRamDq read ports. 2006-04-23 04:26:13 +00:00
steve 94c9af2a5d Add cprop debugging. 2006-04-23 04:25:45 +00:00
steve 9f2e7df0ff vpp.conf is generated, so add it to cvsignore. 2006-04-23 02:44:29 +00:00
steve f02b2c9d7a Fix handling of exploded memories with partial or missing resets. 2006-04-16 19:26:37 +00:00
steve 058dac4290 Exploded memories accessed by constant indices. 2006-04-10 03:43:39 +00:00
steve ce4e21a962 Punt on set/reset if some sources are unconnected. 2006-04-01 01:37:58 +00:00
steve 065d6bc1e3 Add synth debug flag 2006-04-01 01:37:24 +00:00
steve 312d09dc1d Handle asynchronous demux/bit replacements. 2006-03-26 23:09:21 +00:00
steve faf7f30283 Add the .demux device. 2006-03-26 23:09:00 +00:00
steve 5d41e98c1f More installation directory flexibility. 2006-03-26 21:47:26 +00:00
steve 5e8330a4ff Better error messages when synthesis fails. 2006-03-18 18:43:21 +00:00
steve ef8964c65a Fix crash when memory exploding doesnot work 2006-03-16 05:40:18 +00:00
steve aa42ec381c Fix a spelling error in an error message. 2006-03-16 05:39:43 +00:00
steve c9d4aab9cb Right shifts really are allowed. 2006-03-16 05:39:20 +00:00
steve b8bc531f05 Fix the memsynth1 case. 2006-03-12 07:34:16 +00:00
steve 79cb8c883a Add support for negedge FFs by using attributes. 2006-02-25 05:03:28 +00:00
steve 27e633410c Add change callback to vpiMemory objects. 2006-02-19 16:57:31 +00:00
steve 7527c466ed Handle synthesis of FF vectors with l-value decoder. 2006-02-19 00:11:31 +00:00
steve 3ea1214160 More robust test for concat constant-ness. 2006-02-07 22:46:23 +00:00
steve 782542922d Detect nul arguments to concat expressions. 2006-02-07 22:45:54 +00:00
steve 1f8102c4dc Speed up processing of connect when one side is empty. 2006-01-27 02:05:46 +00:00
steve c4b34e8720 Document how the default statement handling works. 2006-01-27 01:58:53 +00:00
steve e494be7cbf Fix pin_Sel overrun. 2006-01-22 00:13:59 +00:00
steve eb0a78e9ce When mux has wide select but sparse choices, use 1hot translation. 2006-01-21 21:42:31 +00:00
steve e80138ec8c Restrict DFF to only one of Sset and Sclr. 2006-01-18 06:16:11 +00:00
steve 943316c6f6 Support DFF with synchronous inputs. 2006-01-18 06:15:45 +00:00
steve 52b8ed9077 Rework l-value handling to allow for more l-value type flexibility. 2006-01-18 01:23:23 +00:00
steve fc227aa3e1 Remember to set DLL= flag. 2006-01-14 20:13:38 +00:00
steve 41993815e9 Show synchronous set/clr of FF. 2006-01-14 20:13:22 +00:00
steve c5063f5d2f Case statement handles partial outputs. 2006-01-01 02:25:07 +00:00
steve f28aa11936 Allow for implicit case default in synchronous processes. 2006-01-01 01:30:39 +00:00
steve 3131fa68b7 Fix crashes caused bu synthesis of sqrt32.v. 2005-12-31 04:28:14 +00:00
steve def3809b3f Handle DFF definitions spread out within a block. 2005-12-19 01:13:47 +00:00
steve 3429c24a6a Properly fail when concat is not actually constant. 2005-12-18 21:06:01 +00:00
steve f47627d752 Fix missing outputs from synchronous conditionals to get out from in. 2005-12-15 02:38:51 +00:00
steve 9468f3d06f Handle both asynchronous set and reset. 2005-12-14 01:53:39 +00:00
steve b997de63a5 Account for sync vs async muxes. 2005-12-14 00:54:29 +00:00
steve f50f06ab4e Handle concatenations in l-values. 2005-12-10 04:26:32 +00:00
steve d5d03812cd Fix crash on block with assignments that assign lval to self. 2005-12-10 03:30:50 +00:00
steve b6d5a0675e Support constant concatenation of constants. 2005-12-07 03:28:44 +00:00
steve e63e830d62 Error messages for missing else clauses. 2005-12-07 02:14:37 +00:00
steve 74ca34bd82 Handle partial sets of conditional clauses. 2005-11-16 00:38:26 +00:00
steve c9d480028e Allow for block output to be set throughout the statements. 2005-11-13 22:28:48 +00:00
steve cc89ba66af Do not panic if case statement is nul. 2005-11-13 22:28:14 +00:00
steve 05e6d51004 Snapshot 0.8.2 2005-09-30 15:13:37 +00:00
steve ae583204e3 Snapshot 0.8.2 2005-09-30 15:01:44 +00:00
steve 018476f7cd More predictable ordering of items in NexusSet. 2005-09-25 23:30:31 +00:00
steve bfabeab6b9 Add Xilinx virtex as a reference EDIF device. 2005-09-25 16:35:36 +00:00
steve 4a3f1a3641 Attach line numbers to NetMux devices. 2005-09-11 02:56:37 +00:00
steve d97560caa7 Fix overly agressive constant propagation through MUX causing lost Z bits. 2005-09-11 02:50:51 +00:00
steve 393102d43a Evaluate magnitude compare with real operands. 2005-09-09 02:17:08 +00:00
steve 8e97a0e4d4 Support b1 edge in primitive tables. 2005-09-09 02:13:15 +00:00
steve 4ea789a2d7 More explicit internal error message. 2005-09-04 15:41:54 +00:00
steve 354f7ad920 More explicit internal error message. 2005-09-04 15:39:19 +00:00
steve f4a6206790 Handle b0 edges in primitives. 2005-09-04 15:33:19 +00:00
steve fd29ba3398 Reduce mux slices that are constant throughout range. 2005-08-28 22:00:39 +00:00
steve 44fbf60885 More thorough constant propagation through MUX devices. 2005-08-28 19:51:02 +00:00
steve a0d69113c3 More thorough constant propagation through MUX devices. 2005-08-28 19:50:03 +00:00
steve 86942ac592 Dump CMP_GE devices. 2005-08-28 17:37:28 +00:00
steve 075f9cbc4b Back-port edif_nexus_to_joint from tgt-edif. 2005-08-27 22:29:30 +00:00
steve 9dab368880 fix configure and build instructions for mingw build. 2005-08-27 22:19:37 +00:00
steve 5f6027fb66 Join cell0 and cell1 instances in LPM target. 2005-08-25 18:52:32 +00:00
steve 53156793fe Add support for implicit defaults in case and conditions. 2005-08-22 01:00:41 +00:00
steve 4644c220e8 Handle statements in blocks overriding previous statement outputs. 2005-08-21 22:49:54 +00:00
steve c30cd9afea Display NOR gates. 2005-08-21 22:27:57 +00:00
steve a8f45a18f0 Fix the comment in the EDIT header. 2005-08-21 22:25:51 +00:00
steve 6828e3e2ea Generate LPM for the CMP_EQ device. 2005-08-21 14:39:33 +00:00
steve 75eb372adf configure tgt-edif subdir. 2005-08-21 02:20:16 +00:00
steve 3b753fe52b Add the tgt-edif target. 2005-08-17 01:17:28 +00:00
steve 8c73fa7840 Fix compilation warnings/errors with newer compilers. 2005-08-13 00:45:53 +00:00
steve d310e656c7 Fix parse errors related to pr766. 2005-07-27 14:48:34 +00:00
steve 0510367b70 Fix compile errors with g++-4. 2005-07-06 22:41:34 +00:00
steve 3e11207a56 Fix gcc4 build issues. 2005-06-14 15:33:54 +00:00
steve 665f31271f popen must be matched by pclose. 2005-03-22 15:53:12 +00:00
steve 9a2b56675c Fix set_width to allow binary logical operands to be self determined. 2005-03-05 01:36:16 +00:00
steve c9f38f5ffa Improve distclean targets. 2005-02-23 18:40:23 +00:00
steve 5ea4152162 Spelling fixes from Larry. 2005-02-23 18:37:52 +00:00
steve 327c897d7e Spellig fixes. 2005-02-19 16:39:30 +00:00
steve 29ebe486b7 Fix multiple delete of an expression. 2005-02-19 16:38:14 +00:00
steve 4af0acb3be Fix (from Tony) for clock compression detection 2005-02-11 17:04:22 +00:00
steve 8435774c26 Fix evaluate of constants in netlist concatenation repeats. 2005-01-29 00:18:23 +00:00
steve 6172748c65 Add stub config files to CVS. 2005-01-28 18:30:11 +00:00
steve ca0ae9040a Add ability to compile real values into index registers. 2005-01-28 18:29:29 +00:00
steve d9cdbde3f6 More robust handling of file name argument to $fopen. 2005-01-01 20:07:41 +00:00
steve 307a97116f Fix leak of word registers in code generator. 2004-12-12 04:25:10 +00:00
steve 83d2c6dfd1 Update for 0.8 files. 2004-10-14 01:12:41 +00:00
6366 changed files with 86466 additions and 531737 deletions

26
.cvsignore Normal file
View File

@ -0,0 +1,26 @@
lexor_keyword.cc
parse.h
parse.cc
parse.cc.output
parse.output
syn-rules.cc
syn-rules.cc.output
syn-rules.output
lexor.cc
iverilog-vpi
iverilog-vpi.pdf
iverilog-vpi.ps
ivl
ivl.exp
dep
configure
Makefile
check
check.cc
config.status
config.log
config.cache
autom4te.cache
config.h
_pli_types.h
dosify

2
.gitattributes vendored
View File

@ -1,2 +0,0 @@
# gperf in MSYS chokes on DOS line endings
*.gperf text eol=lf

View File

@ -1,41 +0,0 @@
name: Deploy documentation
on:
# Every push onto the main branch regerenates the documentation
push:
branches:
- 'master'
jobs:
do-deploy:
runs-on: ubuntu-latest
name: 'Build documentation on Linux'
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
sudo apt update -qq
sudo apt install -y make autoconf python3-venv
python3 -m venv .venv
. .venv/bin/activate
pip install --upgrade pip
pip install -r Documentation/requirements.txt
- name: Make Documentation
run: |
. .venv/bin/activate
cd Documentation
make html
- name: Deploy to GitHub Pages
uses: crazy-max/ghaction-github-pages@v2
with:
target_branch: gh-pages
build_dir: Documentation/_build/html
jekyll: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,161 +0,0 @@
name: test
on:
# Every push onto the main branch triggers a retest.
push:
branches:
- master
# All pull_requests trigger a retest.
pull_request:
workflow_dispatch:
jobs:
mac:
strategy:
fail-fast: false
matrix:
libvvp: [true]
suffix: [true]
runs-on: macos-15-intel
name: 🍏 macOS${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: |
brew install bison
- name: Build, check and install
run: |
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
./configure $CONFIG_OPTS
make -j$(nproc) check
sudo make install
- name: Test
run: |
make check-installed
lin:
strategy:
fail-fast: false
matrix:
os: ['22.04', '24.04']
# libvvp: [false, true]
# suffix: [false, true]
runs-on: ubuntu-${{ matrix.os }}
name: 🐧 Ubuntu ${{ matrix.os }}${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: |
sudo apt update -qq
sudo apt install -y make g++ git bison flex gperf libreadline-dev libbz2-dev autoconf python3-venv
python3 -m venv .venv
. .venv/bin/activate
pip install --upgrade pip
pip install -r Documentation/requirements.txt
- name: Build, check and install
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
./configure $CONFIG_OPTS
make -j$(nproc) check
sudo make install
- name: Test
run:
make check-installed
- name: Documentation
run: |
. .venv/bin/activate
cd Documentation
make html
win:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
msystem: [MINGW64, UCRT64, CLANG64]
# libvvp: [false, true]
# suffix: [false, true]
include:
- { msystem: MINGW64, env: x86_64 }
- { msystem: UCRT64, env: ucrt-x86_64 }
- { msystem: CLANG64, env: clang-x86_64 }
name: 🟪 ${{ matrix.msystem }}${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
defaults:
run:
shell: msys2 {0}
env:
MINGW_ARCH: ${{ matrix.msystem }}
steps:
- run: git config --global core.autocrlf input
shell: bash
- uses: actions/checkout@v6
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
update: true
install: >
git
base-devel
python-pip
mingw-w64-${{ matrix.env }}-perl
- uses: actions/setup-python@v6
with:
python-version: '>=3.5'
- name: Build and check
run: |
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
- name: Install
run: pacman -U --noconfirm msys2/*.zst
- name: Test
run: |
make check-installed
- uses: actions/upload-artifact@v7
with:
name: 🟪 ${{ matrix.msystem }}${{ matrix.libvvp && ' +libvvp' || '' }}
path: msys2/*.zst

122
.gitignore vendored
View File

@ -1,122 +0,0 @@
# Lines that start with '#' are comments.
#
# This file is for the development branch of Icarus Verilog.
#
# The following files will be ignored by git.
# Normal editor rules
*.swp
*~
# Virtual environments
.conda/
.venv/
# Top level generic files
tags
TAGS
cscope.*
*.patch
*.orig
# Object files and libraries
*.[oa]
*.so
gmon*.out
gmon*.txt
# From autoconf
configure
config.log
config.status
Makefile
/_pli_types.h
config.h
/tgt-pcb/pcb_config.h
/tgt-vvp/vvp_config.h
/tgt-vhdl/vhdl_config.h
/vhdlpp/vhdlpp_config.h
/vpi/vpi_config.h
stamp-*-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
autom4te.cache
dep
# Compiler back end and library files
/tgt-vvp/*.conf
*.tgt
*.vpi
/cadpli/cadpli.vpl
# lex, yacc and gperf output
/driver/cflexor.c
/driver/cfparse.c
/driver/cfparse.h
/driver/cfparse.output
/ivlpp/lexor.c
/lexor.cc
/lexor_keyword.cc
/parse.cc
/parse.h
/parse.output
/syn-rules.cc
/syn-rules.output
/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_parse.c
/vpi/sdf_parse.h
/vpi/sdf_parse.output
/vpi/sys_readmem_lex.c
/vpi/table_mod_lexor.c
/vpi/table_mod_parse.c
/vpi/table_mod_parse.h
/vpi/table_mod_parse.output
/vvp/dump.*
/vvp/lexor.cc
/vvp/parse.cc
/vvp/parse.h
/vvp/parse.output
# Program created files
/vvp/tables.cc
# The executables.
*.exe
/driver/iverilog
/driver-vpi/iverilog-vpi
/ivl
/ivlpp/ivlpp
/vhdlpp/vhdlpp
/vvp/vvp
/ivl.exp
/vvp/vvp.exp
# Check output
/check.vvp
/driver/top.vvp

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "config.h"
# include "AStatement.h"
AContrib::AContrib(PExpr*lv, PExpr*rv)
: lval_(lv), rval_(rv)
{
}
AContrib::~AContrib()
{
delete lval_;
delete rval_;
}
AProcess::~AProcess()
{
}

View File

@ -1,88 +0,0 @@
#ifndef IVL_AStatement_H
#define IVL_AStatement_H
/*
* Copyright (c) 2008-2026 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 <map>
# include "ivl_target.h"
# include "StringHeap.h"
# include "LineInfo.h"
# include "Statement.h"
# include "PExpr.h"
class PExpr;
class NetAnalog;
class NetScope;
class Design;
/*
* A contribution statement is like an assignment: there is an l-value
* expression and an r-value expression. The l-value is a branch probe
* expression.
*/
class AContrib : public Statement {
public:
AContrib(PExpr*lval, PExpr*rval);
~AContrib() override;
AContrib(const AContrib&) = delete;
AContrib& operator=(const AContrib&) = delete;
virtual void dump(std::ostream&out, unsigned ind) const override;
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
private:
PExpr*lval_;
PExpr*rval_;
};
/*
* An analog process is not a statement, but contains an analog
* statement. The process is where we attach process characteristics
* such as initial vs. always, attributes....
*/
class AProcess : public LineInfo {
public:
AProcess(ivl_process_type_t t, Statement*st)
: type_(t), statement_(st) { }
~AProcess() override;
bool elaborate(Design*des, NetScope*scope) const;
ivl_process_type_t type() const { return type_; }
Statement*statement() { return statement_; }
std::map<perm_string,PExpr*> attributes;
// Dump the analog process
void dump(std::ostream&out, unsigned ind) const;
private:
ivl_process_type_t type_;
Statement*statement_;
private: // not implemented
AProcess(const AProcess&);
AProcess& operator= (const AProcess&);
};
#endif /* IVL_AStatement_H */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com) * Copyright (c) 2000 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
@ -14,13 +14,16 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.cc,v 1.6 2004/02/20 18:53:33 steve Exp $"
#endif
# include "config.h" # include "config.h"
# include "Attrib.h" # include "Attrib.h"
# include <cassert> # include <assert.h>
Attrib::Attrib() Attrib::Attrib()
{ {
@ -99,3 +102,37 @@ const verinum& Attrib::attr_value(unsigned idx) const
assert(idx < nlist_); assert(idx < nlist_);
return list_[idx].val; return list_[idx].val;
} }
/*
* $Log: Attrib.cc,v $
* Revision 1.6 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.5 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.4 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.3 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
*/

View File

@ -1,7 +1,7 @@
#ifndef IVL_Attrib_H #ifndef __Attrib_H
#define IVL_Attrib_H #define __Attrib_H
/* /*
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com) * Copyright (c) 2000 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
@ -16,8 +16,11 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: Attrib.h,v 1.5 2004/02/20 18:53:33 steve Exp $"
#endif
# include "StringHeap.h" # include "StringHeap.h"
# include "verinum.h" # include "verinum.h"
@ -30,7 +33,7 @@ class Attrib {
public: public:
Attrib(); Attrib();
virtual ~Attrib(); ~Attrib();
const verinum&attribute(perm_string key) const; const verinum&attribute(perm_string key) const;
void attribute(perm_string key, const verinum&value); void attribute(perm_string key, const verinum&value);
@ -57,4 +60,31 @@ class Attrib {
Attrib& operator= (const Attrib&); Attrib& operator= (const Attrib&);
}; };
#endif /* IVL_Attrib_H */ /*
* $Log: Attrib.h,v $
* Revision 1.5 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.
*
* Divide signal reference counts between rval
* and lval references.
*
* Revision 1.2 2002/05/23 03:08:50 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.1 2000/12/04 17:37:03 steve
* Add Attrib class for holding NetObj attributes.
*
*/
#endif

173
BUGS.txt Normal file
View File

@ -0,0 +1,173 @@
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 ivl does that is wrong, and what you expect should
happen. And include the command line flags passed to the compiler to make
the error happen. (This is often overlooked, and sometimes important.)
* The Compiler Doesn't Compile
If the Icarus Verilog don't compile, I need to know about the
compilation tools you are using. Specifically, I need to know:
- Operating system and processor type,
- Compiler w/ version,
- Library version, and
- anything else you think relevant.
Be aware that I do not have at my disposal a porting lab. I have the
alpha on my desk, 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.
Ivl internally checks its state while it works, and if it detects
something wrong that it cannot recover from, it will abort
intentionally. The "assertion failure" message that the program
prints in the process of dying is very important. It tells me where in
the source the bad thing happened. Include that message in the bug
report.
If there are not assertion messages, I need to know that as well.
I also need a complete test program that demonstrates the crash.
* It Doesn't Like My Perfectly Valid Program(tm)
I need to know what you think is right that ivl gets wrong. Does it
reject your "Perfectly Valid Program(tm)" or does it compile it but
give incorrect results? The latter is the most insidious as it doesn't
scream out to be fixed unless someone is watching closely. However, if
I get a sample program from you, and I can compile it, and I run it
and nuclear junk doesn't fall from the sky, I'm moving on to the next
problem.
So, if your program doesn't compile, tell me so, tell me where the
error occurs, and include a complete Perfectly Valid Test Program(tm).
You tell me that it fails to compile for you, and I find that it
compiles for me, then hooray I fixed it. It can happen, you
know. What's on my disk is more recent then the latest snapshot.
If your program does compile, but generates incorrect output, I need
to know what it says and what you think it should say. From this I can
take your sample program and work on ivl until it gets the proper
results. For this to work, of course, I first need to know what is
wrong with the output. Spell it out, because I've been known to miss
the obvious. Compiler writers often get buried in the details of the
wrong problem.
* It Generates Incorrect Target Code (XNF, EDIF/LPM, etc.)
As ivl adds target code generators, there will be cases where errors
in the output netlist format occur. This is a tough nut because I
might not have all the tools to test the target format you are
reporting problems with. However, if you clearly explain what is right
and wrong about the generated netlist, I will probably be able to fix
the problem. It may take a few iterations.
In this case, if possible include not only the sample verilog program,
but the generated netlist file(s) and a clear indication of what went
wrong. If it is not clear to me, I will ask for clarification.
* The Output is Correct, But Less Then Ideal
If the output is strictly correct, but just not good enough for
practical use, I would like to know. These sorts of problems are
likely to be more subjective then a core dump, but are worthy of
consideration. However, realize that outright errors will get more
attention then 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 (after preprocessing) that I need to invoke the error.
Also, include the command line you use to invoke the compiler. For
example:
ivl foo.vl -o foo.cc -tvvm
ivl foo.vl -s starthere
If the error occurs with the null target (``-tnull'') then a top level
module may not be needed as long as the ``-s <name>'' switch is
given.
So when you send a test case, ask yourself "Can poor overworked Steve
invoke the error without any Verilog other then what is included?" And
while we are at it, please place a copyright notice in your test
program and include a GPL license statement if you can. Your test
program may find its way into the test suite, and the notices will
make it all nice and legal.
RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS
The URL <http://www.icarus.com/cgi-bin/ivl-bugs> is the main bug
tracking system. Once you believe you have found a bug, you may browse
the bugs database for existing bugs that may be related to yours. You
might find that your bug has already been fixed in a later release or
snapshot. If that's the case, then you are set.
The bug database supports basic keyword searches, and you can
optionally limit your search to active bugs, or fixed bugs. You may
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. You may submit it via the web form, or via
e-mail.
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 context diffs as emitted by diff from GNU diffutils. Human
beings can read such things, and they are resilient to changing
originals. A good set of flags to diff are ``diff -cNB''. With such
diffs, I can look at the changes you are offering and probably tell at
a glance that they are plausible. Then I can use patch(1) to apply
them. Or I can apply them by hand.
However, if you send patches, *please* tell me what this patch is
supposed to accomplish, and if appropriate include a test program that
demonstrates the efficacy of the patch. (If I have no idea what the
patch is for, I will ask for clarification before applying it.)
COPYRIGHT ISSUES
Icarus Verilog is Copyright (c) 1998-2003 Stephen Williams except
where otherwise noted. Minor patches are covered as derivative works
(or editorial comment or whatever the appropriate legal term is) and
folded into the rest of ivl. However, if a submission can reasonably
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.
$Id: BUGS.txt,v 1.4 2003/02/19 04:36:31 steve Exp $
$Log: BUGS.txt,v $
Revision 1.4 2003/02/19 04:36:31 steve
Notes on hte bug database.
Revision 1.3 2003/01/30 16:23:07 steve
Spelling fixes.
Revision 1.2 1999/08/06 04:05:28 steve
Handle scope of parameters.

42
COPYING
View File

@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
Preamble Preamble
The licenses for most software are designed to take away your The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public freedom to share and change it. By contrast, the GNU General Public
@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to the GNU Library General Public License instead.) You can apply it to
your programs, too. your programs, too.
When we speak of free software, we are referring to freedom, not When we speak of free software, we are referring to freedom, not
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and The precise terms and conditions for copying, distribution and
modification follow. modification follow.
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains 0. This License applies to any program or other work which contains
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on does not normally print such an announcement, your work based on
the Program is not required to print an announcement.) the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program, identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in and can be reasonably considered independent and separate works in
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not distribution of the source code, even though third parties are not
compelled to copy the source along with the object code. compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program 4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is otherwise to copy, modify, sublicense or distribute the Program is
@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License. be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in 8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License original copyright holder who places the Program under this License
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally. of promoting the sharing and reuse of software generally.
NO WARRANTY NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES. POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it possible use to the public, the best way to achieve this is to make it
@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found. the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.> <one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author> Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License along You should have received a copy of the GNU General Public License
with this program; if not, write to the Free Software Foundation, Inc., along with this program; if not, write to the Free Software
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this If the program is interactive, make it output a short notice like this
when it starts in an interactive mode: when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details. under certain conditions; type `show c' for details.
@ -335,5 +335,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General library. If this is what you want to do, use the GNU Library General
Public License instead of this License. Public License instead of this License.

View File

@ -1,2 +0,0 @@
_build/
!Makefile

View File

@ -1,20 +0,0 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = IcarusVerilog
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@ -1,172 +0,0 @@
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'Icarus Verilog'
copyright = '2024-2026, Stephen Williams'
author = 'Stephen Williams'
# The short X.Y version
version = ''
# The full version, including alpha/beta/rc tags
release = ''
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path .
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If no language is specified, use none
highlight_language = 'none'
# -- 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
# a list of builtin themes.
#
html_theme = 'shibuya'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
"github_url": "https://github.com/steveicarus/iverilog",
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']
html_static_path = []
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
html_favicon = 'favicon.ico'
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'IcarusVerilogdoc'
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'IcarusVerilog.tex', 'Icarus Verilog Documentation',
'Stephen Williams', 'manual'),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'iverilog-docs', 'Icarus Verilog Documentation',
[author], 1)
]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'IcarusVerilog', 'Icarus Verilog Documentation',
author, 'IcarusVerilog', 'One line description of project.',
'Miscellaneous'),
]

View File

@ -1,248 +0,0 @@
Getting Started as a Contributor
================================
Icarus Verilog development is centered around the github repository at
`github.com/steveicarus/iverilog <http://github.com/steveicarus/iverilog>`_.
Contributing to Icarus Verilog requires a basic knowledge of git and github,
so see the github documentation for more information. The sections below will
step you through the basics of getting the source code from github, making a
branch, and submitting a pull request for review.
Getting Icarus Verilog
----------------------
To start, you will need to clone the code. It is preferred that you use the
"ssh" method, and the ssh based clone with the command:
.. code-block:: console
% git clone git@github.com:steveicarus/iverilog.git
This assumes that you have a github account (accounts are free) and you have
set up your ssh authentication keys. See the
`Authentication Guides here <https://docs.github.com/en/authentication>`_.
The "git clone" command will get you all the source:
.. code-block:: console
% git clone git@github.com:steveicarus/iverilog.git
Cloning into 'iverilog'...
remote: Enumerating objects: 66234, done.
remote: Counting objects: 100% (6472/6472), done.
remote: Compressing objects: 100% (4123/4123), done.
remote: Total 66234 (delta 2412), reused 6039 (delta 2190), pack-reused 59762
Receiving objects: 100% (66234/66234), 27.98 MiB | 2.53 MiB/s, done.
Resolving deltas: 100% (50234/50234), done.
% cd iverilog/
Normally, this is enough as you are now pointing at the most current
development code, and you have implicitly created a branch "master" that
tracks the development head. However, If you want to actually be working on a
specific version, say for example version 11, the v11-branch, you checkout
that branch with the command:
.. code-block:: console
% git checkout --track -b v11-branch origin/v11-branch
This creates a local branch that tracks the v11-branch in the repository, and
switches you over to your new v11-branch. The tracking is important as it
causes pulls from the repository to re-merge your local branch with the remote
v11-branch. You always work on a local branch, then merge only when you
push/pull from the remote repository.
Now that you've cloned the repository and optionally selected the branch you
want to work on, your local source tree may later be synced up with the
development source by using the git command:
.. code-block:: console
% git pull
Already up to date.
Finally, configuration files are built by the extra step:
.. code-block:: console
% sh autoconf.sh
Autoconf in root...
Precompiling lexor_keyword.gperf
Precompiling vhdlpp/lexor_keyword.gperf
You will need autoconf and gperf installed in order for the script to work.
If you get errors such as:
.. code-block:: console
% sh autoconf.sh
Autoconf in root...
autoconf.sh: 10: autoconf: not found
Precompiling lexor_keyword.gperf
autoconf.sh: 13: gperf: not found.
You will need to install download and install the autoconf and gperf tools.
Now you are ready to configure and compile the source.
Icarus Specific Configuration Options
-------------------------------------
Icarus takes many of the standard configuration options and those will not be
described here. The following are specific to Icarus Verilog:
.. code-block:: none
--enable-suffix[=suffix]
This option allows the user to build Icarus with a default suffix or when
provided a user defined suffix. All programs or directories are tagged with
this suffix. e.g.(iverilog-0.8, vvp-0.8, etc.). The output of iverilog will
reference the correct run time files and directories. The run time will check
that it is running a file with a compatible version e.g.(you can not run a
V0.9 file with the V0.8 run time).
.. 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:
.. code-block:: none
--with-valgrind
This option adds extra memory cleanup code and pool management code to allow
better memory leak checking when valgrind is available. This option is not
needed when checking for basic errors with valgrind.
Compiling on Linux
------------------
(Note: You will need to install bison, flex, g++ and gcc) This is probably the
easiest step. Given that you have the source tree from the above instructions,
the compile and install is generally as simple as:
.. code-block:: console
% ./configure
configure: loading site script /usr/share/site/x86_64-unknown-linux-gnu
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
[...and so on...]
% make
mkdir dep
Using git-describe for VERSION_TAG
g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c main.cc -o main.o
mv main.d dep/main.d
g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c async.cc -o async.o
mv async.d dep/async.d
g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c design_dump.cc -o design_dump.o
mv design_dump.d dep/design_dump.d
g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c discipline.cc -o discipline.o
[...and so on...]
The end result is a complete build of Icarus Verilog. You can install your
compiled version with a command like this:
.. code-block:: console
% sudo make install
Regression Tests
----------------
Icarus Verilog comes with a fairly extensive regression test suite. As of
2022, that test suite is included with the source in the "ivtest"
directory. Contained in that directory are a couple driver scripts that run
all the regression tests on the installed version of Icarus Verilog. So for
example:
.. code-block:: console
% cd ivtest
% ./vvp_reg.pl
% ./vvp_reg.py
% ./vpi_reg.pl
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
patches to the developers. Also, if you are adding a new feature, you should
add test programs to the regression test suite to validate your new feature
(or bug fix.). The python script is the preferred method to add new tests.
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
being merged.
Forks, Branches and Pull Requests
---------------------------------
Currently, the preferred way to submit patches to Icarus Verilog is via pull
requests.
`Pull requests <https://docs.github.com/en/github-ae@latest/pull-requests>`_
can be created from the main repository if you have write access (very few
people have write access) or more commonly from a fork, so the first step is
to create a fork that you can work with. It is easy enough to create a fork,
just go to the
`github.com/steveicarus/iverilog <http://github.com/steveicarus/iverilog>`_
page and use the "fork" button in the upper right corner. This will create
a new repository that you can clone instead of the steveicarus/iverilog
repository. You then use your local repository to create feature branches,
then submit them for inclusion in the main repository as pull
requests. Remember to `synchronize your fork
<https://docs.github.com/en/github-ae@latest/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork>`_
periodically with the main repository. This will make sure your work is based
on the latest upstream and avoid merge conflicts.
Create your patch by first creating a branch that contains your commits:
.. code-block:: console
% git checkout -b my-github-id/branch-name
We are encouraging using this scheme for naming your branches that are
destined for pull requests. Use your github id in the branch name. So for
example:
.. code-block:: console
% git checkout -b steveicarus/foo-feature
Do your work in this branch, then when you are ready to create a pull request,
first push the branch up to github:
.. code-block:: console
% git push -u origin my-github-id/branch-name
Then go to github.com to create your pull request. `Create your pull request
against the "master" branch of the upstream repository
<https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork>`_,
or the version branch that you are working on. Your pull request will be run
through continuous integration, and reviewed by one of the main
authors. Feedback may be offered to your PR, and once accepted, an approved
individual will merge it for you. Then you are done.

View File

@ -1,169 +0,0 @@
Developer Guide
===============
The developer guide is intended to give you a gross structure of the
Icarus Verilog compiler source. This will help orient you to the
source code itself, so that you can find the global parts where you
can look for even better detail.
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
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/)
This is the binary that is installed as "iverilog". This program takes
the command line arguments and assembles invocations of all the other
subcommands to perform the steps of compilation.
- The preprocessor (ivlpp/)
This implements the Verilog pre-processor. In Icarus Verilog, the
compiler directives \`define, \`include, \`ifdef and etc. are implemented
in an external program. The ivlpp/ directory contains the source for
this program.
- The core compiler (root directory)
The "ivl" program is the core that does all the Verilog compiler
processing that is not handled elsewhere. This is the main core of the
Icarus Verilog compiler, not the runtime. See below for more details
on the core itself.
- The loadable code generators (tgt-\*/)
This core compiler, after it is finished with parsing and semantic
analysis, uses loadable code generators to emit code for supported
targets. The tgt-\*/ directories contains the source for the target
code generators that are bundled with Icarus Verilog. The tgt-vvp/
directory in particular contains the code generator for the vvp
runtime.
Runtime Components
------------------
- The vvp runtime (vvp/)
This program implements the runtime environment for Icarus
Verilog. It implements the "vvp" command described in the user
documentation. See the vvp/ subdirectory for further developer
documentation.
- The system tasks implementations (vpi/)
The standard Verilog system tasks are implemented using VPI (PLI-2)
and the source is in this subdirectory.
- The PLI-1 compatibility library (libveriuser/)
The Icarus Verilog support for the deprecated PLI-1 is in this
subdirectory. The vvp runtime does not directly support the
PLI-1. Instead, the libveriuser library emulates it using the builtin
PLI-2 support.
- The Cadence PLI module compatibility module (cadpli/)
It is possible in some specialized situations to load and execute
PLI-1 code written for Verilog-XL. This directory contains the source
for the module that provides the Cadence PLI interface.
The Core Compiler
-----------------
The "ivl" binary is the core compiler that does the heavy lifting of
compiling the Verilog source (including libraries) and generating the
output. This is the most complex component of the Icarus Verilog
compilation system.
The process in the abstract starts with the Verilog lexical analysis
and parsing to generate an internal "pform". The pform is then
translated by elaboration into the "netlist" form. The netlist is
processed by some functors (which include some optimizations and
optional synthesis) then is translated into the ivl_target internal
form. And finally, the ivl_target form is passed via the ivl_target.h
API to the code generators.
- Lexical Analysis
Lexical analysis and parsing use the tools "flex", "gperf", and
"bison". The "flex" input file "lexor.lex" recognizes the tokens in
the input stream. This is called "lexical analysis". The lexical
analyzer also does some processing of compiler directives that are not
otherwise taken care of by the external preprocessor. The lexical
analyzer uses a table of keywords that is generated using the "gperf"
program and the input file "lexor_keywords.gperf". This table allows
the lexical analyzer to efficiently check input words with the rather
large set of potential keywords.
- Parsing
The parser input file "parse.y" is passed to the "bison" program to
generate the parser. The parser uses the functions in parse*.h,
parse*.cc, pform.h, and pform*.cc to generate the pform from the
stream of input tokens. The pform is what compiler writers call a
"decorated parse tree".
The pform itself is described by the classes in the header files
"PScope.h", "Module.h", "PGenerate.h", "Statement.h", and
"PExpr.h". The implementations of the classes in those header files
are in the similarly named C++ files.
- Elaboration
Elaboration transforms the pform to the netlist form. Elaboration is
conceptually divided into several major steps: Scope elaboration,
parameter overrides and defparam propagation, signal elaboration, and
statement and expression elaboration.
The elaboration of scopes and parameter overrides and defparam
propagation are conceptually separate, but are in practice
intermingled. The elaboration of scopes scans the pform to find and
instantiate all the scopes of the design. New scopes are created by
instantiation of modules (starting with the root instances) by user
defined tasks and functions, named blocks, and generate schemes. The
elaborate_scope methods implement scope elaboration, and the
elab_scope.cc source file has the implementations of those
methods.
The elaborate.cc source file contains the initial calls to the
elaborate_scope for the root scopes to get the process started. In
particular, see the "elaborate" function near the bottom of the
elaborate.cc source file. The calls to Design::make_root_scope create
the initial root scopes, and the creation and enqueue of the
elaborate_root_scope_t work items primes the scope elaboration work
list.
Intermingled in the work list are defparms work items that call the
Design::run_defparams and Design::evaluate_parameters methods that
override and evaluate parameters. The override and evaluation of
parameters must be intermingled with the elaboration of scopes because
the exact values of parameters may impact the scopes created (imagine
generate schemes and instance arrays) and the created scopes in turn
create new parameters that need override and evaluation.
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,12 +0,0 @@
IVL - The Core Compiler
=======================
.. toctree::
:maxdepth: 1
netlist
attributes
ivl_target
lpm
t-dll

View File

@ -1,131 +0,0 @@
Loadable Target API (ivl_target)
================================
In addition to the standard VPI API, Icarus Verilog supports a non-standard
loadable target module API. This API helps C programmers write modules that
Icarus Verilog can use to generate code. These modules are used at compile
time to write the elaborated design to the simulation or netlist files. For
example, the vvp code generator is a loadable target module that writes vvp
code into the specified file.
Loadable target modules gain access to the 'elaborated' design. That means,
the source files have been checked for syntax and correctness, any synthesis
and general optimization steps have been performed, and what is left is a
design that reflects but is not exactly the same as the input Verilog source
code. This relieves the modules of the burden of supporting all the odd
corners and complexities of the Verilog language.
The Target Module API
---------------------
The API is defined in the header file "ivl_target.h" which is installed with
Icarus Verilog. The header defines the functions that the module writer can
use to get at the elaborated design during the course of writing the output
format.
The target module API function "target_design" is special in that the API does
not provide this function: The target module itself provides it. When the
compiler loads the target module, it invokes the "target_design" function with
a handle to the design. This is the point where the target module takes over
to process the design.
Compiling Target Modules
------------------------
Compiling loadable target modules is similar to compiling VPI modules, in that
the module must be compiled with the "-fPIC" flag to gcc, and linked with the
"-shared" flag. The module that you compile is then installed in a place where
the "iverilog" command can find it, and configuration files are adjusted to
account for the new module.
This code::
# include <ivl_target.h>
int target_design(ivl_design_t des)
{
return 0;
}
is an example module that we can write into the file "empty.c"; and let us
compile it into the module file "empty.tgt" like so::
% gcc -o empty.tgt -fpic -shared empty.c
This makes the "empty.tgt" file an a dynamically loaded shared object.
Creating the Target Config File
-------------------------------
The target config file tells the Icarus Verilog core how to process your new
code generator. The ivl core expects two configuration files: the name.conf
and the name-s.config files. The "-s" version is what is used if the user
gives the "-S" (synthesis) flag on the command line.
The stub target, included in most distributions, demonstrates the config
files. The "stub.conf" file is::
functor:cprop
functor:nodangle
-t:dll
flag:DLL=stub.tgt
and the "stub-s.conf" file is::
functor:synth2
functor:synth
functor:syn-rules
functor:cprop
functor:nodangle
-t:dll
flag:DLL=stub.tgt
Note that the "stub-s.conf" file contains more lines to invoke internal
synthesis functions, whereas the "stub.conf" invokes only the basic
optimization steps.
In general, only the last line (The "flag:DLL=<name>.tgt" record) varies for
each target. For your target, replace the <name> with the name of your target
and you have a configuration file ready to install. Note that this is the name
of your target module. This is in fact how the config file tells the compiler
the name of your module.
The rest of the config file is best taken as boiler plate and installed as is,
with one difference. If your target is a synthesis target (for example a mosis
code generator or a pld code generator) that expects synthesis to happen, then
it makes the most sense to create both your config file like the "stub-s.conf"
config file. This causes the compiler to do synthesis for your target whether
the user gives the "-S" flag or not.
Installing the Target Module
----------------------------
Finally, the "empty.conf", the "empty-s.conf" and the "empty.tgt" files need
to be installed. Where they go depends on your system, but in Linux they are
normally installed in "/usr/lib/ivl".
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

@ -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,100 +0,0 @@
Verilog-A math library
======================
License.
--------
Verilog-A math library built for Icarus Verilog
https://github.com/steveicarus/iverilog/
Copyright (C) 2007-2024 Cary R. (cygcary@yahoo.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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.
Standard Verilog-A Mathematical Functions.
------------------------------------------
The va_math VPI module implements all the standard math functions provided
by Verilog-A as Verilog-D system functions. The names are the same except
like all Verilog-D system functions the name must be prefixed with a '$'.
For reference the functions are::
$ln(x) -- Natural logarithm
$log10(x) -- Decimal logarithm
$exp(x) -- Exponential
$sqrt(x) -- Square root
$min(x,y) -- Minimum
$max(x,y) -- Maximum
$abs(x) -- Absolute value
$floor(x) -- Floor
$ceil(x) -- Ceiling
$pow(x,y) -- Power (x**y)
$sin(x) -- Sine
$cos(x) -- Cosine
$tan(x) -- Tangent
$asin(x) -- Arc-sine
$acos(x) -- Arc-cosine
$atan(x) -- Arc-tangent
$atan2(y,x) -- Arc-tangent of y/x
$hypot(x,y) -- Hypotenuse (sqrt(x**2 + y**2))
$sinh(x) -- Hyperbolic sine
$cosh(x) -- Hyperbolic cosine
$tanh(x) -- Hyperbolic tangent
$asinh(x) -- Arc-hyperbolic sine
$acosh(x) -- Arc-hyperbolic cosine
$atanh(x) -- Arc-hyperbolic tangent
The only limit placed on the x and y arguments by the library is that they
must be numbers (not constant strings). The underlying C library controls
any other limits placed on the arguments. Most libraries return +-Inf or
NaN for results that cannot be represented with real numbers. All functions
return a real result.
Standard Verilog-A Mathematical Constants.
------------------------------------------
The Verilog-A mathematical constants can be accessed by including the
"constants.vams" header file. It is located in the standard include
directory. Recent version of Icarus Verilog (0.9.devel) automatically
add this directory to the end of the list used to find include files.
For reference the mathematical constants are::
`M_PI -- Pi
`M_TWO_PI -- 2*Pi
`M_PI_2 -- Pi/2
`M_PI_4 -- Pi/4
`M_1_PI -- 1/Pi
`M_2_PI -- 2/Pi
`M_2_SQRTPI -- 2/sqrt(Pi)
`M_E -- e
`M_LOG2E -- log base 2 of e
`M_LOG10E -- log base 10 of e
`M_LN2 -- log base e of 2
`M_LN10 -- log base e of 10
`M_SQRT2 -- sqrt(2)
`M_SQRT1_2 -- 1/sqrt(2)
Using the Library.
------------------
Just add "-m va_math" to your iverilog command line/command file and
\`include the "constants.vams" file as needed.
Thanks
------
I would like to thank Larry Doolittle for his suggestions and
Stephen Williams for developing Icarus Verilog.

View File

@ -1,50 +0,0 @@
VPI Modules in Icarus Verilog
================================
The VPI interface for Icarus Verilog works by creating from a
collection of PLI applications a single vpi module. The vpi module
includes compiled code for the applications linked together (with any
other libraries that the applications need) into a module with two
exported symbols, the vpip_set_callback function and the
vlog_startup_routines array.
The product that wishes to invoke the module (normally at run time) loads
the module, locates and calls the vpip_set_callback function to pass the
the module a jump table that allows the module to access the VPI routines
implemented by the product, then locates the vlog_startup_routines table
and calls all the startup routines contained in that table. It is possible
for a product to link with many modules. In that case, all the modules are
linked in and startup routines are called in order.
The product that uses vpi modules uses the environment variable
VPI_MODULE_PATH as a ':' separated list of directories. This is the
module search path. When a module is specified by name (using whatever
means the product supports) the module search path is scanned until
the module is located.
The special module names "system.vpi", "v2005_math.vpi", "v2009.vpi",
and "va_math.vpi" are part of the core Icarus Verilog distribution and
include implementations of the standard system tasks/functions. The
additional special module names "vhdl_sys.vpi" and "vhdl_textio.vpi"
include implementations of private functions used to support VHDL.
Compiling A VPI Module
----------------------
See the documentation under: :doc:`Using VPI <../../../usage/vpi>`
Tracing VPI Use
---------------
The vvp command includes the ability to trace VPI calls. This is
useful if you are trying to debug a problem with your code. To
activate tracing simply set the VPI_TRACE environment variable, with
the path to a file where trace text gets written. For example::
setenv VPI_TRACE /tmp/foo.txt
This tracing is pretty verbose, so you don't want to run like this
normally. Also, the format of the tracing messages will change
according to my needs (and whim) so don't expect to be able to parse
it in software.

View File

@ -1,19 +0,0 @@
Debug Aids For VVP
==================
Debugging vvp can be fiendishly difficult, so there are some built in
debugging aids. These are enabled by setting the environment variable
VVP_DEBUG to the path to an output file. Then, various detailed debug
tools can be enabled as described below.
* .resolv
The .resolv can print debug information along with a label by
specifying the debug output label on the .resolv line::
.resolv tri$<label>
In this case, the "$" character directly after the "tri" enables debug
dumps for this node, and the <label> is the label to prepend to log
messages from this node.

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
Icarus Verilog Developer Support
================================
This section contains documents to help support developers who contribute to
Icarus Verilog.
.. toctree::
:maxdepth: 1
getting_started
regression_tests
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

@ -1,32 +0,0 @@
Files With Version Information
==============================
These are the only files that have version information in them:
* version_base.h -- This should be the 1 source for version info.
* version_tag.h -- Generated automatically with git tag information.
* verilog.spec -- Used to stamp RPM packages
When versions are changed, the above files need to be edited to account for
the new version information. The following used to have version information in
them, but now their version information is generated:
The version_tag.h file is generated from git tag information using
the "make version" target, or automatically if the version_tag.h
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:
* iverilog-vpi.man -- The .TH tag has a version string
* driver/iverilog.man -- The .TH tag has a version string
* driver-vpi/res.rc -- Used to build Windows version stamp
* vvp/vvp.man -- The .TH tag has a version string
This now includes version_base.h to get the version:
* vpi/vams_simparam.c -- Hard coded result to simulatorVersion query
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

@ -1,26 +0,0 @@
.. Icarus Verilog documentation master file, created by
sphinx-quickstart on Sun Apr 10 16:28:38 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Icarus Verilog
==============
Welcome to the documentation for Icarus Verilog.
.. toctree::
:maxdepth: 2
:caption: Contents:
releases/index
usage/index
targets/index
developer/index
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -1,36 +0,0 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
set SPHINXPROJ=IcarusVerilog
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd

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

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

View File

@ -1,44 +0,0 @@
The BLIF Code Generator (-tblif)
================================
The BLIF code generator supports emitting the design to a blif format
file as accepted by:
ABC: A System for Sequential Synthesis and Verification
<http://www.eecs.berkeley.edu/~alanmi/abc/>
This package contains tools sometimes used by ASIC designers. This
blif target emits .blif file that the ABC system can read int via
the "read_blif" command.
USAGE
-----
This code generator is intended to process structural Verilog source
code. To convert a design to blif, use this command::
% iverilog -tblif -o<path>.blif <source files>...
The source files can be Verilog, SystemVerilog, VHDL, whatever Icarus
Verilog supports, so long as it elaborates down to the limited subset
that the code generator supports. In other words, the files must be
structural.
The root module of the elaborated design becomes the model is
generated. That module may instantiate sub-modules and so on down the
design, completing the design. The output model is flattened, so it
doesn't invoke any subcircuits. Bit vectors are exploded out at the
model ports and internally. This is necessary since blif in particular
and ABC in general processes bits, not vectors.
LIMITATIONS
-----------
Currently, only explicit logic gates and continuous assignments are
supported.
The design must contain only one root module. The name of that root
module becomes the name of the blif model in the ".model" record.

View File

@ -1,7 +0,0 @@
The null Code Generator (-tnull)
================================
The null target generates no code. Invoking this code generator causes no code
generation to happen.

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,61 +0,0 @@
The PCB Code Generator (-tpcb)
==============================
The PCB target code generator is designed to allow a user to enter a netlist
in Verilog format, then generate input files for the GNU PCB layout program.
Invocation
----------
The PCB target code generation is invoked with the -tpcb flag to the iverilog
command. The default output file, "a.out", contains the generated .PCB
file. Use the "-o" flag to set the output file name explicitly. The default
output file contains only the elements. To generate a "netlist" file, add the
flag "-pnetlist=<path>" command line flag.
Altogether, this example generates the foo.net and foo.pcb files from the
foo.v source file::
% iverilog -tpcb -ofoo.pcb -pnetlist=foo.net foo.v
Flags
-----
* -o <path>
Set the output (pcb) file path
* -pnetlist=path
Write a netlist file to the given path.
Attributes Summary
------------------
Attributes are attached to various constructs using the Verilog "(\* \*)"
attribute syntax.
* ivl_black_box
Attached to a module declaration or module instantiation, this indicates
that the module is a black box. The code generator will create an element
for black box instances.
Parameters Summary
------------------
Within modules, The PCB code generator uses certain parameters to control
details. Parameters may have defaults, and can be overridden using the usual
Verilog parameter override syntax. Parameters have preferred types.
* description (string, default="")
The "description" is a text string that describes the black box. This string
is written into the description field of the PCB Element.
* value (string, default="")
The "value" is a text tring that describes some value for the black
box. Like the description, the code generator does not interpret this value,
other then to write it to the appropriate field in the PCB Element."

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,82 +0,0 @@
The VHDL Code Generator (-tvhdl)
================================
Icarus Verilog contains a code generator to emit VHDL from the Verilog
netlist. This allows Icarus Verilog to function as a Verilog to VHDL
translator.
Invocation
----------
To translate a Verilog program to VHDL, invoke "iverilog" with the -tvhdl
flag::
% iverilog -t vhdl -o my_design.vhd my_design.v
The generated VHDL will be placed in a single file (a.out by default), even if
the Verilog is spread over multiple files.
Flags
-----
* -pdebug=1
Print progress messages as the code generator visits each part of the
design.
* -pdepth=N
Only output VHDL entities for modules found at depth < N in the
hierarchy. N=0, the default, outputs all entities. For example, -pdepth=1
outputs only the top-level entity.
Supported Constructs
--------------------
TODO
Limitations
-----------
Signal Values and Resolution
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are several cases where the behaviour of the translated VHDL deviates
from the source Verilog:
* The result of division by zero is x in Verilog but raises an exception in
VHDL.
* Similarly, the result of reading past the end of an array in Verilog is x,
whereas VHDL raises an exception.
* Any signal that is driven by two or more processes will have the value
'U'. This is the result of the signal resolution function in the
std_logic_1164 package.
Constructs Not Supported
^^^^^^^^^^^^^^^^^^^^^^^^
The following Verilog constructs cannot be translated to VHDL:
* fork and join
* force and release
* disable
* real-valued variables
* switches
* hierarchical dereferencing
Other Limitations
^^^^^^^^^^^^^^^^^
* The test expressions in case statements must be constant.
* Translation of a parameter to a corresponding VHDL generic
declaration. Instead the default parameter value is used.

View File

@ -1,101 +0,0 @@
The Verilog '95 Code Generator (-tvlog95)
=========================================
Icarus Verilog contains a code generator to emit 1995 compliant Verilog from
the input Verilog netlist. This allows Icarus Verilog to function as a Verilog
> 1995 to Verilog 1995 translator. The main goal of the project was to convert
@*, ANSI style arguments and other constructs to something allowed in 1995
Verilog.
Invocation
----------
To translate a Verilog program to 1995 compliant Verilog, invoke "iverilog"
with the -tvlog95 flag::
% iverilog -tvlog95 -o my_design_95.v my_design.v
The generated Verilog will be placed in a single file (a.out by default), even
if the input Verilog is spread over multiple files.
Generator Flags
---------------
* -pspacing=N
Set the indent spacing (the default is 2).
* -pallowsigned=1
Allow emitting the various signed constructs as an extension to 1995 Verilog
(off by default).
* -pfileline=1
Emit the original file and line information as a comment for each generated
line (off by default).
Structures that cannot be converted to 1995 compatible Verilog
--------------------------------------------------------------
The following Verilog constructs are not translatable to 1995 compatible Verilog:
* Automatic tasks or functions.
* The power operator (**). Expressions of the form (2**N)**<variable> (where N
is a constant) can be converter to a shift.
* Some System Verilog constructs (e.g. final blocks, ++/-- operators,
etc.). 2-state variables are converted to 4-state variables.
Icarus extensions that cannot be translated:
* Integer constants greater than 32 bits.
* Real valued nets.
* Real modulus.
* Most Verilog-A constructs.
Known Issues and Limitations
----------------------------
Some things are just not finished and should generate an appropriate
warning. Here is a list of the major things that still need to be looked at.
* There are still a few module instantiation port issues (pr1723367 and
partselsynth).
* inout ports are not converted (tran-VP).
* Variable selects of a non-zero based vector in a continuous assignment are
not converted.
* There is no support for translating a zero repeat in a continuous
assignment. It is currently just dropped.
* A pull device connected to a signal select is not translated correctly (this
may be fixed).
* L-value indexed part selects with a constant undefined base in a continuous
assignment are not translated.
* Logic gates are not arrayed exactly the same as the input and the instance
name is not always the same.
* The signed support does not generate $signed() or $unsigned() function calls
in a continuous assignment expression.
* The special power operator cases are not converted in a continuous
assignment.
* Currently a signed constant that sets the MSB in an unsigned context will be
displayed as a negative value (e.g. bit = 1 translates to bit = -1).
* Can net arrays, etc. be unrolled?
* Can generate blocks be converted?

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>`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

View File

@ -1,198 +0,0 @@
Command File Format
===================
The basic format of a command file is one source file or compiler argument per
line. Command files may also have comments of various form, and options for
controlling the compiler.
Comments
--------
Lines that start with a "#" character are comments. All text after the "#"
character, is ignored.
The "//" character sequence also starts a comment that continues to the end of
the line.
The "/\*" and "\*/" character sequences surround multi-line comments. All the
text between the comment start and comment end sequences is ignored, even when
that text spans multiple lines. This style of comment does not nest, so a "/\*"
sequence within a multi-line comment is probably an error.
Plus-args
---------
Outside of comments, lines that start with a "+" character are compiler
arguments. These are called plusargs but they are not the same as extended
arguments passed to the "vvp" command. The supported plusargs are definitively
listed in the iverilog manual page.
The plusargs lines are generally "+<name>+..." where the name is the name of
an switch, and the arguments are separated by "+" characters, as in::
+libext+.v+.V+.ver
With plusargs lines, the "+" character separates tokens, and not white space,
so arguments, which may include file paths, may include spaces. A plusarg line
is terminated by the line end.
The line in the command file may also be a "-y" argument. This works exactly
the same as the::
-y <path>
argument to the compiler; it declares a library directory. The "-y" syntax is
also a shorthand for the "+libdir" plusarg, which is a more general form::
+libdir+<path>...
File Names
----------
Any lines that are not comments, compiler arguments or plusargs are taken by
the compiler to be a source file. The path can contain any characters (other
then comment sequences) including blanks, although leading and trailing white
space characters are stripped. The restriction of one file name per line is in
support of operating systems that can name files any which way. It is not
appropriate to expect white spaces to separate file names.
Variable Substitution
---------------------
The syntax "$(name)" is a variable reference, and may be used anywhere within
filenames or directory names. The contents of the variable are read from the
environment and substituted in place of the variable reference. In Windows,
these environment variables are the very same variables that are set through
the Control Panel->System dialog box, and in UNIX these variables are
environment variables as exported by your shell.
Variables are useful for giving command files some installation
independence. For example, one can import a vendor library with the line::
-y $(VENDOR)/verilog/library
in the command file, and the next programmer will be able to use this command
file without editing it to point to the location of VENDOR on his
machine. Note the use of forward slashes as a directory separator. This works
even under Windows, so always use forward slashes in file paths and Windows
and UNIX users will be able to share command files.
An Example
----------
This sample::
# This is a comment in a command file.
# The -y statement declares a library
# search directory
-y $(PROJ_LIBRARY)/prims
#
# This plusarg tells the compiler that
# files in libraries may have .v or .vl
# extensions.
+libext+.v+.vl
#
main.v // This is a source file
#
# This is a file name with blanks.
C:/Project Directory/file name.vl
is a command file that demonstrates the major syntactic elements of command
files. It demonstrates the use of comments, variables, plusargs and file
names. It contains a lot of information about the hypothetical project, and
suggests that command files can be used to describe the project as a whole
fairly concisely.
The syntax of command files is rich enough that they can be used to document
and control the assembly and compilation of large Verilog programs. It is not
unusual to have command files that are hundreds of lines long, although
judicious use of libraries can lead to very short command files even for large
designs. It is also practical to have different command files that pull
together combinations of sources and compiler arguments to make different
designs from the same Verilog source files.
Summary
-------
Given the above description of the command file format, the following is a
list of the special records with their meaning.
* +libdir+*dir-path*
Specify directories to be searched for library modules. The *dir-path* can
have multiple directories, separated by "+" characters.
* +libdir-nocase+dir-path
This is the same as "+libdir+", but when searching "nocase" libraries for
module files, case will not be taken as significant. This is useful when the
library is on a case insensitive file system.
* +libext+*suffix-string*
Declare the suffix strings to use when searching library directories for
Verilog files. The compiler may test a list of suffix strings to support a
variety of naming conventions.
* -y dir-path
This is like "+libdir+" but each line takes only one path. Like "+libdir+"
there can be multiple "-y" records to declare multiple library
directories. This is similar to the "-y" flag on the iverilog command line.
* -v *file-name* or -l *file-name*
This declares a library file. A library file is just like any other Verilog
source file, except that modules declared within it are not implicitly
possible root modules.
NOTE: The "-l" alias is new as of 2 October 2016. It will become available
in releases and snapshots made after that date.
* +incdir+*include-dir-path*
Declare a directory or list of directories to search for files included by
the "include" compiler directive. The directories are searched in
order. This is similar to the "-I" flag on the iverilog command line.
* +define+*name=value*
Define the preprocessor symbol "name" to have the string value "value". If
the value (and the "=") are omitted, then it is assumed to be the string
"1". This is similar to the "-D" on the iverilog command line.
* +timescale+*units/precision*
Define the default timescale. This is the timescale that is used if there is
no other timescale directive in the Verilog source. The compiler default
default is "+timescale+1s/1s", which this command file setting can
change. The format of the units/precision is the same as that for the
timescale directive in the verilog source.
* +toupper-filename
This token causes file names after this in the command file to be translated
to uppercase. this helps with situations where a directory has passed
through a DOS machine (or a FAT file system) and in the process the file
names become munged. This is not meant to be used in general, but only in
emergencies.
* +tolower-filename
The is the lowercase version of "+toupper-filename".
* +parameter+*name=value*
This token causes the compiler to override a parameter value for a top-level
module. For example, if the module main has the parameter WIDTH, set the
width like this "+parameter+main.WIDTH=5". Note the use of the complete
hierarchical name. This currently only works for parameters defined in root
(top level) modules and a defparam may override the command file value.
* +vhdl-work+*path*
When compiling VHDL, this token allows control over the directory to use for
holding working package declarations. For example, "+vhdl-work+workdir" will
cause the directory "workdir" to be used as a directory for holding working
working copies of package headers.

View File

@ -1,476 +0,0 @@
iverilog Command Line Flags
===========================
The iverilog command is the compiler/driver that takes the Verilog input and
generates the output format, whether the simulation file or synthesis
results. This information is at least summarized in the iverilog man page
distributed in typical installations, but here we try to include more detail.
General
-------
These flags affect the general behavior of the compiler.
* -c <cmdfile>
This flag selects the command file to use. The command file is an
alternative to writing a long command line with a lot of file names and
compiler flags. See the Command File Format page for more information.
* -d <flag>
Enable compiler debug output. These are aids for debugging Icarus Verilog,
and this flag is not commonly used.
The flag is one of these debug classes:
* scope
* eval_tree
* elaborate
* synth2
* -g <generation flag>
the generation is the compiler language, and specifies the language and
extensions to use during the compile. The language level can be selected
by a major level selector, and by controlling various features. Various
"-g" flags can be compined. For example, to get Verilog 2001 without
specify supoprt, use "-g2001 -gno-specify".
The supported flags are:
* 1995
This flag enables the IEEE1364-1995 standard.
* 2001
This flag enables the IEEE1364-2001 standard.
* 2001-noconfig
This flag enables the IEEE1364-2001 standard with config file support
disabled. This eliminates the config file keywords from the language and
so helps some programs written to older 2001 support compile.
* 2005
This flag enables the IEEE1364-2005 standard. This is default enabled
after v0.9.
* 2009
This flag enables the IEEE1800-2009 standard, which includes
SystemVerilog. The SystemVerilog support is not present in v0.9 and
earlier. It is new to git master as of November 2009. Actual SystemVerilog
support is ongoing.
* 2012
This flag enables the IEEE1800-2012 standard, which includes
SystemVerilog.
* 2017
This flag enables the IEEE1800-2017 standard, which includes
SystemVerilog.
* 2023
This flag enables the IEEE1800-2023 standard, which includes
SystemVerilog.
* verilog-ams
This flag enables Verilog-AMS features that are supported by Icarus
Verilog. (This is new as of 5 May 2008.)
* assertions/supported-assertions/no-assertions
Enable or disable SystemVerilog assertions. When enabled, assertion
statements are elaborated. When disabled, assertion statements are parsed
but ignored. The supported-assertions option only enables assertions that
are currently supported by the compiler.
* specify/no-specify
Enable or disable support for specify block timing controls. When
disabled, specify blocks are parsed but ignored. When enabled, specify
blocks cause timing path and timing checks to be active.
* std-include/no-std-include
Enable or disable the search of a standard installation include directory
after all other explicit include directories. This standard include
directory is a convenient place to install standard header files that a
Verilog program may include.
* relative-include/no-relative-include
Enable or disable adding the local files directory to the beginning of the
include file search path. This allows files to be included relative to the
current file.
* xtypes/no-xtypes
Enable or disable support for extended types. Enabling types allows for
new types and type syntax that are Icarus Verilog extensions.
* io-range-error/no-io-range-error
When enabled the range for a port and any associated net declaration must
match exactly. When disabled a scalar port is allowed to have a net
declaration with a range (obsolete usage). A warning message will be
printed for this combination. All other permutations are still considered
an error.
* strict-ca-eval/no-strict-ca-eval
The standard requires that if any input to a continuous assignment
expression changes value, the entire expression is re-evaluated. By
default, parts of the expression that do not depend on the changed input
value(s) are not re-evaluated. If an expression contains a call to a
function that doesn't depend solely on its input values or that has side
effects, the resulting behavior will differ from that required by the
standard. Enabling strict-ca-eval will force standard compliant behavior
(with some loss in performance).
* strict-expr-width/no-strict-expr-width
Enable or disable strict compliance with the standard rules for
determining expression bit lengths. When disabled, the RHS of a parameter
assignment is evaluated as a lossless expression, as is any expression
containing an unsized constant number, and unsized constant numbers are
not truncated to integer width.
* 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
Enable or disable the exclusion of for-loop control variables from
implicit event_expression lists. When enabled, if a for-loop control
variable (loop index) is only used inside the for-loop statement, the
compiler will not include it in an implicit event_expression list it
calculates for that statement or any enclosing statement. This allows the
same control variable to be used in multiple processes without risk of
entering an infinite loop caused by each process triggering all other
processes that use the same variable. For strict compliance with the
standards, this behaviour should be disabled.
* -i
Ignore missing modules. Normally it is an error if a module instantiation
refers to an undefined module. This option causes the compiler to skip over
that instantiation. It will also stop the compiler returning an error if
there are no top level modules. This allows the compiler to be used to check
incomplete designs for errors.
NOTE: The "-i" flag was added in v11.0.
* -L <path>
Add the specified directory to the path list used to locate VPI modules. The
default path includes only the install directory for the system.vpi module,
but this flag can add other directories. Multiple paths are allowed, and the
paths will be searched in order.
NOTE: The "-L" flag was added in v11.0.
* -l <path>
Add the specified file to the list of source files to be compiled, but mark
it as a library file. All modules contained within that file will be treated
as library modules, and only elaborated if they are instantiated by other
modules in the design.
NOTE: The "-l" flag is new as of 2 October 2016. It will become available in
releases and snapshots made after that date.
* -M<mode>=<path>
Write into the file specified by path a list of files that contribute to the
compilation of the design.
If _mode_ is *all* or *prefix*, this includes files that are included by
include directives and files that are automatically loaded by library
support as well as the files explicitly specified by the user.
If _mode_ is *include*, only files that are included by include directives
are listed.
If _mode_ is *module*, only files that are specified by the user or that are
automatically loaded by library support are listed. The output is one file
name per line, with no leading or trailing space.
If _mode_ is *prefix*, files that are included by include directives are
prefixed by "I " and other files are prefixed by "M ".
* -m<module>
Add this module to the list of VPI modules to be loaded by the
simulation. Many modules can be specified, and all will be loaded, in the
order specified. The system module is implicit and always included (and
loaded last).
If the specified name includes at least one directory character, it is
assumed to be prefixed by the path to the module, otherwise the module is
searched for in the paths specified by preceding -L options, and if not
found there, in the iverilog base directory.
NOTE: The "-m" flag was added in v11.0.
* -o <path>
Specify the output file. The <path> is the name of the file to hold the
output. The default is "a.out".
* -S
Activate synthesis. This flag tells the compiler to do what synthesis it can
do before calling the code generator. This flag is rarely used explicitly,
and certain code generators will implicitly enable this flag.
* -u
Treat each source file as a separate compilation unit (as defined in
SystemVerilog). If compiling for an IEEE1364 generation, this will just
reset all compiler directives (including macro definitions) before each new
file is processed.
NOTE: The "-u" flag was added in v11.0.
* -v
Be verbose. Print copyright information, progress messages, and some timing
information about various compilation phases.
(New in snapshots after 2014-12-16) If the selected target is vvp, the -v
switch is appended to the shebang line in the compiler output file, so
directly executing the compiler output file will turn on verbose messages in
vvp. This extra verbosity can be avoided by using the vvp command to
indirectly execute the compiler output file.
* -V
Print the version information. This skips all compilation. Just print the
version information, including version details for the various components of
the compiler.
* -R
Print the runtime paths of the compiler. This can be useful to find, e.g.,
the include path of vpi_user.h.
* -W<warning class>
Enable/disable warnings. All the warning types (other then "all") can be
prefixed with no- to disable that warning.
* all
This enables almost all of the available warnings. More specifically, it
enables these warnings::
-Wanachronisms
-Wimplicit
-Wimplicit-dimensions
-Wdeclaration-after-use
-Wmacro-replacement
-Wportbind
-Wselect-range
-Wtimescale
-Wsensitivity-entire-array
* anachronisms
This enables warnings for use of features that have been deprecated or
removed in the selected generation of the Verilog language.
* implicit
This enables warnings for creation of implicit declarations. For example,
if a scalar wire X is used but not declared in the Verilog source, this
will print a warning at its first use.
* implicit-dimensions
This enables warnings for the case where a port declaration or a var/net
declaration for the same name is missing dimensions. Normally, Verilog
allows you to do this (the undecorated declaration gets its dimensions
form the decorated declaration) but this is no longer common, and some
other tools (notable Xilix synthesizers) do not handle this correctly.
This flag is supported in release 10.1 or master branch snapshots after
2016-02-06.
* 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
This enables warnings when a macro is redefined, even if the macro text
remains the same.
NOTE: The "macro-redefinition" flag was added in v11.0.
* macro-replacement
This enables warnings when a macro is redefined and the macro text
changes. Use no-macro-redefinition to disable this,
NOTE: The "macro-replacement" flag was added in v11.0.
* portbind
This enables warnings for ports of module instantiations that are not
connected properly, but probably should be. Dangling input ports, for
example, will generate a warning.
* select-range
This enables warnings for constant out-of-bound selects. This includes
partial or fully out-of-bound select as well as a select containing a 'bx
or 'bz in the index.
* timescale
This enables warnings for inconsistent use of the timescale directive. It
detects if some modules have no timescale, or if modules inherit timescale
from another file. Both probably mean that timescales are inconsistent,
and simulation timing can be confusing and dependent on compilation order.
* infloop
This enables warnings for always statements that may have runtime infinite
loops (i.e. has paths with zero or no delay). This class of warnings is
not included in -Wall and hence does not have a no- variant. A fatal error
message will always be printed when the compiler can determine that there
will definitely be an infinite loop (all paths have no or zero delay).
When you suspect an always statement is producing a runtine infinite loop,
use this flag to find the always statements that need to have their logic
verified. it is expected that many of the warnings will be false
positives, since the code treats the value of all variables and signals as
indeterninite.
* sensitivity-entire-vector
This enables warnings for when a part select with an "always @*" statement
results in the entire vector being added to the implicit sensitivity
list. Although this behavior is prescribed by the IEEE standard, it is not
what might be expected and can have performance implications if the vector
is large.
* sensitivity-entire-array
This enables warnings for when a word select with an "always @*" statement
results in the entire array being added to the implicit sensitivity
list. Although this behavior is prescribed by the IEEE standard, it is not
what might be expected and can have performance implications if the array
is large.
* floating-nets
This enables warnings for nets that are present but have no drivers.
This flag was added in version 11.0 or later (and is in the master branch
as of 2015-10-01).
* -y<libdir>
Append the directory to the library module search path. When the compiler
finds an undefined module, it looks in these directories for files with the
right name.
* -Y<suf>
Appends suf to the list of file extensions that are used to resolve an
undefined module to a file name. Should be specified before any -y flag. For
example, this command::
% iverilog -Y .sv -y sources src.v
will try to resolve any undefined module m by looking into the directory
sources and checking if there exist files named m.v or m.sv.
Preprocessor Flags
------------------
These flags control the behavior of the preprocessor. They are similar to
flags for the typical "C" compiler, so C programmers will find them familiar.
* -E
This flag is special in that it tells the compiler to only run the
preprocessor. This is useful for example as a way to resolve preprocessing
for other tools. For example, this command::
% iverilog -E -ofoo.v -DKEY=10 src1.v src2.v
runs the preprocessor on the source files src1.v and src2.v and produces the
single output file foo.v that has all the preprocessing (including header
includes and ifdefs) processed.
* -D<macro>
Assign a value to the macro name. The format of this flag is one of::
-Dkey=value
-Dkey
The key is defined to have the given value. If no value is given, then it is
assumed to be "1". The above examples are the same as these defines in
Verilog source::
`define key value
`define key
* -I<path>
Append directory <path> to list of directories searched for Verilog include
files. The -I switch may be used many times to specify several directories
to search, the directories are searched in the order they appear on the
command line.
Elaboration Flags
-----------------
These are flags that pass information to the elaboration steps.
* -P<symbol>=<value>
Define a parameter using the defparam behavior to override a parameter
values. This can only be used for parameters of root module instances.
* -s <topmodule>
Specify the top level module to elaborate. Icarus Verilog will by default
choose modules that are not instantiated in any other modules, but sometimes
that is not sufficient, or instantiates too many modules. If the user
specifies one or more root modules with "-s" flags, then they will be used
as root modules instead.
* -Tmin, -Ttyp, -Tmax
Select the timings to use. The Verilog language allows many timings to be
specified as three numbers, min:typical:max, but for simulation you need to
choose which set to use. The "-Tmin" flag tells the compiler to at
elaboration time choose "min" times. The default is "-Ttyp".
Target Flags
------------

View File

@ -1,167 +0,0 @@
Getting Started With Icarus Verilog
===================================
Before getting started with actual examples, here are a few notes on
conventions. First, command lines and sequences take the same arguments on all
supported operating environments, including Linux, Windows and the various
Unix systems. When an example command is shown in a figure, the generic prompt
character "% " takes the place of whatever prompt string is appropriate for
your system. Under Windows, the commands are invoked in a command window.
Second, when creating a file to hold Verilog code, it is common to use the
".v" or the ".vl" suffix. This is not a requirement imposed by Icarus Verilog,
but a useful convention. Some people also use the suffixes ".ver" or even
".vlg". Examples in this book will use the ".v" suffix.
So let us start. Given that you are going to use Icarus Verilog as part of
your design process, the first thing to do as a designer is learn how to
compile and execute even the most trivial design. For the purposes of
simulation, we use as our example the most trivial simulation, a simple Hello,
World program.
.. code-block:: verilog
module hello;
initial
begin
$display("Hello, World");
$finish ;
end
endmodule
Use a text editor to place the program in a text file, hello.v, then compile
this program with the command::
% iverilog -o hello hello.v
The results of this compile are placed into the file "hello", because the "-o"
flag tells the compiler where to place the compiled result. Next, execute the
compiled program like so::
% vvp hello
Hello, World
And there it is, the program has been executed. So what happened? The first
step, the "iverilog" command, read and interpreted the source file, then
generated a compiled result. The compiled form may be selected by command line
switches, but the default is the "vvp" format, which is actually run later, as
needed. The "vvp" command of the second step interpreted the "hello" file from
the first step, causing the program to execute.
The "iverilog" and "vvp" commands are the most important commands available to
users of Icarus Verilog. The "iverilog" command is the compiler, and the "vvp"
command is the simulation runtime engine. What sort of output the compiler
actually creates is controlled by command line switches, but normally it
produces output in the default vvp format, which is in turn executed by the
vvp program.
As designs get larger and more complex, they gain hierarchy in the form of
modules that are instantiated within others, and it becomes convenient to
organize them into multiple files. A common convention is to write one
moderate sized module per file (or group related tiny modules into a single
file) then combine the files of the design together during compilation. For
example, the counter model in counter.v
.. code-block:: verilog
module counter(out, clk, reset);
parameter WIDTH = 8;
output [WIDTH-1 : 0] out;
input clk, reset;
reg [WIDTH-1 : 0] out;
wire clk, reset;
always @(posedge clk or posedge reset)
if (reset)
out <= 0;
else
out <= out + 1;
endmodule // counter
and the test bench in counter_tb.v
.. code-block:: verilog
module test;
/* Make a reset that pulses once. */
reg reset = 0;
initial begin
# 17 reset = 1;
# 11 reset = 0;
# 29 reset = 1;
# 11 reset = 0;
# 100 $stop;
end
/* Make a regular pulsing clock. */
reg clk = 0;
always #5 clk = !clk;
wire [7:0] value;
counter c1 (value, clk, reset);
initial
$monitor("At time %t, value = %h (%0d)",
$time, value, value);
endmodule // test
are written into different files.
The "iverilog" command supports multi-file designs by two methods. The
simplest is to list the files on the command line::
% iverilog -o my_design counter_tb.v counter.v
% vvp my_design
This command compiles the design, which is spread across two input files, and
generates the compiled result into the "my_design" file. This works for small
to medium sized designs, but gets cumbersome when there are lots of files.
Another technique is to use a commandfile, which lists the input files in a
text file. For example, create a text file called "file_list.txt" with the
files listed one per line::
counter.v
counter_tb.v
Then compile and execute the design with a command like so::
% iverilog -o my_design -c file_list.txt
% vvp my_design
The command file technique clearly supports much larger designs simply by
saving you the trouble of listing all the source files on the command
line. Name the files that are part of the design in the command file and use
the "-c" flag to tell iverilog to read the command file as a list of Verilog
input files.
As designs get more complicated, they almost certainly contain many Verilog
modules that represent the hierarchy of your design. Typically, there is one
module that instantiates other modules but is not instantiated by any other
modules. This is called a root module. Icarus Verilog chooses as roots (There
can be more than one root) all the modules that are not instantiated by other
modules. If there are no such modules, the compiler will not be able to choose
any root, and the designer must use the "-sroot" switch to identify the root
module, like this::
% iverilog -s main -o hello hello.v
If there are multiple candidate roots, all of them will be elaborated. The
compiler will do this even if there are many root modules that you do not
intend to simulate, or that have no effect on the simulation. This can happen,
for example, if you include a source file that has multiple modules, but are
only really interested in some of them. The "-s" flag identifies a specific
root module and also turns off the automatic search for other root
modules. You can use this feature to prevent instantiation of unwanted roots.
As designs get even larger, they become spread across many dozens or even
hundreds of files. When designs are that complex, more advanced source code
management techniques become necessary. These are described in later chapters,
along with other advanced design management techniques supported by Icarus
Verilog.

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

@ -1,25 +0,0 @@
Icarus Verilog Usage
====================
This section contains documents to help support Icarus Verilog users.
.. toctree::
:maxdepth: 1
installation
getting_started
simulation
command_line_flags
command_files
verilog_attributes
ivlpp_flags
vvp_flags
vvp_debug
vvp_library
vhdlpp_flags
waveform_viewer
vpi
icarus_verilog_extensions
icarus_verilog_quirks
reporting_issues

View File

@ -1,377 +0,0 @@
Installation Guide
==================
Icarus Verilog may be installed from source code (either from ``git`` or a
released `tar/zip` file), or from pre-packaged binary distributions. If you
don't have a need for the very latest, and prepackaged binaries are available,
that is the easiest place to start.
Installation From Source
------------------------
Icarus is developed for Unix-like environments but can also be compiled on
Windows systems using the `Cygwin/MSYS2` environments or `MinGW` compilers. The
following instructions are the common steps for obtaining the Icarus Verilog
source code, compiling, installing, and checking the compiled code is working
properly. Note that there are pre-compiled and/or prepackaged versions for a
variety of systems, so if you find an appropriate packaged version, then that
is the easiest way to install.
The source code for Icarus is stored under the `git` source code control
system. You can use ``git`` to get the latest development head or the latest of
a specific branch. Stable releases are placed on branches, and in particular V12
stable releases are on the branch "v12-branch" To get the development version
of the code follow these steps::
% git config --global user.name "Your Name Goes Here"
% git config --global user.email you@yourpublicemail.example.com
% git clone https://github.com/steveicarus/iverilog.git
The first two lines are optional and are used to tell git who you are. This
information is important if/when you submit a patch. We suggest that you add
this information now so you don't forget to do it later. The clone will create
a directory, named `iverilog`, containing the source tree, and will populate
that directory with the most current source from the HEAD of the repository.
Change into this directory using::
% cd iverilog
Normally, this is enough as you are now pointing at the most current
development code, and you have implicitly created a branch `master` that
tracks the development head. However, If you want to actually be working on
the `v12-branch` (the branch where the latest V12 patches are) then you
checkout that branch with the command::
% git checkout --track -b v12-branch origin/v12-branch
This creates a local branch that tracks the `v12-branch` in the repository, and
switches you over to your new `v12-branch`. The tracking is important as it
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
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
want to work on, your local source tree may later be synced up with the
development source by using the git command::
% git pull
The git system remembers the repository that it was cloned from, so you don't
need to re-enter it when you pull.
To build the `configure` script and hash files you need to run the
following::
% sh autoconf.sh
% cd ..
This is not need for the released `tar/zip` files since they already contain
these files. You only need to run this once after cloning. If you are missing
``autoconf`` or ``gperf`` then the script will fail::
Autoconf in root...
autoconf.sh: 10: autoconf: not found
Precompiling lexor_keyword.gperf
autoconf.sh: 13: gperf: not found.
You will need to install the ``autoconf`` and ``gperf`` tools before you can
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 takes many of the standard configuration options and those will not be
described here. The following are specific to Icarus::
--enable-suffix[=suffix]
This option allows the user to build Icarus with a default suffix or when
provided a user defined suffix. Older stable releases have this flag on by
default e.g.(V0.8 by default will build with a "-0.8" suffix). All versions
have an appropriate default suffix ("-<base_version>").
All programs or directories are tagged with this suffix. e.g.(iverilog-0.8,
vvp-0.8, etc.). The output of iverilog will reference the correct run time
files and directories. The run time will check that it is running a file with
a compatible version e.g.(you can not run a V0.9 file with the V0.8 run
time).::
--with-valgrind
This option adds extra memory cleanup code and pool management code to allow
better memory leak checking when valgrind is available. This option is not
needed when checking for basic errors with valgrind and should not be used if
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
-----------------------
Note: For a gcc compile you will need to install ``bison``, ``flex``, ``g++``,
``gcc`` and preferably `bz2`, `zlib` and `readline` development packages. The
`bz2` and `zlib` development packages are required for the non-VCD waveform
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
source tree. If you need multiple variants (optimized, debugging, multiple
compilers) then it is recommended you compile each in their own directory.
For multiple variants create a directory for each of the variants you intend
to create and in each run the following steps, adjusting the options in the
configure stage to get the functionality you want. For a single build you can
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)::
% mkdir gcc
% cd gcc
or
% cd iverilog
You can also use ``clang/clang++``. I usual build optimized version for
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.
Compiling on Macintosh OS X
---------------------------
Since Mac OS X is a BSD flavor of Unix, you can install Icarus Verilog from
source using the procedure described above. You need to install the Xcode
software, which includes the C and C++ compilers for Mac OS X. The package is
available for free download from Apple's developer site. Once Xcode is
installed, you can build Icarus Verilog in a terminal window just like any
other Unix install.
For versions newer than 10.3 the GNU Bison tool (packaged with Xcode) needs to
be updated to version 3. ::
brew install bison
echo 'export PATH="/usr/local/opt/bison/bin:$PATH"' >> ~/.bash_profile
Icarus Verilog is also available through the Homebrew package manager: "brew
install icarus-verilog".
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,146 +0,0 @@
IVLPP - IVL Preprocessor
========================
The ivlpp command is a Verilog preprocessor that handles file
inclusion and macro substitution. The program runs separate from the
actual compiler so as to ease the task of the compiler proper, and
provides a means of preprocessing files off-line.
USAGE:
ivlpp [options] <file>
The <file> parameter is the name of the file to be read and
preprocessed. The resulting output is sent to standard output. The
valid options include:
* -Dname[=value]
Predefine the symbol `name` to have the specified
value. If the value is not specified, then `1` is
used. This is mostly of use for controlling conditional
compilation.
This option does *not* override existing \`define
directives in the source file.
* -F <path>
Read ivlpp options from a FLAGS FILE. This is not the same
as a file list. This file contains flags, not source
files. There may be multiple flags files.
* -f <path>
Read ivlpp input files from a file list. There can be no
more than one file list.
* -I <dir>
Add a directory to the include path. Normally, only "." is
in the search path. The -I flag causes other directories
to be searched for a named file. There may be as many -I
flags as needed.
* -L
Generate \`line directives. The ivl compiler understands
these directives and uses them to keep track of the
current line of the original source file. This makes error
messages more meaningful.
* -o <file>
Send the output to the named file, instead of to standard
output.
* -v
Print version and copyright information before processing
input files.
* -V
Print version and copyright information, then exit WITHOUT
processing any input files.
Flags File
----------
A flags file contains flags for use by ivlpp. This is a convenient way
for programs to pass complex sets of flags to the ivlpp program.
Blank lines and lines that start with "#" are ignored. The latter can
be used as comment lines. All other lines are flag lines. Leading and
trailing white space are removed before the lines are interpreted.
Other lines have the simple format::
<key>:<value>
The colon character separates a key from the value. The supported
keys, with their corresponding values, are:
* D:name=<value>
This is exactly the same as the "-Dname=<value>" described above.
* I:<dir>
This is exactly the same as "-I<dir>".
* relative include:<flag>
The <flag> can be "true" or "false". This enables "relative
includes" nesting behavior.
* vhdlpp:<path>
Give the path to the vhdlpp program. This program is used to
process VHDL input files.
Locating Included Files
-----------------------
The ivlpp preprocessor implements the \`include directives by
substituting the contents of the included file in place of the line
with the \`include directive. The name that the programmer specifies is
a file name. Normally, the preprocessor looks in the current working
directory for the named file. However, the `-I` flags can be used to
specify a path of directories to search for named include files. The
current directory will be searched first, followed by all the include
directories in the order that the -I flag appears.
The exception to this process is include files that have a name that
starts with the '/' character. These file names are `rooted names`
and must be in the rooted location specified.
Generated Line Directives
-------------------------
Compilers generally try to print along with their error messages the
file and line number where the error occurred. Icarus Verilog is no
exception. However, if a separate preprocessor is actually selecting
and opening files, then the line numbers counted by the compiler
proper will not reflect the actual line numbers in the source file.
To handle this situation, the preprocessor can generate line
directives. These directives are lines of the form::
`line <num> <name> <level>
where <name> is the file name in double-quotes and <num> is the line
number in the file. The parser changes the filename and line number
counters in such a way that the next line is line number <num> in
the file named <name>. For example::
`line 6 "foo.vl" 0
// I am on line 6 in file foo.vl.
The preprocessor generates a \`line directive every time it switches
files. That includes starting an included file (\`line 1 "foo.vlh" 1) or
returning to the including file.

View File

@ -1,76 +0,0 @@
Reporting Issues
================
The developers of and contributors to Icarus Verilog use github to track
issues and to create patches for the product. If you believe you have found a
problem, use the Issues tracker at the
`Icarus Verilog github page <https://github.com/steveicarus/iverilog>`__.
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
`Issues <https://github.com/steveicarus/iverilog/issues>`__ link to get to the
list of issues, open and closed. You will find a friendly green button where
you can create a new issue. You will be asked to create a title for your
issue, and to write a detailed description of your issue. Please include
enough information that anyone who sees your issue can understand and
reproduce it.
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
demonstrates the issue. The smaller the better. No developer wants to wade
through hundreds of lines of working Verilog to find the few lines that cause
trouble, so if you can get it down to a 10 line sample program, then your
issue will be far more likely to be addressed.
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
expect, the issue turns out to be a bug in your program, and the person
looking into your issue may point out a bug in your code. You learn something,
and we all win. We are not always correct, though, so if we are incorrect,
help us see our error, if that's appropriate. If we don't understand what your
issue is, we will label your issue with a "Need info" label, and if we never
hear from you again, your issue may be closed summarily.
If you can submit a complete, working program that we can use in the
regression test suite, then that is the best. Check out the existing tests in
the regression test suite to see how they are structured. If you have a
complete test that can go into the test suite, then that saves everyone a lot
of grief, and again you increase the odds that your issue will be addressed.
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

@ -1,495 +0,0 @@
Simulation Using Icarus Verilog
===============================
Simulation is the process of creating models that mimic the behavior of the
device you are designing (simulation models) and creating models to exercise
the device (test benches). The simulation model need not reflect any
understanding of the underlying technology, and the simulator need not know
that the design is intended for any specific technology.
The Verilog simulator, in fact, is usually a different program than the
synthesizer. It may even come from a different vendor. The simulator need not
know of or generate netlists for the target technology, so it is possible to
write one simulator that can be used to model designs intended for a wide
variety of technologies. A synthesizer, on the other hand, does need to know a
great deal about the target technology in order to generate efficient
netlists. Synthesizers are often technology specific and come from vendors
with specialized knowledge, whereas simulators are more general purpose.
Simulation models and test benches, therefore, can use the full range of
Verilog features to model the intended design as clearly as possible. This is
the time to test the algorithms of the design using language that is
relatively easy for humans to read. The simulator, along with the test bench,
can test that the clearly written model really does behave as intended, and
that the intended behavior really does meet expectations.
The test benches model the world outside the design, so they are rarely
destined for real hardware. They are written in Verilog simply as a matter of
convenience, and sometimes they are not written in Verilog at all. The test
benches are not throw-away code either, as they are used to retest the device
under test as it is transformed from a simulation model to a synthesizeable
description.
Compilation and Elaboration
---------------------------
Simulation of a design amounts to compiling and executing a program. The
Verilog source that represents the simulation model and the test bench is
compiled into an executable form and executed by a simulation
engine. Internally, Icarus Verilog divides the compilation of program source
to an executable form into several steps, and basic understanding of these
steps helps understand the nature of failures and errors. The first step is
macro preprocessing, then compilation, elaboration, optional optimizations and
finally code generation. The boundary between these steps is often blurred,
but this progression remains a useful model of the compilation process.
The macro preprocessing step performs textual substitutions of macros defined
with "\`define" statements, textual inclusion with "\`include" statements, and
conditional compilation by "\`ifdef" and "\`ifndef" statements. The
macropreprocessor for Icarus Verilog is internally a separate program that can
be accessed independently by using the "-E" flag to the "iverilog" command,
like so::
% iverilog -E -o out.v example.v
This command causes the input Verilog file "example.v" to be preprocessed, and
the output, a Verilog file without preprocessor statements, written into
"out.v". The "\`include" and "\`ifdef" directives in the input file are interpreted,
and defined macros substituted, so that the output, a single file, is the same
Verilog but with the preprocessor directives gone. All the explicitly
specified source files are also combined by the preprocessor, so that the
preprocessed result is a single Verilog stream.
Normally, however, the "-E" flag is not used and the preprocessed Verilog is
instead sent directly to the next step, the compiler. The compiler core takes
as input preprocessed Verilog and generates an internal parsed form. The
parsed form is an internal representation of the Verilog source, in a format
convenient for further processing, and is not accessible to the user.
The next step, elaboration, takes the parsed form, chooses the root modules,
and instantiates (makes *instances* of) those roots. The root instances may
contain instances of other modules, which may in turn contain instances of yet
other modules. The elaboration process creates a hierarchy of module instances
that ends with primitive gates and statements.
Note that there is a difference between a module and a module instance. A
module is a type. It is a description of the contents of module instances that
have its type. When a module is instantiated within another module, the module
name identifies the type of the instance, and the instance name identifies the
specific instance of the module. There can be many instances of any given
module.
Root modules are a special case, in that the programmer does not give them
instance names. Instead, the instance names of root modules are the same as
the name of the module. This is valid because, due to the nature of the
Verilog syntax, a module can be a root module only once, so the module name
itself is a safe instance name.
Elaboration creates a hierarchy of scopes. Each module instance creates a new
scope within its parent module, with each root module starting a
hierarchy. Every module instance in the elaborated program has a unique scope
path, a hierarchical name, that starts with its root scope and ends with its
own instance name. Every named object, including variables, parameters, nets
and gates, also has a hierarchical name that starts with a root scope and ends
with its own base name. The compiler uses hierarchical names in error messages
generated during or after elaboration, so that erroneous items can be
completely identified. These hierarchical names are also used by waveform
viewers that display waveform output from simulations.
The elaboration process creates from the parsed form the scope hierarchy
including the primitive objects within each scope. The elaborated design then
is optimized to reduce it to a more optimal, but equivalent design. The
optimization step takes the fully elaborated design and transforms it to an
equivalent design that is smaller or more efficient. These optimizations are,
for example, forms of constant propagation and dead code elimination. Useless
logic is eliminated, and constant expressions are pre-calculated. The
resulting design behaves as if the optimizations were not performed, but is
smaller and more efficient. The elimination (and spontaneous creation) of
gates and statements only affects the programmer when writing VPI modules,
which through the API have limited access to the structures of the design.
Finally, the optimized design, which is still in an internal form not
accessible to users, is passed to a code generator that writes the design into
an executable form. For simulation, the code generator is selected to generate
the vvp format--a text format that can be executed by the simulation
engine. Other code generators may be selected by the Icarus Verilog user, even
third party code generators, but the vvp code generator is the default for
simulation purposes.
Making and Using Libraries
--------------------------
Although simple programs may be written into a single source file, this gets
inconvenient as the designs get larger. Also, writing the entire program into
a single file makes it difficult for different programs to share common
code. It therefore makes sense to divide large programs into several source
files, and to put generally useful source code files somewhere accessible to
multiple designs.
Once the program is divided into many files, the compiler needs to be told how
to find the files of the program. The simplest way to do that is to list the
source files on the command line or in a command file. This is for example the
best way to divide up and integrate test bench code with the simulation model
of the device under test.
The Macro Preprocessor
^^^^^^^^^^^^^^^^^^^^^^
Another technique is to use the macro preprocessor to include library files
into a main file. The `include` directive takes the name of a source file to
include. The preprocessor inserts the entire contents of the included file in
place of the `include` directive. The preprocessor normally looks in the
current working directory (the current working directory of the running
compiler, and not the directory where the source file is located) for the
included file, but the "-I" switch to "iverilog" can add directories to the
search locations list. ::
% iverilog -I/directory/to/search example.v
It is common to create include directories shared by a set of programs. The
preprocessor `include` directive can be used by the individual programs to
include the source files that it needs.
The preprocessor method of placing source code into libraries is general
(arbitrary source code can be placed in the included files) but is static, in
the sense that the programmer must explicitly include the desired library
files. The automatic module library is a bit more constrained, but is
automatic.
Automatic Module Libraries
^^^^^^^^^^^^^^^^^^^^^^^^^^
A common use for libraries is to store module definitions that may be of use
to a variety of programs. If modules are divided into a single module per
file, and the files are named appropriately, and the compiler is told where to
look, then the compiler can automatically locate library files when it finds
that a module definition is missing.
For this to work properly, the library files must be Verilog source, they
should contain a single module definition, and the files must be named after
the module they contain. For example, if the module "AND2" is a module in the
library, then it belongs in a file called "AND2.v" and that file contains only
the "AND2" module. A library, then, is a directory that contains properly
named and formatted source files. ::
% iverilog -y/library/to/search example.v
The "-y" flag to "iverilog" tells the compiler to look in the specified
directory for library modules whenever the program instantiates a module that
is not otherwise defined. The programmer may include several "-y" flags on the
command line (or in a command file) and the compiler will search each
directory in order until an appropriate library file is found to resolve the
module.
Once a module is defined, either in the program or by reading a library
module, the loaded definition is used from then on within the program. If the
module is defined within a program file or within an included file, then the
included definition is used instead of any library definition. If a module is
defined in multiple libraries, then the first definition that the compiler
finds is used, and later definitions are never read.
Icarus Verilog accesses automatic libraries during elaboration, after it has
already preprocessed and parsed the non-library source files. Modules in
libraries are not candidates for root modules, and are not even parsed unless
they are instantiated in other source files. However, a library module may
reference other library modules, and reading in a library module causes it to
be parsed and elaborated, and further library references resolved, just like a
non-library module. The library lookup and resolution process iterates until
all referenced modules are resolved, or known to be missing from the
libraries.
The automatic module library technique is useful for including vendor or
technology libraries into a program. Many EDA vendors offer module libraries
that are formatted appropriately; and with this technique, Icarus Verilog can
use them for simulation.
Advanced Command Files
----------------------
Command files were mentioned in the "Getting Started" chapter, but only
briefly. In practice, Verilog programs quickly grow far beyond the usefulness
of simple command line options, and even the macro preprocessor lacks the
flexibility to combine source and library modules according to the advancing
development process.
The main contents of a command file is a list of Verilog source files. You can
name in a command file all the source files that make up your design. This is
a convenient way to collect together all the files that make up your
design. Compiling the design can then be reduced to a simple command line like
the following::
% iverilog -c example.cf
The command file describes a configuration. That is, it lists the specific
files that make up your design. It is reasonable, during the course of
development, to have a set of different but similar variations of your
design. These variations may have different source files but also many common
source files. A command file can be written for each variation, and each
command file lists the source file names used by each variation.
A configuration may also specify the use of libraries. For example, different
configurations may be implementations for different technologies so may use
different parts libraries. To make this work, command files may include "-y"
statements. These work in command files exactly how they work on "iverilog"
command line. Each "-y" flag is followed by a directory name, and the
directories are searched for library modules in the order that they are listed
in the command file.
The include search path can also be specified in configuration files with
"+incdir+" tokens. These tokens start with the "+incdir+" string, then
continue with directory paths, separated from each other with "+" characters
(not spaces) for the length of the line.
Other information can be included in the command file. See the section Command
File Format for complete details on what can go in a command file.
Input Data at Runtime
---------------------
Often, it is useful to compile a program into an executable simulation, then
run the simulation with various inputs. This requires some means to pass data
and arguments to the compiled program each time it is executed. For example,
if the design models a micro-controller, one would like to run the compiled
simulation against a variety of different ROM images.
There are a variety of ways for a Verilog program to get data from the outside
world into the program at run time. Arguments can be entered on the command
line, and larger amounts of data can be read from files. The simplest method
is to take arguments from the command line.
Consider this running example of a square root calculator
.. code-block:: verilog
module sqrt32(clk, rdy, reset, x, .y(acc));
input clk;
output rdy;
input reset;
input [31:0] x;
output [15:0] acc;
// acc holds the accumulated result, and acc2 is
// the accumulated square of the accumulated result.
reg [15:0] acc;
reg [31:0] acc2;
// Keep track of which bit I'm working on.
reg [4:0] bitl;
wire [15:0] bit = 1 << bitl;
wire [31:0] bit2 = 1 << (bitl << 1);
// The output is ready when the bitl counter underflows.
wire rdy = bitl[4];
// guess holds the potential next values for acc,
// and guess2 holds the square of that guess.
wire [15:0] guess = acc | bit;
wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1);
task clear;
begin
acc = 0;
acc2 = 0;
bitl = 15;
end
endtask
initial clear;
always @(reset or posedge clk)
if (reset)
clear;
else begin
if (guess2 <= x) begin
acc <= guess;
acc2 <= guess2;
end
bitl <= bitl - 1;
end
endmodule
One could write the test bench as a program that passes a representative set
of input values into the device and checks the output result. However, we can
also write a program that takes on the command line an integer value to be
used as input to the device. We can write and compile this program, then pass
different input values on the run time command line without recompiling the
simulation.
This example demonstrates the use of the "$value$plusargs" to access command
line arguments of a simulation
.. code-block:: verilog
module main;
reg clk, reset;
reg [31:0] x;
wire [15:0] y;
wire rdy;
sqrt32 dut (clk, rdy, reset, x, y);
always #10 clk = ~clk;
initial begin
clk = 0;
reset = 1;
if (! $value$plusargs("x=%d", x)) begin
$display("ERROR: please specify +x=<value> to start.");
$finish;
end
#35 reset = 0;
wait (rdy) $display("y=%d", y);
$finish;
end // initial begin
endmodule // main
The "$value$plusargs" system function takes a string pattern that describes
the format of the command line argument, and a reference to a variable that
receives the value. The "sqrt_plusargs" program can be compiled and executed
like this::
% iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v
% vvp sqrt_plusargs.vvp +x=81
y= 9
Notice that the "x=%d" string of the "$value$plusargs" function describes the
format of the argument. The "%d" matches a decimal value, which in the sample
run is "81". This gets assigned to "x" by the "$value$plusargs" function,
which returns TRUE, and the simulation continues from there.
If two arguments have to be passed to the testbench then the main module would
be modified as follows
.. code-block:: verilog
module main;
reg clk, reset;
reg [31:0] x;
reg [31:0] z;
wire [15:0] y1,y2;
wire rdy1,rdy2;
sqrt32 dut1 (clk, rdy1, reset, x, y1);
sqrt32 dut2 (clk, rdy2, reset, z, y2);
always #10 clk = ~clk;
initial begin
clk = 0;
reset = 1;
if (! $value$plusargs("x=%d", x)) begin
$display("ERROR: please specify +x=<value> to start.");
$finish;
end
if (! $value$plusargs("z=%d", z)) begin
$display("ERROR: please specify +z=<value> to start.");
$finish;
end
#35 reset = 0;
wait (rdy1) $display("y1=%d", y1);
wait (rdy2) $display("y2=%d", y2);
$finish;
end // initial begin
endmodule // main
and the "sqrt_plusargs" program would be compiled and executed as follows::
% iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v
% vvp sqrt_plusargs.vvp +x=81 +z=64
y1= 9
y2= 8
In general, the "vvp" command that executes the compiled simulation takes a
few predefined argument flags, then the file name of the simulation. All the
arguments after the simulation file name are extended arguments to "vvp" and
are passed to the executed design. Extended arguments that start with a "+"
character are accessible through the "$test$plusargs" and "$value$plusargs"
system functions. Extended arguments that do not start with a "+" character
are only accessible to system tasks and functions written in C using the VPI.
In the previous example, the program pulls the argument from the command line,
assigns it to the variable "x", and runs the sqrt device under test with that
value. This program can take the integer square root of any single value. Of
course, if you wish to test with a large number of input values, executing the
program many times may become tedious.
Another technique would be to put a set of input values into a data file, and
write the test bench to read the file. We can then edit the file to add new
input values, then rerun the simulation without compiling it again. The
advantage of this technique is that we can accumulate a large set of test
input values, and run the lot as a batch.
This example
.. code-block:: verilog
module main;
reg clk, reset;
reg [31:0] data[4:0];
reg [31:0] x;
wire [15:0] y;
wire rdy;
sqrt32 dut (clk, rdy, reset, x, y);
always #10 clk = ~clk;
integer i;
initial begin
/* Load the data set from the hex file. */
$readmemh("sqrt.hex", data);
for (i = 0 ; i <= 4 ; i = i + 1) begin
clk = 0;
reset = 1;
x = data[i];
#35 reset = 0;
wait (rdy) $display("y=%d", y);
end
$finish;
end // initial begin
endmodule // main
demonstrates the use of "$readmemh" to read data samples from a file into a
Verilog array. Start by putting into the file "sqrt.hex" the numbers::
51
19
1a
18
1
Then run the simulation with the command sequence::
% iverilog -osqrt_readmem.vvp sqrt_readmem.vl sqrt.vl
% vvp sqrt_readmem.vvp
y= 9
y= 5
y= 5
y= 4
y= 1
It is easy enough to change this program to work with larger data sets, or to
change the "data.hex" file to contain different data. This technique is also
common for simulating algorithms that take in larger data sets. One can extend
this idea slightly by using a "$value$plusargs" statement to select the file
to read.

View File

@ -1,35 +0,0 @@
Verilog Attributes
==================
This is a description of the various attributes that the Icarus Verilog tools
understand. The attributes are attached to objects using the "(\* ... \*)"
syntax, which is described by the Verilog LRM.
Attributes that start with "ivl\_" are Icarus Verilog specific are are probably
ignored by other tools.
Optimizations
-------------
* ivl_do_not_elide (snapshot 20140619 or later)
This applies to signals (i.e. reg, wire, etc.) and tells the optimizer to
not elide the signal, even if it is not referenced anywhere in the
design. This is useful if the signal is for some reason only accessed by
VPI/PLI code.
Synthesis
---------
* ivl_synthesis_cell
Applied to a module definition, this tells the synthesizer that the module
is a cell. The synthesizer does not descend into synthesis cells, as they
are assumed to be primitives in the target technology.
* ivl_synthesis_off
Attached to an "always" statement, this tells the synthesizer that the
statement is not to be synthesized. This may be useful, for example, to tell
the compiler that a stretch of code is test-bench code.

View File

@ -1,59 +0,0 @@
vhdlpp Command Line Flags
=========================
* -D <token>
Debug flags. The token can be:
* yydebug | no-yydebug
* entities=<path>
* -L <path>
Library path. Add the directory name to the front of the library
search path. The library search path is initially empty.
* -V
Display version on stdout
* -v
Verbose: Display version on stderr, and enable verbose messages to
stderr.
* -w <path>
Work path. This is the directory where the working directory is.
Library Format
--------------
The vhdlpp program stores libraries as directory that contain
packages. The name of the directory (in lower case) is the name of the
library as used on the "import" statement. Within that library, there
are packages in files named <foo>.pkg. For example::
<directory>/...
sample/...
test1.pkg
test2.pkg
bar/...
test3.pkg
Use the "+vhdl-libdir+<directory>" record in a config file to tell
Icarus Verilog that <directory> is a place to look for libraries. Then
in your VHDL code, access packages like this::
library sample;
library bar;
use sample.test1.all;
use bar.test3.all;
The \*.pkg files are just VHDL code containing only the package with
the same name. When Icarus Verilog encounters the "use <lib>.<name>.*;"
statement, it looks for the <name>.pkg file in the <lib> library and
parses that file to get the package header declared therein.

View File

@ -1,248 +0,0 @@
Using VPI
=========
Icarus Verilog implements a portion of the PLI 2.0 API to Verilog. This allows
programmers to write C code that interfaces with Verilog simulations to
perform tasks otherwise impractical with straight Verilog. Many Verilog
designers, especially those who only use Verilog as a synthesis tool, can
safely ignore the entire matter of the PLI (and this chapter) but the designer
who wishes to interface a simulation with the outside world cannot escape VPI.
The rest of this article assumes some knowledge of C programming, Verilog PLI,
and of the compiler on your system. In most cases, Icarus Verilog assumes the
GNU Compilation System is the compiler you are using, so tips and instructions
that follow reflect that. If you are not a C programmer, or are not planning
any VPI modules, you can skip this entire article. There are references at the
bottom for information about more general topics.
How It Works
------------
The VPI modules are compiled loadable object code that the runtime loads at
the user's request. The user commands vvp to locate and load modules with the
"-m" switch. For example, to load the "sample.vpi" module::
% vvp -msample foo.vvp
The vvp run-time loads the modules first, before executing any of the
simulation, or even before compiling the vvp code. Part of the loading
includes invoking initialization routines. These routines register with the
run-time all the system tasks and functions that the module implements. Once
this is done, the run time loader can match names of the called system tasks
of the design with the implementations in the VPI modules.
(There is a special module, the system.vpi module, that is always loaded to
provide the core system tasks.)
The simulator run time (The "vvp" program) gets a handle on a freshly loaded
module by looking for the symbol "vlog_startup_routines" in the loaded
module. This table, provided by the module author and compiled into the
module, is a null terminated table of function pointers. The simulator calls
each of the functions in the table in order. The following simple C definition
defines a sample table::
void (*vlog_startup_routines[])(void) = {
hello_register,
0
};
Note that the "vlog_startup_routines" table is an array of function pointers,
with the last pointer a 0 to mark the end. The programmer can organize the
module to include many startup functions in this table, if desired.
The job of the startup functions that are collected in the startup table is to
declare the system tasks and functions that the module provides. A module may
implement as many tasks/functions as desired, so a module can legitimately be
called a library of system tasks and functions.
Compiling VPI Modules
---------------------
To compile and link a VPI module for use with Icarus Verilog, you must compile
all the source files of a module as if you were compiling for a DLL or shared
object. With gcc under Linux, this means compiling with the "-fpic" flag. The
module is then linked together with the vpi library like so::
% gcc -c -fpic hello.c
% gcc -shared -o hello.vpi hello.o -lvpi
This assumes that the "vpi_user.h header file and the libvpi.a library file
are installed on your system so that gcc may find them. This is normally the
case under Linux and UNIX systems. An easier, the preferred method that works
on all supported systems is to use the single command::
% iverilog-vpi hello.c
The "iverilog-vpi" command takes as command arguments the source files for
your VPI module, compiles them with proper compiler flags, and links them into
a vpi module with any system specific libraries and linker flags that are
required. This simple command makes the "hello.vpi" module with minimum fuss.
A Worked Example
----------------
Let us try a complete, working example. Place the C code that follows into the
file hello.c::
# include <vpi_user.h>
static int hello_compiletf(char*user_data)
{
(void)user_data; // Avoid a warning since user_data is not used.
return 0;
}
static int hello_calltf(char*user_data)
{
(void)user_data; // Avoid a warning since user_data is not used.
vpi_printf("Hello, World!\n");
return 0;
}
void hello_register(void)
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.tfname = "$hello";
tf_data.calltf = hello_calltf;
tf_data.compiletf = hello_compiletf;
tf_data.sizetf = 0;
tf_data.user_data = 0;
vpi_register_systf(&tf_data);
}
void (*vlog_startup_routines[])(void) = {
hello_register,
0
};
and place the Verilog code that follows into hello.v::
module main;
initial $hello;
endmodule
Next, compile and execute the code with these steps::
% iverilog-vpi hello.c
% iverilog -ohello.vvp hello.v
% vvp -M. -mhello hello.vvp
Hello, World!
The compile and link in this example are conveniently combined into the
"iverilog-vpi" command. The "iverilog" command then compiles the "hello.v"
Verilog source file to the "hello.vvp" program. Next, the "vvp" command
demonstrates the use of the "-M" and "-m" flags to specify a vpi module search
directory and vpi module name. Specifically, they tell the "vvp" command where
to find the module we just compiled.
The "vvp" command, when executed as above, loads the "hello.vpi" module that
it finds in the current working directory. When the module is loaded, the
vlog_startup_routines table is scanned, and the "hello_register" function is
executed. The "hello_register" function in turn tells "vvp" about the system
tasks that are included in this module.
After the modules are all loaded, the "hello.vvp" design file is loaded and
its call to the "$hello" system task is matched up to the version declared by
the module. While "vvp" compiles the "hello.vvp" source, any calls to "$hello"
are referred to the "compiletf" function. This function is called at compile
time and can be used to check parameters to system tasks or function. It can
be left empty like this, or left out completely. The "compiletf" function can
help performance by collecting parameter checks in compile time, so they do
not need to be done each time the system task is run, thus potentially saving
execution time overall.
When the run-time executes the call to the hello system task, the
"hello_calltf" function is invoked in the loaded module, and thus the output
is generated. The "calltf" function is called at run time when the Verilog
code actually executes the system task. This is where the active code of the
task belongs.
System Function Return Types
----------------------------
Icarus Verilog supports system functions as well as system tasks, but there is
a complication. Notice how the module that you compile is only loaded by the
"vvp" program. This is mostly not an issue, but elaboration of expressions
needs to keep track of types, so the main compiler needs to know the return
type of functions.
Starting with Icarus Verilog v11, the solution is quite simple. The names and
locations of the user's VPI modules can be passed to the compiler via the
"iverilog" -m and -L flags and the IVERILOG_VPI_MODULE_PATH environment
variable. The compiler will load and analyse the specified modules to
automatically determine any function return types. The compiler will also
automatically pass the names and locations of the specified modules to the
"vvp" program, so that they don't need to be specified again on the "vvp"
command line.
For Icarus Verilog versions prior to v11, the solution requires that the
developer of a module include the table in a form that the compiler can
read. The System Function Table file carries this information. A simple
example looks like this::
# Example sft declarations of some common functions
$random vpiSysFuncInt
$bitstoreal vpiSysFuncReal
$realtobits vpiSysFuncSized 64 unsigned
This demonstrates the format of the file and support types. Each line contains
a comment (starts with "#") or a type declaration for a single function. The
declaration starts with the name of the system function (including the leading
"$") and ends with the type. The supported types are:
* vpiSysFuncInt
* vpiSysFuncReal
* vpiSysFuncSized <wid> <signed|unsigned>
Any functions that do not have an explicit type declaration in an SFT file are
implicitly taken to be "vpiSysFuncSized 32 unsigned".
The module author provides, along with the ".vpi" file that is the module, a
".sft" that declares all the function return types. For example, if the file
is named "example.sft", pass it to the "iverilog" command line or in the
command file exactly as if it were an ordinary source file.
Cadence PLI Modules
-------------------
With the cadpli module, Icarus Verilog is able to load PLI1 applications that
were compiled and linked to be dynamic loaded by Verilog-XL or
NC-Verilog. This allows Icarus Verilog users to run third-party modules that
were compiled to interface with XL or NC. Obviously, this only works on the
operating system that the PLI application was compiled to run on. For example,
a Linux module can only be loaded and run under Linux. In addition, a 64-bit
version of vvp can only load 64-bit PLI1 applications, etc.
Icarus Verilog uses an interface module, the "cadpli" module, to connect the
worlds. This module is installed with Icarus Verilog, and is invoked by the
usual -m flag to iverilog or vvp. This module in turn scans the extended
arguments, looking for -cadpli= arguments. The latter specify the share object
and bootstrap function for running the module. For example, to run the module
product.so, that has the bootstrap function "my_boot"::
% vvp -mcadpli a.out -cadpli=./product.so:my_boot
The "-mcadpli" argument causes vvp to load the cadpli.vpl library module. This
activates the -cadpli= argument interpreter. The -cadpli=<module>:<boot_func>
argument, then, causes vvp, through the cadpli module, to load the loadable
PLI application, invoke the my_boot function to get a veriusertfs table, and
scan that table to register the system tasks and functions exported by that
object. The format of the -cadpli= extended argument is essentially the same
as the +loadpli1= argument to Verilog-XL.
The integration from this point is seamless. The PLI application hardly knows
that it is being invoked by Icarus Verilog instead of Verilog-XL, so operates
as it would otherwise.
Other References
----------------
Since the above only explains how to get PLI/VPI working with Icarus Verilog,
here are some references to material to help with the common aspects of
PLI/VPI.
* Principles of Verilog PLI by Swapnajit Mittra. ISBN 0-7923-8477-6
* The Verilog PLI Handbook by Stuart Sutherland. ISBN 0-7923-8489-X

View File

@ -1,148 +0,0 @@
VVP Interactive Mode
====================
The vvp command has an interactive debug mode, where you can stop the
simulation and browse the current state of the simulation. There are
a couple ways to enter the debug mode, but once in interactive debug
mode, the usage is the same. Consider the example below:
.. code-block:: verilog
module clock(output reg clock);
initial clock = 1'b1;
always #100 clock = !clock;
endmodule // clock
module main;
reg [2:0] foo;
wire clk;
clock foo_clock(clk);
always @(posedge clk)
foo <= foo + 1;
initial begin
foo = 3'b000;
#250 $stop;
end
endmodule
In examples that follow, we will use the above sample program.
Enter Interactive Mode
----------------------
The first and most common method is to put "$stop" system task
calls in the simulation at the times where you want to simulation
to break and enter interactive mode. The example above has a $stop,
so the output looks like this::
../foo.vl:25: $stop called at 250 (1s)
** VVP Stop(0) **
** Flushing output streams.
** Current simulation time is 250 ticks.
>
You can get some interactive help by using the "help" command::
> help
Commands can be from the following table of base commands,
or can be invocations of system tasks/functions.
cd - Synonym for push.
cont - Resume (continue) the simulation
finish - Finish the simulation.
help - Get help.
list - List items in the current scope.
load - Load a VPI module, a la vvp -m.
ls - Shorthand for "list".
pop - Pop one scope from the scope stack.
push - Descend into the named scope.
step - Single-step the scheduler for 1 event.
time - Print the current simulation time.
trace - Control statement tracing (on/off) when the code is instrumented.
where - Show current scope, and scope hierarchy stack.
If the command name starts with a '$' character, it
is taken to be the name of a system task, and a call is
built up and executed. For example, "$display foo" will
call the function as $display(foo).
You can also enter interactive mode at the terminal by interrupting the
execution with a "^C" (Control-C) character. The vvp engine catches the
terminal interrupt and drops you into the interactive prompt::
^C** VVP Stop(0) **
** Flushing output streams.
** Current simulation time is 533928600 ticks.
>
This could be useful if you suspect that your simulation is stuck in
an infinite loop and you want to rummage around and see what's going on.
And finally, you can pass the "-s" command line flag to vvp to tell it
to execute "$stop" at the beginning of the simulation, before any other
events are executed. This may be useful as a way to manually set up some
details about the simulation.
Browsing the Design
-------------------
Now that you are in the interactive prompt, you can browse
around the design::
> ls
2 items in this scope:
package : $unit
module : main
> cd main
> ls
3 items in this scope:
reg : foo[2:0]
module : foo_clock
net : clk
> where
module main
> $display foo
1
> cd foo_clock
> where
module foo_clock
module main
> ls
2 items in this scope:
port : clock -- output
reg : clock
In the above example, the 'cd' and 'pop' commands descend into a scope
or pop back up a scope level. The 'where' command shows the scope stack,
and the 'ls' command lists the items present in the scope. With these
commands, one can browse freely throughout the design scope hierarchy.
It is also possible to call system tasks within the debug mode. The call
to the "$display" function is an example of this. In general, any system
task can be invoked, in the current context, with the objects that are
included on the command line passed as arguments. The arguments can be
variables or nets, and various kinds of literals::
> ls
2 items in this scope:
port : clock -- output
reg : clock
> $display "Hello, World! " 10 " " clock
Hello, World! 10 1
This is a great way to call custom system tasks as well. And system task
that vvp knows about can be invoked this way.
Leave Interactive Mode
----------------------
After you are done probing around in the interactive mode, you can
resume the simulation, or termimate execution. Resume the simulation
with the "cont" command, and terminate the simulation with the
"finish" command. The latter is the same as executing the
"$finish" system task.

View File

@ -1,145 +0,0 @@
VVP Command Line Flags
======================
The vvp command is the simulation run-time engine. The command line for vvp
execution is first the options and flags, then the vvp input file, and finally
extended arguments. Typical usage looks like this::
% vvp <flags> foo.vvp <extended arguments>
Options/Flags
-------------
These options/flags go before the path to the vvp-executable program. They
effect behavior of the vvp runtime engine, including preparation for
simulation.
* -i
This flag causes all output to <stdout> to be unbuffered.
* -l<logfile>
This flag specifies a logfile where all MCI <stdlog> output goes. Specify
logfile as '-' to send log output to <stderr>. $display and friends send
their output both to <stdout> and <stdlog>.
* -M<path>
Add the directory path to the (VPI) module search path. Multiple "-M" flags
are allowed, and the directories are added in the order that they are given
on the command line.
The string "-M-" is special, in that it doesn't add a directory to the
path. It instead *removes* the compiled directory. This is generally used
only for development of the vvp engine.
* -m<module>
Name a VPI module that should be loaded. The vvp engine looks for the named
module in the module search path, which includes the compiled in default
directory and directories given by "-M" flags.
NOTE: Starting with v11.0, the VPI modules to be loaded can be specified
when you compile your design. This allows the compiler to automatically
determine the return types of user-defined system functions. If specified at
compile-time, there is no need to specify them again here.
* -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
$stop right away, in the beginning of the simulation. This kicks the
vvp program into interactive debug mode.
* -v
Show verbose progress while setting up or cleaning up the runtime
engine. This also displays some performance information.
* -V
Print the version of the runtime, and exit.
Extended Arguments
------------------
The extended arguments are available to the simulation runtime, especially
system tasks, system functions and any VPI/PLI code. Extended arguments that
start with a "+" character are left for use by the user via the $plus$flag and
$plus$value functions.
NOTE: The extended arguments must appear *after* the input file name on the
command line.
VCD/FST/LXT Arguments
^^^^^^^^^^^^^^^^^^^^^
If not otherwise specified, the vvp engine will by default use VCD formats to
support the $dumpvars system task. The flags described here can alter that
behavior.
* -none/-vcd-none/-vcd-off/-fst-none
Disable trace output. The trace output will be stubbed so that no trace file
is created and the cost of dumping is avoided. All off these options are
synonyms for turning of dumping.
* -fst
Generate FST format outputs instead of VCD format waveform dumps. This is
the preferred output format if using GTKWave or Surfer for viewing waveforms.
* -lxt/-lxt2
Generate LXT or LXT2format instead of VCD format waveform dumps. The LXT2
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
^^^^^^^^^^^
The Icarus Verilog support for SDF back-annotation can take some extended
arguments to control aspects of SDF support.
* -sdf-warn
Print warnings during load of/annotation from an SDF file.
* -sdf-info
Print interesting information about an SDF file while parsing it.
* -sdf-verbose
Print warnings and info messages.
Environment Variables
---------------------
The vvp program pays attention to certain environment variables.
* IVERILOG_DUMPER

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.

View File

@ -1,128 +0,0 @@
Viewing Waveforms
=================
To view waveforms, either GTKWave or Surfer can be used.
GTKWave is a waveform viewer based on the GTK library. This viewer supports
VCD, FST, LXT, and LXT2 formats for waveform dumps. GTKWave is available on GitHub
`here <https://github.com/gtkwave/gtkwave>`__. Most Linux distributions already
include gtkwave prepackaged and there are binaries for Windows available.
.. image:: GTKWave_Example2.png
Surfer is a waveform viewer based on the Rust egui library. This viewer supports
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
uses $dumpfile and $dumpvars system tasks to enable waveform dumping, then the
vvp runtime takes care of the rest. The output is written into the file
specified by the $dumpfile system task. If the $dumpfile call is absent, the
compiler will choose the file name dump.vcd, dump.lxt, dump.lxt2, or dump.fst,
depending on runtime flags. The example below dumps everything in and below
the test module:
.. code-block:: verilog
// Do this in your test bench
initial
begin
$dumpfile("test.vcd");
$dumpvars(0,test);
end
By default, the vvp runtime will generate VCD dump output. This is the default
because it is the most portable. However, when using gtkwave, the FST output
format is faster and most compact. Use the "-fst", "-lxt", or "-lxt2" extended
argument to activate FST, LXT, or LXT2 output, respectively. For example, if
your compiled output is written into the file "foo.vvp", the command:
.. code-block:: console
% vvp foo.vvp -fst <other-plusargs>
will cause the dumpfile output to be written in FST format. Absent any
specific $dumpfile command, this file will be called dump.fst, which can be
viewed with GTKWave using the command:
.. code-block:: console
% gtkwave dump.fst
A Working Example
-----------------
First, the design itself:
.. code-block:: verilog
module counter(out, clk, reset);
parameter WIDTH = 8;
output [WIDTH-1 : 0] out;
input clk, reset;
reg [WIDTH-1 : 0] out;
wire clk, reset;
always @(posedge clk)
out <= out + 1;
always @reset
if (reset)
assign out = 0;
else
deassign out;
endmodule // counter
Then the simulation file:
.. code-block:: verilog
module test;
/* Make a reset that pulses once. */
reg reset = 0;
initial begin
$dumpfile("test.vcd");
$dumpvars(0,test);
# 17 reset = 1;
# 11 reset = 0;
# 29 reset = 1;
# 5 reset =0;
# 513 $finish;
end
/* Make a regular pulsing clock. */
reg clk = 0;
always #1 clk = !clk;
wire [7:0] value;
counter c1 (value, clk, reset);
initial
$monitor("At time %t, value = %h (%0d)",
$time, value, value);
endmodule // test
Compile, run, and view waveforms with GTKWave using these commands:
.. code-block:: console
% iverilog -o dsn counter_tb.v counter.v
% vvp dsn
% gtkwave test.vcd &
Click on the 'test', then 'c1' in the top left box of GTKWave, then drag the
signals to the Signals box. You will be able to add signals to display,
scanning by scope.

284
HName.cc
View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com) * Copyright (c) 2001 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * 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
@ -14,108 +14,266 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.cc,v 1.5 2002/11/02 03:27:52 steve Exp $"
#endif
# include "config.h" # include "config.h"
# include "HName.h" # include "HName.h"
# include <iostream> # include <iostream>
# include <cstring> # include <string.h>
# include <cstdlib> # include <stdlib.h>
#ifdef HAVE_MALLOC_H
using namespace std; # include <malloc.h>
#endif
hname_t::hname_t() hname_t::hname_t()
{ {
item_ = 0;
count_ = 0;
} }
hname_t::hname_t(perm_string text) hname_t::hname_t(const char*text)
: name_(text)
{
}
hname_t::hname_t(perm_string text, int num)
: name_(text), number_(1)
{
number_[0] = num;
}
hname_t::hname_t(perm_string text, const vector<int>&nums)
: name_(text), number_(nums)
{ {
item_ = strdup(text);
count_ = 1;
} }
hname_t::hname_t(const hname_t&that) hname_t::hname_t(const hname_t&that)
: name_(that.name_), number_(that.number_)
{ {
count_ = that.count_;
switch (count_) {
case 0:
item_ = 0;
break;
case 1:
item_ = strdup(that.item_);
break;
default:
array_ = new char*[count_];
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
array_[idx] = strdup(that.array_[idx]);
break;
}
} }
hname_t& hname_t::operator = (const hname_t&that) hname_t::~hname_t()
{ {
name_ = that.name_; switch (count_) {
number_ = that.number_; case 0:
return *this; break;
case 1:
free(item_);
break;
default:
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
free(array_[idx]);
delete[]array_;
break;
}
} }
bool hname_t::operator < (const hname_t&r) const unsigned hname_t::component_count() const
{ {
int cmp = strcmp(name_, r.name_); return count_;
if (cmp < 0) return true; }
if (cmp > 0) return false;
// The text parts are equal, so compare then number void hname_t::append(const char*text)
// parts. Finish as soon as we find one to be less or more {
// than the other. char**tmp;
size_t idx = 0;
while (number_.size() > idx || r.number_.size() > idx) {
// Ran out of l numbers, so less. switch (count_) {
if (number_.size() <= idx) case 0:
count_ = 1;
item_ = strdup(text);
break;
case 1:
count_ = 2;
tmp = new char*[2];
tmp[0] = item_;
tmp[1] = strdup(text);
array_ = tmp;
break;
default:
tmp = new char*[count_+1];
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
tmp[idx] = array_[idx];
delete[]array_;
array_ = tmp;
array_[count_] = strdup(text);
count_ += 1;
}
}
void hname_t::prepend(const char*text)
{
char**tmp;
switch (count_) {
case 0:
count_ = 1;
item_ = strdup(text);
break;
case 1:
count_ = 2;
tmp = new char*[2];
tmp[0] = strdup(text);
tmp[1] = item_;
array_ = tmp;
break;
default:
tmp = new char*[count_+1];
tmp[0] = strdup(text);
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
tmp[idx+1] = array_[idx];
delete[]array_;
array_ = tmp;
count_ += 1;
}
}
char* hname_t::remove_tail_name()
{
if (count_ == 0)
return 0;
if (count_ == 1) {
char*tmp = item_;
count_ = 0;
item_ = 0;
return tmp;
}
if (count_ == 2) {
char*tmp1 = array_[0];
char*tmp2 = array_[1];
delete[]array_;
count_ = 1;
item_ = tmp1;
return tmp2;
}
char*tmpo = array_[count_-1];
char**tmpa = new char*[count_-1];
for (unsigned idx = 0 ; idx < count_-1 ; idx += 1)
tmpa[idx] = array_[idx];
delete[]array_;
array_ = tmpa;
count_ -= 1;
return tmpo;
}
const char* hname_t::peek_name(unsigned idx) const
{
if (idx >= count_)
return 0;
if (count_ == 1)
return item_;
return array_[idx];
}
const char* hname_t::peek_tail_name() const
{
switch (count_) {
case 0:
return 0;
case 1:
return item_;
default:
return array_[count_-1];
}
}
bool operator < (const hname_t&l, const hname_t&r)
{
unsigned idx = 0;
const char*lc = l.peek_name(idx);
const char*rc = r.peek_name(idx);
while (lc && rc) {
int cmp = strcmp(lc, rc);
if (cmp < 0)
return true; return true;
if (cmp > 0)
// Ran out of r numbers, so greater.
if (r.number_.size() <= idx)
return false; return false;
if (number_[idx] < r.number_[idx])
return true;
if (number_[idx] > r.number_[idx])
return false;
idx += 1; idx += 1;
lc = l.peek_name(idx);
rc = r.peek_name(idx);
} }
// Fall-through means that we are equal, including all the if (lc && !rc)
// number parts, so not less. return false;
if (rc && !lc)
return true;
// Must be ==
return false; return false;
} }
bool hname_t::operator == (const hname_t&r) const bool operator == (const hname_t&l, const hname_t&r)
{ {
if (name_ == r.name_) { unsigned idx = 0;
if (number_.size() != r.number_.size()) const char*lc = l.peek_name(idx);
const char*rc = r.peek_name(idx);
while (lc && rc) {
int cmp = strcmp(lc, rc);
if (cmp != 0)
return false; return false;
idx += 1;
for (size_t idx = 0 ; idx < number_.size() ; idx += 1) lc = l.peek_name(idx);
if (number_[idx] != r.number_[idx]) return false; rc = r.peek_name(idx);
return true;
} }
return false; if (lc || rc)
return false;
// Must be ==
return true;
} }
ostream& operator<< (ostream&out, const hname_t&that) ostream& operator<< (ostream&out, const hname_t&that)
{ {
if (that.peek_name() == 0) { switch (that.count_) {
case 0:
out << ""; out << "";
return out; return out;
case 1:
out << that.item_;
return out;
default:
out << that.array_[0];
for (unsigned idx = 1 ; idx < that.count_ ; idx += 1)
out << "." << that.array_[idx];
return out;
} }
out << that.peek_name();
for (size_t idx = 0 ; idx < that.number_.size() ; idx += 1)
out << "[" << that.number_[idx] << "]";
return out;
} }
/*
* $Log: HName.cc,v $
* Revision 1.5 2002/11/02 03:27:52 steve
* Allow named events to be referenced by
* hierarchical names.
*
* Revision 1.4 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.3 2002/01/05 04:36:06 steve
* include malloc.h only when available.
*
* Revision 1.2 2001/12/18 04:52:45 steve
* Include config.h for namespace declaration.
*
* Revision 1.1 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
*/

135
HName.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_HName_H #ifndef __HName_H
#define IVL_HName_H #define __HName_H
/* /*
* Copyright (c) 2001-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2001 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
@ -16,97 +16,86 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: HName.h,v 1.4 2002/11/02 03:27:51 steve Exp $"
#endif
# include <iostream> # include <iostream>
# include <list> #ifdef __GNUC__
# include <vector> #if __GNUC__ > 2
# include "StringHeap.h" using namespace std;
#endif
# include <cassert> #endif
/* /*
* This class represents a component of a Verilog hierarchical name. A * This class represents a Verilog hierarchical name. A hierarchical
* hierarchical component contains a name string (represented here * name is an ordered list of simple names.
* with a perm_string) and an optional signed number. This signed
* number is used if the scope is part of an array, for example an
* array of module instances or a loop generated scope.
*/ */
class hname_t { class hname_t {
friend std::ostream& operator<< (std::ostream&out, const hname_t&that);
public: public:
hname_t (); hname_t ();
explicit hname_t (perm_string text); explicit hname_t (const char*text);
explicit hname_t (perm_string text, int num);
explicit hname_t (perm_string text, const std::vector<int>&nums);
hname_t (const hname_t&that); hname_t (const hname_t&that);
~hname_t(); ~hname_t();
hname_t& operator= (const hname_t&); // This method adds a name to the end of the hierarchical
// path. This becomes a new base name.
void append(const char*text);
bool operator == (const hname_t&that) const; // This method adds a name to the *front* of the hierarchical
bool operator < (const hname_t&that) const; // path. The base name remains the same, unless this is the
// only component.
void prepend(const char*text);
// Return the string part of the hname_t. // This method removes the tail name from the hierarchy, and
perm_string peek_name(void) const; // returns a pointer to that tail name. That tail name now
// must be removed by the caller.
char* remove_tail_name();
size_t has_numbers() const; // Return the given component in the hierarchical name. If the
int peek_number(size_t idx) const; // idx is too large, return 0.
const std::vector<int>&peek_numbers() const; const char*peek_name(unsigned idx) const;
const char*peek_tail_name() const;
// Return the number of components in the hierarchical
// name. If this is a simple name, this will return 1.
unsigned component_count() const;
friend ostream& operator<< (ostream&, const hname_t&);
private: private:
perm_string name_; union {
// If this vector has size, then the numbers all together make char**array_;
// up part of the hierarchical name. char* item_;
std::vector<int> number_; };
unsigned count_;
private: // not implemented private: // not implemented
hname_t& operator= (const hname_t&);
}; };
inline hname_t::~hname_t() extern bool operator < (const hname_t&, const hname_t&);
{ extern bool operator == (const hname_t&, const hname_t&);
}
inline perm_string hname_t::peek_name(void) const /*
{ * $Log: HName.h,v $
return name_; * Revision 1.4 2002/11/02 03:27:51 steve
} * Allow named events to be referenced by
* hierarchical names.
inline int hname_t::peek_number(size_t idx) const *
{ * Revision 1.3 2002/08/12 01:34:58 steve
assert(number_.size() > idx); * conditional ident string using autoconfig.
return number_[idx]; *
} * Revision 1.2 2002/06/14 03:25:51 steve
* Compiler portability.
inline const std::vector<int>& hname_t::peek_numbers(void) const *
{ * Revision 1.1 2001/12/03 04:47:14 steve
return number_; * Parser and pform use hierarchical names as hname_t
} * objects instead of encoded strings.
*
inline size_t hname_t::has_numbers() const */
{ #endif
return number_.size();
}
extern std::ostream& operator<< (std::ostream&, const hname_t&);
inline bool operator != (const hname_t&l, const hname_t&r)
{ return ! (l == r); }
inline std::ostream& operator<< (std::ostream&out, const std::list<hname_t>&ll)
{
std::list<hname_t>::const_iterator cur = ll.begin();
out << *cur;
++ cur;
while (cur != ll.end()) {
out << "." << *cur;
++ cur;
}
return out;
}
#endif /* IVL_HName_H */

181
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.in' 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.in' 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,127 @@ 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

@ -14,16 +14,19 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: LineInfo.cc,v 1.4.2.1 2005/08/13 00:45:53 steve Exp $"
#endif
# include "config.h"
# include "LineInfo.h" # include "LineInfo.h"
# include <sstream> # include <sstream>
using namespace std;
LineInfo::LineInfo() LineInfo::LineInfo()
: lineno_(0) : file_(0), lineno_(0)
{ {
} }
@ -31,12 +34,12 @@ LineInfo::~LineInfo()
{ {
} }
string LineInfo::get_fileline() const std::string LineInfo::get_line() const
{ {
ostringstream buf; std::ostringstream buf;
buf << (file_.str()? file_.str() : "") << ":" << lineno_; buf << (file_? file_ : "") << ":" << lineno_;
string res = buf.str(); std::string res = buf.str();
return res; return res;
} }
@ -46,7 +49,7 @@ void LineInfo::set_line(const LineInfo&that)
lineno_ = that.lineno_; lineno_ = that.lineno_;
} }
void LineInfo::set_file(perm_string f) void LineInfo::set_file(const char*f)
{ {
file_ = f; file_ = f;
} }
@ -55,3 +58,24 @@ void LineInfo::set_lineno(unsigned n)
{ {
lineno_ = n; lineno_ = n;
} }
/*
* $Log: LineInfo.cc,v $
* Revision 1.4.2.1 2005/08/13 00:45:53 steve
* Fix compilation warnings/errors with newer compilers.
*
* Revision 1.4 2003/01/17 05:49:03 steve
* Use stringstream in place of sprintf.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2000/11/30 17:31:42 steve
* Change LineInfo to store const C strings.
*
*/

View File

@ -1,7 +1,7 @@
#ifndef IVL_LineInfo_H #ifndef __LineInfo_H
#define IVL_LineInfo_H #define __LineInfo_H
/* /*
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 1999 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * 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
@ -16,12 +16,16 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: LineInfo.h,v 1.7.2.2 2005/08/13 00:45:53 steve Exp $"
#endif
# include "StringHeap.h"
# include <string> # include <string>
using namespace std;
/* /*
* This class holds line information for an internal object. * This class holds line information for an internal object.
* *
@ -34,22 +38,41 @@
class LineInfo { class LineInfo {
public: public:
LineInfo(); LineInfo();
virtual ~LineInfo(); ~LineInfo();
std::string get_line() const;
// Get a fully formatted file/lineno
std::string get_fileline() const;
// Set the file/line from another LineInfo object.
void set_line(const LineInfo&that); void set_line(const LineInfo&that);
// Access parts of LineInfo data void set_file(const char*f);
void set_file(perm_string f);
void set_lineno(unsigned n); void set_lineno(unsigned n);
perm_string get_file() const { return file_; }
unsigned get_lineno() const { return lineno_; }
private: private:
perm_string file_; const char* file_;
unsigned lineno_; unsigned lineno_;
}; };
#endif /* IVL_LineInfo_H */ /*
* $Log: LineInfo.h,v $
* Revision 1.7.2.2 2005/08/13 00:45:53 steve
* Fix compilation warnings/errors with newer compilers.
*
* Revision 1.7.2.1 2005/06/14 15:33:54 steve
* Fix gcc4 build issues.
*
* Revision 1.7 2003/01/17 05:49:03 steve
* Use stringstream in place of sprintf.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2000/11/30 17:31:42 steve
* Change LineInfo to store const C strings.
*
* Revision 1.4 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.3 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*/
#endif

View File

@ -12,323 +12,292 @@
# #
# You should have received a copy of the GNU Library General Public # You should have received a copy of the GNU Library General Public
# License along with this program; if not, write to the Free # License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Software Foundation, Inc.,
# Boston, MA 02110-1301, USA. # 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.169.2.6 2007/03/23 23:26:51 steve Exp $"
#
# #
SHELL = /bin/sh SHELL = /bin/sh
# The interesting make targets are: # This version string is only used in the version message printed
# # by the compiler. It reflects the assigned version number for the
# make version # product as a whole. Most components also print the CVS Name: token
# Force the version_tag.h file to be rebuilt. Otherwise, it will only # in order to get a more automatic version stamp as well.
# be built if it is missing. VERSION = 0.8.4
#
# make all
# make install
#
# The "suffix" is used as an installation suffix. It modifies certain
# key install paths/files such that a build and install of Icarus Verilog
# with the same $(prefix) but a different $(suffix) will not interfere.
# The normal configuration leaves suffix empty
suffix = @install_suffix@
prefix = @prefix@ prefix = @prefix@
exec_prefix = @exec_prefix@ exec_prefix = @exec_prefix@
srcdir = @srcdir@ srcdir = @srcdir@
datarootdir = @datarootdir@
VERSION_MAJOR = @VERSION_MAJOR@
VERSION_MINOR = @VERSION_MINOR@
SUBDIRS = ivlpp vhdlpp vvp vpi tgt-null tgt-stub tgt-vvp \ SUBDIRS = @subdirs@
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver \
ivtest
# Only run distclean for these directories.
NOTUSED = tgt-fpga tgt-pal tgt-verilog
ifeq (@LIBVERIUSER@,yes) VPATH = $(srcdir)
SUBDIRS += libveriuser cadpli
else
NOTUSED += libveriuser cadpli
endif
SUBDIRS += driver-vpi
# To get the version headers to build correctly we only want to look
# for C++ files in the source directory. All other files will require
# an explicit $(srcdir). The one exception to this is if we need to
# rebuild the lexor_keyword.cc file. If we do, then we want to use the
# local version instead of the one is $(srcdir).
vpath lexor_keyword.cc .
vpath %.cc $(srcdir)/libmisc
vpath %.cc $(srcdir)
bindir = @bindir@ bindir = @bindir@
libdir = @libdir@ libdir = @libdir@
# This is actually the directory where we install our own header files. includedir = @includedir@
# It is a little different from the generic includedir. mandir = @mandir@
ivl_includedir = @includedir@/iverilog$(suffix)
libdir64 = @libdir64@
dllib=@DLLIB@ dllib=@DLLIB@
strip_dynamic=@strip_dynamic@
# For a cross compile these defines will need to be set accordingly.
HOSTCC = @CC@
HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
BUILDCC = @CC_FOR_BUILD@
BUILDEXT = @BUILD_EXEEXT@
CC = @CC@ CC = @CC@
CXX = @CXX@ CXX = @CXX@
ENV_VVP=@ENV_VVP@
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@
STRIP = @STRIP@
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@
ifeq (@srcdir@,.) CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
INCLUDE_PATH = -I. -Ilibmisc CXXFLAGS = -Wall @CXXFLAGS@
else
INCLUDE_PATH = -I. -I$(srcdir) -I$(srcdir)/libmisc
endif
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
PICFLAGS = @PICFLAG@ PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@ LDFLAGS = @rdynamic@ @LDFLAGS@
CTARGETFLAGS = @CTARGETFLAGS@
# Source files in the libmisc directory # The TARGETS variable lists the target modules that can be build and
M = LineInfo.o StringHeap.o # installed. Some of them depend on external things, so are only
# compiled if the prerequisites are installed.
TARGETS = tgt-null
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o all: dep ivl@EXEEXT@
FF = cprop.o exposenodes.o nodangle.o synth.o synth2.o syn-rules.o for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \ for dir in ivlpp tgt-verilog tgt-stub; \
elab_expr.o elaborate_analog.o elab_lval.o elab_net.o \ do (cd $$dir ; $(MAKE) $@); done
elab_scope.o elab_sig.o elab_sig_analog.o elab_type.o \ cd driver ; $(MAKE) VERSION=$(VERSION) $@
emit.o eval_attrib.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
net_design.o netclass.o netdarray.o \
netenum.o netparray.o netqueue.o netscalar.o netstruct.o netvector.o \
net_event.o net_expr.o net_func.o \
net_func_eval.o net_link.o net_modulo.o \
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
net_udp.o map_named_args.o \
pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
pform_types.o \
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o vpi_modules.o target.o \
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PFunction.o \
PGate.o PGenerate.o PModport.o PNamedItem.o PPackage.o PScope.o PSpec.o PTimingCheck.o \
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@
$(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
# dosify text files. # dosify text files.
ifeq (@MINGW32@,yes) ifeq (@WIN32@,yes)
all: dosify$(BUILDEXT) all: dep dosify.exe
dosify$(BUILDEXT): $(srcdir)/dosify.c dosify.exe: dosify.c
$(BUILDCC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c $(CC) -o dosify.exe 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 for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
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. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
$(ENV_VVP) vvp/vvp$(suffix)@EXEEXT@ -M- -M./vpi ./check.vvp | grep 'Hello, World' vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
check-installed check-installed-vpi check-installed-vvp check-installed-vvp-py:
$(MAKE) -C ivtest $@
clean: clean:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
rm -f *.o parse.cc parse.h lexor.cc for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
rm -f ivl.exp for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
rm -f iverilog_man.ps iverilog_man.pdf iverilog_man_$(VERSION_MAJOR)_$(VERSION_MINOR).pdf do (cd $$dir ; $(MAKE) $@); done
rm -f parse.output syn-rules.output dosify$(BUILDEXT) ivl@EXEEXT@ check.vvp rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
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 ivl@EXEEXT@
distclean: clean distclean: clean
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) $@ && ) true for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
rm -f Makefile config.status config.log config.cache for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
rm -f stamp-config-h config.h do (cd $$dir ; $(MAKE) $@); done
rm -f stamp-_pli_types-h _pli_types.h rm -f Makefile config.status config.log config.cache config.h
rm -f stamp-version_base-h version_base.h
ifneq (@srcdir@,.)
rm -f version_tag.h check.conf
rmdir $(SUBDIRS) $(NOTUSED)
endif
rm -rf autom4te.cache rm -rf autom4te.cache
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-xnf.o
cppcheck --enable=all --std=c99 --std=c++11 -f \ FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o xnfio.o
--check-level=exhaustive \
--suppressions-list=$(srcdir)/cppcheck-global.sup \
--suppressions-list=$(srcdir)/cppcheck.sup \
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
-UYYSTYPE -U__SIZE_TYPE__ -Umalloc -Ufree \
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
cppcheck-all: O = main.o async.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) cppcheck && ) true elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
$(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) cppcheck && ) true elab_sig.o emit.o eval.o eval_attrib.o \
$(MAKE) cppcheck eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.o net_func.o \
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
net_proc.o net_scope.o net_udp.o net_variable.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_dump.o \
set_width.o symbol_search.o sync.o sys_funcs.o \
verinum.o verireal.o target.o targets.o \
Attrib.o HName.o LineInfo.o Module.o PData.o PDelays.o PEvent.o \
PExpr.o PGate.o \
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
$(FF) $(TT)
Makefile: $(srcdir)/Makefile.in config.status Makefile: Makefile.in config.h.in config.status
./config.status --file=$@ ./config.status
ifeq (@WIN32@,yes)
# Under Windows (mingw) I need to make the ivl.exe in two steps.
# The first step makes an ivl.exe that dlltool can use to make an
# 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 ivl.def
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
dlltool --dllname ivl@EXEEXT@ --def ivl.def \
--output-lib libivl.a --output-exp ivl.exp
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
else
ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
ifeq (@MINGW32@,yes)
SUBDIRS += driver-vpi
else
all: dep iverilog-vpi
iverilog-vpi: iverilog-vpi.sh
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
-e 's;@INCLUDEDIR@;@includedir@;' \
-e 's;@LIBDIR64@;@libdir64@;' \
-e 's;@VPIDIR1@;@vpidir1@;' -e 's;@VPIDIR2@;@vpidir2@;' \
-e 's;@LIBDIR@;@libdir@;' $< > $@
chmod +x $@
endif
dep: dep:
mkdir dep mkdir dep
stamp-config-h: $(srcdir)/config.h.in config.status %.o: %.cc
@rm -f $@ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
./config.status config.h
config.h: stamp-config-h
stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
@rm -f $@
./config.status _pli_types.h
_pli_types.h: stamp-_pli_types-h
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
cd $(srcdir) && autoconf
config.status: $(srcdir)/configure
./config.status --recheck
./config.status
ifeq (@WIN32@,yes)
# Under Windows we need to create an import library to allow the target code
# generators to access the items exported by ivl.exe. The .def file controls
# what is visible in the import library.
ivl@EXEEXT@: $O $(srcdir)/ivl.def
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ -Wl,--out-implib=libivl.a $(srcdir)/ivl.def $O $(dllib) @EXTRALIBS@
else
ivl@EXEEXT@: $O
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
endif
%.o: %.cc config.h | dep
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep/$*.d mv $*.d dep/$*.d
# Here are some explicit dependencies needed to get things going.
main.o: main.cc version_tag.h
lexor.o: lexor.cc parse.h lexor.o: lexor.cc parse.h
parse.o: parse.cc parse.o: parse.cc
# 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 -t -p VL -d -o parse.cc $(srcdir)/parse.y
$(YACC) --verbose $(YACC_CONFLICT_FLAGS) -t -p VL --defines=parse.h -o parse.cc $< mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
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 -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
lexor.cc: $(srcdir)/lexor.lex lexor.cc: $(srcdir)/lexor.lex
$(LEX) -s -t $< > $@ $(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex
lexor_keyword.o: lexor_keyword.cc parse.h lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf lexor_keyword.cc: 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-3,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
iverilog_man.ps: driver/iverilog.man vvp/vvp.man driver-vpi/iverilog-vpi.man iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
$(GROFF) -man -rC1 -rD1 -T ps $^ > $@ $(MAN) -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
iverilog_man.pdf: iverilog_man.ps iverilog-vpi.pdf: iverilog-vpi.ps
$(PS2PDF) $< $@ $(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
cp $@ iverilog_man_$(VERSION_MAJOR)_$(VERSION_MINOR).pdf
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a # Build and install the iverilog-vpi.pdf only if there is a man
# release_tag.h file in the source tree (included in snapshots and releases), # program *and* a ps2pdf program.
# and finally use nothing. ifeq (@WIN32@,yes)
ifeq ($(MAN),none)
# "true" and "false" in the next few lines are Unix shell command names INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
ifeq ($(GIT),none)
GIT_PRESENT = false
else else
GIT_PRESENT = true ifeq ($(PS2PDF),none)
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
else
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf $(mandir)/man1/iverilog-vpi.1
all: dep iverilog-vpi.pdf
endif
endif
INSTALL_DOCDIR = $(mandir)/man1
else
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
INSTALL_DOCDIR = $(mandir)/man1
endif endif
version_tag.h version:
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
echo "Using git-describe for VERSION_TAG"; \
tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
elif test -r $(srcdir)/release_tag.h; then \
echo "Using $(srcdir)/release_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; \
else \
echo "Using empty VERSION_TAG"; \
echo '#define VERSION_TAG ""' > version_tag.h; \
fi
install: all installdirs installfiles ifeq (@MINGW32@,yes)
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
else
WIN32_INSTALL = $(bindir)/iverilog-vpi
endif
F = ./ivl@EXEEXT@ \ XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf
$(srcdir)/constants.vams \
$(srcdir)/disciplines.vams \
$(srcdir)/ivl_target.h \
./_pli_types.h \
$(srcdir)/sv_vpi_user.h \
$(srcdir)/vpi_user.h \
$(srcdir)/acc_user.h \
$(srcdir)/veriuser.h
installfiles: $(F) | installdirs install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC) $(XNF_INSTALL)
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@" for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams" for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams" for dir in vpi ivlpp driver; \
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(ivl_includedir)/ivl_target.h" do (cd $$dir ; $(MAKE) $@); done
$(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(ivl_includedir)/_pli_types.h"
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(ivl_includedir)/sv_vpi_user.h"
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(ivl_includedir)/vpi_user.h"
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(ivl_includedir)/acc_user.h"
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(ivl_includedir)/veriuser.h"
installdirs: $(srcdir)/mkinstalldirs $(bindir)/iverilog-vpi: ./iverilog-vpi
$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \ $(INSTALL_SCRIPT) ./iverilog-vpi $(bindir)/iverilog-vpi
"$(DESTDIR)$(ivl_includedir)" \
"$(DESTDIR)$(libdir)/ivl$(suffix)" \ $(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
"$(DESTDIR)$(libdir)/ivl$(suffix)/include" $(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
$(STRIP) $(strip_dynamic) $(libdir)/ivl/ivl@EXEEXT@
$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(libdir)/ivl/xnf-s.conf
$(libdir)/ivl/xnf.conf: $(srcdir)/xnf.conf
$(INSTALL_DATA) $(srcdir)/xnf.conf $(libdir)/ivl/xnf.conf
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(includedir)/ivl_target.h
$(includedir)/_pli_types.h: _pli_types.h
$(INSTALL_DATA) $< $(includedir)/_pli_types.h
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(includedir)/vpi_user.h
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
$(INSTALL_DATA) $(srcdir)/acc_user.h $(includedir)/acc_user.h
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
$(INSTALL_DATA) $(srcdir)/veriuser.h $(includedir)/veriuser.h
$(mandir)/man1/iverilog-vpi.1: $(srcdir)/iverilog-vpi.man
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(mandir)/man1/iverilog-vpi.1
$(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
$(INSTALL_DATA) iverilog-vpi.pdf $(prefix)/iverilog-vpi.pdf
# In windows installations, put a few examples and the quick_start
# into the destination directory.
ifeq (@MINGW32@,yes)
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
mv tmp.vl $(prefix)/hello.vl
$(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
mv tmp.vl $(prefix)/sqrt.vl
$(prefix)/sqrt-virtex.v: $(srcdir)/examples/sqrt-virtex.v
./dosify.exe $(srcdir)/examples/sqrt-virtex.v tmp.vl
mv tmp.vl $(prefix)/sqrt-virtex.v
$(prefix)/QUICK_START.txt: $(srcdir)/QUICK_START.txt
./dosify.exe $(srcdir)/QUICK_START.txt tmp.txt
mv tmp.txt $(prefix)/QUICK_START.txt
endif
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl \
$(mandir) $(mandir)/man1
uninstall: uninstall:
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \ for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done for dir in vpi ivlpp driver; \
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include" do (cd $$dir ; $(MAKE) $@); done
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)" for f in xnf.conf xnf-s.conf ivl; \
for f in verilog$(suffix) gverilog$(suffix)@EXEEXT@; \ do rm -f $(libdir)/ivl/$$f; done
do rm -f "$(DESTDIR)$(bindir)/$$f"; done -rmdir $(libdir)/ivl
for f in ivl_target.h vpi_user.h _pli_types.h sv_vpi_user.h acc_user.h veriuser.h; \ for f in verilog iverilog-vpi gverilog@EXEEXT@; \
do rm -f "$(DESTDIR)$(ivl_includedir)/$$f"; done do rm -f $(bindir)/$$f; done
-test X$(suffix) = X || rmdir "$(DESTDIR)$(ivl_includedir)" for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
do rm -f $(includedir)/$$f; done
rm -f $(mandir)/man1/iverilog-vpi.1
-include $(patsubst %.o, dep/%.d, $O) -include $(patsubst %.o, dep/%.d, $O)
-include $(patsubst %.o, dep/%.d, vpithunk.o)
.PHONY: check-installed check-installed-vpi check-installed-vvp check-installed-vvp-py

267
Module.cc
View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2000 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
@ -14,81 +14,24 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.cc,v 1.25 2004/10/04 01:10:51 steve Exp $"
#endif
# include "config.h" # include "config.h"
# 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 <assert.h>
# include "ivl_assert.h"
# include <iostream>
using namespace std;
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(perm_string n)
: PScopeExtra(n, parent) : name_(n)
{ {
library_flag = false; default_nettype = NetNet::NONE;
is_cell = false;
is_interface = false;
program_block = false;
uc_drive = UCD_NONE;
} }
Module::~Module() Module::~Module()
@ -100,9 +43,34 @@ void Module::add_gate(PGate*gate)
gates_.push_back(gate); gates_.push_back(gate);
} }
void Module::add_task(perm_string name, PTask*task)
{
tasks_[name] = task;
}
void Module::add_function(perm_string name, PFunction *func)
{
funcs_[name] = func;
}
PWire* Module::add_wire(PWire*wire)
{
PWire*&ep = wires_[wire->path()];
if (ep) return ep;
assert(ep == 0);
ep = wire;
return wire;
}
void Module::add_behavior(PProcess*b)
{
behaviors_.push_back(b);
}
unsigned Module::port_count() const unsigned Module::port_count() const
{ {
return ports.size(); return ports.count();
} }
/* /*
@ -110,27 +78,21 @@ unsigned Module::port_count() const
* module. If the port is internally unconnected, return an empty * module. If the port is internally unconnected, return an empty
* array. * array.
*/ */
const vector<PEIdent*>& Module::get_port(unsigned idx) const const svector<PEIdent*>& Module::get_port(unsigned idx) const
{ {
ivl_assert(*this, idx < ports.size()); assert(idx < ports.count());
static const vector<PEIdent*> zero; static svector<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 != "");
for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) { for (unsigned idx = 0 ; idx < ports.count() ; 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
are ports that are skipped in the declaration, are ports that are skipped in the declaration,
@ -139,42 +101,29 @@ 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;
} }
return ports.size(); return ports.count();
} }
perm_string Module::get_port_name(unsigned idx) const
PWire* Module::get_wire(const hname_t&name) const
{ {
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
ivl_assert(*this, idx < ports.size()); if (obj == wires_.end())
if (ports[idx] == 0 || ports[idx]->name.str() == 0) { return 0;
/* It is possible to have undeclared ports. These else
are ports that are skipped in the declaration, return (*obj).second;
for example like so: module foo(x ,, y); The
port between x and y is unnamed and thus
inaccessible to binding by name. Port references
that aren't simple or escaped identifiers are
also inaccessible to binding by name. */
return perm_string::literal("unnamed");
}
return ports[idx]->name;
} }
PExpr* Module::get_port_default_value(unsigned idx) const
{
ivl_assert(*this, idx < ports.size());
return ports[idx] ? ports[idx]->default_value : 0;
}
PGate* Module::get_gate(perm_string name) PGate* Module::get_gate(perm_string name)
{ {
for (list<PGate*>::iterator cur = gates_.begin() for (list<PGate*>::iterator cur = gates_.begin()
; cur != gates_.end() ; ++ cur ) { ; cur != gates_.end()
; cur ++ ) {
if ((*cur)->get_name() == name) if ((*cur)->get_name() == name)
return *cur; return *cur;
@ -183,33 +132,105 @@ PGate* Module::get_gate(perm_string name)
return 0; return 0;
} }
const map<hname_t,PWire*>& Module::get_wires() const
{
return wires_;
}
const list<PGate*>& Module::get_gates() const const list<PGate*>& Module::get_gates() const
{ {
return gates_; return gates_;
} }
PNamedItem::SymbolType Module::symbol_type() const const list<PProcess*>& Module::get_behaviors() const
{ {
if (program_block) return behaviors_;
return PROGRAM;
if (is_interface)
return INTERFACE;
return MODULE;
} }
bool Module::can_be_toplevel() const
{
// Don't choose library modules.
if (library_flag)
return false;
// Don't choose modules with parameters without default value /*
for (std::map<perm_string,param_expr_t*>::const_iterator cur = * $Log: Module.cc,v $
parameters.begin(); cur != parameters.end(); ++cur) { * Revision 1.25 2004/10/04 01:10:51 steve
if (cur->second->expr == 0) * Clean up spurious trailing white space.
return false; *
} * Revision 1.24 2004/06/13 04:56:53 steve
* Add support for the default_nettype directive.
*
* Revision 1.23 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.22 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.21 2003/04/02 03:00:14 steve
* Cope with empty module ports while binding by name.
*
* Revision 1.20 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
* Revision 1.19 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.18 2002/05/19 23:37:28 steve
* Parse port_declaration_lists from the 2001 Standard.
*
* Revision 1.17 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.16 2001/10/20 05:21:51 steve
* Scope/module names are char* instead of string.
*
* Revision 1.15 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.14 2000/11/15 20:31:05 steve
* Fix warning about temporaries.
*
* Revision 1.13 2000/11/05 06:05:59 steve
* Handle connectsion to internally unconnected modules (PR#38)
*
* Revision 1.12 2000/05/16 04:05:15 steve
* Module ports are really special PEIdent
* expressions, because a name can be used
* many places in the port list.
*
* Revision 1.11 2000/03/12 17:09:40 steve
* Support localparam.
*
* Revision 1.10 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.9 2000/01/09 20:37:57 steve
* Careful with wires connected to multiple ports.
*
* Revision 1.8 1999/12/11 05:45:41 steve
* Fix support for attaching attributes to primitive gates.
*
* Revision 1.7 1999/09/17 02:06:25 steve
* Handle unconnected module ports.
*
* Revision 1.6 1999/08/04 02:13:02 steve
* Elaborate module ports that are concatenations of
* module signals.
*
* Revision 1.5 1999/08/03 04:14:49 steve
* Parse into pform arbitrarily complex module
* port declarations.
*
* Revision 1.4 1999/07/31 19:14:47 steve
* Add functions up to elaboration (Ed Carter)
*
* Revision 1.3 1999/07/03 02:12:51 steve
* Elaborate user defined tasks.
*
* Revision 1.2 1999/06/17 05:34:42 steve
* Clean up interface of the PWire class,
* Properly match wire ranges.
*
* Revision 1.1 1998/11/03 23:28:51 steve
* Introduce verilog to CVS.
*
*/
return true;
}

231
Module.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_Module_H #ifndef __Module_H
#define IVL_Module_H #define __Module_H
/* /*
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2004 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
@ -16,116 +16,82 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: Module.h,v 1.37 2004/06/13 04:56:53 steve Exp $"
#endif
# include <list> # include <list>
# include <map> # include <map>
# include <vector> # include "svector.h"
# include <utility>
# include "StringHeap.h" # include "StringHeap.h"
# include "HName.h" # include "HName.h"
# include "named.h" # include "named.h"
# include "PScope.h" # include "LineInfo.h"
# include "PNamedItem.h"
# include "netlist.h" # include "netlist.h"
# include "pform_types.h" class PData;
class PEvent;
class PExpr; class PExpr;
class PEIdent; class PEIdent;
class PGate; class PGate;
class PGenerate;
class PModport;
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;
/* /*
* A module is a named container and scope. A module holds a bunch of * A module is a named container and scope. A module holds a bunch of
* semantic quantities such as wires and gates. The module is * semantic quantities such as wires and gates. The module is
* therefore the handle for grasping the described circuit. * therefore the handle for grasping the described circuit.
*
* SystemVerilog introduces program blocks and interfaces. These have
* much in common with modules, so the Module class is used to represent
* these containers as well.
*/ */
class Module : public PScopeExtra, public PNamedItem { class Module : public LineInfo {
/* The module ports are in general a vector of port_t /* The module ports are in general a vector of port_t
objects. Each port has a name and an ordered list of objects. Each port has a name and an ordered list of
wires. The name is the means that the outside uses to wires. The name is the means that the outside uses to
access the port, the wires are the internal connections to access the port, the wires are the internal connections to
the port. In SystemVerilog, input ports may also have a the port. */
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; svector<PEIdent*> expr;
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 make must be a permallocated string. */
explicit Module(LexicalScope*parent, perm_string name); explicit Module(perm_string name);
~Module() override; ~Module();
/* Initially false. This is set to true if the module has been NetNet::Type default_nettype;
declared as a library module. This makes the module
ineligible for being chosen as an implicit root. It has no
other effect. */
bool library_flag;
bool is_cell; /* The module has parameters that are evaluated when the
module is elaborated. During parsing, I put the parameters
into this map. */
struct param_expr_t {
PExpr*expr;
PExpr*msb;
PExpr*lsb;
bool signed_flag;
};
map<perm_string,param_expr_t>parameters;
map<perm_string,param_expr_t>localparams;
/* This is true if the module represents a program block
instead of a module/cell. Program blocks have content
restrictions and slightly modify scheduling semantics. */
bool program_block;
/* This is true if the module represents a interface /* specparams are simpler then other params, in that they have
instead of a module/cell. Interfaces have different no type information. They are merely constant
content restrictions and some extra allowed items. */ expressions. */
bool is_interface; map<perm_string,PExpr*>specparams;
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
UCDriveType uc_drive;
/* specparams are simpler than other parameters, in that they
can have a range, but not an explicit type. The restrictions
are enforced by the parser. */
std::map<perm_string,param_expr_t*>specparams;
/* The module also has defparam assignments which don't create /* The module also has defparam assignments which don't create
new parameters within the module, but may be used to set new parameters within the module, but may be used to set
values within this module (when instantiated) or in other values within this module (when instantiated) or in other
instantiated modules. */ instantiated modules. */
typedef std::pair<pform_name_t,PExpr*> named_expr_t; map<hname_t,PExpr*>defparms;
std::list<named_expr_t>defparms;
static std::list<named_expr_t>user_defparms;
/* Parameters may be overridden at instantiation time; /* Parameters may be overridden at instantiation time;
the overrides do not contain explicit parameter names, the overrides do not contain explicit parameter names,
@ -133,82 +99,113 @@ class Module : public PScopeExtra, public PNamedItem {
appear in the instantiated module. Therefore a appear in the instantiated module. Therefore a
list of names in module-order is needed to pass from list of names in module-order is needed to pass from
a parameter-index to its name. */ a parameter-index to its name. */
std::list<perm_string> param_names; list<perm_string> param_names;
/* This is an array of port descriptors, which is in turn a /* This is an array of port descriptors, which is in turn a
named array of PEident pointers. */ named array of PEident pointers. */
std::vector<port_t*> ports; svector<port_t*> ports;
std::map<perm_string,PExpr*> attributes; /* Keep a table of named events declared in the module. */
map<perm_string,PEvent*>events;
/* The module has a list of generate schemes that appear in /* Keep a table of datum variables declared in the module. */
the module definition. These are used at elaboration time. */ map<hname_t,PData*>datum;
std::list<PGenerate*> generate_schemes;
/* Nested modules are placed here, and are not elaborated map<perm_string,PExpr*> attributes;
unless they are instantiated, implicitly or explicitly. */
std::map<perm_string,Module*> nested_modules;
/* An interface can contain one or more named modport lists. /* These are the timescale for this module. The default is
The parser will ensure these don't appear in modules or set by the `timescale directive. */
program blocks. */ int time_unit, time_precision;
std::map<perm_string,PModport*> modports;
/* List for specify paths and timing checks */ perm_string mod_name() const { return name_; }
std::list<PSpecPath*> specify_paths;
std::list<PTimingCheck*> timing_checks;
// The mod_name() is the name of the module type.
perm_string mod_name() const { return pscope_name(); }
void add_gate(PGate*gate); void add_gate(PGate*gate);
// The add_wire method adds a wire by name, but only if the
// wire name doesn't already exist. Either way, the result is
// the existing wire or the pointer passed in.
PWire* add_wire(PWire*wire);
void add_behavior(PProcess*behave);
void add_task(perm_string name, PTask*def);
void add_function(perm_string name, PFunction*def);
unsigned port_count() const; unsigned port_count() const;
const std::vector<PEIdent*>& get_port(unsigned idx) const; const svector<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) // Find a wire by name. This is used for connecting gates to
perm_string get_port_name(unsigned idx) const; // existing wires, etc.
PWire* get_wire(const hname_t&name) const;
PExpr* get_port_default_value(unsigned idx) const;
PGate* get_gate(perm_string name); PGate* get_gate(perm_string name);
const std::list<PGate*>& get_gates() const; const map<hname_t,PWire*>& get_wires() const;
const list<PGate*>& get_gates() const;
const list<PProcess*>& get_behaviors() const;
void dump(std::ostream&out) const; void dump(ostream&out) const;
bool elaborate(Design*, NetScope*scope) const; bool elaborate(Design*, NetScope*scope) const;
typedef std::map<perm_string,PExpr*> replace_t; bool elaborate_scope(Design*, NetScope*scope) const;
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep);
bool elaborate_sig(Design*, NetScope*scope) const; bool elaborate_sig(Design*, NetScope*scope) const;
SymbolType symbol_type() const override;
bool can_be_toplevel() const;
private: private:
void dump_specparams_(std::ostream&out, unsigned indent) const; perm_string name_;
void dump_timingchecks_(std::ostream&out, unsigned indent) const;
std::list<PGate*> gates_; map<hname_t,PWire*> wires_;
list<PGate*> gates_;
list<PProcess*> behaviors_;
map<perm_string,PTask*> tasks_;
map<perm_string,PFunction*> funcs_;
private: // Not implemented private: // Not implemented
Module(const Module&); Module(const Module&);
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; * $Log: Module.h,v $
}; * Revision 1.37 2004/06/13 04:56:53 steve
* Add support for the default_nettype directive.
extern bool resolve_interface_formal_port(const LineInfo*li, Design*des, *
const Module::port_t*port, * Revision 1.36 2004/05/25 19:21:06 steve
interface_formal_port_t&res, * More identifier lists use perm_strings.
bool emit_errors); *
* Revision 1.35 2004/02/20 18:53:33 steve
#endif /* IVL_Module_H */ * Addtrbute keys are perm_strings.
*
* Revision 1.34 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.33 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.32 2003/06/20 00:53:19 steve
* Module attributes from the parser
* through to elaborated form.
*
* Revision 1.31 2003/06/13 19:10:45 steve
* Properly manage real variables in subscopes.
*
* Revision 1.30 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
* Revision 1.29 2003/02/27 06:45:11 steve
* specparams as far as pform.
*
* Revision 1.28 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
* Revision 1.27 2002/08/19 02:39:16 steve
* Support parameters with defined ranges.
*
* Revision 1.26 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.25 2002/05/19 23:37:28 steve
* Parse port_declaration_lists from the 2001 Standard.
*/
#endif

View File

@ -1,35 +0,0 @@
/*
* Copyright (c) 2012-2019 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 "PClass.h"
PClass::PClass(perm_string name, LexicalScope*parent)
: PScopeExtra(name, parent), type(0)
{
}
PClass::~PClass()
{
}
PNamedItem::SymbolType PClass::symbol_type() const
{
return CLASS;
}

View File

@ -1,49 +0,0 @@
#ifndef IVL_PClass_H
#define IVL_PClass_H
/*
* Copyright (c) 2012-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 "PScope.h"
# include "PNamedItem.h"
# include "StringHeap.h"
# include <iostream>
class PChainConstructor;
/*
* SystemVerilog supports class declarations with their own lexical
* scope, etc. The parser arranges for these to be created and
* collected.
*/
class PClass : public PScopeExtra, public PNamedItem {
public:
explicit PClass (perm_string name, LexicalScope*parent);
~PClass() override;
void dump(std::ostream&out, unsigned indent) const;
SymbolType symbol_type() const override;
public:
class_type_t*type;
};
#endif /* IVL_PClass_H */

View File

@ -15,19 +15,36 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PData.cc,v 1.2 2003/11/10 20:11:01 steve Exp $"
#endif
# include "config.h"
# include "PData.h"
PData::PData(const hname_t&h)
: hname_(h)
{
}
PData::~PData()
{
}
const hname_t&PData::name() const
{
return hname_;
}
/*
* $Log: PData.cc,v $
* Revision 1.2 2003/11/10 20:11:01 steve
* missing include of config.h
*
* Revision 1.1 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
* *
* $Id: timer.v,v 1.1 2003/04/01 05:55:24 stevewilliams Exp $
*/ */
module timer(output wire rdy, input wire clk, input wire reset);
reg [4:0] count;
assign rdy = count[4];
always @(posedge clk or posedge reset)
if (reset)
count <= 5'h0f;
else
count <= count - 1;
endmodule // timer

63
PData.h Normal file
View File

@ -0,0 +1,63 @@
#ifndef __PData_H
#define __PData_H
/*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PData.h,v 1.1 2003/01/26 21:15:58 steve Exp $"
#endif
# include "HName.h"
# include "netlist.h"
# include "LineInfo.h"
/*
* The PData object represents declaration of atomic datum such as
* real and realtime variables. These are variables that cannot be bit
* or part selected, but can be used in expressions.
*/
class PData : public LineInfo {
public:
PData(const hname_t&hname);
~PData();
// Return a hierarchical name.
const hname_t&name() const;
void elaborate_scope(Design*des, NetScope*scope) const;
map<string,PExpr*> attributes;
private:
hname_t hname_;
private:
PData(const PData&);
PData& operator= (const PData&);
};
/*
* $Log: PData.h,v $
* Revision 1.1 2003/01/26 21:15:58 steve
* Rework expression parsing and elaboration to
* accommodate real/realtime values and expressions.
*
*/
#endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1999 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
@ -14,8 +14,11 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: PDelays.cc,v 1.11.2.1 2006/10/04 00:37:03 steve Exp $"
#endif
# include "config.h" # include "config.h"
@ -24,9 +27,6 @@
# include "PDelays.h" # include "PDelays.h"
# include "PExpr.h" # include "PExpr.h"
# include "verinum.h" # include "verinum.h"
# include "netmisc.h"
using namespace std;
PDelays::PDelays() PDelays::PDelays()
{ {
@ -52,134 +52,156 @@ void PDelays::set_delay(PExpr*del)
} }
void PDelays::set_delays(const list<PExpr*>*del, bool df) void PDelays::set_delays(const svector<PExpr*>*del, bool df)
{ {
assert(del); assert(del);
assert(del->size() <= 3); assert(del->count() <= 3);
for (unsigned idx = 0 ; idx < del->count() ; idx += 1)
list<PExpr*>::const_iterator cur = del->begin(); delay_[idx] = (*del)[idx];
for (unsigned idx = 0 ; cur != del->end() ; idx += 1, ++cur)
delay_[idx] = *cur;
delete_flag_ = df; delete_flag_ = df;
} }
unsigned PDelays::delay_count() const static unsigned long calculate_val(Design*des, NetScope*scope,
const PExpr*expr)
{ {
unsigned dly_cnt = 0;
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
if (delay_[idx]) dly_cnt += 1;
return dly_cnt; NetExpr*dex = expr->elaborate_expr(des, scope);
} if (NetExpr*tmp = dex->eval_tree()) {
delete dex;
dex = tmp;
}
static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr) int shift = scope->time_unit() - des->get_precision();
{ if (sizeof(unsigned) <= 4 && shift > 9) {
NetExpr*dex = elab_and_eval(des, scope, expr, -1); cerr << expr->get_line() << ": error: Precision overflow"
<< " in scope " << scope->name() << "." << endl;
check_for_inconsistent_delays(scope); cerr << expr->get_line() << ": :"
<< " Units are 10e" << scope->time_unit()
<< " minus precision 10e" << des->get_precision()
<< " is 10e" << shift << "." << endl;
cerr << expr->get_line() << ": : Perhaps a timescale "
<< "is missing or incorrect?" << endl;
des->errors += 1;
return 0;
}
/* If the delay expression is a real constant or vector /* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time constant, then evaluate it, scale it to the local time
units, and return an adjusted value. */ units, and return an adjusted value. */
if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) { if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
uint64_t delay = get_scaled_time_from_real(des, scope, tmp); verireal fn = tmp->value();
long delay = fn.as_long(shift);
if (delay < 0)
delay = 0;
delete tmp; delete tmp;
NetEConst*tmp2 = new NetEConst(verinum(delay, 64)); return delay;
tmp2->set_line(*expr);
return tmp2;
} }
if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) { if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
verinum fn = tmp->value(); verinum fn = tmp->value();
uint64_t delay = des->scale_to_precision(fn.as_ulong64(), scope);
unsigned long delay =
des->scale_to_precision(fn.as_ulong(), scope);
delete tmp; delete tmp;
NetEConst*tmp2 = new NetEConst(verinum(delay, 64)); return delay;
tmp2->set_line(*expr);
return tmp2;
} }
/* Oops, cannot evaluate down to a constant. */ /* Oops, cannot evaluate down to a constant. Error message. */
return dex; delete dex;
}
static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
{
if (expr == 0)
return 0;
if (dynamic_cast<NetESignal*> (expr))
return expr;
if (dynamic_cast<NetEConst*> (expr))
return expr;
NetNet*sig = expr->synthesize(des, scope, expr);
if (sig == 0) {
cerr << expr->get_fileline() << ": error: Expression " << *expr
<< " is not suitable as a delay expression." << endl;
des->errors += 1;
return 0;
}
expr = new NetESignal(sig);
return expr;
}
static const NetExpr *calc_decay_time(const NetExpr *rise,
const NetExpr *fall)
{
const NetEConst *c_rise = dynamic_cast<const NetEConst*>(rise);
const NetEConst *c_fall = dynamic_cast<const NetEConst*>(fall);
if (c_rise && c_fall) {
if (c_rise->value() < c_fall->value()) return rise;
else return fall;
}
cerr << expr->get_line() << ": sorry: non-constant "
<< "delays not supported here: " << *expr << endl;
des->errors += 1;
return 0; return 0;
} }
void PDelays::eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays, void PDelays::eval_delays(Design*des, NetScope*scope,
bool as_nets_flag) const unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) 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)
rise = make_delay_nets(des, scope, rise);
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)
fall = make_delay_nets(des, scope, fall);
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)
decay = make_delay_nets(des, scope, decay);
delays.decay = decay;
} else { } else {
// If this is zero then we need to do the min() if (rise_time < fall_time)
// at run time. decay_time = rise_time;
delays.decay = calc_decay_time(delays.rise, else
delays.fall); decay_time = fall_time;
} }
} 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;
} }
} }
/*
* $Log: PDelays.cc,v $
* Revision 1.11.2.1 2006/10/04 00:37:03 steve
* Detect delay precision overflow.
*
* Revision 1.11 2003/06/21 01:21:42 steve
* Harmless fixup of warnings.
*
* Revision 1.10 2003/02/08 19:49:21 steve
* Calculate delay statement delays using elaborated
* expressions instead of pre-elaborated expression
* trees.
*
* Remove the eval_pexpr methods from PExpr.
*
* Revision 1.9 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.8 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
* Revision 1.7 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.6 2001/11/07 04:01:59 steve
* eval_const uses scope instead of a string path.
*
* Revision 1.5 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.4 2001/01/20 02:15:50 steve
* apologize for not supporting non-constant delays.
*
* Revision 1.3 2001/01/14 23:04:55 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.2 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
*/

View File

@ -1,7 +1,7 @@
#ifndef IVL_PDelays_H #ifndef __PDelays_H
#define IVL_PDelays_H #define __PDelays_H
/* /*
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2002 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
@ -16,18 +16,25 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: PDelays.h,v 1.7 2002/08/12 01:34:58 steve Exp $"
#endif
# include "svector.h"
# include <string> # include <string>
# include <list>
# include <iostream> # include <iostream>
#ifdef __GNUC__
#if __GNUC__ > 2
using namespace std;
#endif
#endif
class Design; class Design;
class NetScope; class NetScope;
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,
@ -43,14 +50,14 @@ class PDelays {
this object takes ownership of the expressions, and will this object takes ownership of the expressions, and will
delete it in the destructor. */ delete it in the destructor. */
void set_delay(PExpr*); void set_delay(PExpr*);
void set_delays(const std::list<PExpr*>*del, bool delete_flag=true); void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
unsigned delay_count() const; void eval_delays(Design*des, NetScope*scope,
unsigned long&rise_time,
unsigned long&fall_time,
unsigned long&decay_time) const;
void eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays, void dump_delays(ostream&out) const;
bool as_nets_flag =false) const;
void dump_delays(std::ostream&out) const;
private: private:
PExpr* delay_[3]; PExpr* delay_[3];
@ -61,6 +68,30 @@ class PDelays {
PDelays& operator= (const PDelays&); PDelays& operator= (const PDelays&);
}; };
std::ostream& operator << (std::ostream&o, const PDelays&); ostream& operator << (ostream&o, const PDelays&);
#endif /* IVL_PDelays_H */ /*
* $Log: PDelays.h,v $
* Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2002/06/14 03:25:51 steve
* Compiler portability.
*
* Revision 1.5 2001/12/29 20:19:31 steve
* Do not delete delay expressions of UDP instances.
*
* Revision 1.4 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.3 2001/01/16 02:44:17 steve
* Use the iosfwd header if available.
*
* Revision 1.2 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.1 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
*/
#endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004-2024 Stephen Williams (steve@icarus.com) * Copyright (c) 2004 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
@ -14,15 +14,18 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.cc,v 1.5 2004/02/19 06:57:10 steve Exp $"
#endif
# include "config.h" # include "config.h"
# 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)
{ {
} }
@ -35,7 +38,26 @@ perm_string PEvent::name() const
return name_; return name_;
} }
PNamedItem::SymbolType PEvent::symbol_type() const /*
{ * $Log: PEvent.cc,v $
return EVENT; * Revision 1.5 2004/02/19 06:57:10 steve
} * Memory and Event names use perm_string.
*
* Revision 1.4 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.3 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.2 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.1 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
*/

View File

@ -1,7 +1,7 @@
#ifndef IVL_PEvent_H #ifndef __PEvent_H
#define IVL_PEvent_H #define __PEvent_H
/* /*
* Copyright (c) 2000-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2004 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
@ -16,10 +16,13 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: PEvent.h,v 1.9 2004/02/19 06:57:10 steve Exp $"
#endif
# include "PNamedItem.h" # include "LineInfo.h"
# include "StringHeap.h" # include "StringHeap.h"
# include <string> # include <string>
@ -31,29 +34,58 @@ class NetScope;
* are declared in Verilog as ``event foo;'' The name passed to the * are declared in Verilog as ``event foo;'' The name passed to the
* constructor is the "foo" part of the declaration. * constructor is the "foo" part of the declaration.
*/ */
class PEvent : public PNamedItem { class PEvent : public LineInfo {
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;
private: private:
perm_string name_; perm_string name_;
unsigned lexical_pos_;
private: // not implemented private: // not implemented
PEvent(const PEvent&); PEvent(const PEvent&);
PEvent& operator= (const PEvent&); PEvent& operator= (const PEvent&);
}; };
#endif /* IVL_PEvent_H */ /*
* $Log: PEvent.h,v $
* Revision 1.9 2004/02/19 06:57:10 steve
* Memory and Event names use perm_string.
*
* Revision 1.8 2003/03/01 06:25:30 steve
* Add the lex_strings string handler, and put
* scope names and system task/function names
* into this table. Also, permallocate event
* names from the beginning.
*
* Revision 1.7 2003/01/30 16:23:07 steve
* Spelling fixes.
*
* Revision 1.6 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.5 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.4 2001/01/16 02:44:18 steve
* Use the iosfwd header if available.
*
* Revision 1.3 2000/04/09 17:44:30 steve
* Catch event declarations during scope elaborate.
*
* Revision 1.2 2000/04/04 03:20:15 steve
* Simulate named event trigger and waits.
*
* Revision 1.1 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
*/
#endif

647
PExpr.cc
View File

@ -1,6 +1,5 @@
/* /*
* Copyright (c) 1998-2026 Stephen Williams <steve@icarus.com> * Copyright (c) 1998-1999 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
* 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
@ -15,109 +14,45 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: PExpr.cc,v 1.35.2.1 2006/02/07 22:46:23 steve Exp $"
#endif
# include "config.h" # include "config.h"
# include <algorithm>
# include <iostream> # include <iostream>
# include "compiler.h"
# include "PExpr.h" # include "PExpr.h"
# include "PWire.h"
# include "Module.h" # include "Module.h"
# include "ivl_assert.h"
# include "netmisc.h"
# include "util.h"
# include <typeinfo> # include <typeinfo>
using namespace std;
PExpr::PExpr() PExpr::PExpr()
: expr_type_(IVL_VT_NO_TYPE)
{ {
expr_width_ = 0;
min_width_ = 0;
signed_flag_ = false;
} }
PExpr::~PExpr() PExpr::~PExpr()
{ {
} }
void PExpr::declare_implicit_nets(LexicalScope*, NetNet::Type) bool PExpr::is_the_same(const PExpr*that) const
{ {
return typeid(this) == typeid(that);
} }
bool PExpr::has_aa_term(Design*, NetScope*) const bool PExpr::is_constant(Module*) const
{ {
return false; return false;
} }
NetNet* PExpr::elaborate_lnet(Design*, NetScope*, bool) const NetNet* PExpr::elaborate_lnet(Design*des, NetScope*, bool) const
{ {
cerr << get_fileline() << ": error: " cerr << get_line() << ": error: expression not valid in assign l-value: "
<< "expression not valid in assign l-value: " << *this << endl;
<< *this << endl;
return 0; return 0;
} }
NetNet* PExpr::elaborate_bi_net(Design*, NetScope*, bool) const
{
cerr << get_fileline() << ": error: "
<< "expression not valid as argument to inout port: "
<< *this << endl;
return 0;
}
bool PExpr::is_collapsible_net(Design*, NetScope*, NetNet::PortType) const
{
return false;
}
const char* PExpr::width_mode_name(width_mode_t mode)
{
switch (mode) {
case PExpr::SIZED:
return "sized";
case PExpr::UNSIZED:
return "unsized";
case PExpr::EXPAND:
return "expand";
case PExpr::LOSSLESS:
return "lossless";
case PExpr::UPSIZE:
return "upsize";
default:
return "??";
}
}
PEAssignPattern::PEAssignPattern()
{
}
PEAssignPattern::PEAssignPattern(const list<PExpr*>&p)
: parms_(p.begin(), p.end())
{
}
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)
{ {
@ -127,198 +62,39 @@ PEBinary::~PEBinary()
{ {
} }
void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) bool PEBinary::is_constant(Module*mod) const
{ {
if (left_) left_->declare_implicit_nets(scope, type); return left_->is_constant(mod) && right_->is_constant(mod);
if (right_) right_->declare_implicit_nets(scope, type);
} }
bool PEBinary::has_aa_term(Design*des, NetScope*scope) const PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
{ : path_(n), parms_(parms)
ivl_assert(*this, left_ && right_);
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
}
PECastSize::PECastSize(PExpr*si, PExpr*b)
: size_(si), base_(b)
{ {
} }
PECastSize::~PECastSize() PECallFunction::PECallFunction(const hname_t&n)
{ : path_(n)
}
bool PECastSize::has_aa_term(Design *des, NetScope *scope) const
{
return base_->has_aa_term(des, scope);
}
PECastType::PECastType(data_type_t*t, PExpr*b)
: target_(t), base_(b)
{
target_type_ = nullptr;
}
PECastType::~PECastType()
{
}
bool PECastType::has_aa_term(Design *des, NetScope *scope) const
{
return base_->has_aa_term(des, scope);
}
PECastSign::PECastSign(bool signed_flag, PExpr *base)
: base_(base)
{
signed_flag_ = signed_flag;
}
bool PECastSign::has_aa_term(Design *des, NetScope *scope) const
{
return base_->has_aa_term(des, scope);
}
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
l_width_ = 0;
r_width_ = 0;
}
PEBComp::~PEBComp()
{
}
PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
ivl_assert(*this, op == 'a' || op == 'o' || op == 'q' || op == 'Q');
}
PEBLogic::~PEBLogic()
{
}
PEBLeftWidth::PEBLeftWidth(char op, PExpr*l, PExpr*r)
: PEBinary(op, l, r)
{
}
PEBLeftWidth::~PEBLeftWidth()
{
}
PEBPower::PEBPower(char op, PExpr*l, PExpr*r)
: PEBLeftWidth(op, l, r)
{
}
PEBPower::~PEBPower()
{
}
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
: PEBLeftWidth(op, l, r)
{
}
PEBShift::~PEBShift()
{
}
PECallFunction::PECallFunction(const pform_name_t &n, const vector<named_pexpr_t> &parms)
: path_(n), parms_(parms), is_overridden_(false)
{
}
PECallFunction::PECallFunction(PPackage *pkg, const pform_name_t &n, const vector<named_pexpr_t> &parms)
: path_(pkg, n), parms_(parms), is_overridden_(false)
{
}
static pform_name_t pn_from_ps(perm_string n)
{
name_component_t tmp_name (n);
pform_name_t tmp;
tmp.push_back(tmp_name);
return tmp;
}
PECallFunction::PECallFunction(PPackage *pkg, const pform_name_t &n, const list<named_pexpr_t> &parms)
: path_(pkg, n), parms_(parms.begin(), parms.end()), is_overridden_(false)
{
}
PECallFunction::PECallFunction(perm_string n, const vector<named_pexpr_t> &parms)
: path_(pn_from_ps(n)), parms_(parms), is_overridden_(false)
{
}
PECallFunction::PECallFunction(perm_string n)
: path_(pn_from_ps(n)), is_overridden_(false)
{
}
// NOTE: Anachronism. Try to work all use of svector out.
PECallFunction::PECallFunction(const pform_name_t &n, const list<named_pexpr_t> &parms)
: path_(n), parms_(parms.begin(), parms.end()), is_overridden_(false)
{
}
PECallFunction::PECallFunction(perm_string n, const list<named_pexpr_t> &parms)
: path_(pn_from_ps(n)), parms_(parms.begin(), parms.end()), 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)
{ {
} }
PECallFunction::~PECallFunction() PECallFunction::~PECallFunction()
{ {
delete chain_prefix_;
} }
void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) PEConcat::PEConcat(const svector<PExpr*>&p, PExpr*r)
: parms_(p), repeat_(r)
{ {
if (chain_prefix_) { }
chain_prefix_->declare_implicit_nets(scope, type);
} bool PEConcat::is_constant(Module *mod) const
for (const auto &parm : parms_) { {
if (parm.parm) { bool constant = repeat_? repeat_->is_constant(mod) : true;
parm.parm->declare_implicit_nets(scope, type); for (unsigned i = 0; constant && i < parms_.count(); ++i) {
} if (parms_[i] == 0)
continue;
constant = constant && parms_[i]->is_constant(mod);
} }
} return constant;
bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
{
if (chain_prefix_ && chain_prefix_->has_aa_term(des, scope)) {
return true;
}
for (const auto &parm : parms_) {
if (parm.parm && parm.parm->has_aa_term(des, scope)) {
return true;
}
}
return false;
}
PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r)
: parms_(p.begin(), p.end()), width_modes_(SIZED, p.size()), repeat_(r)
{
tested_scope_ = 0;
repeat_count_ = 1;
} }
PEConcat::~PEConcat() PEConcat::~PEConcat()
@ -326,25 +102,6 @@ PEConcat::~PEConcat()
delete repeat_; delete repeat_;
} }
void PEConcat::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
parms_[idx]->declare_implicit_nets(scope, type);
}
}
bool PEConcat::has_aa_term(Design*des, NetScope*scope) const
{
bool flag = false;
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
flag = parms_[idx]->has_aa_term(des, scope) || flag;
}
if (repeat_)
flag = repeat_->has_aa_term(des, scope) || flag;
return flag;
}
PEEvent::PEEvent(PEEvent::edge_t t, PExpr*e) PEEvent::PEEvent(PEEvent::edge_t t, PExpr*e)
: type_(t), expr_(e) : type_(t), expr_(e)
{ {
@ -359,25 +116,11 @@ PEEvent::edge_t PEEvent::type() const
return type_; return type_;
} }
bool PEEvent::has_aa_term(Design*des, NetScope*scope) const
{
ivl_assert(*this, expr_);
return expr_->has_aa_term(des, scope);
}
PExpr* PEEvent::expr() const PExpr* PEEvent::expr() const
{ {
return expr_; return expr_;
} }
PENull::PENull(void)
{
}
PENull::~PENull()
{
}
PEFNumber::PEFNumber(verireal*v) PEFNumber::PEFNumber(verireal*v)
: value_(v) : value_(v)
{ {
@ -393,19 +136,13 @@ const verireal& PEFNumber::value() const
return *value_; return *value_;
} }
PEIdent::PEIdent(const pform_name_t&that, unsigned lexical_pos) bool PEFNumber::is_constant(Module*) const
: path_(that), lexical_pos_(lexical_pos), no_implicit_sig_(false)
{ {
return true;
} }
PEIdent::PEIdent(perm_string s, unsigned lexical_pos, bool no_implicit_sig) PEIdent::PEIdent(const hname_t&s)
: lexical_pos_(lexical_pos), no_implicit_sig_(no_implicit_sig) : path_(s), msb_(0), lsb_(0), idx_(0)
{
path_.name.push_back(name_component_t(s));
}
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that, unsigned lexical_pos)
: path_(pkg, that), lexical_pos_(lexical_pos), no_implicit_sig_(true)
{ {
} }
@ -413,111 +150,42 @@ PEIdent::~PEIdent()
{ {
} }
static bool find_enum_constant(LexicalScope*scope, perm_string name) const hname_t& PEIdent::path() const
{ {
return std::any_of(scope->enum_sets.cbegin(), scope->enum_sets.cend(), return path_;
[name](const enum_type_t *cur) {
return std::any_of(cur->names->cbegin(), cur->names->cend(),
[name](const named_pexpr_t&idx){return idx.name == name;});
});
} }
void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) /*
* An identifier can be in a constant expression if (and only if) it is
* a parameter.
*/
bool PEIdent::is_constant(Module*mod) const
{ {
/* We create an implicit wire if: if (mod == 0) return false;
- this is a simple identifier
- an identifier of that name has not already been declared in
any enclosing scope.
- this is not an implicit named port connection */
if (no_implicit_sig_)
return;
if (path_.package)
return;
if (path_.name.size() == 1 && path_.name.front().index.empty()) {
perm_string name = path_.name.front().name;
LexicalScope*ss = scope;
while (ss) {
if (ss->wires.find(name) != ss->wires.end())
return;
if (ss->parameters.find(name) != ss->parameters.end())
return;
if (ss->genvars.find(name) != ss->genvars.end())
return;
if (ss->events.find(name) != ss->events.end())
return;
if (find_enum_constant(ss, name))
return;
/* Strictly speaking, we should also check for name clashes
with tasks, functions, named blocks, module instances,
and generate blocks. However, this information is not
readily available. As these names would not be legal in
this context, we can declare implicit nets here and rely
on later checks for name clashes to report the error. */
ss = ss->parent_scope(); /* This is a work-around for map not matching < even when
} there is a perm_string operator that can do the comprare.
PWire*net = new PWire(name, lexical_pos_, type, NetNet::NOT_A_PORT);
net->set_file(get_file()); The real fix is to make the path_ carry perm_strings. */
net->set_lineno(get_lineno()); perm_string tmp = perm_string::literal(path_.peek_name(0));
scope->wires[name] = net;
if (warn_implicit) { { map<perm_string,Module::param_expr_t>::const_iterator cur;
cerr << get_fileline() << ": warning: implicit " cur = mod->parameters.find(tmp);
"definition of wire '" << name << "'." << endl; if (cur != mod->parameters.end()) return true;
}
} }
}
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const { map<perm_string,Module::param_expr_t>::const_iterator cur;
{ cur = mod->localparams.find(tmp);
symbol_search_results sr; if (cur != mod->localparams.end()) return true;
if (!symbol_search(this, des, scope, path_, lexical_pos_, &sr)) }
return false;
// Class properties are not considered automatic since a non-blocking return false;
// assignment to an object stored in an automatic variable is supposed to
// capture a reference to the object, not the variable.
if (!sr.path_tail.empty() && sr.net && sr.net->class_type())
return false;
return sr.scope->is_auto();
}
PENewArray::PENewArray(PExpr*size_expr, PExpr*init_expr)
: size_(size_expr), init_(init_expr)
{
}
PENewArray::~PENewArray()
{
delete size_;
}
PENewClass::PENewClass(void)
{
}
PENewClass::PENewClass(const list<named_pexpr_t> &p, data_type_t *class_type)
: parms_(p.begin(), p.end()), class_type_(class_type)
{
}
PENewClass::~PENewClass()
{
}
PENewCopy::PENewCopy(PExpr*src)
: src_(src)
{
}
PENewCopy::~PENewCopy()
{
} }
PENumber::PENumber(verinum*vp) PENumber::PENumber(verinum*vp)
: value_(vp) : value_(vp)
{ {
ivl_assert(*this, vp); assert(vp);
} }
PENumber::~PENumber() PENumber::~PENumber()
@ -530,6 +198,20 @@ const verinum& PENumber::value() const
return *value_; return *value_;
} }
bool PENumber::is_the_same(const PExpr*that) const
{
const PENumber*obj = dynamic_cast<const PENumber*>(that);
if (obj == 0)
return false;
return *value_ == *obj->value_;
}
bool PENumber::is_constant(Module*) const
{
return true;
}
PEString::PEString(char*s) PEString::PEString(char*s)
: text_(s) : text_(s)
{ {
@ -545,6 +227,11 @@ string PEString::value() const
return text_; return text_;
} }
bool PEString::is_constant(Module*) const
{
return true;
}
PETernary::PETernary(PExpr*e, PExpr*t, PExpr*f) PETernary::PETernary(PExpr*e, PExpr*t, PExpr*f)
: expr_(e), tru_(t), fal_(f) : expr_(e), tru_(t), fal_(f)
{ {
@ -554,29 +241,11 @@ PETernary::~PETernary()
{ {
} }
void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) bool PETernary::is_constant(Module*m) const
{
ivl_assert(*this, expr_ && tru_ && fal_);
expr_->declare_implicit_nets(scope, type);
tru_->declare_implicit_nets(scope, type);
fal_->declare_implicit_nets(scope, type);
}
bool PETernary::has_aa_term(Design*des, NetScope*scope) const
{
ivl_assert(*this, expr_ && tru_ && fal_);
return expr_->has_aa_term(des, scope)
|| tru_->has_aa_term(des, scope)
|| fal_->has_aa_term(des, scope);
}
PETypename::PETypename(data_type_t*dt)
: data_type_(dt)
{
}
PETypename::~PETypename()
{ {
return expr_->is_constant(m)
&& tru_->is_constant(m)
&& fal_->is_constant(m);
} }
PEUnary::PEUnary(char op, PExpr*ex) PEUnary::PEUnary(char op, PExpr*ex)
@ -588,22 +257,150 @@ PEUnary::~PEUnary()
{ {
} }
void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) bool PEUnary::is_constant(Module*m) const
{ {
ivl_assert(*this, expr_); return expr_->is_constant(m);
expr_->declare_implicit_nets(scope, type);
} }
bool PEUnary::has_aa_term(Design*des, NetScope*scope) const /*
{ * $Log: PExpr.cc,v $
ivl_assert(*this, expr_); * Revision 1.35.2.1 2006/02/07 22:46:23 steve
return expr_->has_aa_term(des, scope); * More robust test for concat constant-ness.
} *
* Revision 1.35 2004/10/04 01:10:51 steve
* Clean up spurious trailing white space.
*
* Revision 1.34 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*
* Revision 1.33 2003/01/27 05:09:17 steve
* Spelling fixes.
*
* Revision 1.32 2002/11/09 19:20:48 steve
* Port expressions for output ports are lnets, not nets.
*
* Revision 1.31 2002/08/19 02:39:16 steve
* Support parameters with defined ranges.
*
* Revision 1.30 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.29 2001/12/30 21:32:03 steve
* Support elaborate_net for PEString objects.
*
* Revision 1.28 2001/12/03 04:47:14 steve
* Parser and pform use hierarchical names as hname_t
* objects instead of encoded strings.
*
* Revision 1.27 2001/11/08 05:15:50 steve
* Remove string paths from PExpr elaboration.
*
* Revision 1.26 2001/11/07 04:26:46 steve
* elaborate_lnet uses scope instead of string path.
*
* Revision 1.25 2001/11/06 06:11:55 steve
* Support more real arithmetic in delay constants.
*
* Revision 1.24 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.23 2001/01/14 23:04:55 steve
* Generalize the evaluation of floating point delays, and
* get it working with delay assignment statements.
*
* Allow parameters to be referenced by hierarchical name.
*
* Revision 1.22 2001/01/12 04:31:27 steve
* Handle error idents in constants not in any scope (PR#97)
*
* Revision 1.21 2000/12/16 19:03:30 steve
* Evaluate <= and ?: in parameter expressions (PR#81)
*
* Revision 1.20 2000/12/10 22:01:35 steve
* Support decimal constants in behavioral delays.
*
* Revision 1.19 2000/06/30 15:50:20 steve
* Allow unary operators in constant expressions.
*
* Revision 1.18 2000/05/07 04:37:55 steve
* Carry strength values from Verilog source to the
* pform and netlist for gates.
*
* Change vvm constants to use the driver_t to drive
* a constant value. This works better if there are
* multiple drivers on a signal.
*
* Revision 1.17 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move
* $time to that structure and add $random.
*
* Revision 1.16 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent
* objects in the pform,
*
* Handle named events within the mix of net events
* and edges. As a unified lot they get caught together.
* wait statements are broken into more complex statements
* that include a conditional.
*
* Do not generate NetPEvent or NetNEvent objects in
* elaboration. NetEvent, NetEvWait and NetEvProbe
* take over those functions in the netlist.
*
* Revision 1.15 2000/04/01 19:31:57 steve
* Named events as far as the pform.
*
* Revision 1.14 2000/03/12 18:22:11 steve
* Binary and unary operators in parameter expressions.
*
* Revision 1.13 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.12 1999/12/31 17:38:37 steve
* Standardize some of the error messages.
*
* Revision 1.11 1999/10/31 04:11:27 steve
* Add to netlist links pin name and instance number,
* and arrange in vvm for pin connections by name
* and instance number.
*
* Revision 1.10 1999/09/25 02:57:29 steve
* Parse system function calls.
*
* Revision 1.9 1999/09/16 04:18:15 steve
* elaborate concatenation repeats.
*
* Revision 1.8 1999/09/15 04:17:52 steve
* separate assign lval elaboration for error checking.
*
* Revision 1.7 1999/07/22 02:05:20 steve
* is_constant method for PEConcat.
*
* Revision 1.6 1999/07/17 19:50:59 steve
* netlist support for ternary operator.
*
* Revision 1.5 1999/06/16 03:13:29 steve
* More syntax parse with sorry stubs.
*
* Revision 1.4 1999/06/10 04:03:52 steve
* Add support for the Ternary operator,
* Add support for repeat concatenation,
* Correct some seg faults cause by elaboration
* errors,
* Parse the casex anc casez statements.
*
* Revision 1.3 1999/05/16 05:08:42 steve
* Redo constant expression detection to happen
* after parsing.
*
* Parse more operators and expressions.
*
* Revision 1.2 1998/11/11 00:01:51 steve
* Check net ranges in declarations.
*
* Revision 1.1 1998/11/03 23:28:53 steve
* Introduce verilog to CVS.
*
*/
PEVoid::PEVoid()
{
}
PEVoid::~PEVoid()
{
}

1210
PExpr.h

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 1999 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * 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
@ -14,90 +14,65 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: PFunction.cc,v 1.7 2004/05/31 23:34:36 steve Exp $"
#endif
# include "config.h" # include "config.h"
# include "PTask.h"
# include "Statement.h"
# include "ivl_assert.h"
using namespace std; #include "PTask.h"
PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__) PFunction::PFunction(perm_string name)
: PTaskFunc(name, parent), statement_(0) : name_(name), ports_(0), statement_(0)
{ {
is_auto_ = is_auto__; return_type_.type = PTF_NONE;
return_type_ = 0;
} }
PFunction::~PFunction() PFunction::~PFunction()
{ {
} }
void PFunction::set_ports(svector<PWire *>*p)
{
assert(ports_ == 0);
ports_ = p;
}
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;
} }
void PFunction::push_statement_front(Statement*stmt) void PFunction::set_return(PTaskFuncArg t)
{
// This should not be possible.
ivl_assert(*this, statement_);
// Get the PBlock of the statement. If it is not a PBlock,
// then create one to wrap the existing statement and the new
// statement that we're pushing.
PBlock*blk = dynamic_cast<PBlock*> (statement_);
if (blk == 0) {
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
tmp->set_line(*this);
vector<Statement*>tmp_list(1);
tmp_list[0] = statement_;
tmp->set_statement(tmp_list);
statement_ = tmp;
blk = tmp;
}
// Now do the push.
blk->push_statement_front(stmt);
}
void PFunction::set_return(data_type_t*t)
{ {
return_type_ = t; return_type_ = t;
} }
PChainConstructor* PFunction::extract_chain_constructor() /*
{ * $Log: PFunction.cc,v $
PChainConstructor*res = 0; * Revision 1.7 2004/05/31 23:34:36 steve
* Rewire/generalize parsing an elaboration of
if ((res = dynamic_cast<PChainConstructor*> (statement_))) { * function return values to allow for better
statement_ = new PBlock(PBlock::BL_SEQ); * speed and more type support.
statement_->set_line(*this); *
* Revision 1.6 2002/08/12 01:34:58 steve
} else if (PBlock*blk = dynamic_cast<PBlock*>(statement_)) { * conditional ident string using autoconfig.
res = blk->extract_chain_constructor(); *
} * Revision 1.5 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
return res; * junk, and support gcc 3.0. (Stephan Boettcher)
} *
* Revision 1.4 2001/01/13 22:20:08 steve
PNamedItem::SymbolType PFunction::symbol_type() const * Parse parameters within nested scopes.
{ *
return FUNCTION; * Revision 1.3 2000/02/23 02:56:53 steve
} * Macintosh compilers do not support ident.
*
* Revision 1.2 1999/08/25 22:22:41 steve
PLet::PLet(perm_string name, LexicalScope*parent, list<let_port_t*>*ports, * elaborate some aspects of functions.
PExpr*expr) *
: PTaskFunc(name, parent), ports_(ports), expr_(expr) */
{
}
PLet::~PLet()
{
}

305
PGate.cc
View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2004 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
@ -14,70 +14,68 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGate.cc,v 1.16 2004/02/18 17:11:54 steve Exp $"
#endif
# include "config.h" # include "config.h"
# include "PGate.h" # include "PGate.h"
# include "PExpr.h" # include "PExpr.h"
# include "verinum.h" # include "verinum.h"
# include "ivl_assert.h" # include <assert.h>
using namespace std; PGate::PGate(perm_string name,
svector<PExpr*>*pins,
void PGate::set_pins_(list<PExpr*>*pins) const svector<PExpr*>*del)
: name_(name), pins_(pins)
{ {
ivl_assert(*this, pins);
ivl_assert(*this, pins->size() == pins_.size());
for (size_t idx = 0 ; idx < pins_.size() ; idx += 1) {
pins_[idx] = pins->front();
pins->pop_front();
}
ivl_assert(*this, pins->empty());
delete pins;
}
PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr)
{
if (pins) set_pins_(pins);
if (del) delay_.set_delays(del); if (del) delay_.set_delays(del);
str0_ = STRONG;
str1_ = STRONG;
} }
PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del) PGate::PGate(perm_string name,
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr) svector<PExpr*>*pins,
PExpr*del)
: name_(name), pins_(pins)
{ {
if (pins) set_pins_(pins);
if (del) delay_.set_delay(del); if (del) delay_.set_delay(del);
str0_ = STRONG;
str1_ = STRONG;
} }
PGate::PGate(perm_string name, list<PExpr*>*pins) PGate::PGate(perm_string name, svector<PExpr*>*pins)
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr) : name_(name), pins_(pins)
{ {
if (pins) set_pins_(pins); str0_ = STRONG;
str1_ = STRONG;
} }
PGate::~PGate() PGate::~PGate()
{ {
} }
void PGate::set_ranges(list<pform_range_t>*ranges) PGate::strength_t PGate::strength0() const
{ {
ivl_assert(*this, ranges_ == 0); return str0_;
ranges_ = ranges;
} }
drive_strength_t PGate::strength() const void PGate::strength0(PGate::strength_t s)
{ {
return strength_; str0_ = s;
} }
void PGate::strength(const drive_strength_t &str) PGate::strength_t PGate::strength1() const
{ {
strength_ = str; return str1_;
}
void PGate::strength1(PGate::strength_t s)
{
str1_ = s;
} }
void PGate::elaborate_scope(Design*, NetScope*) const void PGate::elaborate_scope(Design*, NetScope*) const
@ -92,33 +90,24 @@ void PGate::elaborate_scope(Design*, NetScope*) const
* parameters. This method understands how to handle the different * parameters. This method understands how to handle the different
* numbers of expressions. * numbers of expressions.
*/ */
void PGate::eval_delays(Design*des, NetScope*scope,
void PGate::eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays, unsigned long&rise_time,
bool as_net_flag) const unsigned long&fall_time,
unsigned long&decay_time) const
{ {
delay_.eval_delays(des, scope, delays, as_net_flag); delay_.eval_delays(des, scope, rise_time, fall_time, decay_time);
} }
unsigned PGate::delay_count() const PGAssign::PGAssign(svector<PExpr*>*pins)
{
return delay_.delay_count();
}
PNamedItem::SymbolType PGate::symbol_type() const
{
return INSTANCE;
}
PGAssign::PGAssign(list<PExpr*>*pins)
: PGate(perm_string(), pins) : PGate(perm_string(), pins)
{ {
ivl_assert(*this, pin_count() == 2); assert(pins->count() == 2);
} }
PGAssign::PGAssign(list<PExpr*>*pins, list<PExpr*>*dels) PGAssign::PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels)
: PGate(perm_string(), pins, dels) : PGate(perm_string(), pins, dels)
{ {
ivl_assert(*this, pin_count() == 2); assert(pins->count() == 2);
} }
PGAssign::~PGAssign() PGAssign::~PGAssign()
@ -126,16 +115,16 @@ PGAssign::~PGAssign()
} }
PGBuiltin::PGBuiltin(Type t, perm_string name, PGBuiltin::PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins, svector<PExpr*>*pins,
const list<PExpr*>*del) svector<PExpr*>*del)
: PGate(name, pins, del), type_(t) : PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
{ {
} }
PGBuiltin::PGBuiltin(Type t, perm_string name, PGBuiltin::PGBuiltin(Type t, perm_string name,
list<PExpr*>*pins, svector<PExpr*>*pins,
PExpr*del) PExpr*del)
: PGate(name, pins, del), type_(t) : PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
{ {
} }
@ -144,142 +133,118 @@ PGBuiltin::~PGBuiltin()
{ {
} }
const char* PGBuiltin::gate_name() const void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
{ {
switch(type_) { assert(msb_ == 0);
case AND: assert(lsb_ == 0);
return "AND";
break;
case NAND:
return "NAND";
break;
case OR: msb_ = msb;
return "OR"; lsb_ = lsb;
break;
case NOR:
return "NOR";
break;
case XOR:
return "XOR";
break;
case XNOR:
return "XNOR";
break;
case BUF:
return "BUF";
break;
case NOT:
return "NOT";
break;
case BUFIF0:
return "BUFIF0";
break;
case NOTIF0:
return "NOTIF0";
break;
case BUFIF1:
return "BUFIF1";
break;
case NOTIF1:
return "NOTIF1";
break;
case NMOS:
return "NMOS";
break;
case RNMOS:
return "RNMOS";
break;
case PMOS:
return "PMOS";
break;
case RPMOS:
return "RPMOS";
break;
case TRAN:
return "TRAN";
break;
case RTRAN:
return "RTRAN";
break;
case TRANIF0:
return "TRANIF0";
break;
case RTRANIF0:
return "RTRANIF0";
break;
case TRANIF1:
return "TRANIF1";
break;
case RTRANIF1:
return "RTRANIF1";
break;
case CMOS:
return "CMOS";
break;
case RCMOS:
return "RCMOS";
break;
case PULLUP:
return "PULLUP";
break;
case PULLDOWN:
return "PULLDOWN";
break;
}
return "<unknown>";
} }
PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins) PGModule::PGModule(perm_string type, perm_string name, svector<PExpr*>*pins)
: PGate(name, pins), bound_type_(0), type_(type), overrides_(0), pins_(0), : PGate(name, pins), overrides_(0), pins_(0),
npins_(0), parms_(0), nparms_(0) npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
{ {
type_ = type;
} }
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), overrides_(0), pins_(pins),
npins_(npins), parms_(0), nparms_(0) npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
{
}
PGModule::PGModule(Module*type, perm_string name)
: PGate(name, 0), bound_type_(type), overrides_(0), pins_(0),
npins_(0), parms_(0), nparms_(0)
{ {
type_ = type;
} }
PGModule::~PGModule() PGModule::~PGModule()
{ {
} }
void PGModule::set_parameters(list<PExpr*>*o) void PGModule::set_parameters(svector<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;
} }
perm_string PGModule::get_type() const void PGModule::set_range(PExpr*msb, PExpr*lsb)
{
assert(msb_ == 0);
assert(lsb_ == 0);
msb_ = msb;
lsb_ = lsb;
}
perm_string PGModule::get_type()
{ {
return type_; return type_;
} }
/*
* $Log: PGate.cc,v $
* Revision 1.16 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.15 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
* Revision 1.14 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.13 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.12 2001/10/21 00:42:47 steve
* Module types in pform are char* instead of string.
*
* Revision 1.11 2001/10/19 01:55:32 steve
* Method to get the type_ member
*
* Revision 1.10 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.9 2000/05/06 15:41:56 steve
* Carry assignment strength to pform.
*
* Revision 1.8 2000/03/08 04:36:53 steve
* Redesign the implementation of scopes and parameters.
* I now generate the scopes and notice the parameters
* in a separate pass over the pform. Once the scopes
* are generated, I can process overrides and evalutate
* paremeters before elaboration begins.
*
* Revision 1.7 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.6 2000/02/18 05:15:02 steve
* Catch module instantiation arrays.
*
* Revision 1.5 1999/09/14 01:50:35 steve
* Handle gates without delays.
*
* Revision 1.4 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
* Revision 1.3 1999/08/01 21:18:55 steve
* elaborate rise/fall/decay for continuous assign.
*
* Revision 1.2 1999/08/01 16:34:50 steve
* Parse and elaborate rise/fall/decay times
* for gates, and handle the rules for partial
* lists of times.
*
* Revision 1.1 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
*/

306
PGate.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PGate_H #ifndef __PGate_H
#define IVL_PGate_H #define __PGate_H
/* /*
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2004 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
@ -16,23 +16,24 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: PGate.h,v 1.29 2004/10/04 01:10:52 steve Exp $"
#endif
# include "svector.h"
# include "StringHeap.h" # include "StringHeap.h"
# include "named.h" # include "named.h"
# include "PNamedItem.h" # include "LineInfo.h"
# include "PDelays.h" # include "PDelays.h"
# include "netlist.h"
# include <map> # include <map>
# include <list>
# include <vector>
# include <string> # include <string>
class PExpr; class PExpr;
class PUdp; class PUdp;
class Design;
class NetScope;
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
@ -48,67 +49,56 @@ struct drive_strength_t;
* single strength pair. There is a strength of the 0 drive, and a * single strength pair. There is a strength of the 0 drive, and a
* strength of the 1 drive. * strength of the 1 drive.
*/ */
class PGate : public PNamedItem { class PGate : public LineInfo {
public: public:
explicit PGate(perm_string name, std::list<PExpr*>*pins, enum strength_t { HIGHZ, WEAK, PULL, STRONG, SUPPLY };
const std::list<PExpr*>*del);
explicit PGate(perm_string name, std::list<PExpr*>*pins, explicit PGate(perm_string name, svector<PExpr*>*pins,
const svector<PExpr*>*del);
explicit PGate(perm_string name, svector<PExpr*>*pins,
PExpr*del); PExpr*del);
explicit PGate(perm_string name, std::list<PExpr*>*pins); explicit PGate(perm_string name, svector<PExpr*>*pins);
virtual ~PGate() override; virtual ~PGate();
void set_ranges(std::list<pform_range_t>*ranges);
bool is_array() const { return ranges_ != 0; }
perm_string get_name() const { return name_; } perm_string get_name() const { return name_; }
// This evaluates the delays as far as possible, but returns void eval_delays(Design*des, NetScope*scope,
// an expression, and do not signal errors. unsigned long&rise_time,
void eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays, unsigned long&fall_time,
bool as_net_flag =false) const; unsigned long&decay_time) const;
unsigned delay_count() const; unsigned pin_count() const { return pins_? pins_->count() : 0; }
const PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
unsigned pin_count() const { return pins_.size(); } strength_t strength0() const;
PExpr*pin(unsigned idx) const { return pins_[idx]; } strength_t strength1() const;
drive_strength_t strength() const; void strength0(strength_t);
void strength1(strength_t);
void strength(const drive_strength_t &str); map<perm_string,PExpr*> attributes;
std::map<perm_string,PExpr*> attributes; virtual void dump(ostream&out) const;
virtual void dump(std::ostream&out, unsigned ind =4) const;
virtual void elaborate(Design*des, NetScope*scope) const; virtual void elaborate(Design*des, NetScope*scope) const;
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;
protected: protected:
const std::vector<PExpr*>& get_pins() const { return pins_; } const svector<PExpr*>& get_pins() const { return *pins_; }
unsigned calculate_array_size_(Design*, NetScope*, void dump_pins(ostream&out) const;
long&high, long&low) const; void dump_delays(ostream&out) const;
void dump_pins(std::ostream&out) const;
void dump_delays(std::ostream&out) const;
void dump_ranges(std::ostream&out) const;
private: private:
perm_string name_; perm_string name_;
PDelays delay_; PDelays delay_;
std::vector<PExpr*>pins_; svector<PExpr*>*pins_;
std::list<pform_range_t>*ranges_; strength_t str0_, str1_;
drive_strength_t strength_;
void set_pins_(std::list<PExpr*>*pins);
private: // not implemented private: // not implemented
PGate(const PGate&); PGate(const PGate&);
@ -122,17 +112,14 @@ class PGate : public PNamedItem {
class PGAssign : public PGate { class PGAssign : public PGate {
public: public:
explicit PGAssign(std::list<PExpr*>*pins); explicit PGAssign(svector<PExpr*>*pins);
explicit PGAssign(std::list<PExpr*>*pins, std::list<PExpr*>*dels); explicit PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels);
~PGAssign() override; ~PGAssign();
void dump(std::ostream&out, unsigned ind =4) const override; void dump(ostream&out) const;
virtual void elaborate(Design*des, NetScope*scope) const override; virtual void elaborate(Design*des, NetScope*scope) const;
private: private:
void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval,
const drive_strength_t &drive,
const delay_exprs_t &delays) const;
}; };
@ -156,30 +143,24 @@ class PGBuiltin : public PGate {
public: public:
explicit PGBuiltin(Type t, perm_string name, explicit PGBuiltin(Type t, perm_string name,
std::list<PExpr*>*pins, svector<PExpr*>*pins,
const std::list<PExpr*>*del); svector<PExpr*>*del);
explicit PGBuiltin(Type t, perm_string name, explicit PGBuiltin(Type t, perm_string name,
std::list<PExpr*>*pins, svector<PExpr*>*pins,
PExpr*del); PExpr*del);
~PGBuiltin() override; ~PGBuiltin();
Type type() const { return type_; } Type type() const { return type_; }
const char * gate_name() const; void set_range(PExpr*msb, PExpr*lsb);
virtual void dump(std::ostream&out, unsigned ind =4) const override; virtual void dump(ostream&out) const;
virtual void elaborate(Design*, NetScope*scope) const override; virtual void elaborate(Design*, NetScope*scope) const;
private: private:
void calculate_gate_and_lval_count_(unsigned&gate_count,
unsigned&lval_count) const;
NetNode* create_gate_for_output_(Design*, NetScope*,
perm_string gate_name,
unsigned instance_width) const;
bool check_delay_count(Design*des) const;
Type type_; Type type_;
PExpr*msb_;
PExpr*lsb_;
}; };
/* /*
@ -196,67 +177,174 @@ class PGModule : public PGate {
// If the binding of ports is by position, this constructor // If the binding of ports is by position, this constructor
// builds everything all at once. // builds everything all at once.
explicit PGModule(perm_string type, perm_string name, explicit PGModule(perm_string type, perm_string name,
std::list<PExpr*>*pins); svector<PExpr*>*pins);
// If the binding of ports is by name, this constructor takes // 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
// constructor.
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(svector<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; // Modules can be instantiated in ranges. The parser uses this
virtual void elaborate(Design*, NetScope*scope) const override; // method to pass the range to the pform.
virtual void elaborate_scope(Design*des, NetScope*sc) const override; void set_range(PExpr*msb, PExpr*lsb);
virtual bool elaborate_sig(Design*des, NetScope*scope) const override;
virtual void dump(ostream&out) const;
virtual void elaborate(Design*, NetScope*scope) const;
virtual void elaborate_scope(Design*des, NetScope*sc) const;
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
// This returns the module name of this module. It is a // This returns the module name of this module. It is a
// permallocated string. // permallocated string.
perm_string get_type() const; perm_string get_type();
private: private:
Module*bound_type_;
perm_string type_; perm_string type_;
std::list<PExpr*>*overrides_; svector<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; // Arrays of modules are give if these are set.
void elaborate_mod_(Design*, const Module*mod, NetScope*scope) const; PExpr*msb_;
PExpr*lsb_;
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; bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
bool elaborate_sig_mod_(Design*des, NetScope*scope, const 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.
#if 0
bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const;
#endif
NetNet*resize_net_to_port_(Design*des, NetScope*scope,
NetNet*sig, unsigned port_wid,
NetNet::PortType dir, bool as_signed) const;
}; };
#endif /* IVL_PGate_H */ /*
* $Log: PGate.h,v $
* Revision 1.29 2004/10/04 01:10:52 steve
* Clean up spurious trailing white space.
*
* Revision 1.28 2004/03/08 00:47:44 steve
* primitive ports can bind bi name.
*
* Revision 1.27 2004/02/20 18:53:33 steve
* Addtrbute keys are perm_strings.
*
* Revision 1.26 2004/02/18 17:11:54 steve
* Use perm_strings for named langiage items.
*
* Revision 1.25 2003/03/06 04:37:12 steve
* lex_strings.add module names earlier.
*
* Revision 1.24 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.23 2002/05/23 03:08:51 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute
* handling, and add number and void value types.
*
* Add to the ivl_target API new functions for access
* of complex attributes attached to gates.
*
* Revision 1.22 2001/11/22 06:20:59 steve
* Use NetScope instead of string for scope path.
*
* Revision 1.21 2001/10/21 00:42:47 steve
* Module types in pform are char* instead of string.
*
* Revision 1.20 2001/10/19 01:55:32 steve
* Method to get the type_ member
*
* Revision 1.19 2001/04/22 23:09:45 steve
* More UDP consolidation from Stephan Boettcher.
*
* Revision 1.18 2000/05/06 15:41:56 steve
* Carry assignment strength to pform.
*
* Revision 1.17 2000/05/02 16:27:38 steve
* Move signal elaboration to a seperate pass.
*
* Revision 1.16 2000/03/29 04:37:10 steve
* New and improved combinational primitives.
*
* Revision 1.15 2000/03/08 04:36:53 steve
* Redesign the implementation of scopes and parameters.
* I now generate the scopes and notice the parameters
* in a separate pass over the pform. Once the scopes
* are generated, I can process overrides and evalutate
* paremeters before elaboration begins.
*
* Revision 1.14 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.13 2000/02/18 05:15:02 steve
* Catch module instantiation arrays.
*
* Revision 1.12 2000/01/09 05:50:48 steve
* Support named parameter override lists.
*
* Revision 1.11 1999/12/11 05:45:41 steve
* Fix support for attaching attributes to primitive gates.
*
* Revision 1.10 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
* Revision 1.9 1999/08/23 16:48:39 steve
* Parameter overrides support from Peter Monta
* AND and XOR support wide expressions.
*
* Revision 1.8 1999/08/01 21:18:55 steve
* elaborate rise/fall/decay for continuous assign.
*
* Revision 1.7 1999/08/01 16:34:50 steve
* Parse and elaborate rise/fall/decay times
* for gates, and handle the rules for partial
* lists of times.
*
* Revision 1.6 1999/05/29 02:36:17 steve
* module parameter bind by name.
*
* Revision 1.5 1999/05/10 00:16:58 steve
* Parse and elaborate the concatenate operator
* in structural contexts, Replace vector<PExpr*>
* and list<PExpr*> with svector<PExpr*>, evaluate
* constant expressions with parameters, handle
* memories as lvalues.
*
* Parse task declarations, integer types.
*
* Revision 1.4 1999/02/15 02:06:15 steve
* Elaborate gate ranges.
*
* Revision 1.3 1999/01/25 05:45:56 steve
* Add the LineInfo class to carry the source file
* location of things. PGate, Statement and PProcess.
*
* elaborate handles module parameter mismatches,
* missing or incorrect lvalues for procedural
* assignment, and errors are propogated to the
* top of the elaboration call tree.
*
* Attach line numbers to processes, gates and
* assignment statements.
*
* Revision 1.2 1998/12/01 00:42:13 steve
* Elaborate UDP devices,
* Support UDP type attributes, and
* pass those attributes to nodes that
* are instantiated by elaboration,
* Put modules into a map instead of
* a simple list.
*
* Revision 1.1 1998/11/03 23:28:54 steve
* Introduce verilog to CVS.
*
*/
#endif

View File

@ -1,77 +0,0 @@
/*
* Copyright (c) 2006-2021 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 "PGenerate.h"
# include "PWire.h"
# include "ivl_assert.h"
using namespace std;
PGenerate::PGenerate(LexicalScope*parent, unsigned id)
: LexicalScope(parent), id_number(id)
{
scheme_type = GS_NONE;
directly_nested = false;
local_index = false;
loop_init = 0;
loop_test = 0;
loop_step = 0;
}
PGenerate::~PGenerate()
{
}
void PGenerate::add_gate(PGate*gate)
{
gates.push_back(gate);
}
ostream& operator << (ostream&out, PGenerate::scheme_t type)
{
switch (type) {
case PGenerate::GS_NONE:
out << "GS_NONE";
break;
case PGenerate::GS_LOOP:
out << "GS_LOOP";
break;
case PGenerate::GS_CONDIT:
out << "GS_CONDIT";
break;
case PGenerate::GS_ELSE:
out << "GS_ELSE";
break;
case PGenerate::GS_CASE:
out << "GS_CASE";
break;
case PGenerate::GS_CASE_ITEM:
out << "GS_CASE_ITEM";
break;
case PGenerate::GS_NBLOCK:
out << "GS_NBLOCK";
break;
}
return out;
}
PNamedItem::SymbolType PGenerate::symbol_type() const
{
return GENBLOCK;
}

View File

@ -1,147 +0,0 @@
#ifndef IVL_PGenerate_H
#define IVL_PGenerate_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 "PNamedItem.h"
# include "StringHeap.h"
# include "HName.h"
# include "PScope.h"
# include <list>
# include <map>
# include <valarray>
# include <vector>
# include "pform_types.h"
class Design;
class NetScope;
class PClass;
class PExpr;
class PFunction;
class PProcess;
class PTask;
class PGate;
class PWire;
/*
* This represents a generate scheme. The interpretation of the
* members depends on the scheme_type.
*
* GS_LOOP
*
* GS_CASE
* loop_test is the expression to be compared.
* generates contains only GS_CASE_ITEM schemes.
* GS_CASE_ITEM
* The parent points to the GS_CASE that contains this item.
* the loop_test is compared with the parent->loop_test expression.
*/
class PGenerate : public PNamedItem, public LexicalScope {
public:
explicit PGenerate(LexicalScope*parent, unsigned id_number);
~PGenerate() override;
// Generate schemes have an ID number, for when the scope is
// implicit.
const unsigned id_number;
perm_string scope_name;
// This is used during parsing to stack lexical scopes within
// this generate scheme.
// LexicalScope*lexical_scope;
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE,
GS_CASE, GS_CASE_ITEM, GS_NBLOCK};
scheme_t scheme_type;
bool directly_nested;
// generate loops have an index variable and three
// expressions: for (index = <init>; <test>; index=<step>)
// the index is local if it was declared in the init expression,
// e.g. for (genvar index = <init>; <test>; index=<step>)
bool local_index;
perm_string loop_index;
PExpr*loop_init;
PExpr*loop_test;
PExpr*loop_step;
// Case items may have multiple guard expression values. It is
// enough for any on of the guards to match the case statement
// test value.
std::valarray<PExpr*> item_test;
// defparam assignments found in this scope.
typedef std::pair<pform_name_t,PExpr*> named_expr_t;
std::list<named_expr_t>defparms;
std::list<PGate*> gates;
void add_gate(PGate*);
// Definitions instantiated within this scheme.
std::map<perm_string,PTask*> tasks;
std::map<perm_string,PFunction*>funcs;
std::map<perm_string,PClass*> classes;
std::vector<PClass*> classes_lexical;
// Generate schemes can contain further generate schemes.
std::list<PGenerate*> generate_schemes;
// PGenerate*parent;
// This method is called by the elaboration of a module to
// generate scopes. the container is the scope that is to
// contain the generated scope.
bool generate_scope(Design*des, NetScope*container);
// Elaborate signals within any of the generated scopes that
// were made by this generate block within the given container scope.
bool elaborate_sig(Design*des, NetScope*container) const;
bool elaborate(Design*des, NetScope*container) const;
void dump(std::ostream&out, unsigned indent) const;
SymbolType symbol_type() const override;
private:
void check_for_valid_genvar_value_(long value);
bool generate_scope_loop_(Design*des, NetScope*container);
bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag);
bool generate_scope_case_(Design*des, NetScope*container);
bool generate_scope_nblock_(Design*des, NetScope*container);
// Elaborate_scope within a generated scope.
void elaborate_subscope_(Design*des, NetScope*scope);
void elaborate_subscope_direct_(Design*des, NetScope*scope);
// These are the scopes created by generate_scope.
std::list<NetScope*>scope_list_;
// internal function called on each scope generated by this scheme.
bool elaborate_sig_(Design*des, NetScope*scope) const;
bool elaborate_sig_direct_(Design*des, NetScope*scope) const;
bool elaborate_(Design*des, NetScope*scope) const;
bool elaborate_direct_(Design*des, NetScope*scope) const;
private: // not implemented
PGenerate(const PGenerate&);
PGenerate& operator= (const PGenerate&);
};
extern std::ostream& operator << (std::ostream&, PGenerate::scheme_t);
#endif /* IVL_PGenerate_H */

View File

@ -1,36 +0,0 @@
/*
* Copyright (c) 2015-2019 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "config.h"
# include "PModport.h"
PModport::PModport(perm_string n)
: name_(n)
{
}
PModport::~PModport()
{
}
PNamedItem::SymbolType PModport::symbol_type() const
{
return MODPORT;
}

View File

@ -1,54 +0,0 @@
#ifndef IVL_PModport_H
#define IVL_PModport_H
/*
* Copyright (c) 2015-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 "PNamedItem.h"
# include "PScope.h"
# include "StringHeap.h"
# include "netlist.h"
# include <vector>
/*
* The PModport class represents a parsed SystemVerilog modport list.
*/
class PModport : public PNamedItem {
public:
// The name is a perm-allocated string. It is the simple name
// of the modport, without any scope.
explicit PModport(perm_string name);
~PModport() override;
perm_string name() const { return name_; }
typedef std::pair <NetNet::PortType,PExpr*> simple_port_t;
std::map<perm_string,simple_port_t> simple_ports;
SymbolType symbol_type() const override;
private:
perm_string name_;
private: // not implemented
PModport(const PModport&);
PModport& operator= (const PModport&);
};
#endif /* IVL_PModport_H */

View File

@ -1,116 +0,0 @@
/*
* Copyright (c) 2019 Martin Whitaker (icarus@martin-whitaker.me.uk)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "PNamedItem.h"
# include <ostream>
PNamedItem::PNamedItem()
{
}
PNamedItem::~PNamedItem()
{
}
PNamedItem::SymbolType PNamedItem::symbol_type() const
{
return ANY;
}
std::ostream& operator << (std::ostream&o, PNamedItem::SymbolType st)
{
switch (st) {
case PNamedItem::ANY:
o << "a symbol";
break;
case PNamedItem::PARAM:
o << "a parameter";
break;
case PNamedItem::NET:
o << "a net";
break;
case PNamedItem::VAR:
o << "a variable";
break;
case PNamedItem::GENVAR:
o << "a genvar";
break;
case PNamedItem::EVENT:
o << "an event";
break;
case PNamedItem::TYPE:
o << "a type";
break;
case PNamedItem::ENUM:
o << "an enum type or value";
break;
case PNamedItem::CLASS:
o << "a class";
break;
case PNamedItem::FUNCTION:
o << "a function";
break;
case PNamedItem::TASK:
o << "a task";
break;
case PNamedItem::BLOCK:
o << "a named block";
break;
case PNamedItem::GENBLOCK:
o << "a generate block";
break;
case PNamedItem::MODPORT:
o << "a modport";
break;
case PNamedItem::PACKAGE:
o << "a package";
break;
case PNamedItem::MODULE:
o << "a module";
break;
case PNamedItem::PROGRAM:
o << "a program";
break;
case PNamedItem::INTERFACE:
o << "an interface";
break;
case PNamedItem::PRIMITIVE:
o << "a primitive";
break;
case PNamedItem::INSTANCE:
o << "an instance name";
break;
default:
break;
}
return o;
}
PGenvar::PGenvar()
{
}
PGenvar::~PGenvar()
{
}
PNamedItem::SymbolType PGenvar::symbol_type() const
{
return GENVAR;
}

View File

@ -1,57 +0,0 @@
#ifndef IVL_PNamedItem_H
#define IVL_PNamedItem_H
/*
* Copyright (c) 2019-2025 Martin Whitaker (icarus@martin-whitaker.me.uk)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "LineInfo.h"
/*
* The PNamedItem class is the base class for all items that can be added
* to a scope's local symbol map.
*/
class PNamedItem : virtual public LineInfo {
public:
enum SymbolType { ANY, PARAM, NET, VAR, GENVAR, EVENT, TYPE, ENUM,
CLASS, FUNCTION, TASK, BLOCK, GENBLOCK, MODPORT,
PACKAGE, MODULE, PROGRAM, INTERFACE, PRIMITIVE,
INSTANCE };
explicit PNamedItem();
virtual ~PNamedItem() override;
virtual SymbolType symbol_type() const;
};
extern std::ostream& operator << (std::ostream&, PNamedItem::SymbolType);
/*
* The PGenvar class represents a genvar. This is only used to represent
* genvar in a scope's local symbol map.
*/
class PGenvar : public PNamedItem {
public:
explicit PGenvar();
virtual ~PGenvar() override;
SymbolType symbol_type() const override;
};
#endif /* IVL_PNamedItem_H */

View File

@ -1,30 +0,0 @@
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / 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 "PPackage.h"
PPackage::PPackage(perm_string name, LexicalScope*parent)
: PScopeExtra(name, parent)
{
}
PPackage::~PPackage()
{
}

View File

@ -1,55 +0,0 @@
#ifndef IVL_PPackage_H
#define IVL_PPackage_H
/*
* Copyright (c) 2012-2025 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / 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 "PScope.h"
# include "LineInfo.h"
# include "StringHeap.h"
# include <iostream>
# include <vector>
/*
* SystemVerilog supports class declarations with their own lexical
* scope, etc. The parser arranges for these to be created and
* collected.
*/
class PPackage : public PScopeExtra, public LineInfo {
public:
explicit PPackage (perm_string name, LexicalScope*parent);
~PPackage() override;
bool elaborate_scope(Design*des, NetScope*scope);
bool elaborate_sig(Design*des, NetScope*scope) const;
bool elaborate(Design*des, NetScope*scope) const;
void pform_dump(std::ostream&out) const;
struct export_t {
PPackage *pkg;
perm_string name;
};
std::vector<export_t> exports;
};
#endif /* IVL_PPackage_H */

View File

@ -1,68 +0,0 @@
/*
* Copyright (c) 2008-2021 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 "PScope.h"
using namespace std;
bool LexicalScope::var_init_needs_explicit_lifetime() const
{
return false;
}
PWire* LexicalScope::wires_find(perm_string name)
{
map<perm_string,PWire*>::const_iterator cur = wires.find(name);
if (cur == wires.end())
return 0;
else
return (*cur).second;
}
PNamedItem::SymbolType LexicalScope::param_expr_t::symbol_type() const
{
return PARAM;
}
PScope::PScope(perm_string n, LexicalScope*parent)
: LexicalScope(parent), name_(n)
{
time_unit = 0;
time_precision = 0;
time_unit_is_default = true;
time_prec_is_default = true;
}
PScope::~PScope()
{
for(typedef_map_t::iterator it = typedefs.begin(); it != typedefs.end();
++it)
delete it->second;
}
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
: PScope(n, parent)
{
time_unit_is_local = false;
time_prec_is_local = false;
}
PScopeExtra::~PScopeExtra()
{
}

259
PScope.h
View File

@ -1,259 +0,0 @@
#ifndef IVL_PScope_H
#define IVL_PScope_H
/*
* Copyright (c) 2008-2026 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 "PNamedItem.h"
# include "StringHeap.h"
# include "pform_types.h"
# include "ivl_target.h"
# include <map>
# include <set>
# include <unordered_set>
# include <vector>
class PEvent;
class PExpr;
class PFunction;
class PPackage;
class AProcess;
class PProcess;
class PClass;
class PTask;
class PWire;
class Statement;
class PCallTask;
class Design;
class NetScope;
/*
* The PScope class is a base representation of an object that
* represents lexical scope. For example, a module, a function/task, a
* named block is derived from a PScope.
*
* NOTE: This is not the same concept as the "scope" of an elaborated
* hierarchy. That is represented by NetScope objects after elaboration.
*/
class LexicalScope {
public:
enum lifetime_t { INHERITED, STATIC, AUTOMATIC };
explicit LexicalScope(LexicalScope*parent)
: default_lifetime(INHERITED), has_parameter_port_list(false),
generate_counter(0), parent_(parent) { }
// A virtual destructor is so that dynamic_cast can work.
virtual ~LexicalScope() { }
lifetime_t default_lifetime;
// Symbols that are defined or declared in this scope.
std::map<perm_string,PNamedItem*>local_symbols;
// Symbols that are explicitly imported. This contains the package where
// the symbol has been decelared. When using exports, this might not be
// the same as the package where it has been imported from.
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
// these packages are referenced, they will be added to the
// explicit imports (IEEE 1800-2012 26.3).
std::list<PPackage*>potential_imports;
// A task or function call may reference a task or function defined
// later in the scope. So here we stash the potential imports for
// task and function calls. They will be added to the explicit
// imports if we don't find a local definition.
std::map<perm_string,PPackage*>possible_imports;
struct range_t {
// True if this is an exclude
bool exclude_flag;
// lower bound
// If low_open_flag is false and low_expr=0, then use -inf
bool low_open_flag;
PExpr*low_expr;
// upper bound
// If high_open_flag is false and high_expr=0, then use +inf
bool high_open_flag;
PExpr*high_expr;
// Next range description in list
struct range_t*next;
};
/* The scope has parameters that are evaluated when the scope
is elaborated. During parsing, I put the parameters into
this map. */
struct param_expr_t : public PNamedItem {
inline param_expr_t() : data_type(0), expr(0), range(0),
local_flag(false), overridable(true) { }
// Type information.
data_type_t*data_type;
// Value expression
PExpr*expr;
// If there are range constraints, list them here
range_t*range;
// Whether it is a local parameter
bool local_flag;
// Whether the parameter can be overridden
bool overridable;
// Whether the parameter is a type parameter
bool type_flag = false;
// 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;
};
std::map<perm_string,param_expr_t*>parameters;
bool has_parameter_port_list;
// Defined types in the scope.
typedef std::map<perm_string,typedef_t*> typedef_map_t;
typedef_map_t typedefs;
// Named events in the scope.
std::map<perm_string,PEvent*>events;
// Nets and variables (wires) in the scope
std::map<perm_string,PWire*>wires;
PWire* wires_find(perm_string name);
// Genvars in the scope. These will only be present in module
// scopes, but are listed here to allow them to be found when
// creating implicit nets.
std::map<perm_string,LineInfo*> genvars;
// Variable initializations in this scope
std::vector<Statement*> var_inits;
// Behaviors (processes) in this scope
std::list<PProcess*> behaviors;
std::list<AProcess*> analog_behaviors;
// The elaboration tasks in this scope
std::list<PCallTask*> elab_tasks;
// Enumeration sets.
std::vector<enum_type_t*> enum_sets;
// A count of the generate constructs in this scope. This is
// used to automatically name unnamed generate blocks, as
// specified in the LRM.
unsigned generate_counter;
LexicalScope* parent_scope() const { return parent_; }
virtual bool var_init_needs_explicit_lifetime() const;
protected:
void dump_typedefs_(std::ostream&out, unsigned indent) const;
void dump_parameters_(std::ostream&out, unsigned indent) const;
void dump_enumerations_(std::ostream&out, unsigned indent) const;
void dump_events_(std::ostream&out, unsigned indent) const;
void dump_wires_(std::ostream&out, unsigned indent) const;
void dump_var_inits_(std::ostream&out, unsigned indent) const;
bool elaborate_var_inits_(Design*des, NetScope*scope) const;
private:
LexicalScope*parent_;
};
class PScope : public LexicalScope {
public:
// When created, a scope has a name and a parent. The name is
// the name of the definition. For example, if this is a
// module declaration, the name is the name after the "module"
// keyword, and if this is a task scope, the name is the task
// name. The parent is the lexical parent of this scope. Since
// modules do not nest in Verilog, the parent must be nil for
// modules. Scopes for tasks and functions point to their
// containing module.
explicit PScope(perm_string name, LexicalScope*parent =0);
virtual ~PScope() override;
perm_string pscope_name() const { return name_; }
/* These are the timescale for this scope. The value is
set by the `timescale directive or, in SystemVerilog,
by timeunit and timeprecision statements. */
int time_unit, time_precision;
/* Flags used to support warnings about timescales. */
bool time_unit_is_default;
bool time_prec_is_default;
bool has_explicit_timescale() const {
return !(time_unit_is_default || time_prec_is_default);
}
protected:
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
bool elaborate_behaviors_(Design*des, NetScope*scope) const;
private:
perm_string name_;
};
/*
* Some scopes can carry definitions. These include Modules and PClass
* scopes. These derive from PScopeExtra so that they hold the maps of
* extra definitions.
*/
class PScopeExtra : public PScope {
public:
explicit PScopeExtra(perm_string, LexicalScope*parent =0);
~PScopeExtra() override;
/* Task definitions within this module */
std::map<perm_string,PTask*> tasks;
std::map<perm_string,PFunction*> funcs;
/* Class definitions within this module. */
std::map<perm_string,PClass*> classes;
/* This is the lexical order of the classes, and is used by
elaboration to choose an elaboration order. */
std::vector<PClass*> classes_lexical;
/* Flags used to support warnings about timescales. */
bool time_unit_is_local;
bool time_prec_is_local;
protected:
void dump_classes_(std::ostream&out, unsigned indent) const;
void dump_tasks_(std::ostream&out, unsigned indent) const;
void dump_funcs_(std::ostream&out, unsigned indent) const;
};
#endif /* IVL_PScope_H */

View File

@ -1,35 +0,0 @@
/*
* Copyright (c) 2006-2011 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 "PSpec.h"
PSpecPath::PSpecPath(const std::list<perm_string> &src_list,
const std::list<perm_string> &dst_list,
char polarity, bool full_flag)
: conditional(false), condition(0), edge(0),
src(src_list.begin(), src_list.end()), dst(dst_list.begin(), dst_list.end()),
data_source_expression(0)
{
full_flag_ = full_flag;
polarity_ = polarity;
}
PSpecPath::~PSpecPath()
{
}

89
PSpec.h
View File

@ -1,89 +0,0 @@
#ifndef IVL_PSpec_H
#define IVL_PSpec_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 "StringHeap.h"
# include <vector>
# include <list>
class PExpr;
/*
* The PSpecPath is the parse of a specify path, which is in its most
* general form <path> = <delays>. The <delays> are collected into the
* "delays" vector in all cases, and the variety is in the other
* members.
*
* All paths also have a list of source names in the src vector, and a
* list of destination names in the dst vector. These pairs are the
* actual paths.
*
* If the path is a simple path, then:
* condition == nil
* edge == 0
* data_source_expression == nil
*
* If the path is conditional, then conditional == true and condition
* is the condition expression. If the condition expression is nil,
* then this is an ifnone conditional path.
*
* If data_source_expression != nil, then the path is edge sensitive
* and the edge might not be 0.
*
* The full flag is used to verify that only vectors of the same size
* are used in a parallel connection. Icarus always creates a full
* connection between the source and destination. The polarity is for
* informational (display) purposes only. The polarity is either '+',
* '-' or 0.
*/
class PSpecPath : public LineInfo {
public:
PSpecPath(const std::list<perm_string> &src_list,
const std::list<perm_string> &dst_list,
char polarity, bool full_flag);
~PSpecPath() override;
void elaborate(class Design*des, class NetScope*scope) const;
void dump(std::ostream&out, unsigned ind) const;
public:
// Condition expression, if present.
bool conditional;
class PExpr* condition;
// Edge specification (-1==negedge, 0 = no edge, 1==posedge)
int edge;
// Is this a full connection.
bool full_flag_;
// What is the polarity of the connection.
char polarity_;
// Ordered set of source nodes of a path
std::vector<perm_string> src;
// Ordered set of destination nodes of a path
std::vector<perm_string> dst;
// Data source expression
class PExpr* data_source_expression;
std::vector<class PExpr*>delays;
};
#endif /* IVL_PSpec_H */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 1999 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * 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
@ -14,69 +14,61 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: PTask.cc,v 1.7 2002/08/12 01:34:58 steve Exp $"
#endif
# include "config.h" # include "config.h"
# include "PTask.h"
# include "ivl_assert.h"
using namespace std; # include "PTask.h"
PTaskFunc::PTaskFunc(perm_string n, LexicalScope*p) PTask::PTask()
: PScope(n,p), this_type_(0), ports_(0) : ports_(0), statement_(0)
{ {
} }
PTaskFunc::~PTaskFunc()
{
}
bool PTaskFunc::var_init_needs_explicit_lifetime() const
{
return default_lifetime == STATIC;
}
void PTaskFunc::set_ports(vector<pform_tf_port_t>*p)
{
ivl_assert(*this, ports_ == 0);
ports_ = p;
}
void PTaskFunc::set_this(class_type_t*type, PWire*this_wire)
{
ivl_assert(*this, this_type_ == 0);
this_type_ = type;
// Push a synthesis argument that is the "this" value.
if (ports_==0)
ports_ = new vector<pform_tf_port_t>;
size_t use_size = ports_->size();
ports_->resize(use_size + 1);
for (size_t idx = use_size ; idx > 0 ; idx -= 1)
ports_->at(idx) = ports_->at(idx-1);
ports_->at(0) = pform_tf_port_t(this_wire);
}
PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__)
: PTaskFunc(name, parent), statement_(0)
{
is_auto_ = is_auto__;
}
PTask::~PTask() PTask::~PTask()
{ {
} }
void PTask::set_ports(svector<PWire*>*p)
{
assert(ports_ == 0);
ports_ = p;
}
void PTask::set_statement(Statement*s) void PTask::set_statement(Statement*s)
{ {
ivl_assert(*this, statement_ == 0); assert(statement_ == 0);
statement_ = s; statement_ = s;
} }
PNamedItem::SymbolType PTask::symbol_type() const
{ /*
return TASK; * $Log: PTask.cc,v $
} * Revision 1.7 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2001/07/25 03:10:48 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.5 2001/04/19 03:04:47 steve
* Spurious assert of empty statemnt.
*
* Revision 1.4 2001/01/13 22:20:08 steve
* Parse parameters within nested scopes.
*
* Revision 1.3 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.2 1999/07/24 02:11:19 steve
* Elaborate task input ports.
*
* Revision 1.1 1999/07/03 02:12:51 steve
* Elaborate user defined tasks.
*
*/

209
PTask.h
View File

@ -1,7 +1,7 @@
#ifndef IVL_PTask_H #ifndef __PTask_H
#define IVL_PTask_H #define __PTask_H
/* /*
* Copyright (c) 1999-2025 Stephen Williams (steve@icarus.com) * Copyright (c) 1999-2000 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
@ -16,72 +16,46 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT
#ident "$Id: PTask.h,v 1.13.2.1 2005/08/13 00:45:53 steve Exp $"
#endif
# include "PScope.h" # include "LineInfo.h"
# include "PNamedItem.h" # include "svector.h"
# include "StringHeap.h" # include "StringHeap.h"
# include <string> # include <string>
# include <vector>
# include <list>
class Design; class Design;
class NetExpr;
class NetNet;
class NetScope; class NetScope;
class PChainConstructor;
class PWire; class PWire;
class Statement; class Statement;
class PExpr; class PExpr;
enum PTaskFuncEnum {
PTF_NONE,
PTF_REG,
PTF_INTEGER,
PTF_REAL,
PTF_REALTIME,
PTF_TIME
};
class PTaskFunc : public PScope, public PNamedItem { struct PTaskFuncArg {
PTaskFuncEnum type;
public: svector<PExpr*>*range;
PTaskFunc(perm_string name, LexicalScope*parent);
~PTaskFunc() override;
bool var_init_needs_explicit_lifetime() const override;
void set_ports(std::vector<pform_tf_port_t>*p);
void set_this(class_type_t*use_type, PWire*this_wire);
// If this task is a method of a class, this returns a pointer
// to the class type.
inline class_type_t* method_of() const { return this_type_; }
virtual void elaborate_sig(Design*des, NetScope*scope) const =0;
virtual void elaborate(Design*des, NetScope*scope) const =0;
virtual void dump(std::ostream&, unsigned) const =0;
protected:
// Elaborate the ports list. Write into the ports vector the
// NetNet pointers for the ports, and write into the pdefs the
// default value expressions, if any.
void elaborate_sig_ports_(Design*des, NetScope*scope,
std::vector<NetNet*>&ports,
std::vector<NetExpr*> &pdefs,
std::vector<perm_string> &port_names) const;
void dump_ports_(std::ostream&out, unsigned ind) const;
private:
class_type_t*this_type_;
std::vector<pform_tf_port_t>*ports_;
}; };
/* /*
* The PTask holds the parsed definitions of a task. * The PTask holds the parsed definitions of a task.
*/ */
class PTask : public PTaskFunc { class PTask : public LineInfo {
public: public:
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto); explicit PTask();
~PTask() override; ~PTask();
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s); void set_statement(Statement *s);
// Tasks introduce scope, to need to be handled during the // Tasks introduce scope, to need to be handled during the
@ -91,20 +65,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_; }; void dump(std::ostream&, unsigned) const;
void dump(std::ostream&, unsigned) const override;
SymbolType symbol_type() const override;
private: private:
svector<PWire*>*ports_;
Statement*statement_; Statement*statement_;
bool is_auto_;
private: // Not implemented private: // Not implemented
PTask(const PTask&); PTask(const PTask&);
@ -118,72 +88,89 @@ class PTask : public PTaskFunc {
* *
* The output value is not elaborated until elaborate_sig. * The output value is not elaborated until elaborate_sig.
*/ */
class PFunction : public PTaskFunc { class PFunction : public LineInfo {
public: public:
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto); explicit PFunction(perm_string name);
~PFunction() override; ~PFunction();
void set_ports(svector<PWire *>*p);
void set_statement(Statement *s); void set_statement(Statement *s);
void set_return(data_type_t*t); void set_return(PTaskFuncArg t);
inline Statement* get_statement() { return statement_; }
// Push this statement to the front of the existing
// definition. If the statement is a simple statement, make a
// block to contain the statements.
void push_statement_front(Statement*stmt);
// This is only used if this function is a constructor. In
// that case, this method looks for a PChainConstructor in the
// statement and extracts it if found.
PChainConstructor*extract_chain_constructor();
void 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_; }; void dump(std::ostream&, unsigned) const;
void dump(std::ostream&, unsigned) const override;
SymbolType symbol_type() const override;
private: private:
data_type_t* return_type_; perm_string name_;
PTaskFuncArg return_type_;
svector<PWire *> *ports_;
Statement *statement_; Statement *statement_;
bool is_auto_;
}; };
// A let is like a simple function that is expanded in the compiler /*
class PLet : public PTaskFunc { * $Log: PTask.h,v $
public: * Revision 1.13.2.1 2005/08/13 00:45:53 steve
typedef struct let_port { * Fix compilation warnings/errors with newer compilers.
data_type_t*type_; *
perm_string name_; * Revision 1.13 2004/05/31 23:34:36 steve
std::list<pform_range_t>*range_; * Rewire/generalize parsing an elaboration of
PExpr*def_; * function return values to allow for better
* speed and more type support.
void dump(std::ostream&, unsigned) const; *
} let_port_t; * Revision 1.12 2002/08/12 01:34:58 steve
* conditional ident string using autoconfig.
// FIXME: Should the port list be a vector. Check once implemented completely *
explicit PLet(perm_string name, LexicalScope*parent, * Revision 1.11 2001/11/22 06:20:59 steve
std::list<let_port_t*>*ports, PExpr*expr); * Use NetScope instead of string for scope path.
~PLet() override; *
* Revision 1.10 2001/01/13 22:20:08 steve
void elaborate_sig(Design*des, NetScope*scope) const override { (void)des; (void)scope; } * Parse parameters within nested scopes.
void elaborate(Design*des, NetScope*scope) const override { (void)des; (void)scope; } *
* Revision 1.9 2000/07/30 18:25:43 steve
void dump(std::ostream&, unsigned) const override; * Rearrange task and function elaboration so that the
* NetTaskDef and NetFuncDef functions are created during
private: * signal enaboration, and carry these objects in the
std::list<let_port_t*>*ports_; * NetScope class instead of the extra, useless map in
PExpr*expr_; * the Design class.
}; *
* Revision 1.8 2000/03/08 04:36:53 steve
#endif /* IVL_PTask_H */ * Redesign the implementation of scopes and parameters.
* I now generate the scopes and notice the parameters
* in a separate pass over the pform. Once the scopes
* are generated, I can process overrides and evalutate
* paremeters before elaboration begins.
*
* Revision 1.7 2000/02/23 02:56:53 steve
* Macintosh compilers do not support ident.
*
* Revision 1.6 1999/09/30 21:28:34 steve
* Handle mutual reference of tasks by elaborating
* task definitions in two passes, like functions.
*
* Revision 1.5 1999/09/01 20:46:19 steve
* Handle recursive functions and arbitrary function
* references to other functions, properly pass
* function parameters and save function results.
*
* Revision 1.4 1999/08/25 22:22:41 steve
* elaborate some aspects of functions.
*
* Revision 1.3 1999/07/31 19:14:47 steve
* Add functions up to elaboration (Ed Carter)
*
* Revision 1.2 1999/07/24 02:11:19 steve
* Elaborate task input ports.
*
* Revision 1.1 1999/07/03 02:12:51 steve
* Elaborate user defined tasks.
*
*/
#endif

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