Merge from master for release.

This commit is contained in:
Wilson Snyder 2020-01-11 07:12:09 -05:00
commit 0c6c83e278
403 changed files with 7172 additions and 2994 deletions

View File

@ -90,10 +90,6 @@ PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
RawStringFormats:
- Delimiter: pb
Language: TextProto
BasedOnStyle: google
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: true
@ -108,7 +104,7 @@ SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
Standard: Cpp03
TabWidth: 8
UseTab: Never
...

View File

@ -1,4 +1,5 @@
---
exclude_paths:
- '.github/**'
- 'ci/build_verilator.sh'
- 'include/vltstd/**'

14
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,14 @@
---
name: Bug report
about: Something isn't working as expected, and it isn't "Unsupported." (Note our contributor agreement at https://github.com/verilator/verilator/.github/blob/master/CONTRIBUTING.adoc)
title: ''
labels: new
assignees: ''
---
Thanks for taking the time to report this.
Can you attach an example that shows the issue? (Must be openly licensed, ideally in test_regress format.)
May we assist you in trying to fix this yourself?

16
.github/ISSUE_TEMPLATE/feature.md vendored Normal file
View File

@ -0,0 +1,16 @@
---
name: Feature Request
about: Request something should be supported, or a new feature added. (Note our contributor agreement at https://github.com/verilator/verilator/.github/blob/master/CONTRIBUTING.adoc)
title: ''
labels: new
assignees: ''
---
Thanks for taking the time to report this.
What would you like added/supported?
Can you attach an example that runs on other simulators? (Must be openly licensed, ideally in test_regress format.)
May we assist you in trying to fix this yourself?

10
.github/ISSUE_TEMPLATE/questions.md vendored Normal file
View File

@ -0,0 +1,10 @@
---
name: Q and A, or Other
about: Ask a question, not related to a specific bug or feature request. (Note our contributor agreement at https://github.com/verilator/verilator/.github/blob/master/CONTRIBUTING.adoc)
title: ''
labels: new
assignees: ''
---
How may we help - what is your question?

1
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1 @@
We appreciate your contributing to Verilator. If this is your first commit, please add your name to docs/CONTRIBUTORS, and read our contributing guidelines in docs/CONTRIBUTING.adoc.

199
.github/labels.toml vendored Normal file
View File

@ -0,0 +1,199 @@
["area: assertions"]
color = "ffffe8"
name = "area: assertions"
description = "Issue involves assertions"
["area: configure/compiling"]
color = "ffffe8"
name = "area: configure/compiling"
description = "Issue involves configuring or compilating Verilator itself"
["area: coverage"]
color = "ffffe8"
name = "area: coverage"
description = "Issue involves coverage generation"
["area: data-types"]
color = "ffffe8"
name = "area: data-types"
description = "Issue involves data-types"
["area: documentation"]
color = "ffffe8"
name = "area: documentation"
description = "Issue involves documentation"
["area: elaboration"]
color = "ffffe8"
name = "area: elaboration"
description = "Issue involves elaboration phase"
["area: invoking/options"]
color = "ffffe8"
name = "area: invoking/options"
description = "Issue involves options passed to Verilator"
["area: lint"]
color = "ffffe8"
name = "area: lint"
description = "Issue involves SystemVerilog lint checking"
["area: parser"]
color = "ffffe8"
name = "area: parser"
description = "Issue involves SystemVerilog parsing"
["area: performance"]
color = "ffffe8"
name = "area: performance"
description = "Issue involves performance issues"
["area: portability"]
color = "ffffe8"
name = "area: portability"
description = "Issue involves operating system/compiler portability"
["area: runtime result"]
color = "ffffe8"
name = "area: runtime result"
description = "Issue involves an incorrect runtine result from Verilated model"
["area: scheduling"]
color = "ffffe8"
name = "area: scheduling"
description = "Issue involves scheduling/ordering of events"
["area: tests"]
color = "ffffe8"
name = "area: tests"
description = "Issue involves the testing system"
["area: usability"]
color = "ffffe8"
name = "area: usability"
description = "Issue involves general usability"
["effort: days"]
color = "d0c0b0"
name = "effort: days"
description = "Expect this issue to require roughly days of invested effort to resolve"
["effort: hours"]
color = "f5e6d6"
name = "effort: hours"
description = "Expect this issue to require roughly hours of invested effort to resolve"
["effort: minutes"]
color = "f5e6d6"
name = "effort: minutes"
description = "Expect this issue to require less than an hour of invested effort to resolve"
["effort: weeks"]
color = "d0c0b0"
name = "effort: weeks"
description = "Expect this issue to require weeks or more of invested effort to resolve"
["good first issue"]
color = "7057ff"
name = "good first issue"
description = "Good for newcomers"
["help wanted"]
color = "008672"
name = "help wanted"
description = "Extra attention is needed"
["new"]
color = "ff4400"
name = "new"
description = "New issue, not yet seen by maintainers"
["resolution: abandoned"]
color = "cfd3d7"
name = "resolution: abandoned"
description = "Closed; not enough information or otherwise never finished"
["resolution: answered"]
color = "cfd3d7"
name = "resolution: answered"
description = "Closed; only applies to questions which were answered"
["resolution: duplicate"]
color = "cfd3d7"
name = "resolution: duplicate"
description = "Closed; issue or pull request already exists"
["resolution: external"]
color = "cfd3d7"
name = "resolution: external"
description = "Closed; passed to another tool's bug tracker"
["resolution: fixed"]
color = "cfd3d7"
name = "resolution: fixed"
description = "Closed; fixed"
["resolution: invalid"]
color = "cfd3d7"
name = "resolution: invalid"
description = "Closed; issue or pull request is no longer relevant"
["resolution: no fix needed"]
color = "cfd3d7"
name = "resolution: no fix needed"
description = "Closed; no fix required (not a bug)"
["resolution: wontfix"]
color = "cfd3d7"
name = "resolution: wontfix"
description = "Closed; work won't continue on an issue or pull request"
["status: asked reporter"]
color = "ffffff"
name = "status: asked reporter"
description = "Bug is waiting for reporter to answer a question"
["status: assigned"]
color = "a0f0ff"
name = "status: assigned"
description = "Issue is assigned to someone to work on"
["status: blocked"]
color = "00007f"
name = "status: blocked"
description = "Issue is waiting for another bug, when other bug is fixed, then goes to 'status: assigned'"
["status: discussion"]
color = "d876e3"
name = "status: discussion"
description = "Issue is waiting for discussions to resolve"
["status: ready"]
color = "b6c92a"
name = "status: ready"
description = "Issue is ready for someone to fix; then goes to 'status: assigned'"
["type: bug"]
color = "d73a4a"
name = "type: bug"
description = "Defect"
["type: feature-IEEE"]
color = "cfccff"
name = "type: feature-IEEE"
description = "Request to add new feature, described in IEEE 1800"
["type: feature-non-IEEE"]
color = "cfccff"
name = "type: feature-non-IEEE"
description = "Request to add new feature, outside IEEE 1800"
["type: maintenance"]
color = "cfccff"
name = "type: maintenance"
description = "Internal maintenance task"
["type: q and a"]
color = "84ba34"
name = "type: q and a"
description = "Question and answer about some feature or user question"

View File

@ -27,6 +27,7 @@ before_install:
- yes yes | sudo cpan -fi Unix::Processors Parallel::Forker Bit::Vector
- sudo apt-get install gdb gtkwave
before_script:
- bash -x ci/build_vcddiff.sh
- bash -x ci/build_verilator.sh
after_script:
- ccache -s

1405
Changes

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
\.clang-tidy
\.git/
\.git$
\.github/
\.svn/
\.(bak|old)/
\.(bak|old)$

View File

@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@ -103,7 +103,7 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
SHELL = /bin/sh
SUBDIRS = src test_regress \
SUBDIRS = docs src test_regress \
examples/cmake_hello_c \
examples/cmake_hello_sc \
examples/cmake_tracing_c \
@ -114,6 +114,7 @@ SUBDIRS = src test_regress \
examples/make_tracing_c \
examples/make_tracing_sc \
examples/make_protect_lib \
examples/xml_py \
INFOS = verilator.txt verilator.html verilator.pdf
@ -513,6 +514,7 @@ clean mostlyclean distclean maintainer-clean::
rm -f *.tex
rm -rf examples/*/obj_dir* examples/*/logs
rm -rf test_*/obj_dir
rm -rf nodist/fuzzer/dictionary
rm -rf nodist/obj_dir
distclean maintainer-clean::

View File

@ -4,7 +4,7 @@
ifdef::env-github[]
image:https://img.shields.io/badge/License-LGPL%20v3-blue.svg[license LGPLv3,link=https://www.gnu.org/licenses/lgpl-3.0]
image:https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg[license Artistic-2.0,link=https://opensource.org/licenses/Artistic-2.0]
image:https://api.codacy.com/project/badge/Grade/ff998fdaa6f64b9a95eb5f342ee6bf4d[Code Quality,link=https://www.codacy.com/manual/wsnyder/verilator]
image:https://api.codacy.com/project/badge/Grade/48478c986f13400682ffe4a5e0939b3a[Code Quality,link=https://www.codacy.com/gh/verilator/verilator]
image:https://travis-ci.com/verilator/verilator.svg?branch=master[Build Status (Travis CI),link=https://travis-ci.com/verilator/verilator]
endif::[]
@ -131,10 +131,10 @@ perhaps Icarus may.
== Open License
Verilator is Copyright 2003-2019 by Wilson Snyder. (Report bugs to
Verilator is Copyright 2003-2020 by Wilson Snyder. (Report bugs to
https://verilator.org/issues[Verilator Issues].)
Verilator is free software; you can redistribute it and/or modify it under
the terms of either the GNU Lesser General Public License Version 3 or the
Perl Artistic License Version 2.0. (See the documentation for more
details.)
Perl Artistic License Version 2.0. See the documentation for more
details.

View File

@ -1,9 +1,7 @@
: # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
#!/usr/bin/env perl
######################################################################
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@ -1078,7 +1076,7 @@ and the remaining files can be compiled on parallel machines. Using
design --output-split 20000 resulted in splitting into approximately
one-minute-compile chunks.
Typically when using this, make with VM_PARALLEL_BUILD=1, and use
Typically when using this, make with VM_PARALLEL_BUILDS=1, and use
I<ccache>.
=item --output-split-cfuncs I<statements>
@ -2114,16 +2112,16 @@ specified, it will come from a default optionally specified at configure
time (before Verilator was compiled), or computed from
SYSTEMC/lib-SYSTEMC_ARCH.
=item VCS_HOME
If set, specifies the directory containing the Synopsys VCS distribution.
When set, a 'make test' in the Verilator distribution will also run VCS
baseline regression tests.
=item VERILATOR_BIN
If set, specifies an alternative name of the Verilator binary. May be used
for debugging and selecting between multiple operating system builds.
If set, specifies an alternative name of the C<verilator> binary. May be
used for debugging and selecting between multiple operating system builds.
=item VERILATOR_COVERAGE_BIN
If set, specifies an alternative name of the C<verilator_coverage binary>.
May be used for debugging and selecting between multiple operating system
builds.
=item VERILATOR_GDB
@ -2674,7 +2672,7 @@ The remainder of this section describe behavior with --threads 1 or
VL_THREADED is defined when compiling a threaded Verilated module, causing
the Verilated support classes become threadsafe.
The thread used for constructing a model must the the same thread that
The thread used for constructing a model must be the same thread that
calls eval() into the model, this is called the "eval thread". The thread
used to perform certain global operations such as saving and tracing must
be done by a "main thread". In most cases the eval thread and main thread
@ -2737,8 +2735,8 @@ controlled by configuration files, typically named with the .vlt
extension. An example:
`verilator_config
lint_off -msg WIDTH
lint_off -msg CASEX -file "silly_vendor_code.v"
lint_off -rule WIDTH
lint_off -rule CASEX -file "silly_vendor_code.v"
This disables WIDTH warnings globally, and CASEX for a specific file.
@ -2756,8 +2754,7 @@ The grammar of configuration commands is as follows:
=item `verilator_config
Take remaining text up the the next `verilog mode switch and treat it as
Verilator configuration commands.
Take remaining text and treat it as Verilator configuration commands.
=item coverage_on [-file "<filename>" [-lines <line> [ - <line> ]]]
@ -2768,9 +2765,9 @@ Enable/disable coverage for the specified filename (or wildcard with '*' or
omitted). Often used to ignore an entire module for coverage analysis
purposes.
=item lint_on [-msg <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
=item lint_on [-rule <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
=item lint_off [-msg <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
=item lint_off [-rule <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
Enable/disables the specified lint warning, in the specified filename (or
wildcard with '*' or '?', or all files if omitted) and range of line
@ -2779,10 +2776,13 @@ numbers (or all lines if omitted).
With lint_off using '*' will override any lint_on directives in the source,
i.e. the warning will still not be printed.
If the -msg is omitted, all lint warnings (see list in -Wno-lint) are
If the -rule is omitted, all lint warnings (see list in -Wno-lint) are
enabled/disabled. This will override all later lint warning enables for
the specified region.
In previous versions -rule was named -msg. The latter is deprecated, but
still works with a deprecation info, it may be removed in future versions.
=item tracing_on [-file "<filename>" [-lines <line> [ - <line> ]]]
=item tracing_off [-file "<filename>" [-lines <line> [ - <line> ]]]
@ -2995,7 +2995,7 @@ may `ifdef around compiler specific constructs.
=item `verilator_config
Take remaining text up the the next `verilog mode switch and treat it as
Take remaining text up to the next `verilog mode switch and treat it as
Verilator configuration commands.
=item `verilog
@ -3317,7 +3317,7 @@ that Verilator will print a list of known scopes to help your debugging.
=head2 Floating Point
Floating Point (real) numbers are supported.
Short floating point (shortreal) numbers are converted to real.
=head2 Latches
@ -3507,6 +3507,11 @@ Assignment patterns with order based, default, constant integer (array) or
member identifier (struct/union) keys are supported. Data type keys and
keys which are computed from a constant expression are not supported.
=item `uselib
Uselib, a vendor specific library specification method, is ignored along
with anything following it until the end of that line.
=item cast operator
Casting is supported only between simple scalar types, signed and unsigned,
@ -3743,6 +3748,14 @@ generally unrolls small loops. You may want to try increasing
--unroll-count (and occasionally --unroll-stmts) which will raise the small
loop bar to avoid this error.
=item BOUNDED
This indicates that bounded queues (e.g. "var name[$ : 3]") are
unsupported.
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item BSSPACE
Warns that a backslash is followed by a space then a newline. Likely the
@ -4844,7 +4857,7 @@ SystemC module *may* be faster.)
=head1 BUGS
First, check the the coding limitations section.
First, check the coding limitations section.
Next, try the --debug switch. This will enable additional internal
assertions, and may help identify the problem.
@ -5016,7 +5029,7 @@ remain anonymous.
The latest version is available from L<https://verilator.org>.
Copyright 2003-2019 by Wilson Snyder. Verilator is free software; you can
Copyright 2003-2020 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify the Verilator internals under the terms of
either the GNU Lesser General Public License Version 3 or the Perl Artistic
License Version 2.0.

View File

@ -1,9 +1,7 @@
: # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
#!/usr/bin/env perl
######################################################################
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@ -271,7 +269,7 @@ Specifies a module search directory.
The latest version is available from L<https://verilator.org>.
Copyright 2003-2019 by Wilson Snyder. Verilator is free software; you can
Copyright 2003-2020 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify the Verilator internals under the terms of
either the GNU Lesser General Public License Version 3 or the Perl Artistic
License Version 2.0.

View File

@ -1,10 +1,7 @@
: # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
require 5.006_001;
use warnings;
use Getopt::Long;
use IO::File;
@ -236,7 +233,7 @@ Do not show differences in line numbering.
The latest version is available from L<https://verilator.org>.
Copyright 2005-2019 by Wilson Snyder. This package is free software; you can
Copyright 2005-2020 by Wilson Snyder. This package is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.

View File

@ -1,11 +1,9 @@
: # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
use strict;
use warnings;
use strict;
use Getopt::Long;
use IO::File;
use Pod::Usage;
@ -540,7 +538,7 @@ verilator_gantt.vcd.
The latest version is available from L<https://verilator.org>.
Copyright 2018-2019 by Wilson Snyder. Verilator is free software; you can
Copyright 2018-2020 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.

View File

@ -1,9 +1,7 @@
: # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
#!/usr/bin/env perl
# DESCRIPTION: Print include statements for each ARGV
#
# Copyright 2003-2019 by Wilson Snyder. This package is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This package is free software; you can
# redistribute it and/or modify it under the terms of either the GNU Lesser
# General Public License Version 3 or the Perl Artistic License Version 2.0.
######################################################################

View File

@ -1,6 +1,4 @@
: # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
@ -230,7 +228,7 @@ Displays this message and program version and exits.
The latest version is available from L<https://verilator.org>.
Copyright 2007-2019 by Wilson Snyder. Verilator is free software; you can
Copyright 2007-2020 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.

18
ci/build_vcddiff.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
# DESCRIPTION: Verilator: Build script for vcddiff
#
# Copyright 2019 by Todd Strader. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
set -e
# NB: it would be better to add this via a PPA
TMP_DIR=$(mktemp -d)
git -C "${TMP_DIR}" clone https://github.com/veripool/vcddiff
VCDDIFF_DIR=${TMP_DIR}/vcddiff
git -C "${VCDDIFF_DIR}" checkout 5112f88b7ba8818dce9dfb72619e64a1fc19542c
make -C "${VCDDIFF_DIR}"
sudo cp "${VCDDIFF_DIR}/vcddiff" /usr/local/bin

View File

@ -0,0 +1,57 @@
# DESCRIPTION: Dockerfile for env to build and fully test Verilator
#
# Copyright 2020 by Stefan Wallentowitz. This program is free
# software; you can redistribute it and/or modify it under the terms
# of either the GNU Lesser General Public License Version 3 or the
# Perl Artistic License Version 2.0.
FROM ubuntu:18.04
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install --no-install-recommends -y \
autoconf=2.69-11 \
bc=1.07.1-2 \
bison=2:3.0.4.dfsg-1build1 \
build-essential=12.4ubuntu1 \
ca-certificates=20180409 \
cmake=3.10.2-1ubuntu2.18.04.1 \
flex=2.6.4-6 \
gdb=8.1-0ubuntu3.2 \
gcc-6=6.5.0-2ubuntu1~18.04 \
gcc-5=5.5.0-12ubuntu1 \
gcc-4.8=4.8.5-4ubuntu8 \
git=1:2.17.1-1ubuntu0.5 \
gtkwave=3.3.86-1 \
g++-6=6.5.0-2ubuntu1~18.04 \
g++-5=5.5.0-12ubuntu1 \
g++-4.8=4.8.5-4ubuntu8 \
libfl2=2.6.4-6 \
libfl-dev=2.6.4-6 \
numactl=2.0.11-2.1ubuntu0.1 \
perl=5.26.1-6ubuntu0.3 \
python3=3.6.7-1~18.04 \
wget=1.19.4-1ubuntu2.2 \
zlibc=0.9k-4.3 \
zlib1g=1:1.2.11.dfsg-0ubuntu2 \
zlib1g-dev=1:1.2.11.dfsg-0ubuntu2 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /tmp
COPY build-systemc.sh /tmp/
RUN ./build-systemc.sh
RUN cpan install -fi Unix::Processors Parallel::Forker Bit::Vector
RUN git clone https://github.com/veripool/vcddiff.git && \
make -C vcddiff && \
cp -p vcddiff/vcddiff /usr/local/bin/vcddiff && \
rm -rf vcddiff
COPY build.sh /tmp/build.sh
ENV VERILATOR_AUTHOR_SITE=1
ENTRYPOINT [ "/tmp/build.sh" ]

View File

@ -0,0 +1,50 @@
= Verilator Build Environment
This container is set up to compile and test a Verilator build based
on the following parameters:
* Source repository (default: https://github.com/verilator/verilator)
* Source revision (default: master)
* GCC version (4.8.5, 5.5.0, 6.5.0, 7.4.0, default: 7.4.0)
The container is published as `verilator/verilator-buildenv` on
https://hub.docker.com/repository/docker/verilator/verilator-buildenv[docker hub].
To run the basic build of current master:
docker run -ti verilator/verilator-buildenv
To also run tests:
docker run -ti verilator/verilator-buildenv test
Change the compiler:
docker run -ti -e CC=gcc-4.8 -e CXX=g++-4.8 verilator/verilator-buildenv test
The tests that involve gdb are not working due to security restrictions.
To run those too:
....
docker run -ti -v ${PWD}:/tmp/repo -e REPO=/tmp/repo -e REV=`git rev-parse --short HEAD` -e CC=gcc-4.8 -e CXX=g++-4.8 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined verilator/verilator-buildenv test
....
You may want to avoid pushing your changes to a remote repository and
instead use a local working copy. You can mount the local working copy
path as a volume and use this as repo. Be careful, that it can only
use committed changes, so you may want to use a work-in-progress
commit or so. To build the current HEAD from top of a repository:
....
docker run -ti -v ${PWD}:/tmp/repo -e REPO=/tmp/repo -e REV=`git rev-parse --short HEAD` --cap-add=SYS_PTRACE --security-opt seccomp=unconfined verilator/verilator-buildenv test
....
== Under the Hood
To rebuild the image, simply run:
docker build .
It will build SystemC in all supported compiler variants to reduce the
impact on testing cycles. A build script will be the entrypoint to the
container that will perform a standard build and test procedure.

View File

@ -0,0 +1,29 @@
#!/bin/bash -e
# DESCRIPTION: Build SystemC in Ubuntu 18.04 with different g++/gcc
#
# Copyright 2020 by Stefan Wallentowitz. This program is free
# software; you can redistribute it and/or modify it under the terms
# of either the GNU Lesser General Public License Version 3 or the
# Perl Artistic License Version 2.0.
build_variant () {
version=$($1 --version | grep gcc | awk '{print $4}')
mkdir "/usr/local/systemc-2.3.3-gcc$version"
mkdir build
cd build
../configure --prefix="/usr/local/systemc-2.3.3-gcc$version" CC="$1" CXX="$2" LD="$2"
make -j
make install
cd ..
rm -r build
}
wget https://www.accellera.org/images/downloads/standards/systemc/systemc-2.3.3.tar.gz
tar -xzf systemc-2.3.3.tar.gz
cd systemc-2.3.3
build_variant gcc g++
build_variant gcc-6 g++-6
build_variant gcc-5 g++-5
build_variant gcc-4.8 g++-4.8
cd ..
rm -r systemc-2.3.3*

30
ci/docker/buildenv/build.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/bash -e
# DESCRIPTION: Build Verilator (inside container)
#
# Copyright 2020 by Stefan Wallentowitz. This program is free
# software; you can redistribute it and/or modify it under the terms
# of either the GNU Lesser General Public License Version 3 or the
# Perl Artistic License Version 2.0.
: "${REPO:=https://github.com/verilator/verilator}"
: "${REV:=master}"
: "${CC:=gcc}"
: "${CXX:=g++}"
GCCVERSION=$(${CC} --version | grep gcc | awk '{print $4}')
export SYSTEMC_INCLUDE="/usr/local/systemc-2.3.3-gcc${GCCVERSION}/include"
export SYSTEMC_LIBDIR="/usr/local/systemc-2.3.3-gcc${GCCVERSION}/lib-linux64"
export LD_LIBRARY_PATH=${SYSTEMC_LIBDIR}
SRCS=$PWD/verilator
git clone "$REPO" "$SRCS"
cd "$SRCS"
git checkout "$REV"
autoconf
./configure --enable-longtests
make -j $(nproc)
if [ "${1:-''}" == "test" ]; then
make test
fi

47
ci/docker/run/Dockerfile Normal file
View File

@ -0,0 +1,47 @@
# DESCRIPTION: Dockerfile for image to run Verilator inside
#
# Copyright 2020 by Stefan Wallentowitz. This program is free
# software; you can redistribute it and/or modify it under the terms
# of either the GNU Lesser General Public License Version 3 or the
# Perl Artistic License Version 2.0.
FROM ubuntu:18.04
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
autoconf=2.69-11 \
bc=1.07.1-2 \
bison=2:3.0.4.dfsg-1build1 \
build-essential=12.4ubuntu1 \
ca-certificates=20180409 \
flex=2.6.4-6 \
git=1:2.17.1-1ubuntu0.5 \
libfl-dev=2.6.4-6 \
perl=5.26.1-6ubuntu0.3 \
python3=3.6.7-1~18.04 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ARG REPO=https://github.com/verilator/verilator
ARG SOURCE_COMMIT=master
WORKDIR /tmp
# Add an exception for the linter, we want to cd here in one layer
# to reduce the number of layers (and thereby size).
# hadolint ignore=DL3003
RUN git clone "${REPO}" verilator && \
cd verilator && \
git checkout "${SOURCE_COMMIT}" && \
autoconf && \
./configure && \
make -j "$(nproc)" && \
make install && \
cd .. && \
rm -r verilator
COPY verilator-wrap.sh /usr/local/bin/verilator-wrap.sh
WORKDIR /work
ENTRYPOINT [ "/usr/local/bin/verilator-wrap.sh" ]

49
ci/docker/run/README.adoc Normal file
View File

@ -0,0 +1,49 @@
= Docker Container as Verilator executable
This allows you to run Verilator easily as a docker image, e.g.:
docker run -ti verilator/verilator:latest --version
This is in particular useful to compare against older version or to
check when an issue was introduced.
You will need to give it access to your files as a volume and fix the
user rights:
....
docker run -ti -v ${PWD}:/work --user $(id -u):$(id -g) verilator/verilator:latest --cc test.v
....
The caveat is that it can only access files below the current
directory then, a workaround is to adopt the volume and set
`-workdir`.
There is a convenience script in this folder that wraps around the
docker calls:
$ verilator-docker 3.922 --version
Verilator 3.922 2018-03-17 rev UNKNOWN_REV
Finally, you can also work in the container by setting the entrypoint
(don't forget to mount a volume if you want your work persistent):
docker run -ti --entrypoint /bin/bash verilator/verilator:latest
The other files in this folder all for building the containers and to
store in them. You could use it to build Verilator at a specific
commit:
docker build --build-arg SOURCE_COMMIT=<commit> .
== Internals
The Dockerfile is pretty straight-forward, it builds Verilator and
removes the tree after that to reduce the image size. It sets a
wrapper script (`verilator-wrap.sh`) as entrypoint. This script calls
Verilator but also copies the verilated runtime files to the `obj_dir`
or the `-Mdir` respectively. This allows the user to build the C++
output with the matching runtime files. The wrapper patches the
generated Makefile accordingly.
There is also a hook defined that is run by docker hub via automated
builds.

View File

@ -0,0 +1,9 @@
#!/bin/bash
# DESCRIPTION: Docker hub hook to pass SOURCE_COMMIT
#
# Copyright 2020 by Stefan Wallentowitz. This program is free
# software; you can redistribute it and/or modify it under the terms
# of either the GNU Lesser General Public License Version 3 or the
# Perl Artistic License Version 2.0.FROM ubuntu:18.04
docker build --build-arg SOURCE_COMMIT=${SOURCE_COMMIT} -f $DOCKERFILE_PATH -t $IMAGE_NAME .

10
ci/docker/run/verilator-docker Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
# DESCRIPTION: Wrap a verilator call to run a docker container
#
# Copyright 2020 by Stefan Wallentowitz. This program is free
# software; you can redistribute it and/or modify it under the terms
# of either the GNU Lesser General Public License Version 3 or the
# Perl Artistic License Version 2.0.
docker pull verilator/verilator:$1 >/dev/null
docker run -ti -v ${PWD}:/work --user $(id -u):$(id -g) verilator/verilator:$1 "${@:2}"

26
ci/docker/run/verilator-wrap.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash -e
# DESCRIPTION: Wrap a Verilator call and copy vlt includes
# (inside docker container)
#
# Copyright 2020 by Stefan Wallentowitz. This program is free
# software; you can redistribute it and/or modify it under the terms
# of either the GNU Lesser General Public License Version 3 or the
# Perl Artistic License Version 2.0.
perl /usr/local/bin/verilator "$@"
# Check if user set an obj_dir
obj_dir=$(echo " $@" | grep -oP '\s--Mdir\s*\K\S+')
if [ "$obj_dir" == "" ]; then
obj_dir="obj_dir"
fi
# If the run was successful: Copy required files to allow build without this container
if [ -e ${obj_dir} ]; then
# Copy files required for the build
mkdir -p ${obj_dir}/vlt
cp -r /usr/local/share/verilator/bin ${obj_dir}/vlt
cp -r /usr/local/share/verilator/include ${obj_dir}/vlt
# Point Makefile to that folder
perl -i -pe 's/VERILATOR_ROOT = \/usr\/local\/share\/verilator/VERILATOR_ROOT = vlt/g' ${obj_dir}/*.mk
fi

View File

@ -1,12 +1,12 @@
# DESCRIPTION: Process this file with autoconf to produce a configure script.
#
# Copyright 2003-2019 by Wilson Snyder. Verilator is free software; you can
# Copyright 2003-2020 by Wilson Snyder. Verilator is free software; you can
# redistribute it and/or modify it under the terms of either the GNU Lesser
# General Public License Version 3 or the Perl Artistic License Version 2.0.
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[4.024 2019-12-08],
AC_INIT([Verilator],[4.026 2020-01-11],
[https://verilator.org],
[verilator],[https://verilator.org])
# When releasing, also update header of Changes file

View File

@ -24,8 +24,8 @@ contributions flow more efficiently.
* Please https://verilator.org/issues/new[Open a new issue].
* You may attach a patch to the issue, or (preferred) may point to a GitHub
repository branch within your GitHub account.
* You may attach a patch to the issue, or (preferred) may request a GitHub
pull request.
** Verilator uses Travis CI to provide continuous integration. You may
want to setup Travis CI on your GitHub branch to ensure your changes

View File

@ -19,10 +19,12 @@ John Coiner
Julien Margetts
Kanad Kanhere
Kevin Kiningham
Kuba Ober
Lukasz Dalek
Maarten De Braekeleer
Matthew Ballance
Mike Popoloski
Peter Monsson
Patrick Stewart
Philipp Wagner
Richard Myers
@ -30,4 +32,5 @@ Sebastien Van Cauwenberghe
Stefan Wallentowitz
Todd Strader
Wilson Snyder
Yutetsu TAKATSUKASA
Yves Mathieu

View File

@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -1,6 +1,6 @@
// DESCRIPTION: Verilator: List of To Do issues.
//
// Copyright 2004-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.

View File

@ -21,9 +21,14 @@ Git, below, maybe a better alternative.) To install as a package:
If this works, skip down to <<Running Verilator>>.
=== Docker
Verilator is available in pre-built Docker containers. See
https://github.com/verilator/verilator/blob/master/ci/docker/run/README.adoc
=== Git
Alternatively, installing Verilator with Git provides the most flexibility.
Installing Verilator with Git provides the most flexibility.
For additional options and details see the additional sections below. In
brief:
@ -96,11 +101,11 @@ Those developing Verilator may also want these (see internals.adoc):
==== Install SystemC
If you will be using SystemC (vs straight C++ output), download
http://www.systemc.org[SystemC]. Follow their installation instructions.
You will need to set `SYSTEMC_INCLUDE` to point to the include directory
with systemc.h in it, and `SYSTEMC_LIBDIR` to points to the directory with
libsystemc.a in it. (Older installations may set `SYSTEMC` and
`SYSTEMC_ARCH` instead.)
https://www.accellera.org/downloads/standards/systemc[SystemC].
Follow their installation instructions. You will need to set `SYSTEMC_INCLUDE`
to point to the include directory with `systemc.h` in it, and `SYSTEMC_LIBDIR`
to points to the directory with `libsystemc.a` in it. (Older installations
may set `SYSTEMC` and `SYSTEMC_ARCH` instead.)
==== Install GTKWave
@ -289,6 +294,6 @@ or https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)].
== License
Copyright 2008-2019 by Wilson Snyder. Verilator is free software; you can
Copyright 2008-2020 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.

View File

@ -382,6 +382,13 @@ changed; if clear, checking those signals for changes may be skipped.
== Coding Conventions
=== Compiler Version and C++11
Verilator supports GCC 4.4.7 and newer. GCC 4.4.7 does not support C++11,
therefore C++11 is generally not required. Exceptions may be made to
require C++11 for features that are only practical with C++11,
e.g. threads.
=== Indentation and Naming Style
We will work with contributors to fix up indentation style issues, but it
@ -973,6 +980,6 @@ list in `src/Makefile_obj.in` and reconfigure.
== Distribution
Copyright 2008-2019 by Wilson Snyder. Verilator is free software; you can
Copyright 2008-2020 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.

View File

@ -5,7 +5,7 @@
# This is an example cmake script to build a verilog to systemc project
# using cmake and verilator.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -6,7 +6,7 @@
# This makefile is here for testing the examples and should
# generally not be added to a CMake project.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -5,7 +5,7 @@
# This is an example cmake script to build a verilog to SystemC project
# using CMake and Verilator.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -6,7 +6,7 @@
# This makefile is here for testing the examples and should
# generally not be added to a CMake project.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -5,7 +5,7 @@
# This is an example cmake script to build a verilog to systemc project
# using cmake and verilator.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -6,7 +6,7 @@
# This makefile is here for testing the examples and should
# generally not be added to a CMake project.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -5,7 +5,7 @@
# This is an example cmake script to build a verilog to systemc project
# using cmake and verilator.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -6,7 +6,7 @@
# This makefile is here for testing the examples and should
# generally not be added to a CMake project.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -5,7 +5,7 @@
# This is an example cmake script to build a verilog to SystemC project
# using CMake and Verilator.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -6,7 +6,7 @@
# This makefile is here for testing the examples and should
# generally not be added to a CMake project.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -5,7 +5,7 @@
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -5,7 +5,7 @@
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -5,7 +5,7 @@
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@ -52,6 +52,9 @@ VERILATOR_FLAGS += --coverage
# Add this trace to get a backtrace in gdb
#VERILATOR_FLAGS += --gdbbt
# Input files for Verilator
VERILATOR_INPUT = -f input.vc top.v sim_main.cpp
######################################################################
default: run
@ -61,7 +64,7 @@ run:
@echo
@echo "-- VERILATE ----------------"
$(VERILATOR) $(VERILATOR_FLAGS) -f input.vc top.v sim_main.cpp
$(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT)
@echo
@echo "-- COMPILE -----------------"
@ -72,11 +75,13 @@ run:
@echo
@echo "-- RUN ---------------------"
@rm -rf logs
@mkdir -p logs
obj_dir/Vtop +trace
@echo
@echo "-- COVERAGE ----------------"
@rm -rf logs/annotated
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
@echo

View File

@ -5,7 +5,7 @@
#
# This is executed in the object directory, and called by ../Makefile
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -5,7 +5,7 @@
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@ -52,6 +52,9 @@ VERILATOR_FLAGS += --coverage
# Add this trace to get a backtrace in gdb
#VERILATOR_FLAGS += --gdbbt
# Input files for Verilator
VERILATOR_INPUT = -f input.vc top.v sc_main.cpp
# Check if SC exists via a verilator call (empty if not)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE)
@ -69,10 +72,10 @@ run:
@echo
@echo "-- VERILATE ----------------"
$(VERILATOR) $(VERILATOR_FLAGS) -f input.vc top.v sc_main.cpp
$(VERILATOR) $(VERILATOR_FLAGS) $(VERILATOR_INPUT)
@echo
@echo "-- COMPILE ----------------="
@echo "-- COMPILE -----------------"
# To compile, we can either just do what Verilator asks,
# or call a submakefile where we can override the rules ourselves
# $(MAKE) -j 4 -C obj_dir -f Vtop.mk
@ -80,11 +83,13 @@ run:
@echo
@echo "-- RUN ---------------------"
@rm -rf logs
@mkdir -p logs
obj_dir/Vtop +trace
@echo
@echo "-- COVERAGE ----------------"
@rm -rf logs/annotated
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
@echo
@ -92,6 +97,7 @@ run:
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
@echo
######################################################################
# Other targets

View File

@ -5,7 +5,7 @@
#
# This is executed in the object directory, and called by ../Makefile
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -2,7 +2,7 @@
#
# DESCRIPTION: Verilator Example: XML tests
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -133,9 +133,9 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
#endif
#ifdef __GNUC__
// Boolean expression more often true than false
/* Boolean expression more often true than false */
#define FST_LIKELY(x) __builtin_expect(!!(x), 1)
// Boolean expression more often false than true
/* Boolean expression more often false than true */
#define FST_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define FST_LIKELY(x) (!!(x))
@ -737,6 +737,9 @@ off_t hier_file_len;
uint32_t *valpos_mem;
unsigned char *curval_mem;
unsigned char *outval_mem; /* for two-state / Verilator-style value changes */
uint32_t outval_alloc_siz;
char *filename;
fstHandle maxhandle;
@ -1944,6 +1947,11 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
}
}
fstDestroyMmaps(xc, 1);
if(xc->outval_mem)
{
free(xc->outval_mem); xc->outval_mem = NULL;
xc->outval_alloc_siz = 0;
}
/* write out geom section */
fflush(xc->geom_handle);
@ -2913,7 +2921,7 @@ if(FST_LIKELY((xc) && (handle <= xc->maxhandle)))
{
xc->vchg_alloc_siz += (xc->fst_break_add_size + len); /* +len added in the case of extremely long vectors and small break add sizes */
xc->vchg_mem = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz);
if(VL_UNLIKELY(!xc->vchg_mem))
if(FST_UNLIKELY(!xc->vchg_mem))
{
fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitValueChange, exiting.\n");
exit(255);
@ -2998,6 +3006,127 @@ if(FST_LIKELY((xc) && (handle <= xc->maxhandle)))
}
}
void fstWriterEmitValueChange32(void *ctx, fstHandle handle,
uint32_t bits, uint32_t val) {
char buf[32];
char *s = buf;
uint32_t i;
for (i = 0; i < bits; ++i)
{
*s++ = '0' + ((val >> (bits - i - 1)) & 1);
}
fstWriterEmitValueChange(ctx, handle, buf);
}
void fstWriterEmitValueChange64(void *ctx, fstHandle handle,
uint32_t bits, uint64_t val) {
char buf[64];
char *s = buf;
uint32_t i;
for (i = 0; i < bits; ++i)
{
*s++ = '0' + ((val >> (bits - i - 1)) & 1);
}
fstWriterEmitValueChange(ctx, handle, buf);
}
void fstWriterEmitValueChangeVec32(void *ctx, fstHandle handle,
uint32_t bits, const uint32_t *val) {
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
if (FST_UNLIKELY(bits <= 32))
{
fstWriterEmitValueChange32(ctx, handle, bits, val[0]);
}
else if(FST_LIKELY(xc))
{
int bq = bits / 32;
int br = bits & 31;
int i;
int w;
uint32_t v;
unsigned char* s;
if (FST_UNLIKELY(bits > xc->outval_alloc_siz))
{
xc->outval_alloc_siz = bits*2 + 1;
xc->outval_mem = (unsigned char*)realloc(xc->outval_mem, xc->outval_alloc_siz);
if (FST_UNLIKELY(!xc->outval_mem))
{
fprintf(stderr,
FST_APIMESS "Could not realloc() in fstWriterEmitValueChangeVec32, exiting.\n");
exit(255);
}
}
s = xc->outval_mem;
{
w = bq;
v = val[w];
for (i = 0; i < br; ++i)
{
*s++ = '0' + ((v >> (br - i - 1)) & 1);
}
}
for (w = bq - 1; w >= 0; --w)
{
v = val[w];
for (i = (32 - 4); i >= 0; i -= 4) {
s[0] = '0' + ((v >> (i + 3)) & 1);
s[1] = '0' + ((v >> (i + 2)) & 1);
s[2] = '0' + ((v >> (i + 1)) & 1);
s[3] = '0' + ((v >> (i + 0)) & 1);
s += 4;
}
}
fstWriterEmitValueChange(ctx, handle, xc->outval_mem);
}
}
void fstWriterEmitValueChangeVec64(void *ctx, fstHandle handle,
uint32_t bits, const uint64_t *val) {
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
if (FST_UNLIKELY(bits <= 64))
{
fstWriterEmitValueChange64(ctx, handle, bits, val[0]);
}
else if(FST_LIKELY(xc))
{
int bq = bits / 64;
int br = bits & 63;
int i;
int w;
uint32_t v;
unsigned char* s;
if (FST_UNLIKELY(bits > xc->outval_alloc_siz))
{
xc->outval_alloc_siz = bits*2 + 1;
xc->outval_mem = (unsigned char*)realloc(xc->outval_mem, xc->outval_alloc_siz);
if (FST_UNLIKELY(!xc->outval_mem))
{
fprintf(stderr,
FST_APIMESS "Could not realloc() in fstWriterEmitValueChangeVec64, exiting.\n");
exit(255);
}
}
s = xc->outval_mem;
{
w = bq;
v = val[w];
for (i = 0; i < br; ++i)
{
*s++ = '0' + ((v >> (br - i - 1)) & 1);
}
}
for (w = bq - 1; w >= 0; --w) {
v = val[w];
for (i = (64 - 4); i >= 0; i -= 4)
{
s[0] = '0' + ((v >> (i + 3)) & 1);
s[1] = '0' + ((v >> (i + 2)) & 1);
s[2] = '0' + ((v >> (i + 1)) & 1);
s[3] = '0' + ((v >> (i + 0)) & 1);
s += 4;
}
}
fstWriterEmitValueChange(ctx, handle, xc->outval_mem);
}
}
void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len)
{

View File

@ -355,6 +355,14 @@ fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDi
void fstWriterEmitDumpActive(void *ctx, int enable);
void fstWriterEmitEnumTableRef(void *ctx, fstEnumHandle handle);
void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val);
void fstWriterEmitValueChange32(void *ctx, fstHandle handle,
uint32_t bits, uint32_t val);
void fstWriterEmitValueChange64(void *ctx, fstHandle handle,
uint32_t bits, uint64_t val);
void fstWriterEmitValueChangeVec32(void *ctx, fstHandle handle,
uint32_t bits, const uint32_t *val);
void fstWriterEmitValueChangeVec64(void *ctx, fstHandle handle,
uint32_t bits, const uint64_t *val);
void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len);
void fstWriterEmitTimeChange(void *ctx, uint64_t tim);
void fstWriterFlushContext(void *ctx);

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@ -30,7 +30,9 @@
#include "verilated_config.h"
#include <algorithm>
#include <cctype>
#include <cerrno>
#include <sys/stat.h> // mkdir
#if defined(_WIN32) || defined(__MINGW32__)
@ -311,7 +313,7 @@ WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE {
if (i<(VL_WORDS_I(obits)-1)) {
outwp[i] = vl_rand64();
} else {
outwp[i] = vl_rand64() & VL_MASK_I(obits);
outwp[i] = vl_rand64() & VL_MASK_E(obits);
}
}
return outwp;
@ -323,7 +325,7 @@ IData VL_RAND_RESET_I(int obits) VL_MT_SAFE {
if (Verilated::randReset()!=1) { // if 2, randomize
data = VL_RANDOM_I(obits);
}
if (obits<32) data &= VL_MASK_I(obits);
data &= VL_MASK_I(obits);
return data;
}
QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE {
@ -332,7 +334,7 @@ QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE {
if (Verilated::randReset()!=1) { // if 2, randomize
data = VL_RANDOM_Q(obits);
}
if (obits<64) data &= VL_MASK_Q(obits);
data &= VL_MASK_Q(obits);
return data;
}
WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
@ -340,7 +342,7 @@ WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
if (i<(VL_WORDS_I(obits)-1)) {
outwp[i] = VL_RAND_RESET_I(32);
} else {
outwp[i] = VL_RAND_RESET_I(32) & VL_MASK_I(obits);
outwp[i] = VL_RAND_RESET_I(32) & VL_MASK_E(obits);
}
}
return outwp;
@ -356,7 +358,9 @@ WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) VL_MT_SAFE {
VL_PRINTF_MT(" Data: w%d: ", lbits);
for (int i=VL_WORDS_I(lbits)-1; i>=0; --i) { VL_PRINTF_MT("%08x ", iwp[i]); }
for (int i = VL_WORDS_I(lbits) - 1; i >= 0; --i) {
VL_PRINTF_MT("%08x ", iwp[i]);
}
VL_PRINTF_MT("\n");
}
@ -499,7 +503,7 @@ WDataOutP VL_POW_WWW(int obits, int, int rbits,
}
WDataOutP VL_POW_WWQ(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, QData rhs) VL_MT_SAFE {
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
WData rhsw[VL_WQ_WORDS_E]; VL_SET_WQ(rhsw, rhs);
return VL_POW_WWW(obits, lbits, rbits, owp, lwp, rhsw);
}
QData VL_POW_QQW(int, int, int rbits, QData lhs, WDataInP rwp) VL_MT_SAFE {
@ -520,14 +524,14 @@ WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, W
if (rsign && VL_SIGN_W(rbits, rwp)) {
int words = VL_WORDS_I(obits);
VL_ZERO_W(obits, owp);
IData lor = 0; // 0=all zeros, ~0=all ones, else mix
EData lor = 0; // 0=all zeros, ~0=all ones, else mix
for (int i=1; i < (words-1); ++i) {
lor |= lwp[i];
}
lor |= ( (lwp[words-1] == VL_MASK_I(rbits)) ? ~VL_UL(0) : 0);
lor |= ( (lwp[words-1] == VL_MASK_E(rbits)) ? ~VL_EUL(0) : 0);
if (lor==0 && lwp[0]==0) { return owp; } // "X" so return 0
else if (lor==0 && lwp[0]==1) { owp[0] = 1; return owp; } // 1
else if (lsign && lor == ~VL_UL(0) && lwp[0]==~VL_UL(0)) { // -1
else if (lsign && lor == ~VL_EUL(0) && lwp[0] == ~VL_EUL(0)) { // -1
if (rwp[0] & 1) { return VL_ALLONES_W(obits, owp); } // -1^odd=-1
else { owp[0] = 1; return owp; } // -1^even=1
}
@ -538,7 +542,7 @@ WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, W
WDataOutP VL_POWSS_WWQ(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, QData rhs,
bool lsign, bool rsign) VL_MT_SAFE {
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
WData rhsw[VL_WQ_WORDS_E]; VL_SET_WQ(rhsw, rhs);
return VL_POWSS_WWW(obits, lbits, rbits, owp, lwp, rhsw, lsign, rsign);
}
QData VL_POWSS_QQW(int obits, int, int rbits,
@ -576,7 +580,7 @@ std::string VL_DECIMAL_NW(int width, WDataInP lwp) VL_MT_SAFE {
for (int nibble_bit = 0; nibble_bit < maxdecwidth; nibble_bit+=4) {
if ((VL_BITRSHIFT_W(bcd, nibble_bit) & 0xf) >= 5) {
VL_ZERO_RESET_W(maxdecwidth, tmp2);
tmp2[VL_BITWORD_I(nibble_bit)] |= 0x3 << VL_BITBIT_I(nibble_bit);
tmp2[VL_BITWORD_E(nibble_bit)] |= VL_EUL(0x3) << VL_BITBIT_E(nibble_bit);
VL_ASSIGN_W(maxdecwidth, tmp, bcd);
VL_ADD_W(VL_WORDS_I(maxdecwidth), bcd, tmp, tmp2);
}
@ -599,7 +603,7 @@ std::string VL_DECIMAL_NW(int width, WDataInP lwp) VL_MT_SAFE {
}
// Do a va_arg returning a quad, assuming input argument is anything less than wide
#define _VL_VA_ARG_Q(ap, bits) (((bits) <= VL_WORDSIZE) ? va_arg(ap, IData) : va_arg(ap, QData))
#define _VL_VA_ARG_Q(ap, bits) (((bits) <= VL_IDATASIZE) ? va_arg(ap, IData) : va_arg(ap, QData))
void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SAFE {
// Format a Verilog $write style format into the output list
@ -658,6 +662,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
case '@': { // Verilog/C++ string
va_arg(ap, int); // # bits is ignored
const std::string* cstrp = va_arg(ap, const std::string*);
if (width > cstrp->size()) output += std::string(width - cstrp->size(), ' ');
output += *cstrp;
break;
}
@ -691,7 +696,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
// Deal with all read-and-print somethings
const int lbits = va_arg(ap, int);
QData ld = 0;
WData qlwp[2];
WData qlwp[VL_WQ_WORDS_E];
WDataInP lwp;
if (lbits <= VL_QUADSIZE) {
ld = _VL_VA_ARG_Q(ap, lbits);
@ -709,13 +714,17 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
output += charval;
break;
}
case 's':
case 's': {
std::string field;
for (; lsb>=0; --lsb) {
lsb = (lsb / 8) * 8; // Next digit
IData charval = VL_BITRSHIFT_W(lwp, lsb) & 0xff;
output += (charval==0)?' ':charval;
field += (charval==0)?' ':charval;
}
if (width > field.size()) output += std::string(width - field.size(), ' ');
output += field;
break;
}
case 'd': { // Signed decimal
int digits;
std::string append;
@ -724,7 +733,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
static_cast<vlsint64_t>(VL_EXTENDS_QQ(lbits, lbits, ld)));
append = tmp;
} else {
if (VL_SIGN_I(lbits, lwp[VL_WORDS_I(lbits)-1])) {
if (VL_SIGN_E(lbits, lwp[VL_WORDS_I(lbits) - 1])) {
WData neg[VL_VALUE_STRING_MAX_WIDTH/4+2];
VL_NEGATE_W(VL_WORDS_I(lbits), neg, lwp);
append = std::string("-") + VL_DECIMAL_NW(lbits, neg);
@ -966,7 +975,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
// Deal with all read-and-scan somethings
// Note LSBs are preserved if there's an overflow
const int obits = va_arg(ap, int);
WData qowp[2] = {0, 0};
WData qowp[VL_WQ_WORDS_E]; VL_SET_WQ(qowp, VL_ULL(0));
WDataOutP owp = qowp;
if (obits > VL_QUADSIZE) {
owp = va_arg(ap, WDataOutP);
@ -1055,7 +1064,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
CData* p = va_arg(ap, CData*); *p = owp[0];
} else if (obits <= VL_SHORTSIZE) {
SData* p = va_arg(ap, SData*); *p = owp[0];
} else if (obits <= VL_WORDSIZE) {
} else if (obits <= VL_IDATASIZE) {
IData* p = va_arg(ap, IData*); *p = owp[0];
} else if (obits <= VL_QUADSIZE) {
QData* p = va_arg(ap, QData*); *p = VL_SET_QW(owp);
@ -1112,9 +1121,9 @@ IData VL_FGETS_IXI(int obits, void* destp, IData fpi) VL_MT_SAFE {
// any read data. This means we can't know in what location the first
// character will finally live, so we need to copy. Yuk.
IData bytes = VL_BYTES_I(obits);
char buffer[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
char buffer[VL_TO_STRING_MAX_WORDS * VL_EDATASIZE + 1];
// V3Emit has static check that bytes < VL_TO_STRING_MAX_WORDS, but be safe
if (VL_UNCOVERABLE(bytes > VL_TO_STRING_MAX_WORDS*VL_WORDSIZE)) {
if (VL_UNCOVERABLE(bytes > VL_TO_STRING_MAX_WORDS * VL_EDATASIZE)) {
VL_FATAL_MT(__FILE__, __LINE__, "", "Internal: fgets buffer overrun"); // LCOV_EXCL_LINE
}
@ -1135,20 +1144,22 @@ IData VL_FGETS_IXI(int obits, void* destp, IData fpi) VL_MT_SAFE {
IData VL_FOPEN_NI(const std::string& filename, IData mode) VL_MT_SAFE {
// While threadsafe, each thread can only access different file handles
char modez[5];
_VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
EData modee = mode;
_VL_VINT_TO_STRING(VL_IDATASIZE, modez, &modee);
return VL_FOPEN_S(filename.c_str(), modez);
}
IData VL_FOPEN_QI(QData filename, IData mode) VL_MT_SAFE {
// While threadsafe, each thread can only access different file handles
WData fnw[2]; VL_SET_WQ(fnw, filename);
return VL_FOPEN_WI(2, fnw, mode);
WData fnw[VL_WQ_WORDS_E]; VL_SET_WQ(fnw, filename);
return VL_FOPEN_WI(VL_WQ_WORDS_E, fnw, mode);
}
IData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) VL_MT_SAFE {
// While threadsafe, each thread can only access different file handles
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, filenamez, filenamep);
char filenamez[VL_TO_STRING_MAX_WORDS * VL_EDATASIZE + 1];
_VL_VINT_TO_STRING(fnwords * VL_EDATASIZE, filenamez, filenamep);
EData modee = mode;
char modez[5];
_VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
_VL_VINT_TO_STRING(4 * sizeof(char), modez, &modee);
return VL_FOPEN_S(filenamez, modez);
}
IData VL_FOPEN_S(const char* filenamep, const char* modep) VL_MT_SAFE {
@ -1277,7 +1288,7 @@ IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) VL_MT_SAFE {
}
IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) VL_MT_SAFE {
WData fnw[2]; VL_SET_WI(fnw, ld);
WData fnw[VL_WQ_WORDS_E]; VL_SET_WI(fnw, ld);
va_list ap;
va_start(ap, formatp);
@ -1286,7 +1297,7 @@ IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) VL_MT_SAFE {
return got;
}
IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) VL_MT_SAFE {
WData fnw[2]; VL_SET_WQ(fnw, ld);
WData fnw[VL_WQ_WORDS_E]; VL_SET_WQ(fnw, ld);
va_list ap;
va_start(ap, formatp);
@ -1312,15 +1323,15 @@ IData VL_SSCANF_INX(int, const std::string& ld, const char* formatp, ...) VL_MT_
void VL_WRITEMEM_Q(bool hex, int width, int depth, int array_lsb, int,
QData filename, const void* memp, IData start,
IData end) VL_MT_SAFE {
WData fnw[2]; VL_SET_WQ(fnw, filename);
return VL_WRITEMEM_W(hex, width, depth, array_lsb,2, fnw, memp, start, end);
WData fnw[VL_WQ_WORDS_E]; VL_SET_WQ(fnw, filename);
return VL_WRITEMEM_W(hex, width, depth, array_lsb, VL_WQ_WORDS_E, fnw, memp, start, end);
}
void VL_WRITEMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
WDataInP filenamep, const void* memp, IData start,
IData end) VL_MT_SAFE {
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, filenamez, filenamep);
char filenamez[VL_TO_STRING_MAX_WORDS * VL_EDATASIZE + 1];
_VL_VINT_TO_STRING(fnwords * VL_EDATASIZE, filenamez, filenamep);
std::string filenames(filenamez);
return VL_WRITEMEM_N(hex, width, depth, array_lsb, filenames, memp, start, end);
}
@ -1425,21 +1436,20 @@ void VL_WRITEMEM_N(
} else {
WDataInP memDatap = reinterpret_cast<WDataInP>(memp);
WDataInP datap = &memDatap[row_offset * VL_WORDS_I(width)];
// output as a sequence of VL_WORDSIZE'd words
// output as a sequence of VL_EDATASIZE'd words
// from MSB to LSB. Mask off the MSB word which could
// contain junk above the top of valid data.
int word_idx = ((width - 1) / VL_WORDSIZE);
int word_idx = ((width - 1) / VL_EDATASIZE);
bool first = true;
while (word_idx >= 0) {
IData data = datap[word_idx];
EData data = datap[word_idx];
if (first) {
data &= VL_MASK_I(width);
int top_word_nbits = ((width - 1) & 0x1f) + 1;
data &= VL_MASK_E(width);
int top_word_nbits = ((width - 1) & (VL_EDATASIZE - 1)) + 1;
fprintf(fp, memhFormat(top_word_nbits), data);
} else {
fprintf(fp, "%08x", data);
}
word_idx--;
first = false;
}
@ -1477,7 +1487,7 @@ IData VL_FREAD_I(int width, int array_lsb, int array_size,
SData* datap = &(reinterpret_cast<SData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
*datap |= (c << shift) & VL_MASK_I(width);
} else if (width <= VL_WORDSIZE) {
} else if (width <= VL_IDATASIZE) {
IData* datap = &(reinterpret_cast<IData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
*datap |= (c << shift) & VL_MASK_I(width);
@ -1489,7 +1499,7 @@ IData VL_FREAD_I(int width, int array_lsb, int array_size,
} else {
WDataOutP datap = &(reinterpret_cast<WDataOutP>(memp))[entry * VL_WORDS_I(width)];
if (shift == start_shift) { VL_ZERO_RESET_W(width, datap); }
datap[VL_BITWORD_I(shift)] |= (c << VL_BITBIT_I(shift));
datap[VL_BITWORD_E(shift)] |= (static_cast<EData>(c) << VL_BITBIT_E(shift));
}
// Prep for next
++read_count;
@ -1505,14 +1515,14 @@ IData VL_FREAD_I(int width, int array_lsb, int array_size,
void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int,
QData filename, void* memp, IData start, IData end) VL_MT_SAFE {
WData fnw[2]; VL_SET_WQ(fnw, filename);
return VL_READMEM_W(hex, width, depth, array_lsb, 2, fnw, memp, start, end);
WData fnw[VL_WQ_WORDS_E]; VL_SET_WQ(fnw, filename);
return VL_READMEM_W(hex, width, depth, array_lsb, VL_WQ_WORDS_E, fnw, memp, start, end);
}
void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
WDataInP filenamep, void* memp, IData start, IData end) VL_MT_SAFE {
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, filenamez, filenamep);
char filenamez[VL_TO_STRING_MAX_WORDS * VL_EDATASIZE + 1];
_VL_VINT_TO_STRING(fnwords * VL_EDATASIZE, filenamez, filenamep);
std::string filenames(filenamez);
return VL_READMEM_N(hex, width, depth, array_lsb, filenames, memp, start, end);
}
@ -1601,7 +1611,7 @@ void VL_READMEM_N(
SData* datap = &(reinterpret_cast<SData*>(memp))[entry];
if (!innum) { *datap = 0; }
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
} else if (width<=VL_WORDSIZE) {
} else if (width <= VL_IDATASIZE) {
IData* datap = &(reinterpret_cast<IData*>(memp))[entry];
if (!innum) { *datap = 0; }
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
@ -1642,12 +1652,12 @@ void VL_READMEM_N(
}
IData VL_SYSTEM_IQ(QData lhs) VL_MT_SAFE {
WData lhsw[2]; VL_SET_WQ(lhsw, lhs);
return VL_SYSTEM_IW(2, lhsw);
WData lhsw[VL_WQ_WORDS_E]; VL_SET_WQ(lhsw, lhs);
return VL_SYSTEM_IW(VL_WQ_WORDS_E, lhsw);
}
IData VL_SYSTEM_IW(int lhswords, WDataInP lhsp) VL_MT_SAFE {
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
_VL_VINT_TO_STRING(lhswords*VL_WORDSIZE, filenamez, lhsp);
char filenamez[VL_TO_STRING_MAX_WORDS * VL_EDATASIZE + 1];
_VL_VINT_TO_STRING(lhswords * VL_EDATASIZE, filenamez, lhsp);
int code = system(filenamez); // Yes, system() is threadsafe
return code >> 8; // Want exit status
}
@ -1803,8 +1813,8 @@ std::string VL_TOUPPER_NN(const std::string& ld) VL_MT_SAFE {
std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE {
// See also _VL_VINT_TO_STRING
char destout[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
int obits = lwords * VL_WORDSIZE;
char destout[VL_TO_STRING_MAX_WORDS * VL_EDATASIZE + 1];
int obits = lwords * VL_EDATASIZE;
int lsb=obits-1;
bool start=true;
char* destp = destout;
@ -1821,6 +1831,66 @@ std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE {
return std::string(destout, len);
}
std::string VL_PUTC_N(const std::string& lhs, IData rhs, CData ths) VL_PURE {
std::string lstring = lhs;
const vlsint32_t rhs_s = rhs; // To signed value
// 6.16.2:str.putc(i, c) does not change the value when i < 0 || i >= str.len() || c == 0
if (0 <= rhs_s && rhs < lhs.length() && ths != 0) lstring[rhs] = ths;
return lstring;
}
CData VL_GETC_N(const std::string& lhs, IData rhs) VL_PURE {
CData v = 0;
const vlsint32_t rhs_s = rhs; // To signed value
// 6.16.3:str.getc(i) returns 0 if i < 0 || i >= str.len()
if (0 <= rhs_s && rhs < lhs.length()) v = lhs[rhs];
return v;
}
std::string VL_SUBSTR_N(const std::string& lhs, IData rhs, IData ths) VL_PURE {
const vlsint32_t rhs_s = rhs; // To signed value
const vlsint32_t ths_s = ths; // To signed value
// 6.16.8:str.substr(i, j) returns an empty string when i < 0 || j < i || j >= str.len()
if (rhs_s < 0 || ths_s < rhs_s || ths >= lhs.length()) return "";
// Second parameter of std::string::substr(i, n) is length, not position as in SystemVerilog
return lhs.substr(rhs, ths - rhs + 1);
}
IData VL_ATOI_N(const std::string& str, int base) VL_PURE {
std::string str_mod = str;
// IEEE 1800-2017 6.16.9 says '_' may exist.
str_mod.erase(std::remove(str_mod.begin(), str_mod.end(), '_'), str_mod.end());
errno = 0;
long v = std::strtol(str_mod.c_str(), NULL, base);
if (errno != 0) v = 0;
return static_cast<IData>(v);
}
//===========================================================================
// Timescale conversion
// Helper function for conversion of timescale strings
// Converts (1|10|100)(s|ms|us|ns|ps|fs) to power of then
int VL_TIME_STR_CONVERT(const char* strp) {
int scale = 0;
if (!strp) return 0;
if (*strp++ != '1') return 0;
while (*strp == '0') { scale++; strp++; }
switch (*strp++) {
case 's': break;
case 'm': scale -= 3; break;
case 'u': scale -= 6; break;
case 'n': scale -= 9; break;
case 'p': scale -= 12; break;
case 'f': scale -= 15; break;
default: return 0;
}
if ((scale < 0) && (*strp++ != 's')) return 0;
if (*strp) return 0;
return scale;
}
//===========================================================================
// Verilated:: Methods

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@ -64,7 +64,8 @@ typedef vluint8_t CData; ///< Verilated pack data, 1-8 bits
typedef vluint16_t SData; ///< Verilated pack data, 9-16 bits
typedef vluint32_t IData; ///< Verilated pack data, 17-32 bits
typedef vluint64_t QData; ///< Verilated pack data, 33-64 bits
typedef vluint32_t WData; ///< Verilated pack data, >64 bits, as an array
typedef vluint32_t EData; ///< Verilated pack element of WData array
typedef EData WData; ///< Verilated pack data, >64 bits, as an array
// float F // No typedef needed; Verilator uses float
// double D // No typedef needed; Verilator uses double
// string N // No typedef needed; Verilator uses string
@ -192,7 +193,8 @@ public:
// CONSTRUCTORS
/// The constructor establishes the thread id for all later calls.
/// If necessary, a different class could be made that inits it otherwise.
VerilatedAssertOneThread() : m_threadid(VL_THREAD_ID()) { }
VerilatedAssertOneThread()
: m_threadid(VL_THREAD_ID()) {}
~VerilatedAssertOneThread() { check(); }
// METHODS
/// Check that the current thread ID is the same as the construction thread ID
@ -671,21 +673,21 @@ extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
/// Return true if data[bit] set; not 0/1 return, but 0/non-zero return.
#define VL_BITISSET_I(data,bit) ((data) & (VL_UL(1) << VL_BITBIT_I(bit)))
#define VL_BITISSET_Q(data,bit) ((data) & (VL_ULL(1) << VL_BITBIT_Q(bit)))
#define VL_BITISSET_W(data,bit) ((data)[VL_BITWORD_I(bit)] & (VL_UL(1) << VL_BITBIT_I(bit)))
#define VL_BITISSETLIMIT_W(data,width,bit) \
(((bit)<(width)) && (data)[VL_BITWORD_I(bit)] & (VL_UL(1) << VL_BITBIT_I(bit)))
#define VL_BITISSET_E(data,bit) ((data) & (VL_EUL(1) << VL_BITBIT_E(bit)))
#define VL_BITISSET_W(data,bit) ((data)[VL_BITWORD_E(bit)] & (VL_EUL(1) << VL_BITBIT_E(bit)))
#define VL_BITISSETLIMIT_W(data,width,bit) (((bit) < (width)) && VL_BITISSET_W(data,bit))
/// Shift appropriate word by bit. Does not account for wrapping between two words
#define VL_BITRSHIFT_W(data,bit) ((data)[VL_BITWORD_I(bit)] >> VL_BITBIT_I(bit))
#define VL_BITRSHIFT_W(data,bit) ((data)[VL_BITWORD_E(bit)] >> VL_BITBIT_E(bit))
/// Create two 32-bit words from quadword
/// WData is always at least 2 words; does not clean upper bits
#define VL_SET_WQ(owp,data) { (owp)[0] = static_cast<IData>(data); \
(owp)[1] = static_cast<IData>((data)>>VL_WORDSIZE); }
(owp)[1] = static_cast<IData>((data) >> VL_EDATASIZE); }
#define VL_SET_WI(owp,data) { (owp)[0] = static_cast<IData>(data); (owp)[1] = 0; }
#define VL_SET_QW(lwp) \
( (static_cast<QData>((lwp)[0])) \
| (static_cast<QData>((lwp)[1]) << (static_cast<QData>(VL_WORDSIZE)) ))
| (static_cast<QData>((lwp)[1]) << (static_cast<QData>(VL_EDATASIZE)) ))
#define _VL_SET_QII(ld,rd) ((static_cast<QData>(ld)<<VL_ULL(32)) | static_cast<QData>(rd))
/// Return FILE* from IData
@ -718,8 +720,10 @@ static inline IData VL_RTOIROUND_I_D(double lhs) VL_PURE {
// (Requires clean input)
#define VL_SIGN_I(nbits,lhs) ((lhs) >> VL_BITBIT_I((nbits) - VL_UL(1)))
#define VL_SIGN_Q(nbits,lhs) ((lhs) >> VL_BITBIT_Q((nbits) - VL_ULL(1)))
#define VL_SIGN_W(nbits,rwp) ((rwp)[VL_BITWORD_I((nbits)-VL_UL(1))] >> VL_BITBIT_I((nbits)-VL_UL(1)))
#define VL_SIGNONES_I(nbits,lhs) (-(VL_SIGN_I(nbits, lhs)))
#define VL_SIGN_E(nbits,lhs) ((lhs) >> VL_BITBIT_E((nbits) - VL_EUL(1)))
#define VL_SIGN_W(nbits,rwp) \
((rwp)[VL_BITWORD_E((nbits) - VL_EUL(1))] >> VL_BITBIT_E((nbits) - VL_EUL(1)))
#define VL_SIGNONES_E(nbits, lhs) (-(VL_SIGN_E(nbits, lhs)))
// Sign bit extended up to MSB, doesn't include unsigned portion
// Optimization bug in GCC 3.3 returns different bitmasks to later states for
@ -734,9 +738,22 @@ extern void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp);
//=========================================================================
// Pli macros
extern int VL_TIME_STR_CONVERT(const char* strp) VL_PURE;
#ifndef VL_TIME_PRECISION
# ifdef VL_TIME_PRECISION_STR
# define VL_TIME_PRECISION VL_TIME_STR_CONVERT(VL_STRINGIFY(VL_TIME_PRECISION_STR))
# else
# define VL_TIME_PRECISION (-12) ///< Timescale units only for for VPI return - picoseconds
# endif
#endif
#ifndef VL_TIME_UNIT
# ifdef VL_TIME_UNIT_STR
# define VL_TIME_UNIT VL_TIME_STR_CONVERT(VL_STRINGIFY(VL_TIME_PRECISION_STR))
# else
# define VL_TIME_UNIT (-12) ///< Timescale units only for for VPI return - picoseconds
# endif
#endif
#ifndef VL_TIME_MULTIPLIER
# define VL_TIME_MULTIPLIER 1
#endif
@ -787,13 +804,13 @@ extern double sc_time_stamp();
#define VL_ASSIGNCLEAN_W(obits,owp,lwp) VL_CLEAN_WW((obits), (obits), (owp), (lwp))
static inline WDataOutP _VL_CLEAN_INPLACE_W(int obits, WDataOutP owp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
owp[words-1] &= VL_MASK_I(obits);
owp[words-1] &= VL_MASK_E(obits);
return owp;
}
static inline WDataOutP VL_CLEAN_WW(int obits, int, WDataOutP owp, WDataInP lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
for (int i=0; (i < (words-1)); ++i) owp[i] = lwp[i];
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
owp[words-1] = lwp[words-1] & VL_MASK_E(obits);
return owp;
}
static inline WDataOutP VL_ZERO_W(int obits, WDataOutP owp) VL_MT_SAFE {
@ -803,8 +820,8 @@ static inline WDataOutP VL_ZERO_W(int obits, WDataOutP owp) VL_MT_SAFE {
}
static inline WDataOutP VL_ALLONES_W(int obits, WDataOutP owp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
for (int i=0; (i < (words-1)); ++i) owp[i] = ~VL_UL(0);
owp[words-1] = VL_MASK_I(obits);
for (int i = 0; i < (words - 1); ++i) owp[i] = ~VL_EUL(0);
owp[words-1] = VL_MASK_E(obits);
return owp;
}
@ -832,12 +849,12 @@ static inline void VL_ASSIGNBIT_II(int, int bit, IData& lhsr, IData rhs) VL_PURE
}
static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) VL_PURE {
lhsr = ((lhsr & ~(VL_ULL(1)<<VL_BITBIT_Q(bit)))
| (rhs<<VL_BITBIT_Q(bit)));
| (static_cast<QData>(rhs) << VL_BITBIT_Q(bit)));
}
static inline void VL_ASSIGNBIT_WI(int, int bit, WDataOutP owp, IData rhs) VL_MT_SAFE {
IData orig = owp[VL_BITWORD_I(bit)];
owp[VL_BITWORD_I(bit)] = ((orig & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| (rhs<<VL_BITBIT_I(bit)));
EData orig = owp[VL_BITWORD_E(bit)];
owp[VL_BITWORD_E(bit)] = ((orig & ~(VL_EUL(1) << VL_BITBIT_E(bit)))
| (static_cast<EData>(rhs) << VL_BITBIT_E(bit)));
}
// Alternative form that is an instruction faster when rhs is constant one.
static inline void VL_ASSIGNBIT_IO(int, int bit, CData& lhsr, IData) VL_PURE {
@ -853,8 +870,8 @@ static inline void VL_ASSIGNBIT_QO(int, int bit, QData& lhsr, IData) VL_PURE {
lhsr = (lhsr | (VL_ULL(1) << VL_BITBIT_Q(bit)));
}
static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) VL_MT_SAFE {
IData orig = owp[VL_BITWORD_I(bit)];
owp[VL_BITWORD_I(bit)] = (orig | (VL_UL(1)<<VL_BITBIT_I(bit)));
EData orig = owp[VL_BITWORD_E(bit)];
owp[VL_BITWORD_E(bit)] = (orig | (VL_EUL(1) << VL_BITBIT_E(bit)));
}
//===================================================================
@ -869,14 +886,14 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) VL_MT_SAF
(od) = ((svar).read().get_word(0)) & VL_MASK_I(obits); \
}
#define VL_ASSIGN_QSW(obits,od,svar) { \
(od) = ((static_cast<QData>((svar).read().get_word(1)))<<VL_WORDSIZE \
(od) = ((static_cast<QData>((svar).read().get_word(1)))<<VL_IDATASIZE \
| (svar).read().get_word(0)) \
& VL_MASK_Q(obits); \
}
#define VL_ASSIGN_WSW(obits,owp,svar) { \
int words = VL_WORDS_I(obits); \
for (int i=0; i < words; ++i) (owp)[i] = (svar).read().get_word(i); \
(owp)[words-1] &= VL_MASK_I(obits); \
(owp)[words-1] &= VL_MASK_E(obits); \
}
#define VL_ASSIGN_ISU(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits), (obits), (svar).read().to_uint()); }
@ -885,11 +902,11 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) VL_MT_SAF
int words = VL_WORDS_I(obits); \
sc_biguint<(obits)> _butemp = (svar).read(); \
for (int i=0; i < words; ++i) { \
int msb = ((i+1)*VL_WORDSIZE) - 1; \
int msb = ((i + 1) * VL_IDATASIZE) - 1; \
msb = (msb >= (obits)) ? ((obits)-1) : msb; \
(owp)[i] = _butemp.range(msb, i*VL_WORDSIZE).to_uint(); \
(owp)[i] = _butemp.range(msb, i * VL_IDATASIZE).to_uint(); \
} \
(owp)[words-1] &= VL_MASK_I(obits); \
(owp)[words-1] &= VL_MASK_E(obits); \
}
// Copying verilog format from systemc integers and bit vectors.
@ -906,7 +923,7 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) VL_MT_SAF
#define VL_ASSIGN_SWQ(obits,svar,rd) { \
sc_bv<(obits)> _bvtemp; \
_bvtemp.set_word(0, static_cast<IData>(rd)); \
_bvtemp.set_word(1, static_cast<IData>((rd)>>VL_WORDSIZE)); \
_bvtemp.set_word(1, static_cast<IData>((rd) >> VL_IDATASIZE)); \
(svar).write(_bvtemp); \
}
#define VL_ASSIGN_SWW(obits,svar,rwp) { \
@ -922,9 +939,9 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) VL_MT_SAF
#define VL_ASSIGN_SBW(obits,svar,rwp) { \
sc_biguint<(obits)> _butemp; \
for (int i=0; i < VL_WORDS_I(obits); ++i) { \
int msb = ((i+1)*VL_WORDSIZE) - 1; \
int msb = ((i + 1) * VL_IDATASIZE) - 1; \
msb = (msb >= (obits)) ? ((obits)-1) : msb; \
_butemp.range(msb, i*VL_WORDSIZE) = (rwp)[i]; \
_butemp.range(msb, i * VL_IDATASIZE) = (rwp)[i]; \
} \
(svar).write(_butemp); \
}
@ -948,7 +965,7 @@ static inline WDataOutP VL_EXTEND_WI(int obits, int, WDataOutP owp, IData ld) VL
}
static inline WDataOutP VL_EXTEND_WQ(int obits, int, WDataOutP owp, QData ld) VL_MT_SAFE {
VL_SET_WQ(owp, ld);
for (int i=2; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
for (int i = VL_WQ_WORDS_E; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
return owp;
}
static inline WDataOutP VL_EXTEND_WW(int obits, int lbits, WDataOutP owp, WDataInP lwp) VL_MT_SAFE {
@ -970,23 +987,23 @@ static inline QData VL_EXTENDS_QQ(int, int lbits, QData lhs) VL_PURE {
}
static inline WDataOutP VL_EXTENDS_WI(int obits, int lbits, WDataOutP owp, IData ld) VL_MT_SAFE {
IData sign = VL_SIGNONES_I(lbits, ld);
owp[0] = ld | (sign & ~VL_MASK_I(lbits));
EData sign = VL_SIGNONES_E(lbits, static_cast<EData>(ld));
owp[0] = ld | (sign & ~VL_MASK_E(lbits));
for (int i = 1; i < VL_WORDS_I(obits); ++i) owp[i] = sign;
return owp;
}
static inline WDataOutP VL_EXTENDS_WQ(int obits, int lbits, WDataOutP owp, QData ld) VL_MT_SAFE {
VL_SET_WQ(owp, ld);
IData sign = VL_SIGNONES_I(lbits, owp[1]);
owp[1] |= sign & ~VL_MASK_I(lbits);
for (int i=2; i < VL_WORDS_I(obits); ++i) owp[i] = sign;
EData sign = VL_SIGNONES_E(lbits, owp[1]);
owp[1] |= sign & ~VL_MASK_E(lbits);
for (int i = VL_WQ_WORDS_E; i < VL_WORDS_I(obits); ++i) owp[i] = sign;
return owp;
}
static inline WDataOutP VL_EXTENDS_WW(int obits, int lbits, WDataOutP owp, WDataInP lwp) VL_MT_SAFE {
for (int i = 0; i < VL_WORDS_I(lbits)-1; ++i) owp[i] = lwp[i];
int lmsw = VL_WORDS_I(lbits) - 1;
IData sign = VL_SIGNONES_I(lbits, lwp[lmsw]);
owp[lmsw] = lwp[lmsw] | (sign & ~VL_MASK_I(lbits));
EData sign = VL_SIGNONES_E(lbits, lwp[lmsw]);
owp[lmsw] = lwp[lmsw] | (sign & ~VL_MASK_E(lbits));
for (int i = VL_WORDS_I(lbits); i < VL_WORDS_I(obits); ++i) owp[i] = sign;
return owp;
}
@ -999,9 +1016,9 @@ static inline WDataOutP VL_EXTENDS_WW(int obits, int lbits, WDataOutP owp, WData
#define VL_REDAND_IQ(obits,lbits,lhs) ((lhs) == VL_MASK_Q(lbits))
static inline IData VL_REDAND_IW(int, int lbits, WDataInP lwp) VL_MT_SAFE {
int words = VL_WORDS_I(lbits);
IData combine = lwp[0];
EData combine = lwp[0];
for (int i = 1; i < words - 1; ++i) combine &= lwp[i];
combine &= ~VL_MASK_I(lbits) | lwp[words-1];
combine &= ~VL_MASK_E(lbits) | lwp[words-1];
return ((~combine)==0);
}
@ -1009,7 +1026,7 @@ static inline IData VL_REDAND_IW(int, int lbits, WDataInP lwp) VL_MT_SAFE {
#define VL_REDOR_I(lhs) ((lhs)!=0)
#define VL_REDOR_Q(lhs) ((lhs)!=0)
static inline IData VL_REDOR_W(int words, WDataInP lwp) VL_MT_SAFE {
IData equal = 0;
EData equal = 0;
for (int i=0; i < words; ++i) equal |= lwp[i];
return (equal != 0);
}
@ -1061,7 +1078,7 @@ static inline IData VL_REDXOR_64(QData r) VL_PURE {
#endif
}
static inline IData VL_REDXOR_W(int words, WDataInP lwp) VL_MT_SAFE {
IData r = lwp[0];
EData r = lwp[0];
for (int i=1; i < words; ++i) r ^= lwp[i];
return VL_REDXOR_32(r);
}
@ -1078,9 +1095,10 @@ static inline IData VL_COUNTONES_I(IData lhs) VL_PURE {
static inline IData VL_COUNTONES_Q(QData lhs) VL_PURE {
return VL_COUNTONES_I(static_cast<IData>(lhs)) + VL_COUNTONES_I(static_cast<IData>(lhs>>32));
}
#define VL_COUNTONES_E VL_COUNTONES_I
static inline IData VL_COUNTONES_W(int words, WDataInP lwp) VL_MT_SAFE {
IData r = 0;
for (int i=0; (i < words); ++i) r+=VL_COUNTONES_I(lwp[i]);
EData r = 0;
for (int i = 0; i < words; ++i) r += VL_COUNTONES_E(lwp[i]);
return r;
}
@ -1091,7 +1109,7 @@ static inline IData VL_ONEHOT_Q(QData lhs) VL_PURE {
return (((lhs & (lhs-1))==0) & (lhs!=0));
}
static inline IData VL_ONEHOT_W(int words, WDataInP lwp) VL_MT_SAFE {
IData one = 0;
EData one = 0;
for (int i=0; (i < words); ++i) {
if (lwp[i]) {
if (one) return 0;
@ -1136,12 +1154,12 @@ static inline IData VL_CLOG2_Q(QData lhs) VL_PURE {
return shifts;
}
static inline IData VL_CLOG2_W(int words, WDataInP lwp) VL_MT_SAFE {
IData adjust = (VL_COUNTONES_W(words, lwp)==1) ? 0 : 1;
EData adjust = (VL_COUNTONES_W(words, lwp) == 1) ? 0 : 1;
for (int i=words-1; i>=0; --i) {
if (VL_UNLIKELY(lwp[i])) { // Shorter worst case if predict not taken
for (int bit=31; bit>=0; --bit) {
if (VL_UNLIKELY(VL_BITISSET_I(lwp[i], bit))) {
return i*VL_WORDSIZE + bit + adjust;
for (int bit = VL_EDATASIZE - 1; bit >= 0; --bit) {
if (VL_UNLIKELY(VL_BITISSET_E(lwp[i], bit))) {
return i * VL_EDATASIZE + bit + adjust;
}
}
// Can't get here - one bit must be set
@ -1154,9 +1172,9 @@ static inline IData VL_MOSTSETBITP1_W(int words, WDataInP lwp) VL_MT_SAFE {
// MSB set bit plus one; similar to FLS. 0=value is zero
for (int i=words-1; i>=0; --i) {
if (VL_UNLIKELY(lwp[i])) { // Shorter worst case if predict not taken
for (int bit=31; bit>=0; --bit) {
if (VL_UNLIKELY(VL_BITISSET_I(lwp[i], bit))) {
return i*VL_WORDSIZE + bit + 1;
for (int bit = VL_EDATASIZE - 1; bit >= 0; --bit) {
if (VL_UNLIKELY(VL_BITISSET_E(lwp[i], bit))) {
return i * VL_EDATASIZE + bit + 1;
}
}
// Can't get here - one bit must be set
@ -1217,7 +1235,7 @@ static inline WDataOutP VL_NOT_W(int words, WDataOutP owp, WDataInP lwp) VL_MT_S
// Output clean, <lhs> AND <rhs> MUST BE CLEAN
static inline IData VL_EQ_W(int words, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
int nequal = 0;
EData nequal = 0;
for (int i=0; (i < words); ++i) nequal |= (lwp[i] ^ rwp[i]);
return (nequal==0);
}
@ -1286,8 +1304,8 @@ static inline int _VL_CMPS_W(int lbits, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
int words = VL_WORDS_I(lbits);
int i = words-1;
// We need to flip sense if negative comparison
IData lsign = VL_SIGN_I(lbits, lwp[i]);
IData rsign = VL_SIGN_I(lbits, rwp[i]);
EData lsign = VL_SIGN_E(lbits, lwp[i]);
EData rsign = VL_SIGN_E(lbits, rwp[i]);
if (!lsign && rsign) return 1; // + > -
if (lsign && !rsign) return -1; // - < +
for (; i>=0; --i) {
@ -1300,6 +1318,22 @@ static inline int _VL_CMPS_W(int lbits, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
//=========================================================================
// Math
// Optimization bug in GCC 2.96 and presumably all-pre GCC 3 versions need this workaround,
// we can't just
//# define VL_NEGATE_I(data) (-(data))
static inline IData VL_NEGATE_I(IData data) VL_PURE { return -data; }
static inline QData VL_NEGATE_Q(QData data) VL_PURE { return -data; }
static inline EData VL_NEGATE_E(EData data) VL_PURE { return -data; }
static inline WDataOutP VL_NEGATE_W(int words, WDataOutP owp, WDataInP lwp) VL_MT_SAFE {
EData carry = 1;
for (int i = 0; i < words; ++i) {
owp[i] = ~lwp[i] + carry;
carry = (owp[i] < ~lwp[i]);
}
return owp;
}
// EMIT_RULE: VL_MUL: oclean=dirty; lclean==clean; rclean==clean;
// EMIT_RULE: VL_DIV: oclean=dirty; lclean==clean; rclean==clean;
// EMIT_RULE: VL_MODDIV: oclean=dirty; lclean==clean; rclean==clean;
@ -1317,6 +1351,7 @@ static inline WDataOutP VL_ADD_W(int words, WDataOutP owp, WDataInP lwp, WDataIn
owp[i] = (carry & VL_ULL(0xffffffff));
carry = (carry >> VL_ULL(32)) & VL_ULL(0xffffffff);
}
// Last output word is dirty
return owp;
}
@ -1325,27 +1360,11 @@ static inline WDataOutP VL_SUB_W(int words, WDataOutP owp, WDataInP lwp, WDataIn
for (int i = 0; i < words; ++i) {
carry = (carry + static_cast<QData>(lwp[i])
+ static_cast<QData>(static_cast<IData>(~rwp[i])));
if (i==0) ++carry; // Negation of temp2
owp[i] = (carry & VL_ULL(0xffffffff));
carry = (carry >> VL_ULL(32)) & VL_ULL(0xffffffff);
}
return owp;
}
// Optimization bug in GCC 2.96 and presumably all-pre GCC 3 versions need this workaround,
// we can't just
//# define VL_NEGATE_I(data) (-(data))
static inline IData VL_NEGATE_I(IData data) VL_PURE { return -data; }
static inline QData VL_NEGATE_Q(QData data) VL_PURE { return -data; }
static inline WDataOutP VL_NEGATE_W(int words, WDataOutP owp, WDataInP lwp) VL_MT_SAFE {
QData carry = 0;
for (int i=0; i<words; ++i) {
carry = carry + static_cast<QData>(static_cast<IData>(~lwp[i]));
if (i==0) ++carry; // Negation of temp2
if (i == 0) ++carry; // Negation of rwp
owp[i] = (carry & VL_ULL(0xffffffff));
carry = (carry >> VL_ULL(32)) & VL_ULL(0xffffffff);
}
// Last output word is dirty
return owp;
}
@ -1385,20 +1404,21 @@ static inline WDataOutP VL_MULS_WWW(int, int lbits, int,
WData rwstore[VL_MULS_MAX_WORDS];
WDataInP lwusp = lwp;
WDataInP rwusp = rwp;
IData lneg = VL_SIGN_I(lbits, lwp[words-1]);
EData lneg = VL_SIGN_E(lbits, lwp[words - 1]);
if (lneg) { // Negate lhs
lwusp = lwstore;
VL_NEGATE_W(words, lwstore, lwp);
lwstore[words-1] &= VL_MASK_I(lbits); // Clean it
lwstore[words - 1] &= VL_MASK_E(lbits); // Clean it
}
IData rneg = VL_SIGN_I(lbits, rwp[words-1]);
EData rneg = VL_SIGN_E(lbits, rwp[words - 1]);
if (rneg) { // Negate rhs
rwusp = rwstore;
VL_NEGATE_W(words, rwstore, rwp);
rwstore[words-1] &= VL_MASK_I(lbits); // Clean it
rwstore[words - 1] &= VL_MASK_E(lbits); // Clean it
}
VL_MUL_W(words, owp, lwusp, rwusp);
owp[words-1] &= VL_MASK_I(lbits); // Clean. Note it's ok for the multiply to overflow into the sign bit
owp[words - 1] &= VL_MASK_E(
lbits); // Clean. Note it's ok for the multiply to overflow into the sign bit
if ((lneg ^ rneg) & 1) { // Negate output (not using NEGATE, as owp==lwp)
QData carry = 0;
for (int i = 0; i < words; ++i) {
@ -1407,7 +1427,7 @@ static inline WDataOutP VL_MULS_WWW(int, int lbits, int,
owp[i] = (carry & VL_ULL(0xffffffff));
carry = (carry >> VL_ULL(32)) & VL_ULL(0xffffffff);
}
//Not needed: owp[words-1] |= 1<<VL_BITBIT_I(lbits-1); // Set sign bit
// Not needed: owp[words-1] |= 1<<VL_BITBIT_E(lbits-1); // Set sign bit
}
// Last output word is dirty
return owp;
@ -1415,33 +1435,34 @@ static inline WDataOutP VL_MULS_WWW(int, int lbits, int,
static inline IData VL_DIVS_III(int lbits, IData lhs, IData rhs) VL_PURE {
if (VL_UNLIKELY(rhs == 0)) return 0;
vlsint32_t lhs_signed = VL_EXTENDS_II(32, lbits, lhs);
vlsint32_t rhs_signed = VL_EXTENDS_II(32, lbits, rhs);
vlsint32_t lhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, lhs);
vlsint32_t rhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, rhs);
return lhs_signed / rhs_signed;
}
static inline QData VL_DIVS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
if (VL_UNLIKELY(rhs == 0)) return 0;
vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
vlsint64_t lhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, lhs);
vlsint64_t rhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, rhs);
return lhs_signed / rhs_signed;
}
static inline IData VL_MODDIVS_III(int lbits, IData lhs, IData rhs) VL_PURE {
if (VL_UNLIKELY(rhs == 0)) return 0;
vlsint32_t lhs_signed = VL_EXTENDS_II(32, lbits, lhs);
vlsint32_t rhs_signed = VL_EXTENDS_II(32, lbits, rhs);
vlsint32_t lhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, lhs);
vlsint32_t rhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, rhs);
return lhs_signed % rhs_signed;
}
static inline QData VL_MODDIVS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
if (VL_UNLIKELY(rhs == 0)) return 0;
vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
vlsint64_t lhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, lhs);
vlsint64_t rhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, rhs);
return lhs_signed % rhs_signed;
}
static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP lwp,
WDataInP rwp) VL_MT_SAFE {
int words = VL_WORDS_I(lbits);
IData lsign = VL_SIGN_I(lbits, lwp[words-1]);
IData rsign = VL_SIGN_I(lbits, rwp[words-1]);
EData lsign = VL_SIGN_E(lbits, lwp[words - 1]);
EData rsign = VL_SIGN_E(lbits, rwp[words - 1]);
// cppcheck-suppress variableScope
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
// cppcheck-suppress variableScope
@ -1451,7 +1472,7 @@ static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP lwp, WDat
if (lsign) { ltup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp)); }
if (rsign) { rtup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp)); }
if ((lsign && !rsign) || (!lsign && rsign)) {
IData qNoSign[VL_MULS_MAX_WORDS];
WData qNoSign[VL_MULS_MAX_WORDS];
VL_DIV_WWW(lbits, qNoSign, ltup, rtup);
_VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), owp, qNoSign));
return owp;
@ -1459,10 +1480,11 @@ static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP lwp, WDat
return VL_DIV_WWW(lbits, owp, ltup, rtup);
}
}
static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp, WDataInP lwp,
WDataInP rwp) VL_MT_SAFE {
int words = VL_WORDS_I(lbits);
IData lsign = VL_SIGN_I(lbits, lwp[words-1]);
IData rsign = VL_SIGN_I(lbits, rwp[words-1]);
EData lsign = VL_SIGN_E(lbits, lwp[words - 1]);
EData rsign = VL_SIGN_E(lbits, rwp[words - 1]);
// cppcheck-suppress variableScope
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
// cppcheck-suppress variableScope
@ -1484,7 +1506,8 @@ static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp, WDataInP lwp, W
#define VL_POW_IIQ(obits, lbits, rbits, lhs, rhs) VL_POW_QQQ(obits, lbits, rbits, lhs, rhs)
#define VL_POW_IIW(obits, lbits, rbits, lhs, rwp) VL_POW_QQW(obits, lbits, rbits, lhs, rwp)
#define VL_POW_QQI(obits, lbits, rbits, lhs, rhs) VL_POW_QQQ(obits, lbits, rbits, lhs, rhs)
#define VL_POW_WWI(obits,lbits,rbits,owp,lwp,rhs) VL_POW_WWQ(obits,lbits,rbits,owp,lwp,rhs)
#define VL_POW_WWI(obits, lbits, rbits, owp, lwp, rhs) \
VL_POW_WWQ(obits, lbits, rbits, owp, lwp, rhs)
static inline IData VL_POW_III(int, int, int rbits, IData lhs, IData rhs) VL_PURE {
if (VL_UNLIKELY(rhs == 0)) return 1;
@ -1580,24 +1603,24 @@ static inline void _VL_INSERT_QQ(int, QData& lhsr, QData ld, int hbit, int lbit)
lhsr = (lhsr & ~insmask) | ((ld << lbit) & insmask);
}
static inline void _VL_INSERT_WI(int, WDataOutP owp, IData ld, int hbit, int lbit) VL_MT_SAFE {
int hoffset = VL_BITBIT_I(hbit);
int loffset = VL_BITBIT_I(lbit);
if (hoffset==VL_SIZEBITS_I && loffset==0) {
int hoffset = VL_BITBIT_E(hbit);
int loffset = VL_BITBIT_E(lbit);
if (hoffset == VL_SIZEBITS_E && loffset == 0) {
// Fast and common case, word based insertion
owp[VL_BITWORD_I(lbit)] = ld;
}
else {
int hword = VL_BITWORD_I(hbit);
int lword = VL_BITWORD_I(lbit);
if (hword==lword) { // know < 32 bits because above checks it
IData insmask = (VL_MASK_I(hoffset-loffset+1))<<loffset;
owp[lword] = (owp[lword] & ~insmask) | ((ld<<loffset) & insmask);
owp[VL_BITWORD_E(lbit)] = ld;
} else {
IData hinsmask = (VL_MASK_I(hoffset-0+1))<<0;
IData linsmask = (VL_MASK_I(31-loffset+1))<<loffset;
int nbitsonright = 32-loffset; // bits that end up in lword
owp[lword] = (owp[lword] & ~linsmask) | ((ld<<loffset) & linsmask);
owp[hword] = (owp[hword] & ~hinsmask) | ((ld>>nbitsonright) & hinsmask);
int hword = VL_BITWORD_E(hbit);
int lword = VL_BITWORD_E(lbit);
EData lde = static_cast<EData>(ld);
if (hword == lword) { // know < EData bits because above checks it
EData insmask = (VL_MASK_E(hoffset - loffset + 1)) << loffset;
owp[lword] = (owp[lword] & ~insmask) | ((lde << loffset) & insmask);
} else {
EData hinsmask = (VL_MASK_E(hoffset - 0 + 1)) << 0;
EData linsmask = (VL_MASK_E((VL_EDATASIZE - 1) - loffset + 1)) << loffset;
int nbitsonright = VL_EDATASIZE - loffset; // bits that end up in lword
owp[lword] = (owp[lword] & ~linsmask) | ((lde << loffset) & linsmask);
owp[hword] = (owp[hword] & ~hinsmask) | ((lde >> nbitsonright) & hinsmask);
}
}
}
@ -1605,11 +1628,11 @@ static inline void _VL_INSERT_WI(int, WDataOutP owp, IData ld, int hbit, int lbi
// INTERNAL: Stuff large LHS bit 0++ into OUTPUT at specified offset
// lwp may be "dirty"
static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int lbit) VL_MT_SAFE {
int hoffset = hbit & VL_SIZEBITS_I;
int loffset = lbit & VL_SIZEBITS_I;
int lword = VL_BITWORD_I(lbit);
int hoffset = hbit & VL_SIZEBITS_E;
int loffset = lbit & VL_SIZEBITS_E;
int lword = VL_BITWORD_E(lbit);
int words = VL_WORDS_I(hbit - lbit + 1);
if (hoffset==VL_SIZEBITS_I && loffset==0) {
if (hoffset == VL_SIZEBITS_E && loffset == 0) {
// Fast and common case, word based insertion
for (int i=0; i<words; ++i) {
owp[lword+i] = lwp[i];
@ -1620,29 +1643,33 @@ static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int
for (int i=0; i<(words-1); ++i) {
owp[lword+i] = lwp[i];
}
IData hinsmask = (VL_MASK_I(hoffset-0+1)); // Know it's not a full word as above fast case handled it
owp[lword+words-1] = (owp[words+lword-1] & ~hinsmask) | (lwp[words-1] & hinsmask);
// Know it's not a full word as above fast case handled it
EData hinsmask = (VL_MASK_E(hoffset - 0 + 1));
owp[lword + words - 1]
= (owp[words + lword - 1] & ~hinsmask) | (lwp[words - 1] & hinsmask);
}
else {
IData hinsmask = (VL_MASK_I(hoffset-0+1))<<0;
IData linsmask = (VL_MASK_I(31-loffset+1))<<loffset;
int nbitsonright = 32-loffset; // bits that end up in lword (know loffset!=0)
EData hinsmask = (VL_MASK_E(hoffset - 0 + 1)) << 0;
EData linsmask = (VL_MASK_E((VL_EDATASIZE - 1) - loffset + 1)) << loffset;
int nbitsonright = VL_EDATASIZE - loffset; // bits that end up in lword (know loffset!=0)
// Middle words
int hword = VL_BITWORD_I(hbit);
int hword = VL_BITWORD_E(hbit);
for (int i=0; i<words; ++i) {
{ // Lower word
int oword = lword+i;
IData d = lwp[i]<<loffset;
IData od = (owp[oword] & ~linsmask) | (d & linsmask);
if (oword==hword) owp[oword] = (owp[oword] & ~hinsmask) | (od & hinsmask);
EData d = lwp[i] << loffset;
EData od = (owp[oword] & ~linsmask) | (d & linsmask);
if (oword == hword)
owp[oword] = (owp[oword] & ~hinsmask) | (od & hinsmask);
else owp[oword] = od;
}
{ // Upper word
int oword = lword+i+1;
if (oword <= hword) {
IData d = lwp[i]>>nbitsonright;
IData od = (d & ~linsmask) | (owp[oword] & linsmask);
if (oword==hword) owp[oword] = (owp[oword] & ~hinsmask) | (od & hinsmask);
EData d = lwp[i] >> nbitsonright;
EData od = (d & ~linsmask) | (owp[oword] & linsmask);
if (oword == hword)
owp[oword] = (owp[oword] & ~hinsmask) | (od & hinsmask);
else owp[oword] = od;
}
}
@ -1651,7 +1678,7 @@ static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int
}
static inline void _VL_INSERT_WQ(int obits, WDataOutP owp, QData ld, int hbit, int lbit) VL_MT_SAFE {
WData lwp[2]; VL_SET_WQ(lwp, ld);
WData lwp[VL_WQ_WORDS_E]; VL_SET_WQ(lwp, ld);
_VL_INSERT_WW(obits, owp, lwp, hbit, lbit);
}
@ -1748,7 +1775,7 @@ static inline IData VL_STREAML_FAST_III(int, int lbits, int, IData ld, IData rd_
case 4:
ret = ((ret >> 16) | (ret << 16));
}
return ret >> (VL_WORDSIZE - lbits);
return ret >> (VL_IDATASIZE - lbits);
}
static inline QData VL_STREAML_FAST_QQI(int, int lbits, int, QData ld, IData rd_log2) VL_PURE {
@ -1818,8 +1845,8 @@ static inline WDataOutP VL_STREAML_WWI(int, int lbits, int,
for (int sbit=0; sbit<ssize && sbit<lbits-istart; ++sbit) {
// Extract a single bit from lwp and shift it to the correct
// location for owp.
WData bit= (VL_BITRSHIFT_W(lwp, (istart+sbit)) & 1) << VL_BITBIT_I(ostart+sbit);
owp[VL_BITWORD_I(ostart+sbit)] |= bit;
EData bit = (VL_BITRSHIFT_W(lwp, (istart + sbit)) & 1) << VL_BITBIT_E(ostart + sbit);
owp[VL_BITWORD_E(ostart + sbit)] |= bit;
}
}
return owp;
@ -1864,7 +1891,7 @@ static inline WDataOutP VL_CONCAT_WIW(int obits, int lbits, int rbits,
static inline WDataOutP VL_CONCAT_WIQ(int obits, int lbits, int rbits,
WDataOutP owp, IData ld, QData rd) VL_MT_SAFE {
VL_SET_WQ(owp, rd);
for (int i=2; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
for (int i = VL_WQ_WORDS_E; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WI(obits, owp, ld, rbits+lbits-1, rbits);
return owp;
}
@ -1878,14 +1905,14 @@ static inline WDataOutP VL_CONCAT_WQI(int obits, int lbits, int rbits,
static inline WDataOutP VL_CONCAT_WQQ(int obits, int lbits, int rbits,
WDataOutP owp, QData ld, QData rd) VL_MT_SAFE {
VL_SET_WQ(owp, rd);
for (int i=2; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
for (int i = VL_WQ_WORDS_E; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WQ(obits, owp, ld, rbits+lbits-1, rbits);
return owp;
}
static inline WDataOutP VL_CONCAT_WWQ(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, QData rd) VL_MT_SAFE {
VL_SET_WQ(owp, rd);
for (int i=2; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
for (int i = VL_WQ_WORDS_E; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
_VL_INSERT_WW(obits, owp, lwp, rbits+lbits-1, rbits);
return owp;
}
@ -1911,12 +1938,12 @@ static inline WDataOutP VL_CONCAT_WWW(int obits, int lbits, int rbits,
// The output is the same as the input - it overlaps!
static inline void _VL_SHIFTL_INPLACE_W(int obits, WDataOutP iowp, IData rd/*1 or 4*/) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
IData linsmask = VL_MASK_I(rd);
EData linsmask = VL_MASK_E(rd);
for (int i=words-1; i>=1; --i) {
iowp[i] = ((iowp[i]<<rd) & ~linsmask) | ((iowp[i-1] >> (32-rd)) & linsmask);
iowp[i] = ((iowp[i]<<rd) & ~linsmask) | ((iowp[i-1] >> (VL_EDATASIZE - rd)) & linsmask);
}
iowp[0] = ((iowp[0]<<rd) & ~linsmask);
iowp[VL_WORDS_I(obits)-1] &= VL_MASK_I(obits);
iowp[VL_WORDS_I(obits)-1] &= VL_MASK_E(obits);
}
// EMIT_RULE: VL_SHIFTL: oclean=lclean; rclean==clean;
@ -1924,8 +1951,8 @@ static inline void _VL_SHIFTL_INPLACE_W(int obits, WDataOutP iowp, IData rd/*1 o
// expression. Thus consider this when optimizing. (And perhaps have 2 funcs?)
static inline WDataOutP VL_SHIFTL_WWI(int obits, int, int,
WDataOutP owp, WDataInP lwp, IData rd) VL_MT_SAFE {
int word_shift = VL_BITWORD_I(rd);
int bit_shift = VL_BITBIT_I(rd);
int word_shift = VL_BITWORD_E(rd);
int bit_shift = VL_BITBIT_E(rd);
if (rd >= static_cast<IData>(obits)) { // rd may be huge with MSB set
for (int i=0; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
} else if (bit_shift==0) { // Aligned word shift (<<0,<<32,<<64 etc)
@ -1969,8 +1996,8 @@ static inline QData VL_SHIFTL_QQW(int obits, int, int rbits, QData lhs, WDataInP
// expression. Thus consider this when optimizing. (And perhaps have 2 funcs?)
static inline WDataOutP VL_SHIFTR_WWI(int obits, int, int,
WDataOutP owp, WDataInP lwp, IData rd) VL_MT_SAFE {
int word_shift = VL_BITWORD_I(rd); // Maybe 0
int bit_shift = VL_BITBIT_I(rd);
int word_shift = VL_BITWORD_E(rd); // Maybe 0
int bit_shift = VL_BITBIT_E(rd);
if (rd >= static_cast<IData>(obits)) { // rd may be huge with MSB set
for (int i=0; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
} else if (bit_shift==0) { // Aligned word shift (>>0,>>32,>>64 etc)
@ -1978,8 +2005,8 @@ static inline WDataOutP VL_SHIFTR_WWI(int obits, int, int,
for (int i=0; i < copy_words; ++i) owp[i] = lwp[i+word_shift];
for (int i=copy_words; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
} else {
int loffset = rd & VL_SIZEBITS_I;
int nbitsonright = 32-loffset; // bits that end up in lword (know loffset!=0)
int loffset = rd & VL_SIZEBITS_E;
int nbitsonright = VL_EDATASIZE - loffset; // bits that end up in lword (know loffset!=0)
// Middle words
int words = VL_WORDS_I(obits-rd);
for (int i=0; i<words; ++i) {
@ -2041,22 +2068,22 @@ static inline IData VL_SHIFTRS_IQI(int obits, int lbits, int rbits,
}
static inline WDataOutP VL_SHIFTRS_WWI(int obits, int lbits, int,
WDataOutP owp, WDataInP lwp, IData rd) VL_MT_SAFE {
int word_shift = VL_BITWORD_I(rd);
int bit_shift = VL_BITBIT_I(rd);
int word_shift = VL_BITWORD_E(rd);
int bit_shift = VL_BITBIT_E(rd);
int lmsw = VL_WORDS_I(obits)-1;
IData sign = VL_SIGNONES_I(lbits, lwp[lmsw]);
EData sign = VL_SIGNONES_E(lbits, lwp[lmsw]);
if (rd >= static_cast<IData>(obits)) { // Shifting past end, sign in all of lbits
for (int i=0; i <= lmsw; ++i) owp[i] = sign;
owp[lmsw] &= VL_MASK_I(lbits);
owp[lmsw] &= VL_MASK_E(lbits);
} else if (bit_shift==0) { // Aligned word shift (>>0,>>32,>>64 etc)
int copy_words = (VL_WORDS_I(obits)-word_shift);
for (int i=0; i < copy_words; ++i) owp[i] = lwp[i+word_shift];
if (copy_words>=0) owp[copy_words-1] |= ~VL_MASK_I(obits) & sign;
if (copy_words >= 0) owp[copy_words - 1] |= ~VL_MASK_E(obits) & sign;
for (int i = copy_words; i < VL_WORDS_I(obits); ++i) owp[i] = sign;
owp[lmsw] &= VL_MASK_I(lbits);
owp[lmsw] &= VL_MASK_E(lbits);
} else {
int loffset = rd & VL_SIZEBITS_I;
int nbitsonright = 32-loffset; // bits that end up in lword (know loffset!=0)
int loffset = rd & VL_SIZEBITS_E;
int nbitsonright = VL_EDATASIZE - loffset; // bits that end up in lword (know loffset!=0)
// Middle words
int words = VL_WORDS_I(obits-rd);
for (int i=0; i<words; ++i) {
@ -2066,51 +2093,57 @@ static inline WDataOutP VL_SHIFTRS_WWI(int obits, int lbits, int,
owp[i] |= lwp[upperword]<< nbitsonright;
}
}
if (words) owp[words-1] |= sign & ~VL_MASK_I(obits-loffset);
if (words) owp[words - 1] |= sign & ~VL_MASK_E(obits - loffset);
for (int i = words; i < VL_WORDS_I(obits); ++i) owp[i] = sign;
owp[lmsw] &= VL_MASK_I(lbits);
owp[lmsw] &= VL_MASK_E(lbits);
}
return owp;
}
static inline WDataOutP VL_SHIFTRS_WWW(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
EData overshift = 0; // Huge shift 1>>32 or more
for (int i = 1; i < VL_WORDS_I(rbits); ++i) {
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
int lmsw = VL_WORDS_I(obits)-1;
IData sign = VL_SIGNONES_I(lbits, lwp[lmsw]);
for (int j=0; j <= lmsw; ++j) owp[j] = sign;
owp[lmsw] &= VL_MASK_I(lbits);
return owp;
overshift |= rwp[i];
}
if (VL_UNLIKELY(overshift)) {
int lmsw = VL_WORDS_I(obits) - 1;
EData sign = VL_SIGNONES_E(lbits, lwp[lmsw]);
for (int j = 0; j <= lmsw; ++j) owp[j] = sign;
owp[lmsw] &= VL_MASK_E(lbits);
return owp;
}
return VL_SHIFTRS_WWI(obits, lbits, 32, owp, lwp, rwp[0]);
}
static inline IData VL_SHIFTRS_IIW(int obits, int lbits, int rbits,
IData lhs, WDataInP rwp) VL_MT_SAFE {
EData overshift = 0; // Huge shift 1>>32 or more
for (int i = 1; i < VL_WORDS_I(rbits); ++i) {
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
overshift |= rwp[i];
}
if (VL_UNLIKELY(overshift)) {
IData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative
return VL_CLEAN_II(obits, obits, sign);
}
}
return VL_SHIFTRS_III(obits, lbits, 32, lhs, rwp[0]);
}
static inline QData VL_SHIFTRS_QQW(int obits, int lbits, int rbits,
QData lhs, WDataInP rwp) VL_MT_SAFE {
EData overshift = 0; // Huge shift 1>>32 or more
for (int i = 1; i < VL_WORDS_I(rbits); ++i) {
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
overshift |= rwp[i];
}
if (VL_UNLIKELY(overshift)) {
QData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative
return VL_CLEAN_QQ(obits, obits, sign);
}
}
return VL_SHIFTRS_QQI(obits, lbits, 32, lhs, rwp[0]);
}
static inline IData VL_SHIFTRS_IIQ(int obits, int lbits, int rbits, IData lhs, QData rhs) VL_PURE {
WData rwp[2]; VL_SET_WQ(rwp, rhs);
WData rwp[VL_WQ_WORDS_E]; VL_SET_WQ(rwp, rhs);
return VL_SHIFTRS_IIW(obits, lbits, rbits, lhs, rwp);
}
static inline QData VL_SHIFTRS_QQQ(int obits, int lbits, int rbits, QData lhs, QData rhs) VL_PURE {
WData rwp[2]; VL_SET_WQ(rwp, rhs);
WData rwp[VL_WQ_WORDS_E]; VL_SET_WQ(rwp, rhs);
return VL_SHIFTRS_QQW(obits, lbits, rbits, lhs, rwp);
}
@ -2124,12 +2157,12 @@ static inline QData VL_SHIFTRS_QQQ(int obits, int lbits, int rbits, QData lhs, Q
#define VL_BITSEL_IQII(obits,lbits,rbits,zbits,lhs,rhs) (static_cast<IData>((lhs)>>(rhs)))
static inline IData VL_BITSEL_IWII(int, int lbits, int, int, WDataInP lwp, IData rd) VL_MT_SAFE {
int word = VL_BITWORD_I(rd);
int word = VL_BITWORD_E(rd);
if (VL_UNLIKELY(rd > static_cast<IData>(lbits))) {
return ~0; // Spec says you can go outside the range of a array. Don't coredump if so.
// We return all 1's as that's more likely to find bugs (?) than 0's.
} else {
return (lwp[word]>>VL_BITBIT_I(rd));
return (lwp[word] >> VL_BITBIT_E(rd));
}
}
@ -2144,12 +2177,12 @@ static inline IData VL_SEL_IWII(int, int lbits, int, int,
int msb = lsb+width-1;
if (VL_UNLIKELY(msb>lbits)) {
return ~0; // Spec says you can go outside the range of a array. Don't coredump if so.
} else if (VL_BITWORD_I(msb)==VL_BITWORD_I(static_cast<int>(lsb))) {
} else if (VL_BITWORD_E(msb) == VL_BITWORD_E(static_cast<int>(lsb))) {
return VL_BITRSHIFT_W(lwp, lsb);
} else {
// 32 bit extraction may span two words
int nbitsfromlow = 32-VL_BITBIT_I(lsb); // bits that come from low word
return ((lwp[VL_BITWORD_I(msb)]<<nbitsfromlow)
int nbitsfromlow = VL_EDATASIZE - VL_BITBIT_E(lsb); // bits that come from low word
return ((lwp[VL_BITWORD_E(msb)] << nbitsfromlow)
| VL_BITRSHIFT_W(lwp, lsb));
}
}
@ -2159,20 +2192,20 @@ static inline QData VL_SEL_QWII(int, int lbits, int, int,
int msb = lsb+width-1;
if (VL_UNLIKELY(msb>lbits)) {
return ~0; // Spec says you can go outside the range of a array. Don't coredump if so.
} else if (VL_BITWORD_I(msb)==VL_BITWORD_I(static_cast<int>(lsb))) {
} else if (VL_BITWORD_E(msb) == VL_BITWORD_E(static_cast<int>(lsb))) {
return VL_BITRSHIFT_W(lwp, lsb);
} else if (VL_BITWORD_I(msb)==1+VL_BITWORD_I(static_cast<int>(lsb))) {
int nbitsfromlow = 32-VL_BITBIT_I(lsb);
QData hi = (lwp[VL_BITWORD_I(msb)]);
} else if (VL_BITWORD_E(msb) == 1 + VL_BITWORD_E(static_cast<int>(lsb))) {
int nbitsfromlow = VL_EDATASIZE - VL_BITBIT_E(lsb);
QData hi = (lwp[VL_BITWORD_E(msb)]);
QData lo = VL_BITRSHIFT_W(lwp, lsb);
return (hi << nbitsfromlow) | lo;
} else {
// 64 bit extraction may span three words
int nbitsfromlow = 32-VL_BITBIT_I(lsb);
QData hi = (lwp[VL_BITWORD_I(msb)]);
QData mid= (lwp[VL_BITWORD_I(lsb)+1]);
int nbitsfromlow = VL_EDATASIZE - VL_BITBIT_E(lsb);
QData hi = (lwp[VL_BITWORD_E(msb)]);
QData mid = (lwp[VL_BITWORD_E(lsb) + 1]);
QData lo = VL_BITRSHIFT_W(lwp, lsb);
return (hi<<(nbitsfromlow+32)) | (mid<<nbitsfromlow) | lo;
return (hi << (nbitsfromlow + VL_EDATASIZE)) | (mid << nbitsfromlow) | lo;
}
}
@ -2180,23 +2213,23 @@ static inline WDataOutP VL_SEL_WWII(int obits, int lbits, int, int,
WDataOutP owp, WDataInP lwp,
IData lsb, IData width) VL_MT_SAFE {
int msb = lsb+width-1;
int word_shift = VL_BITWORD_I(lsb);
int word_shift = VL_BITWORD_E(lsb);
if (VL_UNLIKELY(msb>lbits)) { // Outside bounds,
for (int i=0; i<VL_WORDS_I(obits)-1; ++i) owp[i] = ~0;
owp[VL_WORDS_I(obits)-1] = VL_MASK_I(obits);
} else if (VL_BITBIT_I(lsb)==0) {
owp[VL_WORDS_I(obits) - 1] = VL_MASK_E(obits);
} else if (VL_BITBIT_E(lsb) == 0) {
// Just a word extract
for (int i=0; i<VL_WORDS_I(obits); ++i) owp[i] = lwp[i+word_shift];
} else {
// Not a _VL_INSERT because the bits come from any bit number and goto bit 0
int loffset = lsb & VL_SIZEBITS_I;
int nbitsfromlow = 32-loffset; // bits that end up in lword (know loffset!=0)
int loffset = lsb & VL_SIZEBITS_E;
int nbitsfromlow = VL_EDATASIZE - loffset; // bits that end up in lword (know loffset!=0)
// Middle words
int words = VL_WORDS_I(msb-lsb+1);
for (int i=0; i<words; ++i) {
owp[i] = lwp[i+word_shift]>>loffset;
int upperword = i+word_shift+1;
if (upperword <= static_cast<int>(VL_BITWORD_I(msb))) {
if (upperword <= static_cast<int>(VL_BITWORD_E(msb))) {
owp[i] |= lwp[upperword] << nbitsfromlow;
}
}
@ -2264,83 +2297,83 @@ static inline WDataOutP VL_COND_WIWW(int obits, int, int, int,
return o
static inline WDataOutP VL_CONST_W_1X(int obits, WDataOutP o,
IData d0) VL_MT_SAFE {
EData d0) VL_MT_SAFE {
o[0]=d0;
_END(obits,1); }
static inline WDataOutP VL_CONST_W_2X(int obits, WDataOutP o,
IData d1, IData d0) VL_MT_SAFE {
EData d1, EData d0) VL_MT_SAFE {
o[0]=d0; o[1]=d1;
_END(obits,2); }
static inline WDataOutP VL_CONST_W_3X(int obits, WDataOutP o,
IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d2, EData d1, EData d0) VL_MT_SAFE {
o[0]=d0; o[1]=d1; o[2]=d2;
_END(obits,3); }
static inline WDataOutP VL_CONST_W_4X(int obits, WDataOutP o,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3;
_END(obits,4); }
static inline WDataOutP VL_CONST_W_5X(int obits, WDataOutP o,
IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d4,
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4;
_END(obits,5); }
static inline WDataOutP VL_CONST_W_6X(int obits, WDataOutP o,
IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d5, EData d4,
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5;
_END(obits,6); }
static inline WDataOutP VL_CONST_W_7X(int obits, WDataOutP o,
IData d6, IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d6, EData d5, EData d4,
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6;
_END(obits,7); }
static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o,
IData d7, IData d6, IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d7, EData d6, EData d5, EData d4,
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
_END(obits,8); }
//
static inline WDataOutP VL_CONSTHI_W_1X(int obits, int lsb, WDataOutP obase,
IData d0) VL_MT_SAFE {
EData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0;
_END(obits,1); }
static inline WDataOutP VL_CONSTHI_W_2X(int obits, int lsb, WDataOutP obase,
IData d1, IData d0) VL_MT_SAFE {
EData d1, EData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1;
_END(obits,2); }
static inline WDataOutP VL_CONSTHI_W_3X(int obits, int lsb, WDataOutP obase,
IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d2, EData d1, EData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2;
_END(obits,3); }
static inline WDataOutP VL_CONSTHI_W_4X(int obits, int lsb, WDataOutP obase,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3;
_END(obits,4); }
static inline WDataOutP VL_CONSTHI_W_5X(int obits, int lsb, WDataOutP obase,
IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d4,
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4;
_END(obits,5); }
static inline WDataOutP VL_CONSTHI_W_6X(int obits, int lsb, WDataOutP obase,
IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d5, EData d4,
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5;
_END(obits,6); }
static inline WDataOutP VL_CONSTHI_W_7X(int obits, int lsb, WDataOutP obase,
IData d6, IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d6, EData d5, EData d4,
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6;
_END(obits,7); }
static inline WDataOutP VL_CONSTHI_W_8X(int obits, int lsb, WDataOutP obase,
IData d7, IData d6, IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d7, EData d6, EData d5, EData d4,
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
_END(obits,8); }
@ -2349,8 +2382,8 @@ static inline WDataOutP VL_CONSTHI_W_8X(int obits, int lsb, WDataOutP obase,
// Partial constant, lower words of vector wider than 8*32, starting at bit number lsb
static inline void VL_CONSTLO_W_8X(int lsb, WDataOutP obase,
IData d7, IData d6, IData d5, IData d4,
IData d3, IData d2, IData d1, IData d0) VL_MT_SAFE {
EData d7, EData d6, EData d5, EData d4,
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7; }

View File

@ -2,7 +2,7 @@
######################################################################
# DESCRIPTION: Makefile commands for all verilated target files
#
# Copyright 2003-2019 by Wilson Snyder. Verilator is free software; you can
# Copyright 2003-2020 by Wilson Snyder. Verilator is free software; you can
# redistribute it and/or modify it under the terms of either the GNU Lesser
# General Public License Version 3 or the Perl Artistic License Version 2.0.
######################################################################

View File

@ -4,7 +4,7 @@
//
//*************************************************************************
//
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
// Copyright 2001-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
// Copyright 2001-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
// Copyright 2001-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
// Copyright 2001-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
@ -118,7 +118,7 @@ void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, vluint32_t elem
void VerilatedFst::declSymbol(vluint32_t code, const char* name,
int dtypenum, fstVarDir vardir, fstVarType vartype,
int arraynum, vluint32_t len) {
bool array, int arraynum, vluint32_t len) {
std::pair<Code2SymbolType::iterator, bool> p
= m_code2symbol.insert(std::make_pair(code, static_cast<fstHandle>(NULL)));
std::istringstream nameiss(name);
@ -153,8 +153,7 @@ void VerilatedFst::declSymbol(vluint32_t code, const char* name,
std::stringstream name_ss;
name_ss << symbol_name;
if (arraynum >= 0)
name_ss << "(" << arraynum << ")";
if (array) name_ss << "(" << arraynum << ")";
std::string name_str = name_ss.str();
if (dtypenum > 0) {
@ -205,51 +204,6 @@ void VerilatedFst::dump(vluint64_t timeui) {
}
}
//=============================================================================
// Helpers
char* VerilatedFst::word2Str(vluint32_t newval, int bits) {
// Constructor makes sure m_valueStrBuffer.reserve() > 32+1
char* s = m_valueStrBuffer.data();
for (int i = 0; i < bits; ++i) {
*s++ = '0' + ((newval>>(bits-i-1))&1);
}
*s = '\0';
return m_valueStrBuffer.data();
}
char* VerilatedFst::quad2Str(vluint64_t newval, int bits) {
// Constructor makes sure m_valueStrBuffer.reserve() > 64+1
char* s = m_valueStrBuffer.data();
for (int i = 0; i < bits; ++i) {
*s++ = '0' + ((newval>>(bits-i-1))&1);
}
*s = '\0';
return m_valueStrBuffer.data();
}
char* VerilatedFst::array2Str(const vluint32_t* newval, int bits) {
int bq = VL_BITWORD_I(bits), br = VL_BITBIT_I(bits);
m_valueStrBuffer.reserve(bits+1);
char* s = m_valueStrBuffer.data();
vluint32_t v = newval[bq];
for (int i = 0; i < br; ++i) {
*s++ = '0' + ((v>>(br-i-1))&1);
}
for (int w = bq-1; w >= 0; --w) {
v = newval[w];
for (int i = 28; i >= 0; i-=4) {
s[0] = '0' + ((v>>(i+3))&1);
s[1] = '0' + ((v>>(i+2))&1);
s[2] = '0' + ((v>>(i+1))&1);
s[3] = '0' + ((v>>(i+0))&1);
s+=4;
}
}
*s = '\0';
return m_valueStrBuffer.data();
}
//********************************************************************
// Local Variables:
// End:

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
// Copyright 2001-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
@ -60,12 +60,9 @@ private:
VL_UNCOPYABLE(VerilatedFst);
void declSymbol(vluint32_t code, const char* name,
int dtypenum, fstVarDir vardir, fstVarType vartype,
int arraynum, vluint32_t len);
bool array, int arraynum, vluint32_t len);
// helpers
std::vector<char> m_valueStrBuffer;
char* word2Str(vluint32_t newval, int bits);
char* quad2Str(vluint64_t newval, int bits);
char* array2Str(const vluint32_t *newval, int bits);
public:
explicit VerilatedFst(void* fst=NULL);
~VerilatedFst() { if (m_fst == NULL) { fstWriterClose(m_fst); } }
@ -106,33 +103,33 @@ public:
/// Inside dumping routines, declare a signal
void declBit(vluint32_t code, const char* name,
int dtypenum, fstVarDir vardir, fstVarType vartype,
int arraynum) {
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, 1);
bool array, int arraynum) {
declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, 1);
}
void declBus(vluint32_t code, const char* name,
int dtypenum, fstVarDir vardir, fstVarType vartype,
int arraynum, int msb, int lsb) {
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, msb - lsb + 1);
bool array, int arraynum, int msb, int lsb) {
declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, msb - lsb + 1);
}
void declDouble(vluint32_t code, const char* name,
int dtypenum, fstVarDir vardir, fstVarType vartype,
int arraynum) {
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, 2);
bool array, int arraynum) {
declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, 2);
}
void declFloat(vluint32_t code, const char* name,
int dtypenum, fstVarDir vardir, fstVarType vartype,
int arraynum) {
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, 1);
bool array, int arraynum) {
declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, 1);
}
void declQuad(vluint32_t code, const char* name,
int dtypenum, fstVarDir vardir, fstVarType vartype,
int arraynum, int msb, int lsb) {
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, msb - lsb + 1);
bool array, int arraynum, int msb, int lsb) {
declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, msb - lsb + 1);
}
void declArray(vluint32_t code, const char* name,
int dtypenum, fstVarDir vardir, fstVarType vartype,
int arraynum, int msb, int lsb) {
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, msb - lsb + 1);
bool array, int arraynum, int msb, int lsb) {
declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, msb - lsb + 1);
}
/// Inside dumping routines, dump one signal if it has changed
@ -140,7 +137,7 @@ public:
fstWriterEmitValueChange(m_fst, m_code2symbol[code], newval ? "1" : "0");
}
void chgBus(vluint32_t code, const vluint32_t newval, int bits) {
fstWriterEmitValueChange(m_fst, m_code2symbol[code], word2Str(newval, bits));
fstWriterEmitValueChange32(m_fst, m_code2symbol[code], bits, newval);
}
void chgDouble(vluint32_t code, const double newval) {
double val = newval;
@ -151,10 +148,10 @@ public:
fstWriterEmitValueChange(m_fst, m_code2symbol[code], &val);
}
void chgQuad(vluint32_t code, const vluint64_t newval, int bits) {
fstWriterEmitValueChange(m_fst, m_code2symbol[code], quad2Str(newval, bits));
fstWriterEmitValueChange64(m_fst, m_code2symbol[code], bits, newval);
}
void chgArray(vluint32_t code, const vluint32_t* newval, int bits) {
fstWriterEmitValueChange(m_fst, m_code2symbol[code], array2Str(newval, bits));
fstWriterEmitValueChangeVec32(m_fst, m_code2symbol[code], bits, newval);
}
void fullBit(vluint32_t code, const vluint32_t newval) {

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2010-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2010-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@ -185,7 +185,8 @@ std::string VL_TO_STRING(const VlAssocArray<T_Key, T_Value>& obj) {
// There are no multithreaded locks on this; the base variable must
// be protected by other means
//
template <class T_Value> class VlQueue {
// Bound here is the maximum size() allowed, e.g. 1 + SystemVerilog bound
template <class T_Value, size_t T_MaxSize = 0> class VlQueue {
private:
// TYPES
typedef std::deque<T_Value> Deque;
@ -215,9 +216,14 @@ public:
void erase(size_t index) { if (VL_LIKELY(index < m_deque.size())) m_deque.erase(index); }
// function void q.push_front(value)
void push_front(const T_Value& value) { m_deque.push_front(value); }
void push_front(const T_Value& value) {
m_deque.push_front(value);
if (VL_UNLIKELY(T_MaxSize != 0 && m_deque.size() > T_MaxSize)) m_deque.pop_back();
}
// function void q.push_back(value)
void push_back(const T_Value& value) { m_deque.push_back(value); }
void push_back(const T_Value& value) {
if (VL_LIKELY(T_MaxSize == 0 || m_deque.size() < T_MaxSize)) m_deque.push_back(value);
}
// function value_t q.pop_front();
T_Value pop_front() {
if (m_deque.empty()) return m_defaultValue;
@ -278,14 +284,14 @@ std::string VL_TO_STRING(const VlQueue<T_Value>& obj) {
extern std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE;
inline std::string VL_CVT_PACK_STR_NQ(QData lhs) VL_PURE {
WData lw[2]; VL_SET_WQ(lw, lhs);
return VL_CVT_PACK_STR_NW(2, lw);
WData lw[VL_WQ_WORDS_E]; VL_SET_WQ(lw, lhs);
return VL_CVT_PACK_STR_NW(VL_WQ_WORDS_E, lw);
}
inline std::string VL_CVT_PACK_STR_NN(const std::string& lhs) VL_PURE {
return lhs;
}
inline std::string VL_CVT_PACK_STR_NI(IData lhs) VL_PURE {
WData lw[1]; lw[0] = lhs;
WData lw[VL_WQ_WORDS_E]; VL_SET_WI(lw, lhs);
return VL_CVT_PACK_STR_NW(1, lw);
}
inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs) VL_PURE {
@ -331,7 +337,7 @@ inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, SData& rdr)
return got;
}
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, IData& rdr) VL_MT_SAFE {
WData rwp[2]; // WData must always be at least 2
WData rwp[2];
IData got = VL_VALUEPLUSARGS_INW(rbits, ld, rwp);
if (got) rdr = rwp[0];
return got;
@ -350,4 +356,25 @@ inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, double& rdr)
}
extern IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) VL_MT_SAFE;
//======================================================================
// Strings
extern std::string VL_PUTC_N(const std::string& lhs, IData rhs, CData ths) VL_PURE;
extern CData VL_GETC_N(const std::string& lhs, IData rhs) VL_PURE;
extern std::string VL_SUBSTR_N(const std::string& lhs, IData rhs, IData ths) VL_PURE;
inline IData VL_CMP_NN(const std::string& lhs, const std::string& rhs, bool ignoreCase) VL_PURE {
// SystemVerilog does not allow a string variable to contain '\0'.
// So C functions such as strcmp() can correctly compare strings.
int result;
if (ignoreCase) {
result = VL_STRCASECMP(lhs.c_str(), rhs.c_str());
} else {
result = std::strcmp(lhs.c_str(), rhs.c_str());
}
return result;
}
extern IData VL_ATOI_N(const std::string& str, int base) VL_PURE;
#endif // Guard

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
// Copyright 2001-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2012-2019 by Wilson Snyder. This program is free software;
// Copyright 2012-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@ -41,7 +41,8 @@
class VlScBvExposer : public sc_bv_base {
public:
static const vluint32_t* sp_datap(const sc_bv_base& base) VL_MT_SAFE {
return static_cast<const VlScBvExposer*>(&base)->sp_datatp(); }
return static_cast<const VlScBvExposer*>(&base)->sp_datatp();
}
const vluint32_t* sp_datatp() const { return reinterpret_cast<vluint32_t*>(m_data); }
// Above reads this protected element in sc_bv_base:
// sc_digit* m_data; // data array

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@ -42,9 +42,7 @@
/// Class to sort maps keyed by const char*'s
struct VerilatedCStrCmp {
bool operator() (const char* a, const char* b) const {
return std::strcmp(a, b) < 0;
}
bool operator()(const char* a, const char* b) const { return std::strcmp(a, b) < 0; }
};
/// Map of sorted scope names to find associated scope class
@ -56,8 +54,7 @@ public:
};
/// Map of sorted variable names to find associated variable class
class VerilatedVarNameMap
: public std::map<const char*, VerilatedVar, VerilatedCStrCmp> {
class VerilatedVarNameMap : public std::map<const char*, VerilatedVar, VerilatedCStrCmp> {
public:
VerilatedVarNameMap() {}
~VerilatedVarNameMap() {}
@ -65,8 +62,7 @@ public:
typedef std::vector<const VerilatedScope*> VerilatedScopeVector;
class VerilatedHierarchyMap
: public std::map<const VerilatedScope*, VerilatedScopeVector> {
class VerilatedHierarchyMap : public std::map<const VerilatedScope*, VerilatedScopeVector> {
public:
VerilatedHierarchyMap() {}
~VerilatedHierarchyMap() {}

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2012-2019 by Wilson Snyder. This program is free software;
// Copyright 2012-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2012-2019 by Wilson Snyder. This program is free software;
// Copyright 2012-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
@ -153,7 +153,7 @@ public:
#elif defined(__APPLE__)
vluint32_t info[4];
__cpuid_count(1, 0, info[0], info[1], info[2], info[3]);
/* info[1] is EBX, bits 24-31 are APIC ID */
// info[1] is EBX, bits 24-31 are APIC ID
if ((info[3] & (1 << 9)) == 0) {
return -1; // no APIC on chip
} else {

View File

@ -7,7 +7,7 @@
//
//*************************************************************************
//
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
// Copyright 2001-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
@ -525,7 +525,7 @@ void VerilatedVcd::module(const std::string& name) {
}
void VerilatedVcd::declare(vluint32_t code, const char* name, const char* wirep,
int arraynum, bool tri, bool bussed, int msb, int lsb) {
bool array, int arraynum, bool tri, bool bussed, int msb, int lsb) {
if (!code) { VL_FATAL_MT(__FILE__, __LINE__, "",
"Internal: internal trace problem, code 0 is illegal"); }
@ -584,7 +584,7 @@ void VerilatedVcd::declare(vluint32_t code, const char* name, const char* wirep,
}
decl += " ";
decl += basename;
if (arraynum>=0) {
if (array) {
sprintf(buf, "(%d)", arraynum);
decl += buf;
hiername += buf;
@ -597,26 +597,42 @@ void VerilatedVcd::declare(vluint32_t code, const char* name, const char* wirep,
m_namemapp->insert(std::make_pair(hiername,decl));
}
void VerilatedVcd::declBit (vluint32_t code, const char* name, int arraynum)
{ declare(code, name, "wire", arraynum, false, false, 0, 0); }
void VerilatedVcd::declBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
{ declare(code, name, "wire", arraynum, false, true, msb, lsb); }
void VerilatedVcd::declQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
{ declare(code, name, "wire", arraynum, false, true, msb, lsb); }
void VerilatedVcd::declArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
{ declare(code, name, "wire", arraynum, false, true, msb, lsb); }
void VerilatedVcd::declTriBit (vluint32_t code, const char* name, int arraynum)
{ declare(code, name, "wire", arraynum, true, false, 0, 0); }
void VerilatedVcd::declTriBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
{ declare(code, name, "wire", arraynum, true, true, msb, lsb); }
void VerilatedVcd::declTriQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
{ declare(code, name, "wire", arraynum, true, true, msb, lsb); }
void VerilatedVcd::declTriArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
{ declare(code, name, "wire", arraynum, true, true, msb, lsb); }
void VerilatedVcd::declFloat (vluint32_t code, const char* name, int arraynum)
{ declare(code, name, "real", arraynum, false, false, 31, 0); }
void VerilatedVcd::declDouble (vluint32_t code, const char* name, int arraynum)
{ declare(code, name, "real", arraynum, false, false, 63, 0); }
void VerilatedVcd::declBit(vluint32_t code, const char* name, bool array, int arraynum) {
declare(code, name, "wire", array, arraynum, false, false, 0, 0);
}
void VerilatedVcd::declBus(vluint32_t code, const char* name, bool array, int arraynum, int msb,
int lsb) {
declare(code, name, "wire", array, arraynum, false, true, msb, lsb);
}
void VerilatedVcd::declQuad(vluint32_t code, const char* name, bool array, int arraynum, int msb,
int lsb) {
declare(code, name, "wire", array, arraynum, false, true, msb, lsb);
}
void VerilatedVcd::declArray(vluint32_t code, const char* name, bool array, int arraynum, int msb,
int lsb) {
declare(code, name, "wire", array, arraynum, false, true, msb, lsb);
}
void VerilatedVcd::declTriBit(vluint32_t code, const char* name, bool array, int arraynum) {
declare(code, name, "wire", array, arraynum, true, false, 0, 0);
}
void VerilatedVcd::declTriBus(vluint32_t code, const char* name, bool array, int arraynum, int msb,
int lsb) {
declare(code, name, "wire", array, arraynum, true, true, msb, lsb);
}
void VerilatedVcd::declTriQuad(vluint32_t code, const char* name, bool array, int arraynum,
int msb, int lsb) {
declare(code, name, "wire", array, arraynum, true, true, msb, lsb);
}
void VerilatedVcd::declTriArray(vluint32_t code, const char* name, bool array, int arraynum,
int msb, int lsb) {
declare(code, name, "wire", array, arraynum, true, true, msb, lsb);
}
void VerilatedVcd::declFloat(vluint32_t code, const char* name, bool array, int arraynum) {
declare(code, name, "real", array, arraynum, false, false, 31, 0);
}
void VerilatedVcd::declDouble(vluint32_t code, const char* name, bool array, int arraynum) {
declare(code, name, "real", array, arraynum, false, false, 63, 0);
}
//=============================================================================

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
// Copyright 2001-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
@ -43,7 +43,8 @@ private:
int m_fd; ///< File descriptor we're writing to
public:
// METHODS
VerilatedVcdFile() : m_fd(0) {}
VerilatedVcdFile()
: m_fd(0) {}
virtual ~VerilatedVcdFile() {}
virtual bool open(const std::string& name) VL_MT_UNSAFE;
virtual void close() VL_MT_UNSAFE;
@ -60,7 +61,8 @@ protected:
vluint32_t m_code; ///< VCD file code number
int m_bits; ///< Size of value in bits
VerilatedVcdSig(vluint32_t code, int bits)
: m_code(code), m_bits(bits) {}
: m_code(code)
, m_bits(bits) {}
public:
~VerilatedVcdSig() {}
};
@ -123,8 +125,8 @@ private:
void printStr(const char* str);
void printQuad(vluint64_t n);
void printTime(vluint64_t timeui);
void declare(vluint32_t code, const char* name, const char* wirep,
int arraynum, bool tri, bool bussed, int msb, int lsb);
void declare(vluint32_t code, const char* name, const char* wirep, bool array, int arraynum,
bool tri, bool bussed, int msb, int lsb);
void dumpHeader();
void dumpPrep(vluint64_t timeui);
@ -199,16 +201,16 @@ public:
/// Inside dumping routines, declare a module
void module(const std::string& name);
/// Inside dumping routines, declare a signal
void declBit (vluint32_t code, const char* name, int arraynum);
void declBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
void declQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
void declArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
void declTriBit (vluint32_t code, const char* name, int arraynum);
void declTriBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
void declTriQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
void declTriArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
void declDouble (vluint32_t code, const char* name, int arraynum);
void declFloat (vluint32_t code, const char* name, int arraynum);
void declBit( vluint32_t code, const char* name, bool array, int arraynum);
void declBus( vluint32_t code, const char* name, bool array, int arraynum, int msb, int lsb);
void declQuad( vluint32_t code, const char* name, bool array, int arraynum, int msb, int lsb);
void declArray( vluint32_t code, const char* name, bool array, int arraynum, int msb, int lsb);
void declTriBit( vluint32_t code, const char* name, bool array, int arraynum);
void declTriBus( vluint32_t code, const char* name, bool array, int arraynum, int msb, int lsb);
void declTriQuad( vluint32_t code, const char* name, bool array, int arraynum, int msb, int lsb);
void declTriArray(vluint32_t code, const char* name, bool array, int arraynum, int msb, int lsb);
void declDouble( vluint32_t code, const char* name, bool array, int arraynum);
void declFloat( vluint32_t code, const char* name, bool array, int arraynum);
// ... other module_start for submodules (based on cell name)
/// Inside dumping routines, dump one signal

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
// Copyright 2001-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//

View File

@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
// Copyright 2001-2020 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@ -1224,6 +1224,9 @@ PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) {
case vpiTimePrecision: {
return VL_TIME_PRECISION;
}
case vpiTimeUnit: {
return VL_TIME_UNIT;
}
case vpiType: {
VerilatedVpio* vop = VerilatedVpio::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
@ -1333,7 +1336,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
VL_FATAL_MT(__FILE__, __LINE__, "",
"vpi_get_value with more than VL_MULS_MAX_WORDS; increase and recompile");
}
WDataInP datap = (reinterpret_cast<IData*>(vop->varDatap()));
WDataInP datap = (reinterpret_cast<EData*>(vop->varDatap()));
for (int i=0; i<words; ++i) {
out[i].aval = datap[i];
out[i].bval = 0;
@ -1617,7 +1620,7 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
return object;
case VLVT_WDATA: {
int words = VL_WORDS_I(vop->varp()->packed().elements());
WDataOutP datap = (reinterpret_cast<IData*>(vop->varDatap()));
WDataOutP datap = (reinterpret_cast<EData*>(vop->varDatap()));
for (int i=0; i<words; ++i) {
datap[i] = value_p->value.vector[i].aval;
if (i==(words-1)) {

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.

View File

@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@ -317,16 +317,20 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
//=========================================================================
// Integer size macros
#define VL_BYTESIZE 8 ///< Bits in a byte
#define VL_SHORTSIZE 16 ///< Bits in a short
#define VL_WORDSIZE 32 ///< Bits in a word
#define VL_QUADSIZE 64 ///< Bits in a quadword
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
#define VL_BYTESIZE 8 ///< Bits in a CData / byte
#define VL_SHORTSIZE 16 ///< Bits in a SData / short
#define VL_IDATASIZE 32 ///< Bits in a IData / word
#define VL_WORDSIZE IDATASIZE ///< Legacy define
#define VL_QUADSIZE 64 ///< Bits in a QData / quadword
#define VL_EDATASIZE 32 ///< Bits in a EData (WData entry)
#define VL_EDATASIZE_LOG2 5 ///< log2(VL_EDATASIZE)
/// Bytes this number of bits needs (1 bit=1 byte)
#define VL_BYTES_I(nbits) (((nbits) + (VL_BYTESIZE - 1)) / VL_BYTESIZE)
/// Words this number of bits needs (1 bit=1 word)
#define VL_WORDS_I(nbits) (((nbits) + (VL_WORDSIZE - 1)) / VL_WORDSIZE)
/// Words/EDatas this number of bits needs (1 bit=1 word)
#define VL_WORDS_I(nbits) (((nbits) + (VL_EDATASIZE - 1)) / VL_EDATASIZE)
/// Words/EDatas a quad requires
#define VL_WQ_WORDS_E VL_WORDS_I(VL_QUADSIZE)
//=========================================================================
// Class definition helpers
@ -345,8 +349,9 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
//=========================================================================
// Base macros
#define VL_SIZEBITS_I (VL_WORDSIZE - 1) ///< Bit mask for bits in a word
#define VL_SIZEBITS_I (VL_IDATASIZE - 1) ///< Bit mask for bits in a word
#define VL_SIZEBITS_Q (VL_QUADSIZE - 1) ///< Bit mask for bits in a quad
#define VL_SIZEBITS_E (VL_EDATASIZE - 1) ///< Bit mask for bits in a quad
/// Mask for words with 1's where relevant bits are (0=all bits)
#define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) \
@ -354,9 +359,15 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
/// Mask for quads with 1's where relevant bits are (0=all bits)
#define VL_MASK_Q(nbits) (((nbits) & VL_SIZEBITS_Q) \
? ((VL_ULL(1) << ((nbits) & VL_SIZEBITS_Q) )-VL_ULL(1)) : VL_ULL(~0))
#define VL_BITWORD_I(bit) ((bit)/VL_WORDSIZE) ///< Word number for a wide quantity
/// Mask for EData with 1's where relevant bits are (0=all bits)
#define VL_MASK_E(nbits) VL_MASK_I(nbits)
#define VL_EUL(n) VL_UL(n) ///< Make constant number EData sized
#define VL_BITWORD_I(bit) ((bit) / VL_IDATASIZE) ///< Word number for sv DPI vectors
#define VL_BITWORD_E(bit) ((bit) >> VL_EDATASIZE_LOG2) ///< Word number for a wide quantity
#define VL_BITBIT_I(bit) ((bit) & VL_SIZEBITS_I) ///< Bit number for a bit in a long
#define VL_BITBIT_Q(bit) ((bit) & VL_SIZEBITS_Q) ///< Bit number for a bit in a quad
#define VL_BITBIT_E(bit) ((bit) & VL_SIZEBITS_E) ///< Bit number for a bit in a EData
//=========================================================================
// Floating point
@ -412,6 +423,21 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
# endif
#endif
//=========================================================================
// String related OS-specific functions
#ifdef _MSC_VER
# define VL_STRCASECMP _stricmp
#else
# define VL_STRCASECMP strcasecmp
#endif
//=========================================================================
// Stringify macros
#define VL_STRINGIFY(x) VL_STRINGIFY2(x)
#define VL_STRINGIFY2(x) #x
//=========================================================================
#endif // Guard

View File

@ -1,7 +1,7 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
######################################################################
#
# Copyright 2007-2019 by Wilson Snyder. This package is free software; you
# Copyright 2007-2020 by Wilson Snyder. This package is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@ -15,6 +15,7 @@
# DESCRIPTION: Diff bison files
use warnings;
use Getopt::Long;
use IO::File;
use strict;

View File

@ -1,7 +1,7 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
######################################################################
#
# Copyright 2007-2019 by Wilson Snyder. This package is free software; you
# Copyright 2007-2020 by Wilson Snyder. This package is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@ -15,6 +15,7 @@
# DESCRIPTION: Debugging of bison output
use warnings;
use strict;
my $Debug;

View File

@ -1,7 +1,8 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
use warnings;
use Cwd;
use File::Copy qw(cp);
use File::Path qw(mkpath);
@ -242,7 +243,7 @@ Runs a specific stage (see the script).
=head1 DISTRIBUTION
Copyright 2019-2019 by Wilson Snyder. This package is free software; you
Copyright 2019-2020 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.

View File

@ -1,7 +1,7 @@
# -*- Perl -*-
# DESCRIPTION: Verilator: Internal C++ code lcov control file
#
# Copyright 2019-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2019-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -1,8 +1,8 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
require 5.006_001;
use warnings;
use Getopt::Long;
use IO::File;
use Pod::Usage;
@ -143,7 +143,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2019 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2020 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.

View File

@ -1,8 +1,8 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
require 5.006_001;
use warnings;
use Getopt::Long;
use IO::File;
use Pod::Usage;
@ -184,7 +184,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2019 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2020 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.

View File

@ -1,7 +1,7 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
######################################################################
#
# Copyright 2007-2019 by Wilson Snyder. This package is free software; you
# Copyright 2007-2020 by Wilson Snyder. This package is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@ -15,6 +15,7 @@
# DESCRIPTION: Diff flex files
use warnings;
use IO::File;
use strict;

View File

@ -1,7 +1,8 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
use warnings;
use Getopt::Long;
#use Data::Dumper; $Data::Dumper::Indent=1; $Data::Dumper::Sortkeys=1; #Debug
use IO::File;
@ -235,7 +236,7 @@ Displays program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2019 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2020 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.

View File

@ -1,7 +1,8 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
use warnings;
use Getopt::Long;
use Cwd;
use IO::File;
@ -189,7 +190,7 @@ Runs a specific test stage (see the script).
=head1 DISTRIBUTION
Copyright 2009-2019 by Wilson Snyder. This package is free software; you
Copyright 2009-2020 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.

View File

@ -1,8 +1,8 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
require 5.006_001;
use warnings;
use strict;
#======================================================================
@ -28,7 +28,7 @@ invoke_atsim - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2019 by Wilson Snyder. This package is free software; you
Copyright 2005-2020 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.

View File

@ -1,8 +1,8 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
require 5.006_001;
use warnings;
use strict;
#======================================================================
@ -28,7 +28,7 @@ invoke_iccr - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2007-2019 by Wilson Snyder. This package is free software; you
Copyright 2007-2020 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.

View File

@ -1,8 +1,8 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
require 5.006_001;
use warnings;
use strict;
#======================================================================
@ -28,7 +28,7 @@ invoke_ncverilog - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2019 by Wilson Snyder. This package is free software; you
Copyright 2005-2020 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.

View File

@ -1,8 +1,8 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
require 5.006_001;
use warnings;
use strict;
#======================================================================
@ -28,7 +28,7 @@ invoke_vcs - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2019 by Wilson Snyder. This package is free software; you
Copyright 2005-2020 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.

View File

@ -1,8 +1,8 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
require 5.006_001;
use warnings;
use Getopt::Long;
use IO::File;
use Pod::Usage;
@ -331,7 +331,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2019 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2020 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.

View File

@ -1,6 +1,6 @@
# DESCRIPTION: Verilator: GDB startup file with useful defines
#
# Copyright 2012-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2012-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

View File

@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.

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