mirror of
https://github.com/verilator/verilator.git
synced 2026-10-03 16:44:11 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4333c201f1 | ||
|
|
1f5913a83c | ||
|
|
159c653b4b | ||
|
|
47a2e2aeb9 | ||
|
|
98b0d19363 | ||
|
|
24a0873f6d | ||
|
|
c5fee7c456 | ||
|
|
d11592cadd | ||
|
|
8ef9ac7dba | ||
|
|
a5aa0e2b0a | ||
|
|
f8ae08c0c2 | ||
|
|
72f5d39ace | ||
|
|
5c9801d42c | ||
|
|
c9ee425ed5 | ||
|
|
1871e2b541 | ||
|
|
3e39c55a97 | ||
|
|
e4d6fa0e3b | ||
|
|
9f8dbc91f2 | ||
|
|
0e37747d2c | ||
|
|
a8519a7a53 | ||
|
|
d4159811d2 | ||
|
|
b2ca4995ab | ||
|
|
7876fe94ad | ||
|
|
cc9f7d1ac3 |
@@ -2,6 +2,25 @@ Revision history for Verilator
|
||||
|
||||
The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
|
||||
* Verilator 4.004 2018-10-6
|
||||
|
||||
** Add GTKWave FST native tracing, bug1356. [Sergi Granell]
|
||||
(Verilator developers need to pull the latest vcddiff.)
|
||||
|
||||
*** Support $past. [Dan Gisselquist]
|
||||
|
||||
*** Support restrict, bug1350. [Clifford Wolf]
|
||||
|
||||
*** Rename include/lxt2 to include/gtkwave.
|
||||
|
||||
**** Fix replication of 64-bit signal change detects.
|
||||
|
||||
**** Fix Mac OSX 10.13.6 / LLVM 9.1 compile issues, bug1348. [Kevin Kiningham]
|
||||
|
||||
**** Fix MinGW compile issues, msg2636. [HyungKi Jeong]
|
||||
|
||||
|
||||
* Verilator 4.002 2018-09-16
|
||||
|
||||
** This is a major release. Any patches may require major rework to apply.
|
||||
|
||||
+10
-7
@@ -129,7 +129,7 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
||||
include/*.[chv]* \
|
||||
include/*.in \
|
||||
include/.*ignore \
|
||||
include/lxt2/*.[chv]* \
|
||||
include/gtkwave/*.[chv]* \
|
||||
include/vltstd/*.[chv]* \
|
||||
.*attributes */.*attributes */*/.*attributes \
|
||||
src/.*ignore src/*.in src/*.cpp src/*.[chly] \
|
||||
@@ -162,7 +162,7 @@ INST_PROJ_FILES = \
|
||||
bin/verilator_profcfunc \
|
||||
include/verilated.mk \
|
||||
include/*.[chv]* \
|
||||
include/lxt2/*.[chv]* \
|
||||
include/gtkwave/*.[chv]* \
|
||||
include/vltstd/*.[chv]* \
|
||||
|
||||
INST_PROJ_BIN_FILES = \
|
||||
@@ -291,7 +291,7 @@ VL_INST_INC_BLDDIR_FILES = \
|
||||
# Files under srcdir, instead of build time
|
||||
VL_INST_INC_SRCDIR_FILES = \
|
||||
include/*.[chv]* \
|
||||
include/lxt2/*.[chv]* \
|
||||
include/gtkwave/*.[chv]* \
|
||||
include/vltstd/*.[chv]* \
|
||||
|
||||
VL_INST_DATA_SRCDIR_FILES = \
|
||||
@@ -318,7 +318,7 @@ installman: $(VL_INST_MAN_FILES)
|
||||
done
|
||||
|
||||
installdata:
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/include/lxt2
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/include/gtkwave
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/include/vltstd
|
||||
for p in $(VL_INST_INC_BLDDIR_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||
@@ -348,7 +348,7 @@ uninstall:
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_DATA_SRCDIR_FILES)
|
||||
-rm $(DESTDIR)$(pkgconfigdir)/verilator.pc
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/bin
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include/lxt2
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include/gtkwave
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include/vltstd
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_c
|
||||
@@ -413,7 +413,7 @@ ifeq ($(CFG_WITH_DEFENV),yes)
|
||||
false
|
||||
endif
|
||||
@echo "Install-cadtools-quick (no strip) to $(VERILATOR_CAD_DIR)"
|
||||
$(MKINSTALLDIRS) $(VERILATOR_CAD_DIR)/include/lxt2
|
||||
$(MKINSTALLDIRS) $(VERILATOR_CAD_DIR)/include/gtkwave
|
||||
$(MKINSTALLDIRS) $(VERILATOR_CAD_DIR)/include/vltstd
|
||||
$(MKINSTALLDIRS) $(VERILATOR_CAD_DIR)/bin
|
||||
for p in $(INST_PROJ_FILES) ; do \
|
||||
@@ -431,7 +431,10 @@ CPPCHECK = src/cppcheck_filtered
|
||||
CPPCHECK_FLAGS = --enable=all --inline-suppr \
|
||||
--suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList
|
||||
CPPCHECK_FLAGS += --xml
|
||||
CPPCHECK_CPP = $(wildcard $(srcdir)/include/*.cpp $(srcdir)/src/*.cpp)
|
||||
CPPCHECK_CPP = $(wildcard \
|
||||
$(srcdir)/include/*.cpp \
|
||||
$(srcdir)/include/gtkwave/*.cpp \
|
||||
$(srcdir)/src/*.cpp)
|
||||
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP))
|
||||
CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
|
||||
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ instead.)
|
||||
To use Verilator you will need the C<perl>, C<make> (or C<gmake>), and
|
||||
C<g++> (or C<clang>) packages.
|
||||
|
||||
To use Verilator LTX2 tracing you will need the C<gtkwave> and C<libgz> (on
|
||||
To use Verilator LXT2 or FST tracing you will need the C<gtkwave> and C<libgz> (on
|
||||
Ubuntu C<zlibc> C<zlib1g> C<zlib1g-dev>) packages installed.
|
||||
|
||||
To compile Verilator in addition to the above you need the C<flex>,
|
||||
|
||||
+76
-17
@@ -356,6 +356,7 @@ detailed descriptions in L</"VERILATION ARGUMENTS"> for more information.
|
||||
--threads-max-mtasks <mtasks> Tune maximum mtask partitioning
|
||||
--top-module <topname> Name of top level input module
|
||||
--trace Enable waveform creation
|
||||
--trace-fst Enable FST waveform creation
|
||||
--trace-lxt2 Enable LXT2 waveform creation
|
||||
--trace-depth <levels> Depth of tracing
|
||||
--trace-max-array <depth> Maximum bit width for tracing
|
||||
@@ -1242,7 +1243,7 @@ designs with only one top.
|
||||
=item --trace
|
||||
|
||||
Adds waveform tracing code to the model using VCD format. This overrides
|
||||
C<--trace-lxt2>.
|
||||
C<--trace-fst> and C<--trace-lxt2>.
|
||||
|
||||
Verilator will generate additional {prefix}__Trace*.cpp files that will
|
||||
need to be compiled. In addition verilated_vcd_sc.cpp (for SystemC traces)
|
||||
@@ -1254,9 +1255,15 @@ need to add these to your Makefile manually.
|
||||
Having tracing compiled in may result in some small performance losses,
|
||||
even when waveforms are not turned on during model execution.
|
||||
|
||||
=item --trace-fst
|
||||
|
||||
Enable FST waveform tracing in the model. This overrides C<--trace> and C<--trace-lxt2>.
|
||||
|
||||
=item --trace-lxt2
|
||||
|
||||
Enable LXT2 waveform tracing in the model. This overrides C<--trace>.
|
||||
Enable LXT2 waveform tracing in the model. This overrides C<--trace> and
|
||||
C<--trace-fst>. This option is deprecated in favor of FST traces and may
|
||||
be removed in the near future.
|
||||
|
||||
=item --trace-depth I<levels>
|
||||
|
||||
@@ -1801,34 +1808,45 @@ For -cc and -sc mode, it also creates:
|
||||
|
||||
{prefix}.cpp // Top level C++ file
|
||||
{prefix}.h // Top level header
|
||||
{prefix}__Slow{__n}.cpp // Constructors and infrequent routines
|
||||
{prefix}{__n}.cpp // Additional top C++ files (--output-split)
|
||||
{prefix}{each_verilog_module}.cpp // Lower level internal C++ files
|
||||
{prefix}{each_verilog_module}.h // Lower level internal header files
|
||||
{prefix}{each_verilog_module}{__n}.cpp // Additional lower C++ files (--output-split)
|
||||
|
||||
In certain optimization modes, it also creates:
|
||||
In certain debug and other modes, it also creates:
|
||||
|
||||
{prefix}.xml // XML tree information (--xml)
|
||||
{prefix}__Dpi.cpp // DPI import and export wrappers
|
||||
{prefix}__Dpi.h // DPI import and export declarations
|
||||
{prefix}__Inlines.h // Inline support functions
|
||||
{prefix}__Slow.cpp // Constructors and infrequent routines
|
||||
{prefix}__Syms.cpp // Global symbol table C++
|
||||
{prefix}__Syms.h // Global symbol table header
|
||||
{prefix}__Trace.cpp // Wave file generation code (--trace)
|
||||
{prefix}__Trace__Slow{__n}.cpp // Wave file generation code (--trace)
|
||||
{prefix}__Trace{__n}.cpp // Wave file generation code (--trace)
|
||||
{prefix}__cdc.txt // Clock Domain Crossing checks (--cdc)
|
||||
{prefix}__stats.txt // Statistics (--stats)
|
||||
|
||||
It also creates internal files that can be mostly ignored:
|
||||
|
||||
{each_verilog_module}.vpp // Post-processed verilog (--debug)
|
||||
{prefix}.flags_vbin // Verilator dependencies
|
||||
{prefix}.flags_vpp // Pre-processor dependencies
|
||||
{mod_prefix}_{each_verilog_module}{__n}.vpp // Post-processed verilog
|
||||
{prefix}__ver.d // Make dependencies (-MMD)
|
||||
{prefix}__verFiles.dat // Timestamps for skip-identical
|
||||
{prefix}{misc}.d // Make dependencies (-MMD)
|
||||
{prefix}{misc}.dot // Debugging graph files (--debug)
|
||||
{prefix}{misc}.tree // Debugging files (--debug)
|
||||
|
||||
After running Make, the C++ compiler should produce the following:
|
||||
After running Make, the C++ compiler may produce the following:
|
||||
|
||||
verilated{misc}.d // Intermediate dependencies
|
||||
verilated{misc}.o // Intermediate objects
|
||||
{mod_prefix}{misc}.d // Intermediate dependencies
|
||||
{mod_prefix}{misc}.o // Intermediate objects
|
||||
{prefix} // Final executable (w/--exe argument)
|
||||
{prefix}__ALL.a // Library of all Verilated objects
|
||||
{prefix}__ALLboth.cpp // Include of classes for single compile
|
||||
{prefix}__ALLcls.cpp // Include of user classes for single compile
|
||||
{prefix}__ALLsup.cpp // Include of support files for single compile
|
||||
{prefix}{misc}.d // Intermediate dependencies
|
||||
{prefix}{misc}.o // Intermediate objects
|
||||
|
||||
|
||||
@@ -3731,6 +3749,17 @@ Change this to:
|
||||
Verilator doesn't do this conversion for you, as some more complicated
|
||||
cases would result in simulator mismatches.
|
||||
|
||||
=item TICKCOUNT
|
||||
|
||||
Warns that the number of ticks to delay a $past variable is greater than
|
||||
10. At present Verilator effectively creates a flop for each delayed
|
||||
signals, and as such any large counts may lead to large design size
|
||||
increases.
|
||||
|
||||
Ignoring this warning will only slow simulations, it will simulate
|
||||
correctly.
|
||||
|
||||
|
||||
=item UNDRIVEN
|
||||
|
||||
Warns that the specified signal is never sourced. Verilator is fairly
|
||||
@@ -3954,17 +3983,30 @@ For example:
|
||||
will toggle forever and thus the executable will give the didn't converge
|
||||
error to prevent an infinite loop.
|
||||
|
||||
To debug this, run Verilator with --prof-cfuncs. Run make on the
|
||||
generated files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in
|
||||
your main.cpp.
|
||||
To debug this, first is to review any UNOPTFLAT warnings that were ignored,
|
||||
though typically these can be ignored (at a performance cost), convergence
|
||||
issues can also be flagged with this warning as Verilator didn't know if
|
||||
they would eventually converge.
|
||||
|
||||
Next, run Verilator with --prof-cfuncs. Run make on the generated
|
||||
files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in your
|
||||
main.cpp.
|
||||
|
||||
This will cause each change in a variable to print a message. Near the
|
||||
bottom you'll see the code and variable that causes the problem. For the
|
||||
program above:
|
||||
bottom you'll see the variables that causes the problem. For the program
|
||||
above:
|
||||
|
||||
CHANGE: filename.v:1: b
|
||||
CHANGE: filename.v:2: a
|
||||
|
||||
If many signals are getting printed then most likely each are oscillating
|
||||
(or there is a bug). It may also be that e.g. "a" may be oscillating, then
|
||||
"a" feeds signal "c" which then is also reported as oscillating.
|
||||
|
||||
Finally, rare more difficult cases can be debugged like a "C" program;
|
||||
either enter GDB and use its tracing facilities, or edit the generated C++
|
||||
code to add appropriate prints to see what is going on.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
@@ -4105,6 +4147,23 @@ trace file if you want all data to land in the same output file.
|
||||
tfp->close();
|
||||
}
|
||||
|
||||
=item How do I generate FST waveforms (traces) in C++?
|
||||
|
||||
FST a format by GTKWave.
|
||||
This version provides a basic FST support.
|
||||
To dump FST format, add the --trace switch to Verilator and change the include path in the testbench to:
|
||||
|
||||
#include "verilated_fst_c.h"
|
||||
VerilatedFstC* tfp = new VerilatedFstC;
|
||||
|
||||
Note that currently supporting both FST and VCD in a single simulation is impossible,
|
||||
but such requirement could be rare.
|
||||
|
||||
=item How do I generate FST waveforms (traces) in SystemC?
|
||||
|
||||
The FST library from GTKWave does not currently support SystemC; use VCD
|
||||
format instead.
|
||||
|
||||
=item How do I generate LXT2 waveforms (traces) in C++?
|
||||
|
||||
LXT2 a format by GTKWave, which is usually 10x smaller than VCD format.
|
||||
@@ -4124,10 +4183,10 @@ format instead.
|
||||
|
||||
=item How do I view waveforms (traces)?
|
||||
|
||||
Verilator makes standard VCD (Value Change Dump) and LXT2 files. VCD files are viewable
|
||||
Verilator makes standard VCD (Value Change Dump), LXT2 and FST files. VCD files are viewable
|
||||
with the public domain GTKWave (recommended) or Dinotrace (legacy)
|
||||
programs, or any of the many commercial offerings;
|
||||
LXT2 is supported by GTKWave only.
|
||||
LXT2 and FST are supported by GTKWave only.
|
||||
|
||||
=item How do I reduce the size of large waveform (trace) files?
|
||||
|
||||
|
||||
+4
-4
@@ -6,7 +6,7 @@
|
||||
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[4.002 2018-09-16],
|
||||
AC_INIT([Verilator],[4.004 2018-10-06],
|
||||
[https://www.veripool.org/verilator],
|
||||
[verilator],[https://www.veripool.org/verilator])
|
||||
# When releasing, also update header of Changes file
|
||||
@@ -234,9 +234,9 @@ _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++03)
|
||||
AC_SUBST(CFG_CXXFLAGS_STD_NEWEST)
|
||||
# And likewise oldest standard (same list above, backwards)
|
||||
# This is used for internal testing
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++03)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++14)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=c++03)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=c++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=c++14)
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++17)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++03)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++11)
|
||||
|
||||
@@ -0,0 +1,547 @@
|
||||
/*
|
||||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Copyright (C) 2007 Ariya Hidayat ([email protected])
|
||||
Copyright (C) 2006 Ariya Hidayat ([email protected])
|
||||
Copyright (C) 2005 Ariya Hidayat ([email protected])
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "fastlz.h"
|
||||
|
||||
#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
|
||||
|
||||
/*
|
||||
* Always check for bound when decompressing.
|
||||
* Generally it is best to leave it defined.
|
||||
*/
|
||||
#define FASTLZ_SAFE
|
||||
|
||||
|
||||
/*
|
||||
* Give hints to the compiler for branch prediction optimization.
|
||||
*/
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2)
|
||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
|
||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
|
||||
#else
|
||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
|
||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use inlined functions for supported systems.
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
|
||||
#define FASTLZ_INLINE inline
|
||||
#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
|
||||
#define FASTLZ_INLINE __inline
|
||||
#else
|
||||
#define FASTLZ_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prevent accessing more than 8-bit at once, except on x86 architectures.
|
||||
*/
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
#define FASTLZ_STRICT_ALIGN
|
||||
#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__amd64) /* GNU C */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(_M_IX86) /* Intel, MSVC */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__386)
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(_X86_) /* MinGW */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__I86__) /* Digital Mars */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* prototypes */
|
||||
int fastlz_compress(const void* input, int length, void* output);
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
|
||||
#define MAX_COPY 32
|
||||
#define MAX_LEN 264 /* 256 + 8 */
|
||||
#define MAX_DISTANCE 8192
|
||||
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
#define FASTLZ_READU16(p) *((const flzuint16*)(p))
|
||||
#else
|
||||
#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
|
||||
#endif
|
||||
|
||||
#define HASH_LOG 13
|
||||
#define HASH_SIZE (1<< HASH_LOG)
|
||||
#define HASH_MASK (HASH_SIZE-1)
|
||||
#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
|
||||
|
||||
#undef FASTLZ_LEVEL
|
||||
#define FASTLZ_LEVEL 1
|
||||
|
||||
#undef FASTLZ_COMPRESSOR
|
||||
#undef FASTLZ_DECOMPRESSOR
|
||||
#define FASTLZ_COMPRESSOR fastlz1_compress
|
||||
#define FASTLZ_DECOMPRESSOR fastlz1_decompress
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
|
||||
#include "fastlz.c"
|
||||
|
||||
#undef FASTLZ_LEVEL
|
||||
#define FASTLZ_LEVEL 2
|
||||
|
||||
#undef MAX_DISTANCE
|
||||
#define MAX_DISTANCE 8191
|
||||
#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
|
||||
|
||||
#undef FASTLZ_COMPRESSOR
|
||||
#undef FASTLZ_DECOMPRESSOR
|
||||
#define FASTLZ_COMPRESSOR fastlz2_compress
|
||||
#define FASTLZ_DECOMPRESSOR fastlz2_decompress
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
|
||||
#include "fastlz.c"
|
||||
|
||||
int fastlz_compress(const void* input, int length, void* output)
|
||||
{
|
||||
/* for short block, choose fastlz1 */
|
||||
if(length < 65536)
|
||||
return fastlz1_compress(input, length, output);
|
||||
|
||||
/* else... */
|
||||
return fastlz2_compress(input, length, output);
|
||||
}
|
||||
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout)
|
||||
{
|
||||
/* magic identifier for compression level */
|
||||
int level = ((*(const flzuint8*)input) >> 5) + 1;
|
||||
|
||||
if(level == 1)
|
||||
return fastlz1_decompress(input, length, output, maxout);
|
||||
if(level == 2)
|
||||
return fastlz2_decompress(input, length, output, maxout);
|
||||
|
||||
/* unknown level, trigger error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output)
|
||||
{
|
||||
if(level == 1)
|
||||
return fastlz1_compress(input, length, output);
|
||||
if(level == 2)
|
||||
return fastlz2_compress(input, length, output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
|
||||
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
|
||||
{
|
||||
const flzuint8* ip = (const flzuint8*) input;
|
||||
const flzuint8* ip_bound = ip + length - 2;
|
||||
const flzuint8* ip_limit = ip + length - 12;
|
||||
flzuint8* op = (flzuint8*) output;
|
||||
|
||||
const flzuint8* htab[HASH_SIZE];
|
||||
const flzuint8** hslot;
|
||||
flzuint32 hval;
|
||||
|
||||
flzuint32 copy;
|
||||
|
||||
/* sanity check */
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
|
||||
{
|
||||
if(length)
|
||||
{
|
||||
/* create literal copy only */
|
||||
*op++ = length-1;
|
||||
ip_bound++;
|
||||
while(ip <= ip_bound)
|
||||
*op++ = *ip++;
|
||||
return length+1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initializes hash table */
|
||||
for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
|
||||
*hslot = ip;
|
||||
|
||||
/* we start with literal copy */
|
||||
copy = 2;
|
||||
*op++ = MAX_COPY-1;
|
||||
*op++ = *ip++;
|
||||
*op++ = *ip++;
|
||||
|
||||
/* main loop */
|
||||
while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
|
||||
{
|
||||
const flzuint8* ref;
|
||||
flzuint32 distance;
|
||||
|
||||
/* minimum match length */
|
||||
flzuint32 len = 3;
|
||||
|
||||
/* comparison starting-point */
|
||||
const flzuint8* anchor = ip;
|
||||
|
||||
/* check for a run */
|
||||
#if FASTLZ_LEVEL==2
|
||||
if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
|
||||
{
|
||||
distance = 1;
|
||||
/* ip += 3; */ /* scan-build, never used */
|
||||
ref = anchor - 1 + 3;
|
||||
goto match;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* find potential match */
|
||||
HASH_FUNCTION(hval,ip);
|
||||
hslot = htab + hval;
|
||||
ref = htab[hval];
|
||||
|
||||
/* calculate distance to the match */
|
||||
distance = anchor - ref;
|
||||
|
||||
/* update hash table */
|
||||
*hslot = anchor;
|
||||
|
||||
/* is this a match? check the first 3 bytes */
|
||||
if(distance==0 ||
|
||||
#if FASTLZ_LEVEL==1
|
||||
(distance >= MAX_DISTANCE) ||
|
||||
#else
|
||||
(distance >= MAX_FARDISTANCE) ||
|
||||
#endif
|
||||
*ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
|
||||
goto literal;
|
||||
|
||||
#if FASTLZ_LEVEL==2
|
||||
/* far, needs at least 5-byte match */
|
||||
if(distance >= MAX_DISTANCE)
|
||||
{
|
||||
if(*ip++ != *ref++ || *ip++!= *ref++)
|
||||
goto literal;
|
||||
len += 2;
|
||||
}
|
||||
|
||||
match:
|
||||
#endif
|
||||
|
||||
/* last matched byte */
|
||||
ip = anchor + len;
|
||||
|
||||
/* distance is biased */
|
||||
distance--;
|
||||
|
||||
if(!distance)
|
||||
{
|
||||
/* zero distance means a run */
|
||||
flzuint8 x = ip[-1];
|
||||
while(ip < ip_bound)
|
||||
if(*ref++ != x) break; else ip++;
|
||||
}
|
||||
else
|
||||
for(;;)
|
||||
{
|
||||
/* safe because the outer check against ip limit */
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
while(ip < ip_bound)
|
||||
if(*ref++ != *ip++) break;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if we have copied something, adjust the copy count */
|
||||
if(copy)
|
||||
/* copy is biased, '0' means 1 byte copy */
|
||||
*(op-copy-1) = copy-1;
|
||||
else
|
||||
/* back, to overwrite the copy count */
|
||||
op--;
|
||||
|
||||
/* reset literal counter */
|
||||
copy = 0;
|
||||
|
||||
/* length is biased, '1' means a match of 3 bytes */
|
||||
ip -= 3;
|
||||
len = ip - anchor;
|
||||
|
||||
/* encode the match */
|
||||
#if FASTLZ_LEVEL==2
|
||||
if(distance < MAX_DISTANCE)
|
||||
{
|
||||
if(len < 7)
|
||||
{
|
||||
*op++ = (len << 5) + (distance >> 8);
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
for(len-=7; len >= 255; len-= 255)
|
||||
*op++ = 255;
|
||||
*op++ = len;
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* far away, but not yet in the another galaxy... */
|
||||
if(len < 7)
|
||||
{
|
||||
distance -= MAX_DISTANCE;
|
||||
*op++ = (len << 5) + 31;
|
||||
*op++ = 255;
|
||||
*op++ = distance >> 8;
|
||||
*op++ = distance & 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance -= MAX_DISTANCE;
|
||||
*op++ = (7 << 5) + 31;
|
||||
for(len-=7; len >= 255; len-= 255)
|
||||
*op++ = 255;
|
||||
*op++ = len;
|
||||
*op++ = 255;
|
||||
*op++ = distance >> 8;
|
||||
*op++ = distance & 255;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
|
||||
while(len > MAX_LEN-2)
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
*op++ = MAX_LEN - 2 - 7 -2;
|
||||
*op++ = (distance & 255);
|
||||
len -= MAX_LEN-2;
|
||||
}
|
||||
|
||||
if(len < 7)
|
||||
{
|
||||
*op++ = (len << 5) + (distance >> 8);
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
*op++ = len - 7;
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* update the hash at match boundary */
|
||||
HASH_FUNCTION(hval,ip);
|
||||
htab[hval] = ip++;
|
||||
HASH_FUNCTION(hval,ip);
|
||||
htab[hval] = ip++;
|
||||
|
||||
/* assuming literal copy */
|
||||
*op++ = MAX_COPY-1;
|
||||
|
||||
continue;
|
||||
|
||||
literal:
|
||||
*op++ = *anchor++;
|
||||
ip = anchor;
|
||||
copy++;
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
|
||||
{
|
||||
copy = 0;
|
||||
*op++ = MAX_COPY-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* left-over as literal copy */
|
||||
ip_bound++;
|
||||
while(ip <= ip_bound)
|
||||
{
|
||||
*op++ = *ip++;
|
||||
copy++;
|
||||
if(copy == MAX_COPY)
|
||||
{
|
||||
copy = 0;
|
||||
*op++ = MAX_COPY-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we have copied something, adjust the copy length */
|
||||
if(copy)
|
||||
*(op-copy-1) = copy-1;
|
||||
else
|
||||
op--;
|
||||
|
||||
#if FASTLZ_LEVEL==2
|
||||
/* marker for fastlz2 */
|
||||
*(flzuint8*)output |= (1 << 5);
|
||||
#endif
|
||||
|
||||
return op - (flzuint8*)output;
|
||||
}
|
||||
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
|
||||
{
|
||||
const flzuint8* ip = (const flzuint8*) input;
|
||||
const flzuint8* ip_limit = ip + length;
|
||||
flzuint8* op = (flzuint8*) output;
|
||||
flzuint8* op_limit = op + maxout;
|
||||
flzuint32 ctrl = (*ip++) & 31;
|
||||
int loop = 1;
|
||||
|
||||
do
|
||||
{
|
||||
const flzuint8* ref = op;
|
||||
flzuint32 len = ctrl >> 5;
|
||||
flzuint32 ofs = (ctrl & 31) << 8;
|
||||
|
||||
if(ctrl >= 32)
|
||||
{
|
||||
#if FASTLZ_LEVEL==2
|
||||
flzuint8 code;
|
||||
#endif
|
||||
len--;
|
||||
ref -= ofs;
|
||||
if (len == 7-1)
|
||||
#if FASTLZ_LEVEL==1
|
||||
len += *ip++;
|
||||
ref -= *ip++;
|
||||
#else
|
||||
do
|
||||
{
|
||||
code = *ip++;
|
||||
len += code;
|
||||
} while (code==255);
|
||||
code = *ip++;
|
||||
ref -= code;
|
||||
|
||||
/* match from 16-bit distance */
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
|
||||
if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
|
||||
{
|
||||
ofs = (*ip++) << 8;
|
||||
ofs += *ip++;
|
||||
ref = op - ofs - MAX_DISTANCE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FASTLZ_SAFE
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
|
||||
return 0;
|
||||
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
|
||||
ctrl = *ip++;
|
||||
else
|
||||
loop = 0;
|
||||
|
||||
if(ref == op)
|
||||
{
|
||||
/* optimize copy for a run */
|
||||
flzuint8 b = ref[-1];
|
||||
*op++ = b;
|
||||
*op++ = b;
|
||||
*op++ = b;
|
||||
for(; len; --len)
|
||||
*op++ = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
const flzuint16* p;
|
||||
flzuint16* q;
|
||||
#endif
|
||||
/* copy from reference */
|
||||
ref--;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
/* copy a byte, so that now it's word aligned */
|
||||
if(len & 1)
|
||||
{
|
||||
*op++ = *ref++;
|
||||
len--;
|
||||
}
|
||||
|
||||
/* copy 16-bit at once */
|
||||
q = (flzuint16*) op;
|
||||
op += len;
|
||||
p = (const flzuint16*) ref;
|
||||
for(len>>=1; len > 4; len-=4)
|
||||
{
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
}
|
||||
for(; len; --len)
|
||||
*q++ = *p++;
|
||||
#else
|
||||
for(; len; --len)
|
||||
*op++ = *ref++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl++;
|
||||
#ifdef FASTLZ_SAFE
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
|
||||
return 0;
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
*op++ = *ip++;
|
||||
for(--ctrl; ctrl; ctrl--)
|
||||
*op++ = *ip++;
|
||||
|
||||
loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
|
||||
if(loop)
|
||||
ctrl = *ip++;
|
||||
}
|
||||
}
|
||||
while(FASTLZ_EXPECT_CONDITIONAL(loop));
|
||||
|
||||
return op - (flzuint8*)output;
|
||||
}
|
||||
|
||||
#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Copyright (C) 2007 Ariya Hidayat ([email protected])
|
||||
Copyright (C) 2006 Ariya Hidayat ([email protected])
|
||||
Copyright (C) 2005 Ariya Hidayat ([email protected])
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FASTLZ_H
|
||||
#define FASTLZ_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define flzuint8 uint8_t
|
||||
#define flzuint16 uint16_t
|
||||
#define flzuint32 uint32_t
|
||||
|
||||
|
||||
#define FASTLZ_VERSION 0x000100
|
||||
|
||||
#define FASTLZ_VERSION_MAJOR 0
|
||||
#define FASTLZ_VERSION_MINOR 0
|
||||
#define FASTLZ_VERSION_REVISION 0
|
||||
|
||||
#define FASTLZ_VERSION_STRING "0.1.0"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
minimum input buffer size is 16.
|
||||
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
and can not be smaller than 66 bytes.
|
||||
|
||||
If the input is not compressible, the return value might be larger than
|
||||
length (input buffer size).
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
*/
|
||||
|
||||
int fastlz_compress(const void* input, int length, void* output);
|
||||
|
||||
/**
|
||||
Decompress a block of compressed data and returns the size of the
|
||||
decompressed block. If error occurs, e.g. the compressed data is
|
||||
corrupted or the output buffer is not large enough, then 0 (zero)
|
||||
will be returned instead.
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
|
||||
Decompression is memory safe and guaranteed not to write the output buffer
|
||||
more than what is specified in maxout.
|
||||
*/
|
||||
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
|
||||
/**
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
minimum input buffer size is 16.
|
||||
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
and can not be smaller than 66 bytes.
|
||||
|
||||
If the input is not compressible, the return value might be larger than
|
||||
length (input buffer size).
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
|
||||
Compression level can be specified in parameter level. At the moment,
|
||||
only level 1 and level 2 are supported.
|
||||
Level 1 is the fastest compression and generally useful for short data.
|
||||
Level 2 is slightly slower but it gives better compression ratio.
|
||||
|
||||
Note that the compressed data, regardless of the level, can always be
|
||||
decompressed using the function fastlz_decompress above.
|
||||
*/
|
||||
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FASTLZ_H */
|
||||
@@ -0,0 +1,12 @@
|
||||
/* This file specifically for FST usage */
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#define HAVE_ALLOCA 1
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#define HAVE_ALLOCA_H 1
|
||||
|
||||
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
|
||||
#define HAVE_FSEEKO 1
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,432 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2017 Tony Bybell.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FST_API_H
|
||||
#define FST_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <zlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#define FST_RDLOAD "FSTLOAD | "
|
||||
|
||||
typedef uint32_t fstHandle;
|
||||
|
||||
enum fstWriterPackType {
|
||||
FST_WR_PT_ZLIB = 0,
|
||||
FST_WR_PT_FASTLZ = 1,
|
||||
FST_WR_PT_LZ4 = 2
|
||||
};
|
||||
|
||||
enum fstFileType {
|
||||
FST_FT_MIN = 0,
|
||||
|
||||
FST_FT_VERILOG = 0,
|
||||
FST_FT_VHDL = 1,
|
||||
FST_FT_VERILOG_VHDL = 2,
|
||||
|
||||
FST_FT_MAX = 2
|
||||
};
|
||||
|
||||
enum fstBlockType {
|
||||
FST_BL_HDR = 0,
|
||||
FST_BL_VCDATA = 1,
|
||||
FST_BL_BLACKOUT = 2,
|
||||
FST_BL_GEOM = 3,
|
||||
FST_BL_HIER = 4,
|
||||
FST_BL_VCDATA_DYN_ALIAS = 5,
|
||||
FST_BL_HIER_LZ4 = 6,
|
||||
FST_BL_HIER_LZ4DUO = 7,
|
||||
FST_BL_VCDATA_DYN_ALIAS2 = 8,
|
||||
|
||||
FST_BL_ZWRAPPER = 254, /* indicates that whole trace is gz wrapped */
|
||||
FST_BL_SKIP = 255 /* used while block is being written */
|
||||
};
|
||||
|
||||
enum fstScopeType {
|
||||
FST_ST_MIN = 0,
|
||||
|
||||
FST_ST_VCD_MODULE = 0,
|
||||
FST_ST_VCD_TASK = 1,
|
||||
FST_ST_VCD_FUNCTION = 2,
|
||||
FST_ST_VCD_BEGIN = 3,
|
||||
FST_ST_VCD_FORK = 4,
|
||||
FST_ST_VCD_GENERATE = 5,
|
||||
FST_ST_VCD_STRUCT = 6,
|
||||
FST_ST_VCD_UNION = 7,
|
||||
FST_ST_VCD_CLASS = 8,
|
||||
FST_ST_VCD_INTERFACE = 9,
|
||||
FST_ST_VCD_PACKAGE = 10,
|
||||
FST_ST_VCD_PROGRAM = 11,
|
||||
|
||||
FST_ST_VHDL_ARCHITECTURE = 12,
|
||||
FST_ST_VHDL_PROCEDURE = 13,
|
||||
FST_ST_VHDL_FUNCTION = 14,
|
||||
FST_ST_VHDL_RECORD = 15,
|
||||
FST_ST_VHDL_PROCESS = 16,
|
||||
FST_ST_VHDL_BLOCK = 17,
|
||||
FST_ST_VHDL_FOR_GENERATE = 18,
|
||||
FST_ST_VHDL_IF_GENERATE = 19,
|
||||
FST_ST_VHDL_GENERATE = 20,
|
||||
FST_ST_VHDL_PACKAGE = 21,
|
||||
|
||||
FST_ST_MAX = 21,
|
||||
|
||||
FST_ST_GEN_ATTRBEGIN = 252,
|
||||
FST_ST_GEN_ATTREND = 253,
|
||||
|
||||
FST_ST_VCD_SCOPE = 254,
|
||||
FST_ST_VCD_UPSCOPE = 255
|
||||
};
|
||||
|
||||
enum fstVarType {
|
||||
FST_VT_MIN = 0, /* start of vartypes */
|
||||
|
||||
FST_VT_VCD_EVENT = 0,
|
||||
FST_VT_VCD_INTEGER = 1,
|
||||
FST_VT_VCD_PARAMETER = 2,
|
||||
FST_VT_VCD_REAL = 3,
|
||||
FST_VT_VCD_REAL_PARAMETER = 4,
|
||||
FST_VT_VCD_REG = 5,
|
||||
FST_VT_VCD_SUPPLY0 = 6,
|
||||
FST_VT_VCD_SUPPLY1 = 7,
|
||||
FST_VT_VCD_TIME = 8,
|
||||
FST_VT_VCD_TRI = 9,
|
||||
FST_VT_VCD_TRIAND = 10,
|
||||
FST_VT_VCD_TRIOR = 11,
|
||||
FST_VT_VCD_TRIREG = 12,
|
||||
FST_VT_VCD_TRI0 = 13,
|
||||
FST_VT_VCD_TRI1 = 14,
|
||||
FST_VT_VCD_WAND = 15,
|
||||
FST_VT_VCD_WIRE = 16,
|
||||
FST_VT_VCD_WOR = 17,
|
||||
FST_VT_VCD_PORT = 18,
|
||||
FST_VT_VCD_SPARRAY = 19, /* used to define the rownum (index) port for a sparse array */
|
||||
FST_VT_VCD_REALTIME = 20,
|
||||
|
||||
FST_VT_GEN_STRING = 21, /* generic string type (max len is defined dynamically via fstWriterEmitVariableLengthValueChange) */
|
||||
|
||||
FST_VT_SV_BIT = 22,
|
||||
FST_VT_SV_LOGIC = 23,
|
||||
FST_VT_SV_INT = 24, /* declare as size = 32 */
|
||||
FST_VT_SV_SHORTINT = 25, /* declare as size = 16 */
|
||||
FST_VT_SV_LONGINT = 26, /* declare as size = 64 */
|
||||
FST_VT_SV_BYTE = 27, /* declare as size = 8 */
|
||||
FST_VT_SV_ENUM = 28, /* declare as appropriate type range */
|
||||
FST_VT_SV_SHORTREAL = 29, /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */
|
||||
|
||||
FST_VT_MAX = 29 /* end of vartypes */
|
||||
};
|
||||
|
||||
enum fstVarDir {
|
||||
FST_VD_MIN = 0,
|
||||
|
||||
FST_VD_IMPLICIT = 0,
|
||||
FST_VD_INPUT = 1,
|
||||
FST_VD_OUTPUT = 2,
|
||||
FST_VD_INOUT = 3,
|
||||
FST_VD_BUFFER = 4,
|
||||
FST_VD_LINKAGE = 5,
|
||||
|
||||
FST_VD_MAX = 5
|
||||
};
|
||||
|
||||
enum fstHierType {
|
||||
FST_HT_MIN = 0,
|
||||
|
||||
FST_HT_SCOPE = 0,
|
||||
FST_HT_UPSCOPE = 1,
|
||||
FST_HT_VAR = 2,
|
||||
FST_HT_ATTRBEGIN = 3,
|
||||
FST_HT_ATTREND = 4,
|
||||
|
||||
/* FST_HT_TREEBEGIN and FST_HT_TREEEND are not yet used by FST but are currently used when fstHier bridges other formats */
|
||||
FST_HT_TREEBEGIN = 5,
|
||||
FST_HT_TREEEND = 6,
|
||||
|
||||
FST_HT_MAX = 6
|
||||
};
|
||||
|
||||
enum fstAttrType {
|
||||
FST_AT_MIN = 0,
|
||||
|
||||
FST_AT_MISC = 0, /* self-contained: does not need matching FST_HT_ATTREND */
|
||||
FST_AT_ARRAY = 1,
|
||||
FST_AT_ENUM = 2,
|
||||
FST_AT_PACK = 3,
|
||||
|
||||
FST_AT_MAX = 3
|
||||
};
|
||||
|
||||
enum fstMiscType {
|
||||
FST_MT_MIN = 0,
|
||||
|
||||
FST_MT_COMMENT = 0, /* use fstWriterSetComment() to emit */
|
||||
FST_MT_ENVVAR = 1, /* use fstWriterSetEnvVar() to emit */
|
||||
FST_MT_SUPVAR = 2, /* use fstWriterCreateVar2() to emit */
|
||||
FST_MT_PATHNAME = 3, /* reserved for fstWriterSetSourceStem() string -> number management */
|
||||
FST_MT_SOURCESTEM = 4, /* use fstWriterSetSourceStem() to emit */
|
||||
FST_MT_SOURCEISTEM = 5, /* use fstWriterSetSourceInstantiationStem() to emit */
|
||||
FST_MT_VALUELIST = 6, /* use fstWriterSetValueList() to emit, followed by fstWriterCreateVar*() */
|
||||
FST_MT_UNKNOWN = 7,
|
||||
|
||||
FST_MT_MAX = 7
|
||||
};
|
||||
|
||||
enum fstArrayType {
|
||||
FST_AR_MIN = 0,
|
||||
|
||||
FST_AR_NONE = 0,
|
||||
FST_AR_UNPACKED = 1,
|
||||
FST_AR_PACKED = 2,
|
||||
FST_AR_SPARSE = 3,
|
||||
|
||||
FST_AR_MAX = 3
|
||||
};
|
||||
|
||||
enum fstEnumValueType {
|
||||
FST_EV_SV_INTEGER = 0,
|
||||
FST_EV_SV_BIT = 1,
|
||||
FST_EV_SV_LOGIC = 2,
|
||||
FST_EV_SV_INT = 3,
|
||||
FST_EV_SV_SHORTINT = 4,
|
||||
FST_EV_SV_LONGINT = 5,
|
||||
FST_EV_SV_BYTE = 6,
|
||||
FST_EV_SV_UNSIGNED_INTEGER = 7,
|
||||
FST_EV_SV_UNSIGNED_BIT = 8,
|
||||
FST_EV_SV_UNSIGNED_LOGIC = 9,
|
||||
FST_EV_SV_UNSIGNED_INT = 10,
|
||||
FST_EV_SV_UNSIGNED_SHORTINT = 11,
|
||||
FST_EV_SV_UNSIGNED_LONGINT = 12,
|
||||
FST_EV_SV_UNSIGNED_BYTE = 13,
|
||||
|
||||
FST_EV_MAX = 13
|
||||
};
|
||||
|
||||
enum fstPackType {
|
||||
FST_PT_NONE = 0,
|
||||
FST_PT_UNPACKED = 1,
|
||||
FST_PT_PACKED = 2,
|
||||
FST_PT_TAGGED_PACKED = 3,
|
||||
|
||||
FST_PT_MAX = 3
|
||||
};
|
||||
|
||||
enum fstSupplementalVarType {
|
||||
FST_SVT_MIN = 0,
|
||||
|
||||
FST_SVT_NONE = 0,
|
||||
|
||||
FST_SVT_VHDL_SIGNAL = 1,
|
||||
FST_SVT_VHDL_VARIABLE = 2,
|
||||
FST_SVT_VHDL_CONSTANT = 3,
|
||||
FST_SVT_VHDL_FILE = 4,
|
||||
FST_SVT_VHDL_MEMORY = 5,
|
||||
|
||||
FST_SVT_MAX = 5
|
||||
};
|
||||
|
||||
enum fstSupplementalDataType {
|
||||
FST_SDT_MIN = 0,
|
||||
|
||||
FST_SDT_NONE = 0,
|
||||
|
||||
FST_SDT_VHDL_BOOLEAN = 1,
|
||||
FST_SDT_VHDL_BIT = 2,
|
||||
FST_SDT_VHDL_BIT_VECTOR = 3,
|
||||
FST_SDT_VHDL_STD_ULOGIC = 4,
|
||||
FST_SDT_VHDL_STD_ULOGIC_VECTOR = 5,
|
||||
FST_SDT_VHDL_STD_LOGIC = 6,
|
||||
FST_SDT_VHDL_STD_LOGIC_VECTOR = 7,
|
||||
FST_SDT_VHDL_UNSIGNED = 8,
|
||||
FST_SDT_VHDL_SIGNED = 9,
|
||||
FST_SDT_VHDL_INTEGER = 10,
|
||||
FST_SDT_VHDL_REAL = 11,
|
||||
FST_SDT_VHDL_NATURAL = 12,
|
||||
FST_SDT_VHDL_POSITIVE = 13,
|
||||
FST_SDT_VHDL_TIME = 14,
|
||||
FST_SDT_VHDL_CHARACTER = 15,
|
||||
FST_SDT_VHDL_STRING = 16,
|
||||
|
||||
FST_SDT_MAX = 16,
|
||||
|
||||
FST_SDT_SVT_SHIFT_COUNT = 10, /* FST_SVT_* is ORed in by fstWriterCreateVar2() to the left after shifting FST_SDT_SVT_SHIFT_COUNT */
|
||||
FST_SDT_ABS_MAX = ((1<<(FST_SDT_SVT_SHIFT_COUNT))-1)
|
||||
};
|
||||
|
||||
|
||||
struct fstHier
|
||||
{
|
||||
unsigned char htyp;
|
||||
|
||||
union {
|
||||
/* if htyp == FST_HT_SCOPE */
|
||||
struct fstHierScope {
|
||||
unsigned char typ; /* FST_ST_MIN ... FST_ST_MAX */
|
||||
const char *name;
|
||||
const char *component;
|
||||
uint32_t name_length; /* strlen(u.scope.name) */
|
||||
uint32_t component_length; /* strlen(u.scope.component) */
|
||||
} scope;
|
||||
|
||||
/* if htyp == FST_HT_VAR */
|
||||
struct fstHierVar {
|
||||
unsigned char typ; /* FST_VT_MIN ... FST_VT_MAX */
|
||||
unsigned char direction; /* FST_VD_MIN ... FST_VD_MAX */
|
||||
unsigned char svt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
unsigned char sdt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
unsigned int sxt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
const char *name;
|
||||
uint32_t length;
|
||||
fstHandle handle;
|
||||
uint32_t name_length; /* strlen(u.var.name) */
|
||||
unsigned is_alias : 1;
|
||||
} var;
|
||||
|
||||
/* if htyp == FST_HT_ATTRBEGIN */
|
||||
struct fstHierAttr {
|
||||
unsigned char typ; /* FST_AT_MIN ... FST_AT_MAX */
|
||||
unsigned char subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */
|
||||
const char *name;
|
||||
uint64_t arg; /* number of array elements, struct members, or some other payload (possibly ignored) */
|
||||
uint64_t arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */
|
||||
uint32_t name_length; /* strlen(u.attr.name) */
|
||||
} attr;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* writer functions
|
||||
*/
|
||||
void fstWriterClose(void *ctx);
|
||||
void * fstWriterCreate(const char *nam, int use_compressed_hier);
|
||||
/* used for Verilog/SV */
|
||||
fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle);
|
||||
/* future expansion for VHDL and other languages. The variable type, data type, etc map onto
|
||||
the current Verilog/SV one. The "type" string is optional for a more verbose or custom description */
|
||||
fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle,
|
||||
const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt);
|
||||
void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val);
|
||||
void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len);
|
||||
void fstWriterEmitDumpActive(void *ctx, int enable);
|
||||
void fstWriterEmitTimeChange(void *ctx, uint64_t tim);
|
||||
void fstWriterFlushContext(void *ctx);
|
||||
int fstWriterGetDumpSizeLimitReached(void *ctx);
|
||||
int fstWriterGetFseekFailed(void *ctx);
|
||||
void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype,
|
||||
const char *attrname, uint64_t arg);
|
||||
void fstWriterSetAttrEnd(void *ctx);
|
||||
void fstWriterSetComment(void *ctx, const char *comm);
|
||||
void fstWriterSetDate(void *ctx, const char *dat);
|
||||
void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes);
|
||||
void fstWriterSetEnvVar(void *ctx, const char *envvar);
|
||||
void fstWriterSetFileType(void *ctx, enum fstFileType filetype);
|
||||
void fstWriterSetPackType(void *ctx, enum fstWriterPackType typ);
|
||||
void fstWriterSetParallelMode(void *ctx, int enable);
|
||||
void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */
|
||||
void fstWriterSetScope(void *ctx, enum fstScopeType scopetype,
|
||||
const char *scopename, const char *scopecomp);
|
||||
void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
|
||||
void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
|
||||
void fstWriterSetTimescale(void *ctx, int ts);
|
||||
void fstWriterSetTimescaleFromString(void *ctx, const char *s);
|
||||
void fstWriterSetTimezero(void *ctx, int64_t tim);
|
||||
void fstWriterSetUpscope(void *ctx);
|
||||
void fstWriterSetValueList(void *ctx, const char *vl);
|
||||
void fstWriterSetVersion(void *ctx, const char *vers);
|
||||
|
||||
|
||||
/*
|
||||
* reader functions
|
||||
*/
|
||||
void fstReaderClose(void *ctx);
|
||||
void fstReaderClrFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderClrFacProcessMaskAll(void *ctx);
|
||||
uint64_t fstReaderGetAliasCount(void *ctx);
|
||||
const char * fstReaderGetCurrentFlatScope(void *ctx);
|
||||
void * fstReaderGetCurrentScopeUserInfo(void *ctx);
|
||||
int fstReaderGetCurrentScopeLen(void *ctx);
|
||||
const char * fstReaderGetDateString(void *ctx);
|
||||
int fstReaderGetDoubleEndianMatchState(void *ctx);
|
||||
uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx);
|
||||
unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx);
|
||||
uint64_t fstReaderGetEndTime(void *ctx);
|
||||
int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx);
|
||||
int fstReaderGetFileType(void *ctx);
|
||||
int fstReaderGetFseekFailed(void *ctx);
|
||||
fstHandle fstReaderGetMaxHandle(void *ctx);
|
||||
uint64_t fstReaderGetMemoryUsedByWriter(void *ctx);
|
||||
uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx);
|
||||
uint64_t fstReaderGetScopeCount(void *ctx);
|
||||
uint64_t fstReaderGetStartTime(void *ctx);
|
||||
signed char fstReaderGetTimescale(void *ctx);
|
||||
int64_t fstReaderGetTimezero(void *ctx);
|
||||
uint64_t fstReaderGetValueChangeSectionCount(void *ctx);
|
||||
char * fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf);
|
||||
uint64_t fstReaderGetVarCount(void *ctx);
|
||||
const char * fstReaderGetVersionString(void *ctx);
|
||||
struct fstHier *fstReaderIterateHier(void *ctx);
|
||||
int fstReaderIterateHierRewind(void *ctx);
|
||||
int fstReaderIterBlocks(void *ctx,
|
||||
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
|
||||
void *user_callback_data_pointer, FILE *vcdhandle);
|
||||
int fstReaderIterBlocks2(void *ctx,
|
||||
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
|
||||
void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len),
|
||||
void *user_callback_data_pointer, FILE *vcdhandle);
|
||||
void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable);
|
||||
void * fstReaderOpen(const char *nam);
|
||||
void * fstReaderOpenForUtilitiesOnly(void);
|
||||
const char * fstReaderPopScope(void *ctx);
|
||||
int fstReaderProcessHier(void *ctx, FILE *vcdhandle);
|
||||
const char * fstReaderPushScope(void *ctx, const char *nam, void *user_info);
|
||||
void fstReaderResetScope(void *ctx);
|
||||
void fstReaderSetFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderSetFacProcessMaskAll(void *ctx);
|
||||
void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time);
|
||||
void fstReaderSetUnlimitedTimeRange(void *ctx);
|
||||
void fstReaderSetVcdExtensions(void *ctx, int enable);
|
||||
|
||||
|
||||
/*
|
||||
* utility functions
|
||||
*/
|
||||
int fstUtilityBinToEsc(unsigned char *d, unsigned char *s, int len);
|
||||
int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "lxt2_config.h"
|
||||
#include "lxt2_write.h"
|
||||
|
||||
|
||||
static char *lxt2_wr_vcd_truncate_bitvec(char *s)
|
||||
{
|
||||
char l, r;
|
||||
@@ -96,7 +97,7 @@ if (lo<hi)
|
||||
|
||||
static void wave_msort(struct lxt2_wr_symbol **a, int num)
|
||||
{
|
||||
struct lxt2_wr_symbol **b = (lxt2_wr_symbol**)malloc(((num/2)+1) * sizeof(struct lxt2_wr_symbol *));
|
||||
struct lxt2_wr_symbol **b = (struct lxt2_wr_symbol**)malloc(((num/2)+1) * sizeof(struct lxt2_wr_symbol *));
|
||||
|
||||
wave_mergesort(a, b, 0, num-1);
|
||||
|
||||
@@ -582,7 +583,7 @@ unsigned int i;
|
||||
if((lt)&&(lt->numfacs))
|
||||
{
|
||||
struct lxt2_wr_symbol *s = lt->symchain;
|
||||
struct lxt2_wr_symbol **aliascache = (lxt2_wr_symbol**)calloc(lt->numalias ? lt->numalias : 1, sizeof(struct lxt2_wr_symbol *));
|
||||
struct lxt2_wr_symbol **aliascache = (struct lxt2_wr_symbol**)calloc(lt->numalias ? lt->numalias : 1, sizeof(struct lxt2_wr_symbol *));
|
||||
unsigned int aliases_encountered, facs_encountered;
|
||||
|
||||
lt->sorted_facs = (struct lxt2_wr_symbol **)calloc(lt->numfacs, sizeof(struct lxt2_wr_symbol *));
|
||||
@@ -2100,7 +2101,7 @@ if((lt)&&(lt->blackout))
|
||||
{
|
||||
if((!(s->flags&LXT2_WR_SYM_F_ALIAS))&&(s->rows<2))
|
||||
{
|
||||
char tmp[16]; // To get rid of the warning
|
||||
char tmp[16]; /* To get rid of the warning */
|
||||
if(!(s->flags&(LXT2_WR_SYM_F_DOUBLE|LXT2_WR_SYM_F_STRING)))
|
||||
{
|
||||
strcpy(tmp, "x");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
LZ4 - Fast LZ compression algorithm
|
||||
Header File
|
||||
Copyright (C) 2011-2015, Yann Collet.
|
||||
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 source repository : https://github.com/Cyan4973/lz4
|
||||
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* lz4.h provides block compression functions, and gives full buffer control to programmer.
|
||||
* If you need to generate inter-operable compressed data (respecting LZ4 frame specification),
|
||||
* and can let the library handle its own memory, please use lz4frame.h instead.
|
||||
*/
|
||||
|
||||
/**************************************
|
||||
* Version
|
||||
**************************************/
|
||||
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
|
||||
#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */
|
||||
#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */
|
||||
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
|
||||
int LZ4_versionNumber (void);
|
||||
|
||||
/**************************************
|
||||
* Tuning parameter
|
||||
**************************************/
|
||||
/*
|
||||
* LZ4_MEMORY_USAGE :
|
||||
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
|
||||
* Increasing memory usage improves compression ratio
|
||||
* Reduced memory usage can improve speed, due to cache effect
|
||||
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
|
||||
*/
|
||||
#define LZ4_MEMORY_USAGE 14
|
||||
|
||||
|
||||
/**************************************
|
||||
* Simple Functions
|
||||
**************************************/
|
||||
|
||||
int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize);
|
||||
int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
|
||||
|
||||
/*
|
||||
LZ4_compress_default() :
|
||||
Compresses 'sourceSize' bytes from buffer 'source'
|
||||
into already allocated 'dest' buffer of size 'maxDestSize'.
|
||||
Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize).
|
||||
It also runs faster, so it's a recommended setting.
|
||||
If the function cannot compress 'source' into a more limited 'dest' budget,
|
||||
compression stops *immediately*, and the function result is zero.
|
||||
As a consequence, 'dest' content is not valid.
|
||||
This function never writes outside 'dest' buffer, nor read outside 'source' buffer.
|
||||
sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE
|
||||
maxDestSize : full or partial size of buffer 'dest' (which must be already allocated)
|
||||
return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize)
|
||||
or 0 if compression fails
|
||||
|
||||
LZ4_decompress_safe() :
|
||||
compressedSize : is the precise full size of the compressed block.
|
||||
maxDecompressedSize : is the size of destination buffer, which must be already allocated.
|
||||
return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize)
|
||||
If destination buffer is not large enough, decoding will stop and output an error code (<0).
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
This function is protected against buffer overflow exploits, including malicious data packets.
|
||||
It never writes outside output buffer, nor reads outside input buffer.
|
||||
*/
|
||||
|
||||
|
||||
/**************************************
|
||||
* Advanced Functions
|
||||
**************************************/
|
||||
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
|
||||
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
|
||||
|
||||
/*
|
||||
LZ4_compressBound() :
|
||||
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
|
||||
This function is primarily useful for memory allocation purposes (destination buffer size).
|
||||
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
|
||||
Note that LZ4_compress_default() compress faster when dest buffer size is >= LZ4_compressBound(srcSize)
|
||||
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
|
||||
return : maximum output size in a "worst case" scenario
|
||||
or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
|
||||
*/
|
||||
int LZ4_compressBound(int inputSize);
|
||||
|
||||
/*
|
||||
LZ4_compress_fast() :
|
||||
Same as LZ4_compress_default(), but allows to select an "acceleration" factor.
|
||||
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
|
||||
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
|
||||
An acceleration value of "1" is the same as regular LZ4_compress_default()
|
||||
Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1.
|
||||
*/
|
||||
int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration);
|
||||
|
||||
|
||||
/*
|
||||
LZ4_compress_fast_extState() :
|
||||
Same compression function, just using an externally allocated memory space to store compression state.
|
||||
Use LZ4_sizeofState() to know how much memory must be allocated,
|
||||
and allocate it on 8-bytes boundaries (using malloc() typically).
|
||||
Then, provide it as 'void* state' to compression function.
|
||||
*/
|
||||
int LZ4_sizeofState(void);
|
||||
int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration);
|
||||
|
||||
|
||||
/*
|
||||
LZ4_compress_destSize() :
|
||||
Reverse the logic, by compressing as much data as possible from 'source' buffer
|
||||
into already allocated buffer 'dest' of size 'targetDestSize'.
|
||||
This function either compresses the entire 'source' content into 'dest' if it's large enough,
|
||||
or fill 'dest' buffer completely with as much data as possible from 'source'.
|
||||
*sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'.
|
||||
New value is necessarily <= old value.
|
||||
return : Nb bytes written into 'dest' (necessarily <= targetDestSize)
|
||||
or 0 if compression fails
|
||||
*/
|
||||
int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize);
|
||||
|
||||
|
||||
/*
|
||||
LZ4_decompress_fast() :
|
||||
originalSize : is the original and therefore uncompressed size
|
||||
return : the number of bytes read from the source buffer (in other words, the compressed size)
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes.
|
||||
note : This function fully respect memory boundaries for properly formed compressed data.
|
||||
It is a bit faster than LZ4_decompress_safe().
|
||||
However, it does not provide any protection against intentionally modified data stream (malicious input).
|
||||
Use this function in trusted environment only (data to decode comes from a trusted source).
|
||||
*/
|
||||
int LZ4_decompress_fast (const char* source, char* dest, int originalSize);
|
||||
|
||||
/*
|
||||
LZ4_decompress_safe_partial() :
|
||||
This function decompress a compressed block of size 'compressedSize' at position 'source'
|
||||
into destination buffer 'dest' of size 'maxDecompressedSize'.
|
||||
The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached,
|
||||
reducing decompression time.
|
||||
return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize)
|
||||
Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller.
|
||||
Always control how many bytes were decoded.
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets
|
||||
*/
|
||||
int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize);
|
||||
|
||||
|
||||
/***********************************************
|
||||
* Streaming Compression Functions
|
||||
***********************************************/
|
||||
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
|
||||
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long))
|
||||
/*
|
||||
* LZ4_stream_t
|
||||
* information structure to track an LZ4 stream.
|
||||
* important : init this structure content before first use !
|
||||
* note : only allocated directly the structure if you are statically linking LZ4
|
||||
* If you are using liblz4 as a DLL, please use below construction methods instead.
|
||||
*/
|
||||
typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t;
|
||||
|
||||
/*
|
||||
* LZ4_resetStream
|
||||
* Use this function to init an allocated LZ4_stream_t structure
|
||||
*/
|
||||
void LZ4_resetStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*
|
||||
* LZ4_createStream will allocate and initialize an LZ4_stream_t structure
|
||||
* LZ4_freeStream releases its memory.
|
||||
* In the context of a DLL (liblz4), please use these methods rather than the static struct.
|
||||
* They are more future proof, in case of a change of LZ4_stream_t size.
|
||||
*/
|
||||
LZ4_stream_t* LZ4_createStream(void);
|
||||
int LZ4_freeStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*
|
||||
* LZ4_loadDict
|
||||
* Use this function to load a static dictionary into LZ4_stream.
|
||||
* Any previous data will be forgotten, only 'dictionary' will remain in memory.
|
||||
* Loading a size of 0 is allowed.
|
||||
* Return : dictionary size, in bytes (necessarily <= 64 KB)
|
||||
*/
|
||||
int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
|
||||
|
||||
/*
|
||||
* LZ4_compress_fast_continue
|
||||
* Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio.
|
||||
* Important : Previous data blocks are assumed to still be present and unmodified !
|
||||
* 'dst' buffer must be already allocated.
|
||||
* If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
|
||||
* If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero.
|
||||
*/
|
||||
int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration);
|
||||
|
||||
/*
|
||||
* LZ4_saveDict
|
||||
* If previously compressed data block is not guaranteed to remain available at its memory location
|
||||
* save it into a safer place (char* safeBuffer)
|
||||
* Note : you don't need to call LZ4_loadDict() afterwards,
|
||||
* dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue()
|
||||
* Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error
|
||||
*/
|
||||
int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize);
|
||||
|
||||
|
||||
/************************************************
|
||||
* Streaming Decompression Functions
|
||||
************************************************/
|
||||
|
||||
#define LZ4_STREAMDECODESIZE_U64 4
|
||||
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
|
||||
typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t;
|
||||
/*
|
||||
* LZ4_streamDecode_t
|
||||
* information structure to track an LZ4 stream.
|
||||
* init this structure content using LZ4_setStreamDecode or memset() before first use !
|
||||
*
|
||||
* In the context of a DLL (liblz4) please prefer usage of construction methods below.
|
||||
* They are more future proof, in case of a change of LZ4_streamDecode_t size in the future.
|
||||
* LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure
|
||||
* LZ4_freeStreamDecode releases its memory.
|
||||
*/
|
||||
LZ4_streamDecode_t* LZ4_createStreamDecode(void);
|
||||
int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
|
||||
|
||||
/*
|
||||
* LZ4_setStreamDecode
|
||||
* Use this function to instruct where to find the dictionary.
|
||||
* Setting a size of 0 is allowed (same effect as reset).
|
||||
* Return : 1 if OK, 0 if error
|
||||
*/
|
||||
int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
|
||||
|
||||
/*
|
||||
*_continue() :
|
||||
These decoding functions allow decompression of multiple blocks in "streaming" mode.
|
||||
Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB)
|
||||
In the case of a ring buffers, decoding buffer must be either :
|
||||
- Exactly same size as encoding buffer, with same update rule (block boundaries at same positions)
|
||||
In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB).
|
||||
- Larger than encoding buffer, by a minimum of maxBlockSize more bytes.
|
||||
maxBlockSize is implementation dependent. It's the maximum size you intend to compress into a single block.
|
||||
In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
and encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||
- _At least_ 64 KB + 8 bytes + maxBlockSize.
|
||||
In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
and encoding ring buffer can have any size, including larger than decoding buffer.
|
||||
Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer,
|
||||
and indicate where it is saved using LZ4_setStreamDecode()
|
||||
*/
|
||||
int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize);
|
||||
int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize);
|
||||
|
||||
|
||||
/*
|
||||
Advanced decoding functions :
|
||||
*_usingDict() :
|
||||
These decoding functions work the same as
|
||||
a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue()
|
||||
They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure.
|
||||
*/
|
||||
int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize);
|
||||
int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize);
|
||||
|
||||
|
||||
|
||||
/**************************************
|
||||
* Obsolete Functions
|
||||
**************************************/
|
||||
/* Deprecate Warnings */
|
||||
/* Should these warnings messages be a problem,
|
||||
it is generally possible to disable them,
|
||||
with -Wno-deprecated-declarations for gcc
|
||||
or _CRT_SECURE_NO_WARNINGS in Visual for example.
|
||||
You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */
|
||||
#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK
|
||||
# define LZ4_DEPRECATE_WARNING_DEFBLOCK
|
||||
# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||
# if (LZ4_GCC_VERSION >= 405) || defined(__clang__)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
# elif (LZ4_GCC_VERSION >= 301)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
|
||||
# elif defined(_MSC_VER)
|
||||
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
|
||||
# else
|
||||
# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
|
||||
# define LZ4_DEPRECATED(message)
|
||||
# endif
|
||||
#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */
|
||||
|
||||
/* Obsolete compression functions */
|
||||
/* These functions are planned to start generate warnings by r131 approximately */
|
||||
int LZ4_compress (const char* source, char* dest, int sourceSize);
|
||||
int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
|
||||
int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
|
||||
int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
|
||||
int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
|
||||
/* Obsolete decompression functions */
|
||||
/* These function names are completely deprecated and must no longer be used.
|
||||
They are only provided here for compatibility with older programs.
|
||||
- LZ4_uncompress is the same as LZ4_decompress_fast
|
||||
- LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe
|
||||
These function prototypes are now disabled; uncomment them only if you really need them.
|
||||
It is highly recommended to stop using these prototypes and migrate to maintained ones */
|
||||
/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */
|
||||
/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */
|
||||
|
||||
/* Obsolete streaming functions; use new streaming interface whenever possible */
|
||||
LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer);
|
||||
LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void);
|
||||
LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer);
|
||||
LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state);
|
||||
|
||||
/* Obsolete streaming decoding functions */
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
|
||||
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Tony Bybell.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WAVE_ALLOCA_H
|
||||
#define WAVE_ALLOCA_H
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#elif defined(__GNUC__)
|
||||
#ifndef __MINGW32__
|
||||
#ifndef alloca
|
||||
#define alloca __builtin_alloca
|
||||
#endif
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#include <malloc.h>
|
||||
#define alloca _alloca
|
||||
#endif
|
||||
#define wave_alloca alloca
|
||||
#endif
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Tony Bybell 1999.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef WAVE_ALLOCA_H
|
||||
#define WAVE_ALLOCA_H
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#elif defined(__GNUC__)
|
||||
#ifndef __MINGW32__
|
||||
#ifndef alloca
|
||||
#define alloca __builtin_alloca
|
||||
#endif
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#include <malloc.h>
|
||||
#define alloca _alloca
|
||||
#endif
|
||||
#define wave_alloca alloca
|
||||
#endif
|
||||
|
||||
@@ -234,7 +234,6 @@ vluint64_t vl_rand64() VL_MT_SAFE {
|
||||
if (VL_UNLIKELY(!t_seeded)) {
|
||||
t_seeded = true;
|
||||
{
|
||||
long seedval;
|
||||
VerilatedLockGuard lock(s_mutex);
|
||||
t_state[0] = (((vluint64_t)vl_sys_rand32())<<32
|
||||
^ ((vluint64_t)vl_sys_rand32()));
|
||||
|
||||
+11
-8
@@ -81,6 +81,8 @@ class VerilatedVcd;
|
||||
class VerilatedVcdC;
|
||||
class VerilatedLxt2;
|
||||
class VerilatedLxt2C;
|
||||
class VerilatedFst;
|
||||
class VerilatedFstC;
|
||||
|
||||
enum VerilatedVarType {
|
||||
VLVT_UNKNOWN=0,
|
||||
@@ -94,15 +96,16 @@ enum VerilatedVarType {
|
||||
};
|
||||
|
||||
enum VerilatedVarFlags {
|
||||
VLVD_IN=1, // == vpiInput
|
||||
VLVD_OUT=2, // == vpiOutput
|
||||
VLVD_INOUT=3, // == vpiInOut
|
||||
VLVD_NODIR=5, // == vpiNoDirection
|
||||
VLVF_MASK_DIR=7, // Bit mask for above directions
|
||||
VLVD_0 = 0, // None
|
||||
VLVD_IN = 1, // == vpiInput
|
||||
VLVD_OUT = 2, // == vpiOutput
|
||||
VLVD_INOUT = 3, // == vpiInOut
|
||||
VLVD_NODIR = 5, // == vpiNoDirection
|
||||
VLVF_MASK_DIR = 7, // Bit mask for above directions
|
||||
// Flags
|
||||
VLVF_PUB_RD=(1<<8), // Public readable
|
||||
VLVF_PUB_RW=(1<<9), // Public writable
|
||||
VLVF_DPI_CLAY=(1<<10) // DPI compatible C standard layout
|
||||
VLVF_PUB_RD = (1<<8), // Public readable
|
||||
VLVF_PUB_RW = (1<<9), // Public writable
|
||||
VLVF_DPI_CLAY = (1<<10) // DPI compatible C standard layout
|
||||
};
|
||||
|
||||
//=========================================================================
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2018 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.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief C++ Tracing in FST Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_fst_c.h"
|
||||
// Include the GTKWave implementation directly
|
||||
#include "gtkwave/fstapi.c"
|
||||
#include "gtkwave/fastlz.c"
|
||||
#include "gtkwave/lz4.c"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <cerrno>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class VerilatedFstCallInfo {
|
||||
protected:
|
||||
friend class VerilatedFst;
|
||||
VerilatedFstCallback_t m_initcb; ///< Initialization Callback function
|
||||
VerilatedFstCallback_t m_fullcb; ///< Full Dumping Callback function
|
||||
VerilatedFstCallback_t m_changecb; ///< Incremental Dumping Callback function
|
||||
void* m_userthis; ///< Fake "this" for caller
|
||||
vluint32_t m_code; ///< Starting code number
|
||||
// CONSTRUCTORS
|
||||
VerilatedFstCallInfo(VerilatedFstCallback_t icb, VerilatedFstCallback_t fcb,
|
||||
VerilatedFstCallback_t changecb,
|
||||
void* ut, vluint32_t code)
|
||||
: m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {};
|
||||
~VerilatedFstCallInfo() {}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFst
|
||||
|
||||
VerilatedFst::VerilatedFst(void* fst)
|
||||
: m_fst(fst),
|
||||
m_fullDump(true),
|
||||
m_scopeEscape('.') {}
|
||||
|
||||
void VerilatedFst::open(const char* filename) VL_MT_UNSAFE {
|
||||
m_assertOne.check();
|
||||
m_fst = fstWriterCreate(filename, 0);
|
||||
m_curScope.clear();
|
||||
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
||||
VerilatedFstCallInfo* cip = m_callbacks[ent];
|
||||
cip->m_code = 1;
|
||||
(cip->m_initcb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
|
||||
// Clear the scope stack
|
||||
std::list<std::string>::iterator it = m_curScope.begin();
|
||||
while (it != m_curScope.end()) {
|
||||
fstWriterSetUpscope(m_fst);
|
||||
it = m_curScope.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedFst::module(const std::string& name) {
|
||||
m_module = name;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Decl
|
||||
|
||||
void VerilatedFst::declSymbol(vluint32_t code, const char* name, fstVarDir vardir,
|
||||
fstVarType vartype,
|
||||
int arraynum, vluint32_t len) {
|
||||
std::pair<Code2SymbolType::iterator, bool> p
|
||||
= m_code2symbol.insert(std::make_pair(code, (fstHandle)(0)));
|
||||
std::istringstream nameiss(name);
|
||||
std::istream_iterator<std::string> beg(nameiss), end;
|
||||
std::list<std::string> tokens(beg, end); // Split name
|
||||
std::string symbol_name(tokens.back());
|
||||
tokens.pop_back(); // Remove symbol name from hierarchy
|
||||
tokens.insert(tokens.begin(), m_module); // Add current module to the hierarchy
|
||||
|
||||
// Find point where current and new scope diverge
|
||||
std::list<std::string>::iterator cur_it = m_curScope.begin();
|
||||
std::list<std::string>::iterator new_it = tokens.begin();
|
||||
while (cur_it != m_curScope.end() && new_it != tokens.end()) {
|
||||
if (*cur_it != *new_it)
|
||||
break;
|
||||
++cur_it;
|
||||
++new_it;
|
||||
}
|
||||
|
||||
// Go back to the common point
|
||||
while (cur_it != m_curScope.end()) {
|
||||
fstWriterSetUpscope(m_fst);
|
||||
cur_it = m_curScope.erase(cur_it);
|
||||
}
|
||||
|
||||
// Follow the hierarchy of the new variable from the common scope point
|
||||
while (new_it != tokens.end()) {
|
||||
fstWriterSetScope(m_fst, FST_ST_VCD_SCOPE, new_it->c_str(), NULL);
|
||||
m_curScope.push_back(*new_it);
|
||||
new_it = tokens.erase(new_it);
|
||||
}
|
||||
|
||||
std::stringstream name_ss;
|
||||
name_ss << symbol_name;
|
||||
if (arraynum >= 0)
|
||||
name_ss << "(" << arraynum << ")";
|
||||
std::string name_str = name_ss.str();
|
||||
|
||||
if (p.second) { // New
|
||||
p.first->second = fstWriterCreateVar(m_fst, vartype, vardir, len, name_str.c_str(), 0);
|
||||
assert(p.first->second);
|
||||
} else { // Alias
|
||||
fstWriterCreateVar(m_fst, vartype, vardir, len, name_str.c_str(), p.first->second);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Callbacks
|
||||
|
||||
void VerilatedFst::addCallback(
|
||||
VerilatedFstCallback_t initcb, VerilatedFstCallback_t fullcb,
|
||||
VerilatedFstCallback_t changecb, void* userthis) VL_MT_UNSAFE_ONE {
|
||||
m_assertOne.check();
|
||||
if (VL_UNLIKELY(isOpen())) {
|
||||
std::string msg = std::string("Internal: ")+__FILE__+"::"+__FUNCTION__+" called with already open file";
|
||||
VL_FATAL_MT(__FILE__,__LINE__,"",msg.c_str());
|
||||
}
|
||||
VerilatedFstCallInfo* vci = new VerilatedFstCallInfo(initcb, fullcb, changecb, userthis, 1);
|
||||
m_callbacks.push_back(vci);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Dumping
|
||||
|
||||
void VerilatedFst::dump(vluint64_t timeui) {
|
||||
if (!isOpen()) return;
|
||||
if (VL_UNLIKELY(m_fullDump)) {
|
||||
m_fullDump = false; // No need for more full dumps
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
||||
VerilatedFstCallInfo* cip = m_callbacks[ent];
|
||||
(cip->m_fullcb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
return;
|
||||
}
|
||||
fstWriterEmitTimeChange(m_fst, timeui);
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
||||
VerilatedFstCallInfo* cip = m_callbacks[ent];
|
||||
(cip->m_changecb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Helpers
|
||||
|
||||
char* VerilatedFst::word2Str(vluint32_t newval, int bits) {
|
||||
m_valueStrBuffer.resize(bits+1);
|
||||
char* s = m_valueStrBuffer.data();
|
||||
for (int i = 0; i < bits; ++i) {
|
||||
*s = '0' + ((newval>>(bits-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
*s = '\0';
|
||||
return m_valueStrBuffer.data();
|
||||
}
|
||||
|
||||
char* VerilatedFst::quad2Str(vluint64_t newval, int bits) {
|
||||
m_valueStrBuffer.resize(bits+1);
|
||||
char* s = m_valueStrBuffer.data();
|
||||
for (int i = 0; i < bits; ++i) {
|
||||
*s = '0' + ((newval>>(bits-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
*s = '\0';
|
||||
return m_valueStrBuffer.data();
|
||||
}
|
||||
|
||||
char* VerilatedFst::array2Str(const vluint32_t* newval, int bits) {
|
||||
int bq = bits/32, br = bits%32;
|
||||
m_valueStrBuffer.resize(bits+1);
|
||||
char* s = m_valueStrBuffer.data();
|
||||
for (int w = bq-1; w >= 0; --w) {
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
*s = '0' + ((newval[w]>>(32-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < br; ++i) {
|
||||
*s = '0' + ((newval[bq]>>(br-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
*s = '\0';
|
||||
return m_valueStrBuffer.data();
|
||||
}
|
||||
|
||||
//********************************************************************
|
||||
// Local Variables:
|
||||
// End:
|
||||
@@ -0,0 +1,217 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2018 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.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief C++ Tracing in FST Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#ifndef _VERILATED_FST_C_H_
|
||||
#define _VERILATED_FST_C_H_ 1
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "gtkwave/fstapi.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
class VerilatedFst;
|
||||
class VerilatedFstCallInfo;
|
||||
typedef void (*VerilatedFstCallback_t)(VerilatedFst* vcdp, void* userthis, vluint32_t code);
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFst
|
||||
/// Base class to create a Verilator FST dump
|
||||
/// This is an internally used class - see VerilatedFstC for what to call from applications
|
||||
|
||||
class VerilatedFst {
|
||||
typedef std::map<vluint32_t, fstHandle> Code2SymbolType;
|
||||
typedef std::vector<VerilatedFstCallInfo*> CallbackVec;
|
||||
private:
|
||||
void* m_fst;
|
||||
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
||||
bool m_fullDump;
|
||||
char m_scopeEscape;
|
||||
std::string m_module;
|
||||
CallbackVec m_callbacks; ///< Routines to perform dumping
|
||||
Code2SymbolType m_code2symbol;
|
||||
std::list<std::string> m_curScope;
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedFst);
|
||||
void declSymbol(vluint32_t code, const char* name,
|
||||
fstVarDir vardir, fstVarType vartype,
|
||||
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); } }
|
||||
bool isOpen() const { return m_fst != NULL; }
|
||||
void open(const char* filename) VL_MT_UNSAFE;
|
||||
void flush() VL_MT_UNSAFE { fstWriterFlushContext(m_fst); }
|
||||
void close() VL_MT_UNSAFE {
|
||||
m_assertOne.check();
|
||||
fstWriterClose(m_fst);
|
||||
m_fst = NULL;
|
||||
}
|
||||
// void set_time_unit(const char* unit); ///< Set time units (s/ms, defaults to ns)
|
||||
// void set_time_unit(const std::string& unit) { set_time_unit(unit.c_str()); }
|
||||
|
||||
// void set_time_resolution(const char* unit); ///< Set time resolution (s/ms, defaults to ns)
|
||||
// void set_time_resolution(const std::string& unit) { set_time_resolution(unit.c_str()); }
|
||||
|
||||
// double timescaleToDouble(const char* unitp);
|
||||
// std::string doubleToTimescale(double value);
|
||||
|
||||
/// Change character that splits scopes. Note whitespace are ALWAYS escapes.
|
||||
void scopeEscape(char flag) { m_scopeEscape = flag; }
|
||||
/// Is this an escape?
|
||||
bool isScopeEscape(char c) { return isspace(c) || c==m_scopeEscape; }
|
||||
/// Inside dumping routines, called each cycle to make the dump
|
||||
void dump(vluint64_t timeui);
|
||||
/// Inside dumping routines, declare callbacks for tracings
|
||||
void addCallback(VerilatedFstCallback_t init, VerilatedFstCallback_t full,
|
||||
VerilatedFstCallback_t change,
|
||||
void* userthis) VL_MT_UNSAFE_ONE;
|
||||
|
||||
/// 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, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum) {
|
||||
declSymbol(code, name, vardir, vartype, arraynum, 1);
|
||||
}
|
||||
void declBus(vluint32_t code, const char* name, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum, int msb, int lsb) {
|
||||
declSymbol(code, name, vardir, vartype, arraynum, msb - lsb + 1);
|
||||
}
|
||||
void declDouble(vluint32_t code, const char* name, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum) {
|
||||
declSymbol(code, name, vardir, vartype, arraynum, 2);
|
||||
}
|
||||
void declFloat(vluint32_t code, const char* name, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum) {
|
||||
declSymbol(code, name, vardir, vartype, arraynum, 1);
|
||||
}
|
||||
void declQuad(vluint32_t code, const char* name, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum, int msb, int lsb) {
|
||||
declSymbol(code, name, vardir, vartype, arraynum, msb - lsb + 1);
|
||||
}
|
||||
void declArray(vluint32_t code, const char* name, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum, int msb, int lsb) {
|
||||
declSymbol(code, name, vardir, vartype, arraynum, msb - lsb + 1);
|
||||
}
|
||||
|
||||
/// Inside dumping routines, dump one signal if it has changed
|
||||
void chgBit(vluint32_t code, const vluint32_t newval) {
|
||||
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));
|
||||
}
|
||||
void chgDouble(vluint32_t code, const double newval) {
|
||||
double val = newval;
|
||||
fstWriterEmitValueChange(m_fst, m_code2symbol[code], &val);
|
||||
}
|
||||
void chgFloat(vluint32_t code, const float newval) {
|
||||
double val = (double)newval;
|
||||
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));
|
||||
}
|
||||
void chgArray(vluint32_t code, const vluint32_t* newval, int bits) {
|
||||
fstWriterEmitValueChange(m_fst, m_code2symbol[code], array2Str(newval, bits));
|
||||
}
|
||||
|
||||
void fullBit(vluint32_t code, const vluint32_t newval) { chgBit(code, newval); }
|
||||
void fullBus(vluint32_t code, const vluint32_t newval, int bits) { chgBus(code, newval, bits); }
|
||||
void fullDouble(vluint32_t code, const double newval) { chgDouble(code, newval); }
|
||||
void fullFloat(vluint32_t code, const float newval) { chgFloat(code, newval); }
|
||||
void fullQuad(vluint32_t code, const vluint64_t newval, int bits) { chgQuad(code, newval, bits); }
|
||||
void fullArray(vluint32_t code, const vluint32_t* newval, int bits) { chgArray(code, newval, bits); }
|
||||
|
||||
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 fullTriBit(vluint32_t code, const vluint32_t newval, const vluint32_t newtri);
|
||||
void fullTriBus(vluint32_t code, const vluint32_t newval, const vluint32_t newtri, int bits);
|
||||
void fullTriQuad(vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits);
|
||||
void fullTriArray(vluint32_t code, const vluint32_t* newvalp, const vluint32_t* newtrip, int bits);
|
||||
void fullBitX(vluint32_t code);
|
||||
void fullBusX(vluint32_t code, int bits);
|
||||
void fullQuadX(vluint32_t code, int bits);
|
||||
void fullArrayX(vluint32_t code, int bits);
|
||||
void chgTriBit(vluint32_t code, const vluint32_t newval, const vluint32_t newtri);
|
||||
void chgTriBus(vluint32_t code, const vluint32_t newval, const vluint32_t newtri, int bits);
|
||||
void chgTriQuad(vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits);
|
||||
void chgTriArray(vluint32_t code, const vluint32_t* newvalp, const vluint32_t* newtrip, int bits);
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFstC
|
||||
/// Create a FST dump file in C standalone (no SystemC) simulations.
|
||||
/// Also derived for use in SystemC simulations.
|
||||
/// Thread safety: Unless otherwise indicated, every function is VL_MT_UNSAFE_ONE
|
||||
|
||||
class VerilatedFstC {
|
||||
VerilatedFst m_sptrace; ///< Trace file being created
|
||||
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedFstC);
|
||||
public:
|
||||
explicit VerilatedFstC(void* filep=NULL) : m_sptrace(filep) {}
|
||||
~VerilatedFstC() {}
|
||||
public:
|
||||
// ACCESSORS
|
||||
/// Is file open?
|
||||
bool isOpen() const { return m_sptrace.isOpen(); }
|
||||
// METHODS
|
||||
/// Open a new FST file
|
||||
void open(const char* filename) VL_MT_UNSAFE_ONE { m_sptrace.open(filename); }
|
||||
/// Close dump
|
||||
void close() VL_MT_UNSAFE_ONE { m_sptrace.close(); }
|
||||
/// Flush dump
|
||||
void flush() VL_MT_UNSAFE_ONE { m_sptrace.flush(); }
|
||||
/// Write one cycle of dump data
|
||||
void dump(vluint64_t timeui) { m_sptrace.dump(timeui); }
|
||||
/// Write one cycle of dump data - backward compatible and to reduce
|
||||
/// conversion warnings. It's better to use a vluint64_t time instead.
|
||||
void dump(double timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
||||
void dump(vluint32_t timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
||||
void dump(int timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
||||
/// Set time units (s/ms, defaults to ns)
|
||||
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
||||
void set_time_unit(const char* unit) { /* TODO */ }
|
||||
void set_time_unit(const std::string& unit) { set_time_unit(unit.c_str()); }
|
||||
/// Set time resolution (s/ms, defaults to ns)
|
||||
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
||||
void set_time_resolution(const char* unit) { /* TODO */ }
|
||||
void set_time_resolution(const std::string& unit) { set_time_resolution(unit.c_str()); }
|
||||
|
||||
/// Internal class access
|
||||
inline VerilatedFst* spTrace() { return &m_sptrace; };
|
||||
};
|
||||
|
||||
#endif // guard
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "verilated.h"
|
||||
#include "verilated_lxt2_c.h"
|
||||
// Include the GTKWave implementation directly
|
||||
#include "lxt2/lxt2_write.cpp"
|
||||
#include "gtkwave/lxt2_write.cpp"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "lxt2/lxt2_write.h"
|
||||
#include "gtkwave/lxt2_write.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -93,22 +93,22 @@ public:
|
||||
void module(const std::string& name);
|
||||
/// Inside dumping routines, declare a signal
|
||||
void declBit(vluint32_t code, const char* name, int arraynum) {
|
||||
this->declSymbol(code, name, arraynum, 0, 0, LXT2_WR_SYM_F_BITS);
|
||||
declSymbol(code, name, arraynum, 0, 0, LXT2_WR_SYM_F_BITS);
|
||||
}
|
||||
void declBus(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
|
||||
this->declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
|
||||
declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
|
||||
}
|
||||
void declDouble(vluint32_t code, const char* name, int arraynum) {
|
||||
this->declSymbol(code, name, arraynum, 63, 0, LXT2_WR_SYM_F_DOUBLE);
|
||||
declSymbol(code, name, arraynum, 63, 0, LXT2_WR_SYM_F_DOUBLE);
|
||||
}
|
||||
void declFloat(vluint32_t code, const char* name, int arraynum) {
|
||||
this->declSymbol(code, name, arraynum, 63, 0, LXT2_WR_SYM_F_DOUBLE);
|
||||
declSymbol(code, name, arraynum, 63, 0, LXT2_WR_SYM_F_DOUBLE);
|
||||
}
|
||||
void declQuad(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
|
||||
this->declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
|
||||
declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
|
||||
}
|
||||
void declArray(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
|
||||
this->declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
|
||||
declSymbol(code, name, arraynum, msb, lsb, LXT2_WR_SYM_F_BITS);
|
||||
}
|
||||
|
||||
/// Inside dumping routines, dump one signal if it has changed
|
||||
|
||||
@@ -227,7 +227,7 @@ void VerilatedVcd::makeNameMap() {
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) {
|
||||
VerilatedVcdCallInfo* cip = m_callbacks[ent];
|
||||
cip->m_code = m_nextCode;
|
||||
(cip->m_initcb) (this, cip->m_userthis, cip->m_code);
|
||||
(cip->m_initcb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
|
||||
// Though not speced, it's illegal to generate a vcd with signals
|
||||
|
||||
+41
-2
@@ -45,6 +45,7 @@ private:
|
||||
// STATE
|
||||
AstNodeModule* m_modp; // Last module
|
||||
AstBegin* m_beginp; // Last begin
|
||||
unsigned m_modPastNum; // Module past numbering
|
||||
V3Double0 m_statAsCover; // Statistic tracking
|
||||
V3Double0 m_statAsPsl; // Statistic tracking
|
||||
V3Double0 m_statAsFull; // Statistic tracking
|
||||
@@ -144,6 +145,10 @@ private:
|
||||
// than the sim-killing else clause:
|
||||
ifp->branchPred(AstBranchPred::BP_LIKELY);
|
||||
bodysp = newIfAssertOn(ifp);
|
||||
} else if (VN_IS(nodep, PslRestrict)) {
|
||||
// IEEE says simulator ignores these
|
||||
pushDeletep(nodep->unlinkFrBack()); VL_DANGLING(nodep);
|
||||
return;
|
||||
} else {
|
||||
nodep->v3fatalSrc("Unknown node type");
|
||||
}
|
||||
@@ -185,6 +190,7 @@ private:
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstIf* nodep) {
|
||||
if (nodep->user1SetOnce()) return;
|
||||
if (nodep->uniquePragma() || nodep->unique0Pragma()) {
|
||||
@@ -244,7 +250,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
// VISITORS //========== Case assertions
|
||||
//========== Case assertions
|
||||
virtual void visit(AstCase* nodep) {
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->user1SetOnce()) {
|
||||
@@ -302,7 +308,38 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
// VISITORS //========== Statements
|
||||
//========== Past
|
||||
virtual void visit(AstPast* nodep) {
|
||||
iterateChildren(nodep);
|
||||
uint32_t ticks = 1;
|
||||
if (nodep->ticksp()) {
|
||||
if (!VN_IS(nodep->ticksp(), Const)) nodep->v3fatalSrc("Expected constant ticks, checked in V3Width");
|
||||
ticks = VN_CAST(nodep->ticksp(), Const)->toUInt();
|
||||
}
|
||||
if (ticks<1) nodep->v3fatalSrc("0 tick should have been checked in V3Width");
|
||||
AstNode* inp = nodep->exprp()->unlinkFrBack();
|
||||
AstVar* invarp = NULL;
|
||||
AstSenTree* sentreep = nodep->sentreep(); sentreep->unlinkFrBack();
|
||||
AstAlways* alwaysp = new AstAlways(nodep->fileline(), VAlwaysKwd::ALWAYS,
|
||||
sentreep, NULL);
|
||||
m_modp->addStmtp(alwaysp);
|
||||
for (uint32_t i=0; i<ticks; ++i) {
|
||||
AstVar* outvarp = new AstVar(nodep->fileline(), AstVarType::MODULETEMP,
|
||||
"_Vpast_"+cvtToStr(m_modPastNum++)+"_"+cvtToStr(i),
|
||||
inp->dtypep());
|
||||
m_modp->addStmtp(outvarp);
|
||||
AstNode* assp = new AstAssignDly(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), outvarp, true),
|
||||
inp);
|
||||
alwaysp->addStmtp(assp);
|
||||
//if (debug()>-9) assp->dumpTree(cout, "-ass: ");
|
||||
invarp = outvarp;
|
||||
inp = new AstVarRef(nodep->fileline(), invarp, false);
|
||||
}
|
||||
nodep->replaceWith(inp);
|
||||
}
|
||||
|
||||
//========== Statements
|
||||
virtual void visit(AstDisplay* nodep) {
|
||||
iterateChildren(nodep);
|
||||
// Replace the special types with standard text
|
||||
@@ -330,6 +367,7 @@ private:
|
||||
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
m_modp = nodep;
|
||||
m_modPastNum = 0;
|
||||
//
|
||||
iterateChildren(nodep);
|
||||
// Reset defaults
|
||||
@@ -354,6 +392,7 @@ public:
|
||||
explicit AssertVisitor(AstNetlist* nodep) {
|
||||
m_beginp = NULL;
|
||||
m_modp = NULL;
|
||||
m_modPastNum = 0;
|
||||
// Process
|
||||
iterate(nodep);
|
||||
}
|
||||
|
||||
+26
-5
@@ -44,9 +44,11 @@ private:
|
||||
// NODE STATE/TYPES
|
||||
// STATE
|
||||
// Reset each module:
|
||||
AstNodeSenItem* m_seniDefaultp; // Default sensitivity (from AstDefClock)
|
||||
AstNodeSenItem* m_seniDefaultp; // Default sensitivity (from AstDefClock)
|
||||
// Reset each assertion:
|
||||
AstNodeSenItem* m_senip; // Last sensitivity
|
||||
AstNodeSenItem* m_senip; // Last sensitivity
|
||||
// Reset each always:
|
||||
AstNodeSenItem* m_seniAlwaysp; // Last sensitivity in always
|
||||
|
||||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
@@ -55,7 +57,9 @@ private:
|
||||
// Create sentree based on clocked or default clock
|
||||
// Return NULL for always
|
||||
AstSenTree* newp = NULL;
|
||||
AstNodeSenItem* senip = m_senip ? m_senip : m_seniDefaultp;
|
||||
AstNodeSenItem* senip = m_senip;
|
||||
if (!senip) senip = m_seniDefaultp;
|
||||
if (!senip) senip = m_seniAlwaysp;
|
||||
if (!senip) {
|
||||
nodep->v3error("Unsupported: Unclocked assertion");
|
||||
newp = new AstSenTree(nodep->fileline(), NULL);
|
||||
@@ -68,7 +72,8 @@ private:
|
||||
m_senip = NULL;
|
||||
}
|
||||
|
||||
// VISITORS //========== Statements
|
||||
// VISITORS
|
||||
//========== Statements
|
||||
virtual void visit(AstClocking* nodep) {
|
||||
UINFO(8," CLOCKING"<<nodep<<endl);
|
||||
// Store the new default clock, reset on new module
|
||||
@@ -81,16 +86,31 @@ private:
|
||||
}
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstAlways* nodep) {
|
||||
iterateAndNextNull(nodep->sensesp());
|
||||
if (nodep->sensesp()) {
|
||||
m_seniAlwaysp = nodep->sensesp()->sensesp();
|
||||
}
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
m_seniAlwaysp = NULL;
|
||||
}
|
||||
|
||||
virtual void visit(AstNodePslCoverOrAssert* nodep) {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
clearAssertInfo();
|
||||
// Find PslClocking's burried under nodep->exprsp
|
||||
iterateChildren(nodep);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
clearAssertInfo();
|
||||
}
|
||||
virtual void visit(AstPslClocked* nodep) {
|
||||
virtual void visit(AstPast* nodep) {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
}
|
||||
virtual void visit(AstPslClocked* nodep) {
|
||||
// No need to iterate the body, once replace will get iterated
|
||||
iterateAndNextNull(nodep->sensesp());
|
||||
if (m_senip) {
|
||||
nodep->v3error("Unsupported: Only one PSL clock allowed per assertion");
|
||||
}
|
||||
@@ -120,6 +140,7 @@ public:
|
||||
// CONSTRUCTORS
|
||||
explicit AssertPreVisitor(AstNetlist* nodep) {
|
||||
m_seniDefaultp = NULL;
|
||||
m_seniAlwaysp = NULL;
|
||||
clearAssertInfo();
|
||||
// Process
|
||||
iterate(nodep);
|
||||
|
||||
+3
-3
@@ -181,12 +181,12 @@ void AstVar::combineType(AstVarType type) {
|
||||
// These flags get combined with the existing settings of the flags.
|
||||
// We don't test varType for certain types, instead set flags since
|
||||
// when we combine wires cross-hierarchy we need a union of all characteristics.
|
||||
if (type == AstVarType::SUPPLY0) type = AstVarType::WIRE;
|
||||
if (type == AstVarType::SUPPLY1) type = AstVarType::WIRE;
|
||||
m_varType=type; // For debugging prints only
|
||||
// These flags get combined with the existing settings of the flags.
|
||||
if (type==AstVarType::INPUT || type==AstVarType::INOUT)
|
||||
if (type==AstVarType::INPUT || type==AstVarType::INOUT) {
|
||||
m_input = true;
|
||||
m_declInput = true;
|
||||
}
|
||||
if (type==AstVarType::OUTPUT || type==AstVarType::INOUT) {
|
||||
m_output = true;
|
||||
m_declOutput = true;
|
||||
|
||||
+77
-20
@@ -1093,10 +1093,12 @@ private:
|
||||
string m_origName; // Original name before dot addition
|
||||
string m_tag; // Holds the string of the verilator tag -- used in XML output.
|
||||
AstVarType m_varType; // Type of variable
|
||||
AstBasicDTypeKwd m_declKwd; // Keyword at declaration time
|
||||
bool m_input:1; // Input or inout
|
||||
bool m_output:1; // Output or inout
|
||||
bool m_tristate:1; // Inout or triwire or trireg
|
||||
bool m_declOutput:1; // Inout or output before tristate resolution
|
||||
bool m_declInput:1; // Inout or input before tristate and inline resolution
|
||||
bool m_declOutput:1; // Inout or output before tristate and inline resolution
|
||||
bool m_primaryIO:1; // In/out to top level (or directly assigned from same)
|
||||
bool m_sc:1; // SystemC variable
|
||||
bool m_scClocked:1; // SystemC sc_clk<> needed
|
||||
@@ -1128,7 +1130,7 @@ private:
|
||||
MTaskIdSet m_mtaskIds; // MTaskID's that read or write this var
|
||||
|
||||
void init() {
|
||||
m_input=false; m_output=false; m_tristate=false; m_declOutput=false;
|
||||
m_input=false; m_output=false; m_tristate=false; m_declInput=false; m_declOutput=false;
|
||||
m_primaryIO=false;
|
||||
m_sc=false; m_scClocked=false; m_scSensitive=false;
|
||||
m_usedClock=false; m_usedParam=false; m_usedLoopIdx=false;
|
||||
@@ -1148,6 +1150,8 @@ public:
|
||||
combineType(type);
|
||||
childDTypep(dtp); // Only for parser
|
||||
dtypep(NULL); // V3Width will resolve
|
||||
if (dtp->basicp()) m_declKwd = dtp->basicp()->keyword();
|
||||
else m_declKwd = AstBasicDTypeKwd::LOGIC;
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, AstNodeDType* dtp)
|
||||
:AstNode(fl)
|
||||
@@ -1156,6 +1160,8 @@ public:
|
||||
combineType(type);
|
||||
UASSERT(dtp,"AstVar created with no dtype");
|
||||
dtypep(dtp);
|
||||
if (dtp->basicp()) m_declKwd = dtp->basicp()->keyword();
|
||||
else m_declKwd = AstBasicDTypeKwd::LOGIC;
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagLogicPacked, int wantwidth)
|
||||
:AstNode(fl)
|
||||
@@ -1163,6 +1169,7 @@ public:
|
||||
init();
|
||||
combineType(type);
|
||||
dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED);
|
||||
m_declKwd = AstBasicDTypeKwd::LOGIC;
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagBitPacked, int wantwidth)
|
||||
:AstNode(fl)
|
||||
@@ -1170,6 +1177,7 @@ public:
|
||||
init();
|
||||
combineType(type);
|
||||
dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED);
|
||||
m_declKwd = AstBasicDTypeKwd::BIT;
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, AstVar* examplep)
|
||||
:AstNode(fl)
|
||||
@@ -1180,6 +1188,7 @@ public:
|
||||
childDTypep(examplep->childDTypep()->cloneTree(true));
|
||||
}
|
||||
dtypeFrom(examplep);
|
||||
m_declKwd = examplep->declKwd();
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Var)
|
||||
virtual void dump(std::ostream& str);
|
||||
@@ -1192,6 +1201,7 @@ public:
|
||||
void varType(AstVarType type) { m_varType = type; }
|
||||
void varType2Out() { m_tristate=0; m_input=0; m_output=1; }
|
||||
void varType2In() { m_tristate=0; m_input=1; m_output=0; }
|
||||
AstBasicDTypeKwd declKwd() const { return m_declKwd; }
|
||||
string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
|
||||
string cPubArgType(bool named, bool forReturn) const; // Return C /*public*/ type for argument: bool, uint32_t, uint64_t, etc.
|
||||
string dpiArgType(bool named, bool forReturn) const; // Return DPI-C type for argument
|
||||
@@ -1247,13 +1257,14 @@ public:
|
||||
virtual string tag() const { return m_tag; }
|
||||
virtual string directionName() const { return (isInout() ? "inout" : isInput() ? "input"
|
||||
: isOutput() ? "output" : varType().ascii()); }
|
||||
bool isInput() const { return m_input; }
|
||||
bool isOutput() const { return m_output; }
|
||||
bool isInOnly() const { return m_input && !m_output; }
|
||||
bool isOutOnly() const { return m_output && !m_input; }
|
||||
bool isInout() const { return m_input && m_output; }
|
||||
bool isTristate() const { return m_tristate; }
|
||||
bool isDeclOutput() const { return m_declOutput; }
|
||||
bool isInput() const { return m_input; }
|
||||
bool isOutput() const { return m_output; }
|
||||
bool isInOnly() const { return m_input && !m_output; }
|
||||
bool isOutOnly() const { return m_output && !m_input; }
|
||||
bool isInout() const { return m_input && m_output; }
|
||||
bool isTristate() const { return m_tristate; }
|
||||
bool isDeclInput() const { return m_declInput; }
|
||||
bool isDeclOutput() const { return m_declOutput; }
|
||||
bool isPrimaryIO() const { return m_primaryIO; }
|
||||
bool isPrimaryIn() const { return isPrimaryIO() && isInput(); }
|
||||
bool isIO() const { return (m_input||m_output); }
|
||||
@@ -2155,7 +2166,7 @@ public:
|
||||
//
|
||||
virtual void dump(std::ostream& str);
|
||||
AstSenTree* sensesp() const { return VN_CAST(op1p(), SenTree); } // op1 = Sensitivity list
|
||||
AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate
|
||||
AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate
|
||||
void addStmtp(AstNode* nodep) { addOp2p(nodep); }
|
||||
VAlwaysKwd keyword() const { return m_keyword; }
|
||||
// Special accessors
|
||||
@@ -3351,8 +3362,14 @@ private:
|
||||
VNumRange m_bitRange; // Property of var the trace details
|
||||
VNumRange m_arrayRange; // Property of var the trace details
|
||||
uint32_t m_codeInc; // Code increment
|
||||
AstVarType m_varType; // Type of variable (for localparam vs. param)
|
||||
AstBasicDTypeKwd m_declKwd; // Keyword at declaration time
|
||||
bool m_declInput:1; // Input or inout
|
||||
bool m_declOutput:1; // Output or inout
|
||||
public:
|
||||
AstTraceDecl(FileLine* fl, const string& showname, AstNode* valuep,
|
||||
AstTraceDecl(FileLine* fl, const string& showname,
|
||||
AstVar* varp, // For input/output state etc
|
||||
AstNode* valuep,
|
||||
const VNumRange& bitRange, const VNumRange& arrayRange)
|
||||
: AstNodeStmt(fl)
|
||||
, m_showname(showname), m_bitRange(bitRange), m_arrayRange(arrayRange) {
|
||||
@@ -3360,20 +3377,29 @@ public:
|
||||
m_code = 0;
|
||||
m_codeInc = ((arrayRange.ranged() ? arrayRange.elements() : 1)
|
||||
* valuep->dtypep()->widthWords());
|
||||
m_varType = varp->varType();
|
||||
m_declKwd = varp->declKwd();
|
||||
m_declInput = varp->isDeclInput();
|
||||
m_declOutput = varp->isDeclOutput();
|
||||
}
|
||||
virtual int instrCount() const { return 100; } // Large...
|
||||
virtual int instrCount() const { return 100; } // Large...
|
||||
ASTNODE_NODE_FUNCS(TraceDecl)
|
||||
virtual string name() const { return m_showname; }
|
||||
virtual string name() const { return m_showname; }
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual bool same(const AstNode* samep) const { return false; }
|
||||
string showname() const { return m_showname; } // * = Var name
|
||||
// Details on what we're tracing
|
||||
uint32_t code() const { return m_code; }
|
||||
void code(uint32_t code) { m_code=code; }
|
||||
uint32_t codeInc() const { return m_codeInc; }
|
||||
uint32_t code() const { return m_code; }
|
||||
void code(uint32_t code) { m_code=code; }
|
||||
uint32_t codeInc() const { return m_codeInc; }
|
||||
const VNumRange& bitRange() const { return m_bitRange; }
|
||||
const VNumRange& arrayRange() const { return m_arrayRange; }
|
||||
AstVarType varType() const { return m_varType; }
|
||||
AstBasicDTypeKwd declKwd() const { return m_declKwd; }
|
||||
bool declInput() const { return m_declInput; }
|
||||
bool declOutput() const { return m_declOutput; }
|
||||
bool declInout() const { return m_declInput && m_declOutput; }
|
||||
};
|
||||
|
||||
class AstTraceInc : public AstNodeStmt {
|
||||
@@ -5193,6 +5219,30 @@ public:
|
||||
virtual string emitC() { return "hypot(%li,%ri)"; }
|
||||
};
|
||||
|
||||
class AstPast : public AstNodeMath {
|
||||
// Verilog $past
|
||||
// Parents: math
|
||||
// Children: expression
|
||||
public:
|
||||
AstPast(FileLine* fl, AstNode* exprp, AstNode* ticksp) : AstNodeMath(fl) {
|
||||
addOp1p(exprp);
|
||||
addNOp2p(ticksp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Past)
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
|
||||
virtual string emitC() { V3ERROR_NA; return "";}
|
||||
virtual string emitSimpleOperator() { V3ERROR_NA; return "";}
|
||||
virtual bool cleanOut() { V3ERROR_NA; return "";}
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
AstNode* exprp() const { return op1p(); } // op1 = expression
|
||||
AstNode* ticksp() const { return op2p(); } // op2 = ticks or NULL means 1
|
||||
AstSenTree* sentreep() const { return VN_CAST(op4p(), SenTree); } // op4 = clock domain
|
||||
void sentreep(AstSenTree* sentreep) { addOp4p(sentreep); } // op4 = clock domain
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(const AstNode* samep) const { return true; }
|
||||
};
|
||||
|
||||
class AstPattern : public AstNodeMath {
|
||||
// Verilog '{a,b,c,d...}
|
||||
// Parents: AstNodeAssign, AstPattern, ...
|
||||
@@ -5322,6 +5372,13 @@ public:
|
||||
AstNode* stmtsp() const { return op4p(); } // op4 = statements
|
||||
};
|
||||
|
||||
class AstPslAssert : public AstNodePslCoverOrAssert {
|
||||
public:
|
||||
ASTNODE_NODE_FUNCS(PslAssert)
|
||||
AstPslAssert(FileLine* fl, AstNode* propp, AstNode* stmtsp, const string& name="")
|
||||
: AstNodePslCoverOrAssert(fl, propp, stmtsp, name) {}
|
||||
};
|
||||
|
||||
class AstPslCover : public AstNodePslCoverOrAssert {
|
||||
public:
|
||||
ASTNODE_NODE_FUNCS(PslCover)
|
||||
@@ -5331,11 +5388,11 @@ public:
|
||||
void coverincp(AstCoverInc* nodep) { addOp3p(nodep); } // op3 = coverage node
|
||||
};
|
||||
|
||||
class AstPslAssert : public AstNodePslCoverOrAssert {
|
||||
class AstPslRestrict : public AstNodePslCoverOrAssert {
|
||||
public:
|
||||
ASTNODE_NODE_FUNCS(PslAssert)
|
||||
AstPslAssert(FileLine* fl, AstNode* propp, AstNode* stmtsp, const string& name="")
|
||||
: AstNodePslCoverOrAssert(fl, propp, stmtsp, name) {}
|
||||
ASTNODE_NODE_FUNCS(PslRestrict)
|
||||
AstPslRestrict(FileLine* fl, AstNode* propp)
|
||||
: AstNodePslCoverOrAssert(fl, propp, NULL, "") {}
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
||||
+61
-6
@@ -849,6 +849,7 @@ class EmitCImp : EmitCStmts {
|
||||
// METHODS
|
||||
|
||||
void doubleOrDetect(AstChangeDet* changep, bool& gotOne) {
|
||||
static int s_addDoubleOr = 10; // Determined experimentally as best
|
||||
if (!changep->rhsp()) {
|
||||
if (!gotOne) gotOne = true;
|
||||
else puts(" | ");
|
||||
@@ -857,17 +858,18 @@ class EmitCImp : EmitCStmts {
|
||||
else {
|
||||
AstNode* lhsp = changep->lhsp();
|
||||
AstNode* rhsp = changep->rhsp();
|
||||
static int addDoubleOr = 10; // Determined experimentally as best
|
||||
if (!VN_IS(lhsp, VarRef) && !VN_IS(lhsp, ArraySel)) changep->v3fatalSrc("Not ref?");
|
||||
if (!VN_IS(rhsp, VarRef) && !VN_IS(rhsp, ArraySel)) changep->v3fatalSrc("Not ref?");
|
||||
for (int word=0; word<changep->lhsp()->widthWords(); word++) {
|
||||
for (int word=0;
|
||||
word < (changep->lhsp()->isWide() ? changep->lhsp()->widthWords() : 1);
|
||||
++word) {
|
||||
if (!gotOne) {
|
||||
gotOne = true;
|
||||
addDoubleOr = 10; // Determined experimentally as best
|
||||
s_addDoubleOr = 10;
|
||||
puts("(");
|
||||
} else if (--addDoubleOr == 0) {
|
||||
} else if (--s_addDoubleOr == 0) {
|
||||
puts("|| (");
|
||||
addDoubleOr = 10;
|
||||
s_addDoubleOr = 10;
|
||||
} else {
|
||||
puts(" | (");
|
||||
}
|
||||
@@ -1875,7 +1877,7 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
|
||||
}
|
||||
}
|
||||
ofp()->printf( "vluint64_t __Vcheckval = VL_ULL(0x%" VL_PRI64 "x);\n",
|
||||
hash.digestUInt64());
|
||||
(vluint64_t)hash.digestUInt64());
|
||||
if (de) {
|
||||
puts("os.readAssert(__Vcheckval);\n");
|
||||
} else {
|
||||
@@ -2829,10 +2831,63 @@ class EmitCTrace : EmitCStmts {
|
||||
} else {
|
||||
puts("vcdp->declBit ");
|
||||
}
|
||||
|
||||
puts("(c+"+cvtToStr(nodep->code()));
|
||||
if (nodep->arrayRange().ranged()) puts("+i*"+cvtToStr(nodep->widthWords()));
|
||||
puts(",");
|
||||
putsQuoted(nodep->showname());
|
||||
// Direction
|
||||
if (v3Global.opt.traceFormat() == TraceFormat::FST) {
|
||||
// fstVarDir
|
||||
if (nodep->declInout()) puts(",FST_VD_INOUT");
|
||||
else if (nodep->declInput()) puts(",FST_VD_INPUT");
|
||||
else if (nodep->declOutput()) puts(",FST_VD_OUTPUT");
|
||||
else puts(",FST_VD_IMPLICIT");
|
||||
//
|
||||
// fstVarType
|
||||
AstVarType vartype = nodep->varType();
|
||||
AstBasicDTypeKwd kwd = nodep->declKwd();
|
||||
string fstvt;
|
||||
// Doubles have special decoding properties, so must indicate if a double
|
||||
if (nodep->dtypep()->basicp()->isDouble()) {
|
||||
if (vartype == AstVarType::GPARAM || vartype == AstVarType::LPARAM) {
|
||||
fstvt = "FST_VT_VCD_REAL_PARAMETER";
|
||||
} else fstvt = "FST_VT_VCD_REAL";
|
||||
}
|
||||
else if (vartype == AstVarType::GPARAM) fstvt = "FST_VT_VCD_PARAMETER";
|
||||
else if (vartype == AstVarType::LPARAM) fstvt = "FST_VT_VCD_PARAMETER";
|
||||
else if (vartype == AstVarType::SUPPLY0) fstvt = "FST_VT_VCD_SUPPLY0";
|
||||
else if (vartype == AstVarType::SUPPLY1) fstvt = "FST_VT_VCD_SUPPLY1";
|
||||
else if (vartype == AstVarType::TRI0) fstvt = "FST_VT_VCD_TRI0";
|
||||
else if (vartype == AstVarType::TRI1) fstvt = "FST_VT_VCD_TRI1";
|
||||
else if (vartype == AstVarType::TRIWIRE) fstvt = "FST_VT_VCD_TRI";
|
||||
else if (vartype == AstVarType::WIRE) fstvt = "FST_VT_VCD_WIRE";
|
||||
//
|
||||
else if (kwd == AstBasicDTypeKwd::INTEGER) fstvt = "FST_VT_VCD_INTEGER";
|
||||
else if (kwd == AstBasicDTypeKwd::BIT) fstvt = "FST_VT_SV_BIT";
|
||||
else if (kwd == AstBasicDTypeKwd::LOGIC) fstvt = "FST_VT_SV_LOGIC";
|
||||
else if (kwd == AstBasicDTypeKwd::INT) fstvt = "FST_VT_SV_INT";
|
||||
else if (kwd == AstBasicDTypeKwd::SHORTINT) fstvt = "FST_VT_SV_SHORTINT";
|
||||
else if (kwd == AstBasicDTypeKwd::LONGINT) fstvt = "FST_VT_SV_LONGINT";
|
||||
else if (kwd == AstBasicDTypeKwd::BYTE) fstvt = "FST_VT_SV_BYTE";
|
||||
else fstvt = "FST_VT_SV_BIT";
|
||||
//
|
||||
// Not currently supported
|
||||
// FST_VT_VCD_EVENT
|
||||
// FST_VT_VCD_PORT
|
||||
// FST_VT_VCD_SHORTREAL
|
||||
// FST_VT_VCD_REALTIME
|
||||
// FST_VT_VCD_SPARRAY
|
||||
// FST_VT_VCD_TRIAND
|
||||
// FST_VT_VCD_TRIOR
|
||||
// FST_VT_VCD_TRIREG
|
||||
// FST_VT_VCD_WAND
|
||||
// FST_VT_VCD_WOR
|
||||
// FST_VT_SV_ENUM
|
||||
// FST_VT_GEN_STRING
|
||||
puts(","+fstvt);
|
||||
}
|
||||
// Range
|
||||
if (nodep->arrayRange().ranged()) {
|
||||
puts(",(i+"+cvtToStr(nodep->arrayRange().lo())+")");
|
||||
} else {
|
||||
|
||||
@@ -332,6 +332,15 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
||||
}
|
||||
putqs(nodep,"end\n");
|
||||
}
|
||||
virtual void visit(AstPast* nodep) {
|
||||
putfs(nodep, "$past(");
|
||||
iterateAndNextNull(nodep->exprp());
|
||||
if (nodep->ticksp()) {
|
||||
puts(",");
|
||||
iterateAndNextNull(nodep->ticksp());
|
||||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstReturn* nodep) {
|
||||
putfs(nodep,"return ");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
|
||||
@@ -94,6 +94,7 @@ public:
|
||||
STMTDLY, // Delayed statement
|
||||
SYMRSVDWORD, // Symbol is Reserved Word
|
||||
SYNCASYNCNET, // Mixed sync + async reset
|
||||
TICKCOUNT, // Too large tick count
|
||||
UNDRIVEN, // No drivers
|
||||
UNOPT, // Unoptimizable block
|
||||
UNOPTFLAT, // Unoptimizable block after flattening
|
||||
@@ -140,6 +141,7 @@ public:
|
||||
"PINMISSING", "PINNOCONNECT", "PINCONNECTEMPTY",
|
||||
"REALCVT", "REDEFMACRO",
|
||||
"SELRANGE", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET",
|
||||
"TICKCOUNT",
|
||||
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS",
|
||||
"UNPACKED", "UNSIGNED", "UNUSED",
|
||||
"USERERROR", "USERFATAL", "USERINFO", "USERWARN",
|
||||
|
||||
@@ -406,6 +406,9 @@ private:
|
||||
virtual void visit(AstPslCover* nodep) {
|
||||
visitIterateNoValueMod(nodep);
|
||||
}
|
||||
virtual void visit(AstPslRestrict* nodep) {
|
||||
visitIterateNoValueMod(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) {
|
||||
// Default: Just iterate
|
||||
|
||||
@@ -695,6 +695,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
else if ( !strcmp (sw, "-sv") ) { m_defaultLanguage = V3LangCode::L1800_2005; }
|
||||
else if ( onoff (sw, "-threads-coarsen", flag/*ref*/)) { m_threadsCoarsen = flag; } // Undocumented, debug
|
||||
else if ( onoff (sw, "-trace", flag/*ref*/) ) { m_trace = flag; }
|
||||
else if ( onoff (sw, "-trace-fst", flag/*ref*/) ) { m_trace = flag; m_traceFormat = TraceFormat::FST; addLdLibs("-lz"); }
|
||||
else if ( onoff (sw, "-trace-lxt2", flag/*ref*/) ) { m_trace = flag; m_traceFormat = TraceFormat::LXT2; addLdLibs("-lz"); }
|
||||
else if ( onoff (sw, "-trace-dups", flag/*ref*/) ) { m_traceDups = flag; }
|
||||
else if ( onoff (sw, "-trace-params", flag/*ref*/) ) { m_traceParams = flag; }
|
||||
|
||||
+6
-3
@@ -40,7 +40,8 @@ class TraceFormat {
|
||||
public:
|
||||
enum en {
|
||||
VCD = 0,
|
||||
LXT2
|
||||
LXT2,
|
||||
FST
|
||||
} m_e;
|
||||
inline TraceFormat(en _e = VCD) : m_e(_e) {}
|
||||
explicit inline TraceFormat(int _e) : m_e(static_cast<en>(_e)) {}
|
||||
@@ -48,14 +49,16 @@ public:
|
||||
string classBase() const {
|
||||
static const char* const names[] = {
|
||||
"VerilatedVcd",
|
||||
"VerilatedLxt2"
|
||||
"VerilatedLxt2",
|
||||
"VerilatedFst"
|
||||
};
|
||||
return names[m_e];
|
||||
}
|
||||
string sourceName() const {
|
||||
static const char* const names[] = {
|
||||
"verilated_vcd",
|
||||
"verilated_lxt2"
|
||||
"verilated_lxt2",
|
||||
"verilated_fst"
|
||||
};
|
||||
return names[m_e];
|
||||
}
|
||||
|
||||
@@ -188,6 +188,19 @@ void V3Os::unlinkRegexp(const string& dir, const string& regexp) {
|
||||
}
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// METHODS (random)
|
||||
|
||||
vluint64_t V3Os::rand64(vluint64_t* statep) {
|
||||
// Xoroshiro128+ algorithm
|
||||
vluint64_t result = statep[0] + statep[1];
|
||||
statep[1] ^= statep[0];
|
||||
statep[0] = (((statep[0] << 55) | (statep[0] >> 9))
|
||||
^ statep[1] ^ (statep[1] << 14));
|
||||
statep[1] = (statep[1] << 36) | (statep[1] >> 28);
|
||||
return result;
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// METHODS (performance)
|
||||
|
||||
|
||||
@@ -49,6 +49,9 @@ public:
|
||||
static void createDir(const string& dirname);
|
||||
static void unlinkRegexp(const string& dir, const string& regexp);
|
||||
|
||||
// METHODS (random)
|
||||
static vluint64_t rand64(vluint64_t* statep);
|
||||
|
||||
// METHODS (performance)
|
||||
static uint64_t timeUsecs(); ///< Return wall time since epoch in microseconds, or 0 if not implemented
|
||||
static uint64_t memUsageBytes(); ///< Return memory usage in bytes, or 0 if not implemented
|
||||
|
||||
+3
-3
@@ -347,7 +347,7 @@ private:
|
||||
}
|
||||
void go() {
|
||||
// Generate a pseudo-random graph
|
||||
uint16_t rngState[3] = { 0xdead, 0xbeef, 0xf000 };
|
||||
vluint64_t rngState[2] = {VL_ULL(0x12345678), VL_ULL(0x9abcdef0)};
|
||||
// Create 50 vertices
|
||||
for (unsigned i = 0; i < 50; ++i) {
|
||||
m_vx[i] = new V3GraphVertex(&m_graph);
|
||||
@@ -355,8 +355,8 @@ private:
|
||||
// Create 250 edges at random. Edges must go from
|
||||
// lower-to-higher index vertices, so we get a DAG.
|
||||
for (unsigned i = 0; i < 250; ++i) {
|
||||
unsigned idx1 = nrand48(rngState) % 50;
|
||||
unsigned idx2 = nrand48(rngState) % 50;
|
||||
unsigned idx1 = V3Os::rand64(rngState) % 50;
|
||||
unsigned idx2 = V3Os::rand64(rngState) % 50;
|
||||
if (idx1 > idx2) {
|
||||
new V3GraphEdge(&m_graph, m_vx[idx2], m_vx[idx1], 1);
|
||||
} else if (idx2 > idx1) {
|
||||
|
||||
+1
-1
@@ -387,7 +387,7 @@ private:
|
||||
typedef vl_unordered_set<const T_Elem*> NeedRescoreSet;
|
||||
class CmpElems {
|
||||
public:
|
||||
bool operator() (const T_Elem* const& ap, const T_Elem* const& bp) {
|
||||
bool operator() (const T_Elem* const& ap, const T_Elem* const& bp) const {
|
||||
T_ElemCompare cmp;
|
||||
return cmp.operator()(*ap, *bp);
|
||||
}
|
||||
|
||||
+2
-4
@@ -61,8 +61,7 @@ private:
|
||||
size_t operator() (const AstSenTree* kp) const {
|
||||
return V3Hashed::uncachedHash(kp).fullValue();
|
||||
}
|
||||
private:
|
||||
VL_UNCOPYABLE(HashSenTree);
|
||||
// Copying required for OSX's libc++
|
||||
};
|
||||
|
||||
class EqSenTree {
|
||||
@@ -71,8 +70,7 @@ private:
|
||||
bool operator() (const AstSenTree* ap, const AstSenTree* bp) const {
|
||||
return ap->sameTree(bp);
|
||||
}
|
||||
private:
|
||||
VL_UNCOPYABLE(EqSenTree);
|
||||
// Copying required for OSX's libc++
|
||||
};
|
||||
|
||||
// MEMBERS
|
||||
|
||||
+45
-36
@@ -51,16 +51,16 @@
|
||||
//######################################################################
|
||||
// Simulate class functions
|
||||
|
||||
class SimulateStackNode {
|
||||
class SimStackNode {
|
||||
public:
|
||||
// MEMBERS
|
||||
AstFuncRef* m_funcp;
|
||||
V3TaskConnects* m_tconnects;
|
||||
// CONSTRUCTORS
|
||||
SimulateStackNode(AstFuncRef* funcp, V3TaskConnects* tconnects):
|
||||
SimStackNode(AstFuncRef* funcp, V3TaskConnects* tconnects):
|
||||
m_funcp(funcp),
|
||||
m_tconnects(tconnects) {}
|
||||
~SimulateStackNode() {}
|
||||
~SimStackNode() {}
|
||||
};
|
||||
|
||||
class SimulateVisitor : public AstNVisitor {
|
||||
@@ -103,7 +103,7 @@ private:
|
||||
// Simulating:
|
||||
std::deque<V3Number*> m_numFreeps; ///< List of all numbers free and not in use
|
||||
std::deque<V3Number*> m_numAllps; ///< List of all numbers free and in use
|
||||
std::deque<SimulateStackNode*> m_callStack; ///< Call stack for verbose error messages
|
||||
std::deque<SimStackNode*> m_callStack; ///< Call stack for verbose error messages
|
||||
|
||||
// Cleanup
|
||||
// V3Numbers that represents strings are a bit special and the API for V3Number does not allow changing them.
|
||||
@@ -178,7 +178,7 @@ public:
|
||||
}
|
||||
m_whyNotOptimizable = why;
|
||||
std::ostringstream stack;
|
||||
for (std::deque<SimulateStackNode*>::iterator it=m_callStack.begin(); it !=m_callStack.end(); ++it) {
|
||||
for (std::deque<SimStackNode*>::iterator it=m_callStack.begin(); it !=m_callStack.end(); ++it) {
|
||||
AstFuncRef* funcp = (*it)->m_funcp;
|
||||
stack<<"\nCalled from:\n"<<funcp->fileline()<<" "<<funcp->prettyName()<<"() with parameters:";
|
||||
V3TaskConnects* tconnects = (*it)->m_tconnects;
|
||||
@@ -242,6 +242,12 @@ public:
|
||||
return (fetchOutNumber(nodep));
|
||||
}
|
||||
}
|
||||
void newNumber(AstNode* nodep, const V3Number& numr) {
|
||||
newNumber(nodep)->opAssign(numr);
|
||||
}
|
||||
void newOutNumber(AstNode* nodep, const V3Number& numr) {
|
||||
newOutNumber(nodep)->opAssign(numr);
|
||||
}
|
||||
V3Number* fetchNumberNull(AstNode* nodep) {
|
||||
return ((V3Number*)nodep->user3p());
|
||||
}
|
||||
@@ -309,13 +315,12 @@ private:
|
||||
return (m_jumpp && m_jumpp->labelp()!=nodep);
|
||||
}
|
||||
void assignOutNumber(AstNodeAssign* nodep, AstNode* vscp, const V3Number* nump) {
|
||||
// Don't do setNumber, as value isn't yet visible to following statements
|
||||
if (VN_IS(nodep, AssignDly)) {
|
||||
// Don't do setNumber, as value isn't yet visible to following statements
|
||||
newOutNumber(vscp)->opAssign(*nump);
|
||||
newOutNumber(vscp, *nump);
|
||||
} else {
|
||||
newNumber(vscp)->opAssign(*nump);
|
||||
newOutNumber(vscp)->opAssign(*nump);
|
||||
newNumber(vscp, *nump);
|
||||
newOutNumber(vscp, *nump);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +353,7 @@ private:
|
||||
vscp->user1( vscp->user1() | VU_LVDLY);
|
||||
if (m_checkOnly) varRefCb (nodep);
|
||||
}
|
||||
} else { // nondly asn
|
||||
} else { // nondly asn
|
||||
if (!(vscp->user1() & VU_LV)) {
|
||||
if (!m_params && (vscp->user1() & VU_RV)) clearOptimizable(nodep,"Var read & write");
|
||||
vscp->user1( vscp->user1() | VU_LV);
|
||||
@@ -361,16 +366,16 @@ private:
|
||||
vscp->user1( vscp->user1() | VU_RV);
|
||||
bool isConst = nodep->varp()->isParam();
|
||||
V3Number* nump = isConst ? fetchNumberNull(nodep->varp()->valuep()) : NULL;
|
||||
if (isConst && nump) { // Propagate PARAM constants for constant function analysis
|
||||
if (isConst && nump) { // Propagate PARAM constants for constant function analysis
|
||||
if (!m_checkOnly && optimizable()) {
|
||||
newNumber(vscp)->opAssign(*nump);
|
||||
newNumber(vscp, *nump);
|
||||
}
|
||||
} else {
|
||||
if (m_checkOnly) varRefCb (nodep);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!m_checkOnly && optimizable()) { // simulating
|
||||
if (!m_checkOnly && optimizable()) { // simulating
|
||||
if (nodep->lvalue()) {
|
||||
nodep->v3fatalSrc("LHS varref should be handled in AstAssign visitor.");
|
||||
} else {
|
||||
@@ -390,7 +395,7 @@ private:
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep) {
|
||||
if (jumpingOver(nodep)) return;
|
||||
if (m_scoped) { badNodeType(nodep); return; }
|
||||
if (m_scoped) { badNodeType(nodep); return; }
|
||||
else { clearOptimizable(nodep,"Language violation: Dotted hierarchical references not allowed in constant functions"); }
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) {
|
||||
@@ -431,7 +436,7 @@ private:
|
||||
if (valuep) {
|
||||
iterateAndNextNull(valuep);
|
||||
if (optimizable()) {
|
||||
newNumber(nodep)->opAssign(*fetchNumber(valuep));
|
||||
newNumber(nodep, *fetchNumber(valuep));
|
||||
}
|
||||
} else {
|
||||
clearOptimizable(nodep, "No value found for enum item");
|
||||
@@ -443,7 +448,8 @@ private:
|
||||
checkNodeInfo(nodep);
|
||||
iterateChildren(nodep);
|
||||
if (!m_checkOnly && optimizable()) {
|
||||
nodep->numberOperate(*newNumber(nodep), *fetchNumber(nodep->lhsp()));
|
||||
nodep->numberOperate(*newNumber(nodep),
|
||||
*fetchNumber(nodep->lhsp()));
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep) {
|
||||
@@ -451,7 +457,9 @@ private:
|
||||
checkNodeInfo(nodep);
|
||||
iterateChildren(nodep);
|
||||
if (!m_checkOnly && optimizable()) {
|
||||
nodep->numberOperate(*newNumber(nodep), *fetchNumber(nodep->lhsp()), *fetchNumber(nodep->rhsp()));
|
||||
nodep->numberOperate(*newNumber(nodep),
|
||||
*fetchNumber(nodep->lhsp()),
|
||||
*fetchNumber(nodep->rhsp()));
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeTriop* nodep) {
|
||||
@@ -476,9 +484,9 @@ private:
|
||||
if (optimizable()) {
|
||||
if (fetchNumber(nodep->lhsp())->isNeqZero()) {
|
||||
iterate(nodep->rhsp());
|
||||
newNumber(nodep)->opAssign(*fetchNumber(nodep->rhsp()));
|
||||
newNumber(nodep, *fetchNumber(nodep->rhsp()));
|
||||
} else {
|
||||
newNumber(nodep)->opAssign(*fetchNumber(nodep->lhsp())); // a zero
|
||||
newNumber(nodep, *fetchNumber(nodep->lhsp())); // a zero
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -493,10 +501,10 @@ private:
|
||||
iterate(nodep->lhsp());
|
||||
if (optimizable()) {
|
||||
if (fetchNumber(nodep->lhsp())->isNeqZero()) {
|
||||
newNumber(nodep)->opAssign(*fetchNumber(nodep->lhsp())); // a one
|
||||
newNumber(nodep, *fetchNumber(nodep->lhsp())); // a one
|
||||
} else {
|
||||
iterate(nodep->rhsp());
|
||||
newNumber(nodep)->opAssign(*fetchNumber(nodep->rhsp()));
|
||||
newNumber(nodep, *fetchNumber(nodep->rhsp()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -511,10 +519,10 @@ private:
|
||||
iterate(nodep->lhsp());
|
||||
if (optimizable()) {
|
||||
if (fetchNumber(nodep->lhsp())->isEqZero()) {
|
||||
newNumber(nodep)->opAssign(V3Number(nodep->fileline(), 1, 1)); // a one
|
||||
newNumber(nodep, V3Number(nodep->fileline(), 1, 1)); // a one
|
||||
} else {
|
||||
iterate(nodep->rhsp());
|
||||
newNumber(nodep)->opAssign(*fetchNumber(nodep->rhsp()));
|
||||
newNumber(nodep, *fetchNumber(nodep->rhsp()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -531,10 +539,10 @@ private:
|
||||
if (optimizable()) {
|
||||
if (fetchNumber(nodep->condp())->isNeqZero()) {
|
||||
iterate(nodep->expr1p());
|
||||
newNumber(nodep)->opAssign(*fetchNumber(nodep->expr1p()));
|
||||
newNumber(nodep, *fetchNumber(nodep->expr1p()));
|
||||
} else {
|
||||
iterate(nodep->expr2p());
|
||||
newNumber(nodep)->opAssign(*fetchNumber(nodep->expr2p()));
|
||||
newNumber(nodep, *fetchNumber(nodep->expr2p()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -765,7 +773,7 @@ private:
|
||||
UINFO(5," FUNCREF "<<nodep<<endl);
|
||||
if (!m_params) { badNodeType(nodep); return; }
|
||||
AstNodeFTask* funcp = VN_CAST(nodep->taskp(), NodeFTask); if (!funcp) nodep->v3fatalSrc("Not linked");
|
||||
if (m_params) { V3Width::widthParamsEdit(funcp); } VL_DANGLING(funcp); // Make sure we've sized the function
|
||||
if (m_params) { V3Width::widthParamsEdit(funcp); } VL_DANGLING(funcp); // Make sure we've sized the function
|
||||
funcp = VN_CAST(nodep->taskp(), NodeFTask); if (!funcp) nodep->v3fatalSrc("Not linked");
|
||||
// Apply function call values to function
|
||||
V3TaskConnects tconnects = V3Task::taskConnects(nodep, nodep->taskp()->stmtsp());
|
||||
@@ -789,11 +797,11 @@ private:
|
||||
if (pinp) { // Else too few arguments in function call - ignore it
|
||||
// Apply value to the function
|
||||
if (!m_checkOnly && optimizable()) {
|
||||
newNumber(portp)->opAssign(*fetchNumber(pinp));
|
||||
newNumber(portp, *fetchNumber(pinp));
|
||||
}
|
||||
}
|
||||
}
|
||||
SimulateStackNode stackNode(nodep, &tconnects);
|
||||
SimStackNode stackNode(nodep, &tconnects);
|
||||
m_callStack.push_front(&stackNode);
|
||||
// Evaluate the function
|
||||
iterate(funcp);
|
||||
@@ -801,7 +809,7 @@ private:
|
||||
if (!m_checkOnly && optimizable()) {
|
||||
// Grab return value from output variable (if it's a function)
|
||||
if (!funcp->fvarp()) nodep->v3fatalSrc("Function reference points at non-function");
|
||||
newNumber(nodep)->opAssign(*fetchNumber(funcp->fvarp()));
|
||||
newNumber(nodep, *fetchNumber(funcp->fvarp()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,9 +838,9 @@ private:
|
||||
for (; pos != format.end(); ++pos) {
|
||||
if (!inPct && pos[0] == '%') {
|
||||
inPct = true;
|
||||
} else if (!inPct) { // Normal text
|
||||
} else if (!inPct) { // Normal text
|
||||
result += *pos;
|
||||
} else { // Format character
|
||||
} else { // Format character
|
||||
inPct = false;
|
||||
|
||||
if (V3Number::displayedFmtLegal(tolower(pos[0]))) {
|
||||
@@ -922,8 +930,9 @@ private:
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
SimulateVisitor() {
|
||||
// Note AstUser#InUse ensures only one invocation exists at once
|
||||
setMode(false,false,false);
|
||||
clear(); // We reuse this structure in the main loop, so put initializers inside clear()
|
||||
clear(); // We reuse this structure in the main loop, so put initializers inside clear()
|
||||
}
|
||||
void clear() {
|
||||
m_whyNotOptimizable = "";
|
||||
@@ -935,9 +944,9 @@ public:
|
||||
m_dataCount = 0;
|
||||
m_jumpp = NULL;
|
||||
|
||||
AstNode::user1ClearTree(); // user1p() used on entire tree
|
||||
AstNode::user2ClearTree(); // user2p() used on entire tree
|
||||
AstNode::user3ClearTree(); // user3p() used on entire tree
|
||||
AstNode::user1ClearTree();
|
||||
AstNode::user2ClearTree();
|
||||
AstNode::user3ClearTree();
|
||||
|
||||
// Move all allocated numbers to the free pool
|
||||
m_numFreeps = m_numAllps;
|
||||
@@ -971,4 +980,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
#endif // Guard
|
||||
|
||||
+3
-1
@@ -292,7 +292,9 @@ private:
|
||||
for (std::deque<AstVarScope*>::iterator it = m_inVarps.begin(); it!=m_inVarps.end(); ++it) {
|
||||
AstVarScope* invscp = *it;
|
||||
// LSB is first variable, so extract it that way
|
||||
simvis.newNumber(invscp, VL_MASK_I(invscp->width()) & (inValue>>shift));
|
||||
simvis.newNumber(invscp,
|
||||
V3Number(invscp->fileline(), invscp->width(),
|
||||
VL_MASK_I(invscp->width()) & (inValue>>shift)));
|
||||
shift += invscp->width();
|
||||
// We're just using32 bit arithmetic, because there's no way the input table can be 2^32 bytes!
|
||||
if (shift>31) nodep->v3fatalSrc("shift overflow");
|
||||
|
||||
+2
-1
@@ -110,7 +110,8 @@ private:
|
||||
AstBasicDType* bdtypep = m_traValuep->dtypep()->basicp();
|
||||
if (widthOverride) bitRange = VNumRange(widthOverride-1,0,false);
|
||||
else if (bdtypep) bitRange = bdtypep->nrange();
|
||||
AstTraceDecl* declp = new AstTraceDecl(m_traVscp->fileline(), m_traShowname, m_traValuep,
|
||||
AstTraceDecl* declp = new AstTraceDecl(m_traVscp->fileline(), m_traShowname,
|
||||
m_traVscp->varp(), m_traValuep,
|
||||
bitRange, arrayRange);
|
||||
UINFO(9,"Decl "<<declp<<endl);
|
||||
|
||||
|
||||
@@ -798,6 +798,26 @@ private:
|
||||
// We don't size the constant until we commit the widths, as need parameters
|
||||
// to remain unsized, and numbers to remain unsized to avoid backp() warnings
|
||||
}
|
||||
virtual void visit(AstPast* nodep) {
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckSizedSelf(nodep, "LHS", nodep->exprp(), SELF, BOTH);
|
||||
nodep->dtypeFrom(nodep->exprp());
|
||||
if (nodep->ticksp()) {
|
||||
iterateCheckSizedSelf(nodep, "Ticks", nodep->ticksp(), SELF, BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->ticksp()); // ticksp may change
|
||||
const AstConst* constp = VN_CAST(nodep->ticksp(), Const);
|
||||
if (!constp || constp->toSInt() < 1) {
|
||||
nodep->v3error("$past tick value must be constant and >= 1 (IEEE 2017 16.9.3)");
|
||||
nodep->ticksp()->unlinkFrBack()->deleteTree();
|
||||
} else {
|
||||
if (constp->toSInt() > 10) {
|
||||
nodep->v3warn(TICKCOUNT, "$past tick value of "<<constp->toSInt()
|
||||
<<" may have a large performance cost");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstRand* nodep) {
|
||||
if (m_vup->prelim()) {
|
||||
nodep->dtypeSetSigned32(); // Says the spec
|
||||
|
||||
+13
-7
@@ -71,13 +71,10 @@ sub process {
|
||||
next if $line =~ m!^make.*Entering directory !;
|
||||
next if $line =~ m!^make.*Leaving directory !;
|
||||
next if $line =~ m!^\s+$!g;
|
||||
# Specific suppressions
|
||||
next if $line =~ m!id="missingInclude" .*systemc.h!;
|
||||
next if $line =~ m!id="missingInclude" .*svdpi.h!;
|
||||
next if $line =~ m!id="unusedFunction" .*sv! && $line =~ m!verilated_dpi.cpp!;
|
||||
next if $line =~ m!id="unusedFunction" .*vpi! && $line =~ m!verilated_vpi.cpp!;
|
||||
next if $line =~ m!id="unusedPrivateFunction" .*::debug!; # Doesn't know UINFO will use it
|
||||
next if $line =~ m!file=".*obj_dbg/V3ParseBison.c".* id="unreachableCode"!;
|
||||
|
||||
# Specific suppressions (see _suppress also)
|
||||
next if $line =~ m!id="unusedPrivateFunction" .*::debug!; # Doesn't know UINFO will use it
|
||||
|
||||
# Output
|
||||
if ($line =~ /^cppcheck --/) {
|
||||
print $line if $Debug;
|
||||
@@ -136,6 +133,15 @@ sub _suppress {
|
||||
|
||||
return undef if $filename eq "*";
|
||||
|
||||
# Specific suppressions
|
||||
return 1 if $id eq "missingInclude" && $filename =~ m!systemc.h!;
|
||||
return 1 if $id eq "missingInclude" && $filename =~ m!svdpi.h!;
|
||||
return 1 if $id eq "unusedFunction" && $filename =~ m!verilated_dpi.cpp!;
|
||||
return 1 if $id eq "unusedFunction" && $filename =~ m!verilated_vpi.cpp!;
|
||||
return 1 if $id eq "unreachableCode" && $filename =~ /V3ParseBison.c/;
|
||||
return 1 if $id eq 'variableScope' && $filename =~ /fstapi.c/;
|
||||
return 1 if $id eq 'variableScope' && $filename =~ /lxt2_write.c/;
|
||||
|
||||
my $fh = IO::File->new("<$filename");
|
||||
if (!$fh) {
|
||||
warn "%Warning: $! $filename,";
|
||||
|
||||
+2
-1
@@ -444,6 +444,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
||||
"$low" { FL; return yD_LOW; }
|
||||
"$onehot" { FL; return yD_ONEHOT; }
|
||||
"$onehot0" { FL; return yD_ONEHOT0; }
|
||||
"$past" { FL; return yD_PAST; }
|
||||
"$right" { FL; return yD_RIGHT; }
|
||||
"$size" { FL; return yD_SIZE; }
|
||||
"$unpacked_dimensions" { FL; return yD_UNPACKED_DIMENSIONS; }
|
||||
@@ -490,6 +491,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
||||
"pure" { FL; return yPURE; }
|
||||
"rand" { FL; return yRAND; }
|
||||
"randc" { FL; return yRANDC; }
|
||||
"restrict" { FL; return yRESTRICT; }
|
||||
"return" { FL; return yRETURN; }
|
||||
"shortint" { FL; return ySHORTINT; }
|
||||
"static" { FL; return ySTATIC; }
|
||||
@@ -566,7 +568,6 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
||||
"let" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
|
||||
"nexttime" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
|
||||
"reject_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
|
||||
"restrict" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
|
||||
"s_always" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
|
||||
"s_eventually" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
|
||||
"s_nexttime" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); }
|
||||
|
||||
+9
-1
@@ -399,6 +399,7 @@ class AstSenTree;
|
||||
%token<fl> yREALTIME "realtime"
|
||||
%token<fl> yREG "reg"
|
||||
%token<fl> yREPEAT "repeat"
|
||||
%token<fl> yRESTRICT "restrict"
|
||||
%token<fl> yRETURN "return"
|
||||
%token<fl> yRNMOS "rnmos"
|
||||
%token<fl> yRPMOS "rpmos"
|
||||
@@ -485,6 +486,7 @@ class AstSenTree;
|
||||
%token<fl> yD_LOW "$low"
|
||||
%token<fl> yD_ONEHOT "$onehot"
|
||||
%token<fl> yD_ONEHOT0 "$onehot0"
|
||||
%token<fl> yD_PAST "$past"
|
||||
%token<fl> yD_POW "$pow"
|
||||
%token<fl> yD_RANDOM "$random"
|
||||
%token<fl> yD_READMEMB "$readmemb"
|
||||
@@ -2776,8 +2778,12 @@ system_f_call_or_t<nodep>: // IEEE: part of system_tf_call (can be task or func)
|
||||
| yD_LOW '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LOW,$3,$5); }
|
||||
| yD_ONEHOT '(' expr ')' { $$ = new AstOneHot($1,$3); }
|
||||
| yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); }
|
||||
| yD_PAST '(' expr ')' { $$ = new AstPast($1,$3, NULL); }
|
||||
| yD_PAST '(' expr ',' expr ')' { $$ = new AstPast($1,$3, $5); }
|
||||
| yD_PAST '(' expr ',' expr ',' expr ')' { $1->v3error("Unsupported: $past expr2 and clock arguments"); $$ = $3; }
|
||||
| yD_PAST '(' expr ',' expr ',' expr ',' expr')' { $1->v3error("Unsupported: $past expr2 and clock arguments"); $$ = $3; }
|
||||
| yD_POW '(' expr ',' expr ')' { $$ = new AstPowD($1,$3,$5); }
|
||||
| yD_RANDOM '(' expr ')' { $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")"); }
|
||||
| yD_RANDOM '(' expr ')' { $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")"); $$ = NULL; }
|
||||
| yD_RANDOM parenE { $$ = new AstRand($1); }
|
||||
| yD_REALTIME parenE { $$ = new AstTimeD($1); }
|
||||
| yD_REALTOBITS '(' expr ')' { $$ = new AstRealToBits($1,$3); }
|
||||
@@ -3740,6 +3746,8 @@ concurrent_assertion_statement<nodep>: // ==IEEE: concurrent_assertion_statement
|
||||
yASSERT yPROPERTY '(' property_spec ')' elseStmtBlock { $$ = new AstPslAssert($1,$4,$6); }
|
||||
// // IEEE: cover_property_statement
|
||||
| yCOVER yPROPERTY '(' property_spec ')' stmtBlock { $$ = new AstPslCover($1,$4,$6); }
|
||||
// // IEEE: restrict_property_statement
|
||||
| yRESTRICT yPROPERTY '(' property_spec ')' ';' { $$ = new AstPslRestrict($1,$4); }
|
||||
;
|
||||
|
||||
elseStmtBlock<nodep>: // Part of concurrent_assertion_statement
|
||||
|
||||
+33
-12
@@ -130,7 +130,7 @@ if ($#opt_tests<0) {
|
||||
foreach my $dir (@Test_Dirs) {
|
||||
my @stats = stat($dir); # Uniquify by inode, so different paths to same place get combined
|
||||
next if !$stats[1] || $uniq{$stats[1]}++;
|
||||
push @opt_tests, sort(glob ("${dir}/t_*.pl"));
|
||||
push @opt_tests, sort(glob("${dir}/t_*.pl"));
|
||||
}
|
||||
}
|
||||
if ($#opt_tests>=2 && $opt_jobs>=2) {
|
||||
@@ -587,8 +587,11 @@ sub compile_vlt_flags {
|
||||
@{$param{verilator_flags2}},
|
||||
@{$param{verilator_flags3}});
|
||||
$self->{sc} = 1 if ($checkflags =~ /-sc\b/);
|
||||
$self->{trace} = ($opt_trace || $checkflags =~ /-trace\b/ || $checkflags =~ /-trace-lxt2\b/);
|
||||
$self->{trace_format} = (($checkflags =~ /-trace-lxt2\b/ && 'lxt2-c')
|
||||
$self->{trace} = ($opt_trace || $checkflags =~ /-trace\b/
|
||||
|| $checkflags =~ /-trace-fst\b/
|
||||
|| $checkflags =~ /-trace-lxt2\b/);
|
||||
$self->{trace_format} = (($checkflags =~ /-trace-fst\b/ && 'fst-c')
|
||||
|| ($checkflags =~ /-trace-lxt2\b/ && 'lxt2-c')
|
||||
|| ($self->{sc} && 'vcd-sc')
|
||||
|| (!$self->{sc} && 'vcd-c'));
|
||||
$self->{savable} = 1 if ($checkflags =~ /-savable\b/);
|
||||
@@ -1016,6 +1019,7 @@ sub have_sc {
|
||||
|
||||
sub trace_filename {
|
||||
my $self = shift;
|
||||
return "$self->{obj_dir}/simx.fst" if $self->{trace_format} =~ /^fst/;
|
||||
return "$self->{obj_dir}/simx.lxt2" if $self->{trace_format} =~ /^lxt2/;
|
||||
return "$self->{obj_dir}/simx.vcd";
|
||||
}
|
||||
@@ -1185,6 +1189,7 @@ sub _make_main {
|
||||
print $fh "// General headers\n";
|
||||
print $fh "#include \"verilated.h\"\n";
|
||||
print $fh "#include \"systemc.h\"\n" if $self->sc;
|
||||
print $fh "#include \"verilated_fst_c.h\"\n" if $self->{trace} && $self->{trace_format} eq 'fst-c';
|
||||
print $fh "#include \"verilated_lxt2_c.h\"\n" if $self->{trace} && $self->{trace_format} eq 'lxt2-c';
|
||||
print $fh "#include \"verilated_vcd_c.h\"\n" if $self->{trace} && $self->{trace_format} eq 'vcd-c';
|
||||
print $fh "#include \"verilated_vcd_sc.h\"\n" if $self->{trace} && $self->{trace_format} eq 'vcd-sc';
|
||||
@@ -1249,13 +1254,14 @@ sub _make_main {
|
||||
$fh->print("\n");
|
||||
$fh->print("#if VM_TRACE\n");
|
||||
$fh->print(" Verilated::traceEverOn(true);\n");
|
||||
$fh->print(" VerilatedFstC* tfp = new VerilatedFstC;\n") if $self->{trace_format} eq 'fst-c';
|
||||
$fh->print(" VerilatedLxt2C* tfp = new VerilatedLxt2C;\n") if $self->{trace_format} eq 'lxt2-c';
|
||||
$fh->print(" VerilatedVcdC* tfp = new VerilatedVcdC;\n") if $self->{trace_format} eq 'vcd-c';
|
||||
$fh->print(" VerilatedVcdSc* tfp = new VerilatedVcdSc;\n") if $self->{trace_format} eq 'vcd-sc';
|
||||
$fh->print(" VerilatedLxt2C* tfp = new VerilatedLxt2C;\n") if $self->{trace_format} eq 'lxt2-c';
|
||||
$fh->print(" topp->trace(tfp, 99);\n");
|
||||
$fh->print(" tfp->open(\"".$self->trace_filename."\");\n");
|
||||
if ($self->{trace} && !$self->sc) {
|
||||
$fh->print(" if (tfp) tfp->dump (main_time);\n");
|
||||
$fh->print(" if (tfp) tfp->dump(main_time);\n");
|
||||
}
|
||||
$fh->print("#endif\n");
|
||||
}
|
||||
@@ -1308,12 +1314,12 @@ sub _make_main {
|
||||
if ($self->{coverage}) {
|
||||
$fh->print("#if VM_COVERAGE\n");
|
||||
$fh->print(" VerilatedCov::write(\"",$self->{coverage_filename},"\");\n");
|
||||
$fh->print("#endif //VM_COVERAGE\n");
|
||||
$fh->print("#endif // VM_COVERAGE\n");
|
||||
}
|
||||
if ($self->{trace}) {
|
||||
$fh->print("#if VM_TRACE\n");
|
||||
$fh->print(" if (tfp) tfp->close();\n");
|
||||
$fh->print("#endif //VM_TRACE\n");
|
||||
$fh->print("#endif // VM_TRACE\n");
|
||||
}
|
||||
$fh->print("\n");
|
||||
|
||||
@@ -1344,8 +1350,8 @@ sub _print_advance_time {
|
||||
print $fh " ${set}eval();\n";
|
||||
if ($self->{trace} && !$self->sc) {
|
||||
$fh->print("#if VM_TRACE\n");
|
||||
$fh->print(" if (tfp) tfp->dump (main_time);\n");
|
||||
$fh->print("#endif //VM_TRACE\n");
|
||||
$fh->print(" if (tfp) tfp->dump(main_time);\n");
|
||||
$fh->print("#endif // VM_TRACE\n");
|
||||
}
|
||||
}
|
||||
print $fh " main_time += ${time};\n";
|
||||
@@ -1571,7 +1577,7 @@ sub vcd_identical {
|
||||
my $cmd = qq{vcddiff --help};
|
||||
print "\t$cmd\n" if $::Debug;
|
||||
my $out = `$cmd`;
|
||||
if ($out !~ /Usage:/) { $self->skip("No vcddiff installed\n"); return 0; }
|
||||
if (!$out || $out !~ /Usage:/) { $self->skip("No vcddiff installed\n"); return 0; }
|
||||
|
||||
$cmd = qq{vcddiff "$fn1" "$fn2"};
|
||||
print "\t$cmd\n" if $::Debug;
|
||||
@@ -1604,6 +1610,22 @@ sub vcd_identical {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub fst2vcd {
|
||||
my $self = (ref $_[0]? shift : $Self);
|
||||
my $fn1 = shift;
|
||||
my $fn2 = shift;
|
||||
if (!-r $fn1) { $self->error("File does not exist $fn1\n"); return 0; }
|
||||
my $cmd = qq{fst2vcd --help};
|
||||
print "\t$cmd\n" if $::Debug;
|
||||
my $out = `$cmd`;
|
||||
if (!$out || $out !~ /Usage:/) { $self->skip("No fst2vcd installed\n"); return 0; }
|
||||
|
||||
$cmd = qq{fst2vcd "$fn1" -o "$fn2"};
|
||||
print "\t$cmd\n" if $::Debug;
|
||||
$out = `$cmd`;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub lxt2vcd {
|
||||
my $self = (ref $_[0]? shift : $Self);
|
||||
my $fn1 = shift;
|
||||
@@ -1612,7 +1634,7 @@ sub lxt2vcd {
|
||||
my $cmd = qq{lxt2vcd --help};
|
||||
print "\t$cmd\n" if $::Debug;
|
||||
my $out = `$cmd`;
|
||||
if ($out !~ /Usage:/) { $self->skip("No lxt2vcd installed\n"); return 0; }
|
||||
if (!$out || $out !~ /Usage:/) { $self->skip("No lxt2vcd installed\n"); return 0; }
|
||||
|
||||
$cmd = qq{lxt2vcd "$fn1" -o "$fn2"};
|
||||
print "\t$cmd\n" if $::Debug;
|
||||
@@ -1620,7 +1642,6 @@ sub lxt2vcd {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub _vcd_read {
|
||||
my $self = (ref $_[0]? shift : $Self);
|
||||
my $filename = shift;
|
||||
|
||||
@@ -45,6 +45,8 @@ module Test
|
||||
|
||||
assert property (@(posedge clk) cyc < 100);
|
||||
|
||||
restrict property (@(posedge clk) cyc==1); // Ignored in simulators
|
||||
|
||||
// Unclocked is not supported:
|
||||
// assert property (cyc != 6);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ if (!-r "$root/.git") {
|
||||
my $grep = `$cmd`;
|
||||
foreach my $line (split /\n/, $grep) {
|
||||
next if $line =~ m!include/vltstd/vpi_user.h!; # IEEE Standard file - can't change it
|
||||
next if $line =~ m!include/lxt2/!; # Standard file - can't change it
|
||||
next if $line =~ m!include/gtkwave/!; # Standard file - can't change it
|
||||
my $hit;
|
||||
$hit = 1 if $line =~ /\bassert\.h/;
|
||||
$hit = 1 if $line =~ /\bctype\.h/;
|
||||
|
||||
@@ -8,6 +8,7 @@ module t;
|
||||
endmodule
|
||||
|
||||
module sub;
|
||||
//verilator no_inline_module
|
||||
string scope;
|
||||
initial begin
|
||||
scope = $sformatf("%m");
|
||||
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,98 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2018 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
reg [63:0] crc;
|
||||
reg [63:0] sum;
|
||||
|
||||
// Take CRC data and apply to testblock inputs
|
||||
wire [31:0] in = crc[31:0];
|
||||
|
||||
Test test (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.in (in[31:0]));
|
||||
|
||||
Test2 test2 (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.in (in[31:0]));
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Test (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk, in
|
||||
);
|
||||
|
||||
input clk;
|
||||
input [31:0] in;
|
||||
|
||||
reg [31:0] dly0;
|
||||
reg [31:0] dly1;
|
||||
reg [31:0] dly2;
|
||||
reg [31:0] dly3;
|
||||
|
||||
// If called in an assertion, sequence, or property, the appropriate clocking event.
|
||||
// Otherwise, if called in a disable condition or a clock expression in an assertion, sequence, or prop, explicit.
|
||||
// Otherwise, if called in an action block of an assertion, the leading clock of the assertion is used.
|
||||
// Otherwise, if called in a procedure, the inferred clock
|
||||
// Otherwise, default clocking
|
||||
|
||||
always @(posedge clk) begin
|
||||
dly0 <= in;
|
||||
dly1 <= dly0;
|
||||
dly2 <= dly1;
|
||||
dly3 <= dly2;
|
||||
// $past(expression, ticks, expression, clocking)
|
||||
// In clock expression
|
||||
if (dly0 != $past(in)) $stop;
|
||||
if (dly0 != $past(in,1)) $stop;
|
||||
if (dly1 != $past(in,2)) $stop;
|
||||
end
|
||||
|
||||
assert property (@(posedge clk) dly0 == $past(in));
|
||||
|
||||
endmodule
|
||||
|
||||
module Test2 (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk, in
|
||||
);
|
||||
|
||||
input clk;
|
||||
input [31:0] in;
|
||||
|
||||
reg [31:0] dly0;
|
||||
reg [31:0] dly1;
|
||||
|
||||
default clocking @(posedge clk); endclocking
|
||||
assert property (@(posedge clk) dly1 == $past(in, 2));
|
||||
|
||||
endmodule
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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.
|
||||
|
||||
scenarios(vlt_all => 1);
|
||||
|
||||
compile(
|
||||
fails => 1,
|
||||
expect =>
|
||||
'%Error: t/t_past_bad.v:\d+:.* \$past tick value must be constant and >= 1 \(IEEE 2017 16.9.3\)
|
||||
%Warning-TICKCOUNT: t/t_past_bad.v:\d+: \$past tick value of 10000 may have a large performance cost
|
||||
.*%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2018 by Wilson Snyder.
|
||||
|
||||
module t (d, clk);
|
||||
input d;
|
||||
input clk;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if ($past(d, 0)) $stop; // IEEE 16.9.3 must be >- 0
|
||||
if ($past(d, 10000)) $stop; // TICKCOUNT
|
||||
end
|
||||
endmodule
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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.
|
||||
|
||||
scenarios(vlt_all => 1);
|
||||
|
||||
compile(
|
||||
fails => 1,
|
||||
expect =>
|
||||
'%Error: t/t_past_unsup_bad.v:12: Unsupported: \$past expr2 and clock arguments
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2018 by Wilson Snyder.
|
||||
|
||||
module t (d, clk);
|
||||
input d;
|
||||
input clk;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
// Unsupported
|
||||
if ($past(d, 0, 0, 0)) $stop;
|
||||
end
|
||||
endmodule
|
||||
File diff suppressed because one or more lines are too long
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
top_filename("t/t_trace_array.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--cc --trace-fst --trace-structs'],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
fst2vcd($Self->trace_filename, "$Self->{obj_dir}/simx-fst2vcd.vcd");
|
||||
vcd_identical("$Self->{obj_dir}/simx-fst2vcd.vcd", "t/$Self->{name}.out");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -1,46 +1,47 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Tue Apr 15 19:42:28 2014
|
||||
$date Fri Oct 5 18:30:09 2018
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 9 clk $end
|
||||
$var wire 1 : clk $end
|
||||
$scope module $unit $end
|
||||
$var wire 1 # global_bit $end
|
||||
$upscope $end
|
||||
$scope module t $end
|
||||
$var wire 1 9 clk $end
|
||||
$var wire 1 : clk $end
|
||||
$var wire 32 $ cyc [31:0] $end
|
||||
$var real 64 3 v_arr_real(0) $end
|
||||
$var real 64 5 v_arr_real(1) $end
|
||||
$var wire 2 * v_arrp [2:1] $end
|
||||
$var wire 4 + v_arrp_arrp [3:0] $end
|
||||
$var wire 4 , v_arrp_strp [3:0] $end
|
||||
$var wire 1 : v_arru(1) $end
|
||||
$var wire 1 ; v_arru(2) $end
|
||||
$var wire 1 ; v_arru(1) $end
|
||||
$var wire 1 < v_arru(2) $end
|
||||
$var wire 2 - v_arru_arrp(3) [2:1] $end
|
||||
$var wire 2 . v_arru_arrp(4) [2:1] $end
|
||||
$var wire 1 < v_arru_arru(3)(1) $end
|
||||
$var wire 1 = v_arru_arru(3)(2) $end
|
||||
$var wire 1 > v_arru_arru(4)(1) $end
|
||||
$var wire 1 ? v_arru_arru(4)(2) $end
|
||||
$var wire 1 = v_arru_arru(3)(1) $end
|
||||
$var wire 1 > v_arru_arru(3)(2) $end
|
||||
$var wire 1 ? v_arru_arru(4)(1) $end
|
||||
$var wire 1 @ v_arru_arru(4)(2) $end
|
||||
$var wire 2 / v_arru_strp(3) [1:0] $end
|
||||
$var wire 2 0 v_arru_strp(4) [1:0] $end
|
||||
$var wire 32 7 v_enumed [31:0] $end
|
||||
$var real 64 1 v_real $end
|
||||
$var wire 64 % v_str32x2 [63:0] $end
|
||||
$var wire 2 ' v_strp [1:0] $end
|
||||
$var wire 4 ( v_strp_strp [3:0] $end
|
||||
$var wire 2 ) v_unip_strp [1:0] $end
|
||||
$scope module p2 $end
|
||||
$var wire 32 @ PARAM [31:0] $end
|
||||
$upscope $end
|
||||
$scope module p3 $end
|
||||
$var wire 32 A PARAM [31:0] $end
|
||||
$upscope $end
|
||||
$scope module p3 $end
|
||||
$var wire 32 B PARAM [31:0] $end
|
||||
$upscope $end
|
||||
$scope module unnamedblk1 $end
|
||||
$var wire 32 7 b [31:0] $end
|
||||
$var wire 32 8 b [31:0] $end
|
||||
$scope module unnamedblk2 $end
|
||||
$var wire 32 8 a [31:0] $end
|
||||
$var wire 32 9 a [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
@@ -67,15 +68,16 @@ r0 3
|
||||
r0 5
|
||||
b00000000000000000000000000000000 7
|
||||
b00000000000000000000000000000000 8
|
||||
09
|
||||
b00000000000000000000000000000000 9
|
||||
0:
|
||||
0;
|
||||
0<
|
||||
0=
|
||||
0>
|
||||
0?
|
||||
b00000000000000000000000000000010 @
|
||||
b00000000000000000000000000000011 A
|
||||
0@
|
||||
b00000000000000000000000000000010 A
|
||||
b00000000000000000000000000000011 B
|
||||
#10
|
||||
b00000000000000000000000000000001 $
|
||||
b0000000000000000000000000000000100000000000000000000000011111110 %
|
||||
@@ -92,11 +94,12 @@ b11 0
|
||||
r0.1 1
|
||||
r0.2 3
|
||||
r0.3 5
|
||||
b00000000000000000000000000000101 7
|
||||
b00000000000000000000000000000001 7
|
||||
b00000000000000000000000000000101 8
|
||||
19
|
||||
b00000000000000000000000000000101 9
|
||||
1:
|
||||
#15
|
||||
09
|
||||
0:
|
||||
#20
|
||||
b00000000000000000000000000000010 $
|
||||
b0000000000000000000000000000001000000000000000000000000011111101 %
|
||||
@@ -113,9 +116,10 @@ b00 0
|
||||
r0.2 1
|
||||
r0.4 3
|
||||
r0.6 5
|
||||
19
|
||||
b00000000000000000000000000000010 7
|
||||
1:
|
||||
#25
|
||||
09
|
||||
0:
|
||||
#30
|
||||
b00000000000000000000000000000011 $
|
||||
b0000000000000000000000000000001100000000000000000000000011111100 %
|
||||
@@ -132,9 +136,10 @@ b11 0
|
||||
r0.3 1
|
||||
r0.6000000000000001 3
|
||||
r0.8999999999999999 5
|
||||
19
|
||||
b00000000000000000000000000000011 7
|
||||
1:
|
||||
#35
|
||||
09
|
||||
0:
|
||||
#40
|
||||
b00000000000000000000000000000100 $
|
||||
b0000000000000000000000000000010000000000000000000000000011111011 %
|
||||
@@ -151,9 +156,10 @@ b00 0
|
||||
r0.4 1
|
||||
r0.8 3
|
||||
r1.2 5
|
||||
19
|
||||
b00000000000000000000000000000100 7
|
||||
1:
|
||||
#45
|
||||
09
|
||||
0:
|
||||
#50
|
||||
b00000000000000000000000000000101 $
|
||||
b0000000000000000000000000000010100000000000000000000000011111010 %
|
||||
@@ -170,9 +176,10 @@ b11 0
|
||||
r0.5 1
|
||||
r1 3
|
||||
r1.5 5
|
||||
19
|
||||
b00000000000000000000000000000101 7
|
||||
1:
|
||||
#55
|
||||
09
|
||||
0:
|
||||
#60
|
||||
b00000000000000000000000000000110 $
|
||||
b0000000000000000000000000000011000000000000000000000000011111001 %
|
||||
@@ -189,4 +196,5 @@ b00 0
|
||||
r0.6 1
|
||||
r1.2 3
|
||||
r1.8 5
|
||||
19
|
||||
b00000000000000000000000000000110 7
|
||||
1:
|
||||
|
||||
@@ -56,6 +56,9 @@ module t (clk);
|
||||
initial v_str32x2[0] = 32'hff;
|
||||
initial v_str32x2[1] = 0;
|
||||
|
||||
typedef enum int { ZERO=0, ONE, TWO, THREE } enumed_t;
|
||||
enumed_t v_enumed;
|
||||
|
||||
p #(.PARAM(2)) p2 ();
|
||||
p #(.PARAM(3)) p3 ();
|
||||
|
||||
@@ -71,6 +74,7 @@ module t (clk);
|
||||
v_string <= cyc[0] ? "foo" : "bar";
|
||||
v_arr_real[0] <= v_arr_real[0] + 0.2;
|
||||
v_arr_real[1] <= v_arr_real[1] + 0.3;
|
||||
v_enumed <= v_enumed + 1;
|
||||
for (integer b=3; b<=4; b++) begin
|
||||
v_arru[b] <= ~v_arru[b];
|
||||
v_arru_strp[b] <= ~v_arru_strp[b];
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
$date
|
||||
Fri Oct 5 18:31:31 2018
|
||||
|
||||
$end
|
||||
$version
|
||||
fstWriter
|
||||
$end
|
||||
$timescale
|
||||
1ns
|
||||
$end
|
||||
$scope module top $end
|
||||
$var bit 1 ! clk $end
|
||||
$scope module t $end
|
||||
$var wire 1 ! clk $end
|
||||
$var integer 32 " cyc $end
|
||||
$var logic 2 # v_strp $end
|
||||
$var logic 4 $ v_strp_strp $end
|
||||
$var logic 2 % v_unip_strp $end
|
||||
$var logic 2 & v_arrp $end
|
||||
$var logic 4 ' v_arrp_arrp $end
|
||||
$var logic 4 ( v_arrp_strp $end
|
||||
$var logic 1 ) v_arru(1) $end
|
||||
$var logic 1 * v_arru(2) $end
|
||||
$var logic 1 + v_arru_arru(3)(1) $end
|
||||
$var logic 1 , v_arru_arru(3)(2) $end
|
||||
$var logic 1 - v_arru_arru(4)(1) $end
|
||||
$var logic 1 . v_arru_arru(4)(2) $end
|
||||
$var logic 2 / v_arru_arrp(3) $end
|
||||
$var logic 2 0 v_arru_arrp(4) $end
|
||||
$var logic 2 1 v_arru_strp(3) $end
|
||||
$var logic 2 2 v_arru_strp(4) $end
|
||||
$var real 64 3 v_real $end
|
||||
$var real 64 4 v_arr_real(0) $end
|
||||
$var real 64 5 v_arr_real(1) $end
|
||||
$var logic 64 6 v_str32x2 $end
|
||||
$var logic 32 7 v_enumed $end
|
||||
$scope module unnamedblk1 $end
|
||||
$var integer 32 8 b $end
|
||||
$scope module unnamedblk2 $end
|
||||
$var integer 32 9 a $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module p2 $end
|
||||
$var parameter 32 : PARAM $end
|
||||
$upscope $end
|
||||
$scope module p3 $end
|
||||
$var parameter 32 ; PARAM $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module $unit $end
|
||||
$var bit 1 < global_bit $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$dumpvars
|
||||
0!
|
||||
b00000000000000000000000000000000 "
|
||||
b00 #
|
||||
b0000 $
|
||||
b00 %
|
||||
b00 &
|
||||
b0000 '
|
||||
b0000 (
|
||||
0)
|
||||
0*
|
||||
0+
|
||||
0,
|
||||
0-
|
||||
0.
|
||||
b00 /
|
||||
b00 0
|
||||
b00 1
|
||||
b00 2
|
||||
r0 3
|
||||
r0 4
|
||||
r0 5
|
||||
b0000000000000000000000000000000000000000000000000000000011111111 6
|
||||
b00000000000000000000000000000000 7
|
||||
b00000000000000000000000000000000 8
|
||||
b00000000000000000000000000000000 9
|
||||
b00000000000000000000000000000010 :
|
||||
b00000000000000000000000000000011 ;
|
||||
1<
|
||||
#10
|
||||
b00000000000000000000000000000101 9
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000001 7
|
||||
b0000000000000000000000000000000100000000000000000000000011111110 6
|
||||
r0.3 5
|
||||
r0.2 4
|
||||
r0.1 3
|
||||
b11 2
|
||||
b11 1
|
||||
b11 0
|
||||
b11 /
|
||||
b1111 (
|
||||
b1111 '
|
||||
b11 &
|
||||
b11 %
|
||||
b1111 $
|
||||
b11 #
|
||||
b00000000000000000000000000000001 "
|
||||
1!
|
||||
#15
|
||||
0!
|
||||
#20
|
||||
1!
|
||||
b00000000000000000000000000000010 "
|
||||
b00 #
|
||||
b0000 $
|
||||
b00 %
|
||||
b00 &
|
||||
b0000 '
|
||||
b0000 (
|
||||
b00 /
|
||||
b00 0
|
||||
b00 1
|
||||
b00 2
|
||||
r0.2 3
|
||||
r0.4 4
|
||||
r0.6 5
|
||||
b0000000000000000000000000000001000000000000000000000000011111101 6
|
||||
b00000000000000000000000000000010 7
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 9
|
||||
#25
|
||||
0!
|
||||
#30
|
||||
1!
|
||||
b00000000000000000000000000000101 9
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000011 7
|
||||
b0000000000000000000000000000001100000000000000000000000011111100 6
|
||||
r0.8999999999999999 5
|
||||
r0.6000000000000001 4
|
||||
r0.3 3
|
||||
b11 2
|
||||
b11 1
|
||||
b11 0
|
||||
b11 /
|
||||
b1111 (
|
||||
b1111 '
|
||||
b11 &
|
||||
b11 %
|
||||
b1111 $
|
||||
b11 #
|
||||
b00000000000000000000000000000011 "
|
||||
#35
|
||||
0!
|
||||
#40
|
||||
1!
|
||||
b00000000000000000000000000000100 "
|
||||
b00 #
|
||||
b0000 $
|
||||
b00 %
|
||||
b00 &
|
||||
b0000 '
|
||||
b0000 (
|
||||
b00 /
|
||||
b00 0
|
||||
b00 1
|
||||
b00 2
|
||||
r0.4 3
|
||||
r0.8 4
|
||||
r1.2 5
|
||||
b0000000000000000000000000000010000000000000000000000000011111011 6
|
||||
b00000000000000000000000000000100 7
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 9
|
||||
#45
|
||||
0!
|
||||
#50
|
||||
1!
|
||||
b00000000000000000000000000000101 9
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 7
|
||||
b0000000000000000000000000000010100000000000000000000000011111010 6
|
||||
r1.5 5
|
||||
r1 4
|
||||
r0.5 3
|
||||
b11 2
|
||||
b11 1
|
||||
b11 0
|
||||
b11 /
|
||||
b1111 (
|
||||
b1111 '
|
||||
b11 &
|
||||
b11 %
|
||||
b1111 $
|
||||
b11 #
|
||||
b00000000000000000000000000000101 "
|
||||
#55
|
||||
0!
|
||||
#60
|
||||
1!
|
||||
b00000000000000000000000000000110 "
|
||||
b00 #
|
||||
b0000 $
|
||||
b00 %
|
||||
b00 &
|
||||
b0000 '
|
||||
b0000 (
|
||||
b00 /
|
||||
b00 0
|
||||
b00 1
|
||||
b00 2
|
||||
r0.6 3
|
||||
r1.2 4
|
||||
r1.8 5
|
||||
b0000000000000000000000000000011000000000000000000000000011111001 6
|
||||
b00000000000000000000000000000110 7
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 9
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_trace_complex.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--cc --trace-fst'],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
fst2vcd($Self->trace_filename, "$Self->{obj_dir}/simx-fst2vcd.vcd");
|
||||
vcd_identical("$Self->{obj_dir}/simx-fst2vcd.vcd", "t/$Self->{name}.out");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -1,5 +1,5 @@
|
||||
$date
|
||||
Tue Aug 28 15:03:55 2018
|
||||
Fri Oct 5 18:31:36 2018
|
||||
$end
|
||||
$version
|
||||
lxt2vcd
|
||||
@@ -39,11 +39,12 @@ $var wire 1 3 v_arru_arru(4)(1) $end
|
||||
$var wire 1 4 v_arru_arru(4)(2) $end
|
||||
$var wire 2 5 v_arru_strp(3) [1:0] $end
|
||||
$var wire 2 6 v_arru_strp(4) [1:0] $end
|
||||
$var real 1 7 v_real $end
|
||||
$var wire 64 8 v_str32x2 [63:0] $end
|
||||
$var wire 2 9 v_strp [1:0] $end
|
||||
$var wire 4 : v_strp_strp [3:0] $end
|
||||
$var wire 2 ; v_unip_strp [1:0] $end
|
||||
$var wire 32 7 v_enumed [31:0] $end
|
||||
$var real 1 8 v_real $end
|
||||
$var wire 64 9 v_str32x2 [63:0] $end
|
||||
$var wire 2 : v_strp [1:0] $end
|
||||
$var wire 4 ; v_strp_strp [3:0] $end
|
||||
$var wire 2 < v_unip_strp [1:0] $end
|
||||
$var wire 1 " clk $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
@@ -72,17 +73,19 @@ b0 0
|
||||
04
|
||||
b0 5
|
||||
b0 6
|
||||
r0 7
|
||||
b11111111 8
|
||||
b0 9
|
||||
b0 7
|
||||
r0 8
|
||||
b11111111 9
|
||||
b0 :
|
||||
b0 ;
|
||||
b0 <
|
||||
#10
|
||||
b11 ;
|
||||
b1111 :
|
||||
b11 9
|
||||
b100000000000000000000000011111110 8
|
||||
r0.1 7
|
||||
b11 <
|
||||
b1111 ;
|
||||
b11 :
|
||||
b100000000000000000000000011111110 9
|
||||
r0.1 8
|
||||
b1 7
|
||||
b11 6
|
||||
b11 5
|
||||
b11 0
|
||||
@@ -110,20 +113,22 @@ b0 /
|
||||
b0 0
|
||||
b0 5
|
||||
b0 6
|
||||
r0.2 7
|
||||
b1000000000000000000000000011111101 8
|
||||
b0 9
|
||||
b10 7
|
||||
r0.2 8
|
||||
b1000000000000000000000000011111101 9
|
||||
b0 :
|
||||
b0 ;
|
||||
b0 <
|
||||
#25
|
||||
0"
|
||||
#30
|
||||
1"
|
||||
b11 ;
|
||||
b1111 :
|
||||
b11 9
|
||||
b1100000000000000000000000011111100 8
|
||||
r0.3 7
|
||||
b11 <
|
||||
b1111 ;
|
||||
b11 :
|
||||
b1100000000000000000000000011111100 9
|
||||
r0.3 8
|
||||
b11 7
|
||||
b11 6
|
||||
b11 5
|
||||
b11 0
|
||||
@@ -148,20 +153,22 @@ b0 /
|
||||
b0 0
|
||||
b0 5
|
||||
b0 6
|
||||
r0.4 7
|
||||
b10000000000000000000000000011111011 8
|
||||
b0 9
|
||||
b100 7
|
||||
r0.4 8
|
||||
b10000000000000000000000000011111011 9
|
||||
b0 :
|
||||
b0 ;
|
||||
b0 <
|
||||
#45
|
||||
0"
|
||||
#50
|
||||
1"
|
||||
b11 ;
|
||||
b1111 :
|
||||
b11 9
|
||||
b10100000000000000000000000011111010 8
|
||||
r0.5 7
|
||||
b11 <
|
||||
b1111 ;
|
||||
b11 :
|
||||
b10100000000000000000000000011111010 9
|
||||
r0.5 8
|
||||
b101 7
|
||||
b11 6
|
||||
b11 5
|
||||
b11 0
|
||||
@@ -186,8 +193,9 @@ b0 /
|
||||
b0 0
|
||||
b0 5
|
||||
b0 6
|
||||
r0.6 7
|
||||
b11000000000000000000000000011111001 8
|
||||
b0 9
|
||||
b110 7
|
||||
r0.6 8
|
||||
b11000000000000000000000000011111001 9
|
||||
b0 :
|
||||
b0 ;
|
||||
b0 <
|
||||
|
||||
@@ -1,46 +1,47 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Tue Apr 15 19:42:37 2014
|
||||
$date Fri Oct 5 18:38:00 2018
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 9 clk $end
|
||||
$var wire 1 : clk $end
|
||||
$scope module $unit $end
|
||||
$var wire 1 # global_bit $end
|
||||
$upscope $end
|
||||
$scope module t $end
|
||||
$var wire 1 9 clk $end
|
||||
$var wire 1 : clk $end
|
||||
$var wire 32 $ cyc [31:0] $end
|
||||
$var real 64 3 v_arr_real(0) $end
|
||||
$var real 64 5 v_arr_real(1) $end
|
||||
$var wire 2 * v_arrp [2:1] $end
|
||||
$var wire 4 + v_arrp_arrp [3:0] $end
|
||||
$var wire 4 , v_arrp_strp [3:0] $end
|
||||
$var wire 1 : v_arru(1) $end
|
||||
$var wire 1 ; v_arru(2) $end
|
||||
$var wire 1 ; v_arru(1) $end
|
||||
$var wire 1 < v_arru(2) $end
|
||||
$var wire 2 - v_arru_arrp(3) [2:1] $end
|
||||
$var wire 2 . v_arru_arrp(4) [2:1] $end
|
||||
$var wire 1 < v_arru_arru(3)(1) $end
|
||||
$var wire 1 = v_arru_arru(3)(2) $end
|
||||
$var wire 1 > v_arru_arru(4)(1) $end
|
||||
$var wire 1 ? v_arru_arru(4)(2) $end
|
||||
$var wire 1 = v_arru_arru(3)(1) $end
|
||||
$var wire 1 > v_arru_arru(3)(2) $end
|
||||
$var wire 1 ? v_arru_arru(4)(1) $end
|
||||
$var wire 1 @ v_arru_arru(4)(2) $end
|
||||
$var wire 2 / v_arru_strp(3) [1:0] $end
|
||||
$var wire 2 0 v_arru_strp(4) [1:0] $end
|
||||
$var wire 32 7 v_enumed [31:0] $end
|
||||
$var real 64 1 v_real $end
|
||||
$var wire 64 % v_str32x2 [63:0] $end
|
||||
$var wire 2 ' v_strp [1:0] $end
|
||||
$var wire 4 ( v_strp_strp [3:0] $end
|
||||
$var wire 2 ) v_unip_strp [1:0] $end
|
||||
$scope module p2 $end
|
||||
$var wire 32 @ PARAM [31:0] $end
|
||||
$upscope $end
|
||||
$scope module p3 $end
|
||||
$var wire 32 A PARAM [31:0] $end
|
||||
$upscope $end
|
||||
$scope module p3 $end
|
||||
$var wire 32 B PARAM [31:0] $end
|
||||
$upscope $end
|
||||
$scope module unnamedblk1 $end
|
||||
$var wire 32 7 b [31:0] $end
|
||||
$var wire 32 8 b [31:0] $end
|
||||
$scope module unnamedblk2 $end
|
||||
$var wire 32 8 a [31:0] $end
|
||||
$var wire 32 9 a [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
@@ -67,15 +68,16 @@ r0 3
|
||||
r0 5
|
||||
b00000000000000000000000000000000 7
|
||||
b00000000000000000000000000000000 8
|
||||
09
|
||||
b00000000000000000000000000000000 9
|
||||
0:
|
||||
0;
|
||||
0<
|
||||
0=
|
||||
0>
|
||||
0?
|
||||
b00000000000000000000000000000010 @
|
||||
b00000000000000000000000000000011 A
|
||||
0@
|
||||
b00000000000000000000000000000010 A
|
||||
b00000000000000000000000000000011 B
|
||||
#10
|
||||
b00000000000000000000000000000001 $
|
||||
b0000000000000000000000000000000100000000000000000000000011111110 %
|
||||
@@ -92,11 +94,12 @@ b11 0
|
||||
r0.1 1
|
||||
r0.2 3
|
||||
r0.3 5
|
||||
b00000000000000000000000000000101 7
|
||||
b00000000000000000000000000000001 7
|
||||
b00000000000000000000000000000101 8
|
||||
19
|
||||
b00000000000000000000000000000101 9
|
||||
1:
|
||||
#15
|
||||
09
|
||||
0:
|
||||
#20
|
||||
b00000000000000000000000000000010 $
|
||||
b0000000000000000000000000000001000000000000000000000000011111101 %
|
||||
@@ -113,9 +116,10 @@ b00 0
|
||||
r0.2 1
|
||||
r0.4 3
|
||||
r0.6 5
|
||||
19
|
||||
b00000000000000000000000000000010 7
|
||||
1:
|
||||
#25
|
||||
09
|
||||
0:
|
||||
#30
|
||||
b00000000000000000000000000000011 $
|
||||
b0000000000000000000000000000001100000000000000000000000011111100 %
|
||||
@@ -132,9 +136,10 @@ b11 0
|
||||
r0.3 1
|
||||
r0.6000000000000001 3
|
||||
r0.8999999999999999 5
|
||||
19
|
||||
b00000000000000000000000000000011 7
|
||||
1:
|
||||
#35
|
||||
09
|
||||
0:
|
||||
#40
|
||||
b00000000000000000000000000000100 $
|
||||
b0000000000000000000000000000010000000000000000000000000011111011 %
|
||||
@@ -151,9 +156,10 @@ b00 0
|
||||
r0.4 1
|
||||
r0.8 3
|
||||
r1.2 5
|
||||
19
|
||||
b00000000000000000000000000000100 7
|
||||
1:
|
||||
#45
|
||||
09
|
||||
0:
|
||||
#50
|
||||
b00000000000000000000000000000101 $
|
||||
b0000000000000000000000000000010100000000000000000000000011111010 %
|
||||
@@ -170,9 +176,10 @@ b11 0
|
||||
r0.5 1
|
||||
r1 3
|
||||
r1.5 5
|
||||
19
|
||||
b00000000000000000000000000000101 7
|
||||
1:
|
||||
#55
|
||||
09
|
||||
0:
|
||||
#60
|
||||
b00000000000000000000000000000110 $
|
||||
b0000000000000000000000000000011000000000000000000000000011111001 %
|
||||
@@ -189,4 +196,5 @@ b00 0
|
||||
r0.6 1
|
||||
r1.2 3
|
||||
r1.8 5
|
||||
19
|
||||
b00000000000000000000000000000110 7
|
||||
1:
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
$date
|
||||
Fri Oct 5 18:38:01 2018
|
||||
|
||||
$end
|
||||
$version
|
||||
fstWriter
|
||||
$end
|
||||
$timescale
|
||||
1ns
|
||||
$end
|
||||
$scope module top $end
|
||||
$var bit 1 ! clk $end
|
||||
$scope module t $end
|
||||
$var wire 1 ! clk $end
|
||||
$var integer 32 " cyc $end
|
||||
$var logic 2 # v_strp $end
|
||||
$var logic 4 $ v_strp_strp $end
|
||||
$var logic 2 % v_unip_strp $end
|
||||
$var logic 2 & v_arrp $end
|
||||
$var logic 4 ' v_arrp_arrp $end
|
||||
$var logic 4 ( v_arrp_strp $end
|
||||
$var logic 1 ) v_arru(1) $end
|
||||
$var logic 1 * v_arru(2) $end
|
||||
$var logic 1 + v_arru_arru(3)(1) $end
|
||||
$var logic 1 , v_arru_arru(3)(2) $end
|
||||
$var logic 1 - v_arru_arru(4)(1) $end
|
||||
$var logic 1 . v_arru_arru(4)(2) $end
|
||||
$var logic 2 / v_arru_arrp(3) $end
|
||||
$var logic 2 0 v_arru_arrp(4) $end
|
||||
$var logic 2 1 v_arru_strp(3) $end
|
||||
$var logic 2 2 v_arru_strp(4) $end
|
||||
$var real 64 3 v_real $end
|
||||
$var real 64 4 v_arr_real(0) $end
|
||||
$var real 64 5 v_arr_real(1) $end
|
||||
$var logic 64 6 v_str32x2 $end
|
||||
$var logic 32 7 v_enumed $end
|
||||
$scope module unnamedblk1 $end
|
||||
$var integer 32 8 b $end
|
||||
$scope module unnamedblk2 $end
|
||||
$var integer 32 9 a $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module p2 $end
|
||||
$var parameter 32 : PARAM $end
|
||||
$upscope $end
|
||||
$scope module p3 $end
|
||||
$var parameter 32 ; PARAM $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module $unit $end
|
||||
$var bit 1 < global_bit $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$dumpvars
|
||||
0!
|
||||
b00000000000000000000000000000000 "
|
||||
b00 #
|
||||
b0000 $
|
||||
b00 %
|
||||
b00 &
|
||||
b0000 '
|
||||
b0000 (
|
||||
0)
|
||||
0*
|
||||
0+
|
||||
0,
|
||||
0-
|
||||
0.
|
||||
b00 /
|
||||
b00 0
|
||||
b00 1
|
||||
b00 2
|
||||
r0 3
|
||||
r0 4
|
||||
r0 5
|
||||
b0000000000000000000000000000000000000000000000000000000011111111 6
|
||||
b00000000000000000000000000000000 7
|
||||
b00000000000000000000000000000000 8
|
||||
b00000000000000000000000000000000 9
|
||||
b00000000000000000000000000000010 :
|
||||
b00000000000000000000000000000011 ;
|
||||
1<
|
||||
#10
|
||||
b00000000000000000000000000000101 9
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000001 7
|
||||
b0000000000000000000000000000000100000000000000000000000011111110 6
|
||||
r0.3 5
|
||||
r0.2 4
|
||||
r0.1 3
|
||||
b11 2
|
||||
b11 1
|
||||
b11 0
|
||||
b11 /
|
||||
b1111 (
|
||||
b1111 '
|
||||
b11 &
|
||||
b11 %
|
||||
b1111 $
|
||||
b11 #
|
||||
b00000000000000000000000000000001 "
|
||||
1!
|
||||
#15
|
||||
0!
|
||||
#20
|
||||
1!
|
||||
b00000000000000000000000000000010 "
|
||||
b00 #
|
||||
b0000 $
|
||||
b00 %
|
||||
b00 &
|
||||
b0000 '
|
||||
b0000 (
|
||||
b00 /
|
||||
b00 0
|
||||
b00 1
|
||||
b00 2
|
||||
r0.2 3
|
||||
r0.4 4
|
||||
r0.6 5
|
||||
b0000000000000000000000000000001000000000000000000000000011111101 6
|
||||
b00000000000000000000000000000010 7
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 9
|
||||
#25
|
||||
0!
|
||||
#30
|
||||
1!
|
||||
b00000000000000000000000000000101 9
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000011 7
|
||||
b0000000000000000000000000000001100000000000000000000000011111100 6
|
||||
r0.8999999999999999 5
|
||||
r0.6000000000000001 4
|
||||
r0.3 3
|
||||
b11 2
|
||||
b11 1
|
||||
b11 0
|
||||
b11 /
|
||||
b1111 (
|
||||
b1111 '
|
||||
b11 &
|
||||
b11 %
|
||||
b1111 $
|
||||
b11 #
|
||||
b00000000000000000000000000000011 "
|
||||
#35
|
||||
0!
|
||||
#40
|
||||
1!
|
||||
b00000000000000000000000000000100 "
|
||||
b00 #
|
||||
b0000 $
|
||||
b00 %
|
||||
b00 &
|
||||
b0000 '
|
||||
b0000 (
|
||||
b00 /
|
||||
b00 0
|
||||
b00 1
|
||||
b00 2
|
||||
r0.4 3
|
||||
r0.8 4
|
||||
r1.2 5
|
||||
b0000000000000000000000000000010000000000000000000000000011111011 6
|
||||
b00000000000000000000000000000100 7
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 9
|
||||
#45
|
||||
0!
|
||||
#50
|
||||
1!
|
||||
b00000000000000000000000000000101 9
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 7
|
||||
b0000000000000000000000000000010100000000000000000000000011111010 6
|
||||
r1.5 5
|
||||
r1 4
|
||||
r0.5 3
|
||||
b11 2
|
||||
b11 1
|
||||
b11 0
|
||||
b11 /
|
||||
b1111 (
|
||||
b1111 '
|
||||
b11 &
|
||||
b11 %
|
||||
b1111 $
|
||||
b11 #
|
||||
b00000000000000000000000000000101 "
|
||||
#55
|
||||
0!
|
||||
#60
|
||||
1!
|
||||
b00000000000000000000000000000110 "
|
||||
b00 #
|
||||
b0000 $
|
||||
b00 %
|
||||
b00 &
|
||||
b0000 '
|
||||
b0000 (
|
||||
b00 /
|
||||
b00 0
|
||||
b00 1
|
||||
b00 2
|
||||
r0.6 3
|
||||
r1.2 4
|
||||
r1.8 5
|
||||
b0000000000000000000000000000011000000000000000000000000011111001 6
|
||||
b00000000000000000000000000000110 7
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 9
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t_trace_complex.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--cc --trace-fst --no-trace-structs --trace-params'],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
fst2vcd($Self->trace_filename, "$Self->{obj_dir}/simx-fst2vcd.vcd");
|
||||
vcd_identical("$Self->{obj_dir}/simx-fst2vcd.vcd", "t/$Self->{name}.out");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -1,5 +1,5 @@
|
||||
$date
|
||||
Tue Aug 28 15:09:58 2018
|
||||
Fri Oct 5 18:38:02 2018
|
||||
$end
|
||||
$version
|
||||
lxt2vcd
|
||||
@@ -39,11 +39,12 @@ $var wire 1 3 v_arru_arru(4)(1) $end
|
||||
$var wire 1 4 v_arru_arru(4)(2) $end
|
||||
$var wire 2 5 v_arru_strp(3) [1:0] $end
|
||||
$var wire 2 6 v_arru_strp(4) [1:0] $end
|
||||
$var real 1 7 v_real $end
|
||||
$var wire 64 8 v_str32x2 [63:0] $end
|
||||
$var wire 2 9 v_strp [1:0] $end
|
||||
$var wire 4 : v_strp_strp [3:0] $end
|
||||
$var wire 2 ; v_unip_strp [1:0] $end
|
||||
$var wire 32 7 v_enumed [31:0] $end
|
||||
$var real 1 8 v_real $end
|
||||
$var wire 64 9 v_str32x2 [63:0] $end
|
||||
$var wire 2 : v_strp [1:0] $end
|
||||
$var wire 4 ; v_strp_strp [3:0] $end
|
||||
$var wire 2 < v_unip_strp [1:0] $end
|
||||
$var wire 1 " clk $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
@@ -72,17 +73,19 @@ b0 0
|
||||
04
|
||||
b0 5
|
||||
b0 6
|
||||
r0 7
|
||||
b11111111 8
|
||||
b0 9
|
||||
b0 7
|
||||
r0 8
|
||||
b11111111 9
|
||||
b0 :
|
||||
b0 ;
|
||||
b0 <
|
||||
#10
|
||||
b11 ;
|
||||
b1111 :
|
||||
b11 9
|
||||
b100000000000000000000000011111110 8
|
||||
r0.1 7
|
||||
b11 <
|
||||
b1111 ;
|
||||
b11 :
|
||||
b100000000000000000000000011111110 9
|
||||
r0.1 8
|
||||
b1 7
|
||||
b11 6
|
||||
b11 5
|
||||
b11 0
|
||||
@@ -110,20 +113,22 @@ b0 /
|
||||
b0 0
|
||||
b0 5
|
||||
b0 6
|
||||
r0.2 7
|
||||
b1000000000000000000000000011111101 8
|
||||
b0 9
|
||||
b10 7
|
||||
r0.2 8
|
||||
b1000000000000000000000000011111101 9
|
||||
b0 :
|
||||
b0 ;
|
||||
b0 <
|
||||
#25
|
||||
0"
|
||||
#30
|
||||
1"
|
||||
b11 ;
|
||||
b1111 :
|
||||
b11 9
|
||||
b1100000000000000000000000011111100 8
|
||||
r0.3 7
|
||||
b11 <
|
||||
b1111 ;
|
||||
b11 :
|
||||
b1100000000000000000000000011111100 9
|
||||
r0.3 8
|
||||
b11 7
|
||||
b11 6
|
||||
b11 5
|
||||
b11 0
|
||||
@@ -148,20 +153,22 @@ b0 /
|
||||
b0 0
|
||||
b0 5
|
||||
b0 6
|
||||
r0.4 7
|
||||
b10000000000000000000000000011111011 8
|
||||
b0 9
|
||||
b100 7
|
||||
r0.4 8
|
||||
b10000000000000000000000000011111011 9
|
||||
b0 :
|
||||
b0 ;
|
||||
b0 <
|
||||
#45
|
||||
0"
|
||||
#50
|
||||
1"
|
||||
b11 ;
|
||||
b1111 :
|
||||
b11 9
|
||||
b10100000000000000000000000011111010 8
|
||||
r0.5 7
|
||||
b11 <
|
||||
b1111 ;
|
||||
b11 :
|
||||
b10100000000000000000000000011111010 9
|
||||
r0.5 8
|
||||
b101 7
|
||||
b11 6
|
||||
b11 5
|
||||
b11 0
|
||||
@@ -186,8 +193,9 @@ b0 /
|
||||
b0 0
|
||||
b0 5
|
||||
b0 6
|
||||
r0.6 7
|
||||
b11000000000000000000000000011111001 8
|
||||
b0 9
|
||||
b110 7
|
||||
r0.6 8
|
||||
b11000000000000000000000000011111001 9
|
||||
b0 :
|
||||
b0 ;
|
||||
b0 <
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Tue Apr 15 12:58:17 2014
|
||||
$date Fri Oct 5 18:38:02 2018
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 D clk $end
|
||||
$var wire 1 E clk $end
|
||||
$scope module $unit $end
|
||||
$var wire 1 # global_bit $end
|
||||
$upscope $end
|
||||
$scope module t $end
|
||||
$var wire 1 D clk $end
|
||||
$var wire 1 E clk $end
|
||||
$var wire 32 $ cyc [31:0] $end
|
||||
$var real 64 > v_arr_real(0) $end
|
||||
$var real 64 @ v_arr_real(1) $end
|
||||
$var wire 2 / v_arrp [2:1] $end
|
||||
$var wire 2 0 v_arrp_arrp(3) [1:0] $end
|
||||
$var wire 2 1 v_arrp_arrp(4) [1:0] $end
|
||||
$var wire 1 E v_arru(1) $end
|
||||
$var wire 1 F v_arru(2) $end
|
||||
$var wire 1 F v_arru(1) $end
|
||||
$var wire 1 G v_arru(2) $end
|
||||
$var wire 2 6 v_arru_arrp(3) [2:1] $end
|
||||
$var wire 2 7 v_arru_arrp(4) [2:1] $end
|
||||
$var wire 1 G v_arru_arru(3)(1) $end
|
||||
$var wire 1 H v_arru_arru(3)(2) $end
|
||||
$var wire 1 I v_arru_arru(4)(1) $end
|
||||
$var wire 1 J v_arru_arru(4)(2) $end
|
||||
$var wire 1 H v_arru_arru(3)(1) $end
|
||||
$var wire 1 I v_arru_arru(3)(2) $end
|
||||
$var wire 1 J v_arru_arru(4)(1) $end
|
||||
$var wire 1 K v_arru_arru(4)(2) $end
|
||||
$var wire 32 B v_enumed [31:0] $end
|
||||
$var real 64 < v_real $end
|
||||
$scope module unnamedblk1 $end
|
||||
$var wire 32 B b [31:0] $end
|
||||
$var wire 32 C b [31:0] $end
|
||||
$scope module unnamedblk2 $end
|
||||
$var wire 32 C a [31:0] $end
|
||||
$var wire 32 D a [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module v_arrp_strp(3) $end
|
||||
@@ -113,13 +114,14 @@ r0 >
|
||||
r0 @
|
||||
b00000000000000000000000000000000 B
|
||||
b00000000000000000000000000000000 C
|
||||
0D
|
||||
b00000000000000000000000000000000 D
|
||||
0E
|
||||
0F
|
||||
0G
|
||||
0H
|
||||
0I
|
||||
0J
|
||||
0K
|
||||
#10
|
||||
b00000000000000000000000000000001 $
|
||||
b00000000000000000000000011111110 %
|
||||
@@ -148,11 +150,12 @@ b11 7
|
||||
r0.1 <
|
||||
r0.2 >
|
||||
r0.3 @
|
||||
b00000000000000000000000000000101 B
|
||||
b00000000000000000000000000000001 B
|
||||
b00000000000000000000000000000101 C
|
||||
1D
|
||||
b00000000000000000000000000000101 D
|
||||
1E
|
||||
#15
|
||||
0D
|
||||
0E
|
||||
#20
|
||||
b00000000000000000000000000000010 $
|
||||
b00000000000000000000000011111101 %
|
||||
@@ -181,9 +184,10 @@ b00 7
|
||||
r0.2 <
|
||||
r0.4 >
|
||||
r0.6 @
|
||||
1D
|
||||
b00000000000000000000000000000010 B
|
||||
1E
|
||||
#25
|
||||
0D
|
||||
0E
|
||||
#30
|
||||
b00000000000000000000000000000011 $
|
||||
b00000000000000000000000011111100 %
|
||||
@@ -212,9 +216,10 @@ b11 7
|
||||
r0.3 <
|
||||
r0.6000000000000001 >
|
||||
r0.8999999999999999 @
|
||||
1D
|
||||
b00000000000000000000000000000011 B
|
||||
1E
|
||||
#35
|
||||
0D
|
||||
0E
|
||||
#40
|
||||
b00000000000000000000000000000100 $
|
||||
b00000000000000000000000011111011 %
|
||||
@@ -243,9 +248,10 @@ b00 7
|
||||
r0.4 <
|
||||
r0.8 >
|
||||
r1.2 @
|
||||
1D
|
||||
b00000000000000000000000000000100 B
|
||||
1E
|
||||
#45
|
||||
0D
|
||||
0E
|
||||
#50
|
||||
b00000000000000000000000000000101 $
|
||||
b00000000000000000000000011111010 %
|
||||
@@ -274,9 +280,10 @@ b11 7
|
||||
r0.5 <
|
||||
r1 >
|
||||
r1.5 @
|
||||
1D
|
||||
b00000000000000000000000000000101 B
|
||||
1E
|
||||
#55
|
||||
0D
|
||||
0E
|
||||
#60
|
||||
b00000000000000000000000000000110 $
|
||||
b00000000000000000000000011111001 %
|
||||
@@ -305,4 +312,5 @@ b00 7
|
||||
r0.6 <
|
||||
r1.2 >
|
||||
r1.8 @
|
||||
1D
|
||||
b00000000000000000000000000000110 B
|
||||
1E
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
$date
|
||||
Fri Oct 5 18:38:03 2018
|
||||
|
||||
$end
|
||||
$version
|
||||
fstWriter
|
||||
$end
|
||||
$timescale
|
||||
1ns
|
||||
$end
|
||||
$scope module top $end
|
||||
$var bit 1 ! clk $end
|
||||
$scope module t $end
|
||||
$var wire 1 ! clk $end
|
||||
$var integer 32 " cyc $end
|
||||
$scope module v_strp $end
|
||||
$var logic 1 # b1 $end
|
||||
$var logic 1 $ b0 $end
|
||||
$upscope $end
|
||||
$scope module v_strp_strp $end
|
||||
$scope module x1 $end
|
||||
$var logic 1 % b1 $end
|
||||
$var logic 1 & b0 $end
|
||||
$upscope $end
|
||||
$scope module x0 $end
|
||||
$var logic 1 ' b1 $end
|
||||
$var logic 1 ( b0 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module v_unip_strp $end
|
||||
$scope module x1 $end
|
||||
$var logic 1 ) b1 $end
|
||||
$var logic 1 * b0 $end
|
||||
$upscope $end
|
||||
$scope module x0 $end
|
||||
$var logic 1 ) b1 $end
|
||||
$var logic 1 * b0 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$var logic 2 + v_arrp $end
|
||||
$var logic 2 , v_arrp_arrp(3) $end
|
||||
$var logic 2 - v_arrp_arrp(4) $end
|
||||
$scope module v_arrp_strp(3) $end
|
||||
$var logic 1 . b1 $end
|
||||
$var logic 1 / b0 $end
|
||||
$upscope $end
|
||||
$scope module v_arrp_strp(4) $end
|
||||
$var logic 1 0 b1 $end
|
||||
$var logic 1 1 b0 $end
|
||||
$upscope $end
|
||||
$var logic 1 2 v_arru(1) $end
|
||||
$var logic 1 3 v_arru(2) $end
|
||||
$var logic 1 4 v_arru_arru(3)(1) $end
|
||||
$var logic 1 5 v_arru_arru(3)(2) $end
|
||||
$var logic 1 6 v_arru_arru(4)(1) $end
|
||||
$var logic 1 7 v_arru_arru(4)(2) $end
|
||||
$var logic 2 8 v_arru_arrp(3) $end
|
||||
$var logic 2 9 v_arru_arrp(4) $end
|
||||
$scope module v_arru_strp(3) $end
|
||||
$var logic 1 : b1 $end
|
||||
$var logic 1 ; b0 $end
|
||||
$upscope $end
|
||||
$scope module v_arru_strp(4) $end
|
||||
$var logic 1 < b1 $end
|
||||
$var logic 1 = b0 $end
|
||||
$upscope $end
|
||||
$var real 64 > v_real $end
|
||||
$var real 64 ? v_arr_real(0) $end
|
||||
$var real 64 @ v_arr_real(1) $end
|
||||
$scope module v_str32x2(0) $end
|
||||
$var logic 32 A data $end
|
||||
$upscope $end
|
||||
$scope module v_str32x2(1) $end
|
||||
$var logic 32 B data $end
|
||||
$upscope $end
|
||||
$var logic 32 C v_enumed $end
|
||||
$scope module unnamedblk1 $end
|
||||
$var integer 32 D b $end
|
||||
$scope module unnamedblk2 $end
|
||||
$var integer 32 E a $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module $unit $end
|
||||
$var bit 1 F global_bit $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$dumpvars
|
||||
0!
|
||||
b00000000000000000000000000000000 "
|
||||
0#
|
||||
0$
|
||||
0%
|
||||
0&
|
||||
0'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
b00 +
|
||||
b00 ,
|
||||
b00 -
|
||||
0.
|
||||
0/
|
||||
00
|
||||
01
|
||||
02
|
||||
03
|
||||
04
|
||||
05
|
||||
06
|
||||
07
|
||||
b00 8
|
||||
b00 9
|
||||
0:
|
||||
0;
|
||||
0<
|
||||
0=
|
||||
r0 >
|
||||
r0 ?
|
||||
r0 @
|
||||
b00000000000000000000000011111111 A
|
||||
b00000000000000000000000000000000 B
|
||||
b00000000000000000000000000000000 C
|
||||
b00000000000000000000000000000000 D
|
||||
b00000000000000000000000000000000 E
|
||||
1F
|
||||
#10
|
||||
b00000000000000000000000000000101 E
|
||||
b00000000000000000000000000000101 D
|
||||
b00000000000000000000000000000001 C
|
||||
b00000000000000000000000000000001 B
|
||||
b00000000000000000000000011111110 A
|
||||
r0.3 @
|
||||
r0.2 ?
|
||||
r0.1 >
|
||||
1=
|
||||
1<
|
||||
1;
|
||||
1:
|
||||
b11 9
|
||||
b11 8
|
||||
11
|
||||
10
|
||||
1/
|
||||
1.
|
||||
b11 -
|
||||
b11 ,
|
||||
b11 +
|
||||
1*
|
||||
1)
|
||||
1(
|
||||
1'
|
||||
1&
|
||||
1%
|
||||
1$
|
||||
1#
|
||||
b00000000000000000000000000000001 "
|
||||
1!
|
||||
#15
|
||||
0!
|
||||
#20
|
||||
1!
|
||||
b00000000000000000000000000000010 "
|
||||
0#
|
||||
0$
|
||||
0%
|
||||
0&
|
||||
0'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
b00 +
|
||||
b00 ,
|
||||
b00 -
|
||||
0.
|
||||
0/
|
||||
00
|
||||
01
|
||||
b00 8
|
||||
b00 9
|
||||
0:
|
||||
0;
|
||||
0<
|
||||
0=
|
||||
r0.2 >
|
||||
r0.4 ?
|
||||
r0.6 @
|
||||
b00000000000000000000000011111101 A
|
||||
b00000000000000000000000000000010 B
|
||||
b00000000000000000000000000000010 C
|
||||
b00000000000000000000000000000101 D
|
||||
b00000000000000000000000000000101 E
|
||||
#25
|
||||
0!
|
||||
#30
|
||||
1!
|
||||
b00000000000000000000000000000101 E
|
||||
b00000000000000000000000000000101 D
|
||||
b00000000000000000000000000000011 C
|
||||
b00000000000000000000000000000011 B
|
||||
b00000000000000000000000011111100 A
|
||||
r0.8999999999999999 @
|
||||
r0.6000000000000001 ?
|
||||
r0.3 >
|
||||
1=
|
||||
1<
|
||||
1;
|
||||
1:
|
||||
b11 9
|
||||
b11 8
|
||||
11
|
||||
10
|
||||
1/
|
||||
1.
|
||||
b11 -
|
||||
b11 ,
|
||||
b11 +
|
||||
1*
|
||||
1)
|
||||
1(
|
||||
1'
|
||||
1&
|
||||
1%
|
||||
1$
|
||||
1#
|
||||
b00000000000000000000000000000011 "
|
||||
#35
|
||||
0!
|
||||
#40
|
||||
1!
|
||||
b00000000000000000000000000000100 "
|
||||
0#
|
||||
0$
|
||||
0%
|
||||
0&
|
||||
0'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
b00 +
|
||||
b00 ,
|
||||
b00 -
|
||||
0.
|
||||
0/
|
||||
00
|
||||
01
|
||||
b00 8
|
||||
b00 9
|
||||
0:
|
||||
0;
|
||||
0<
|
||||
0=
|
||||
r0.4 >
|
||||
r0.8 ?
|
||||
r1.2 @
|
||||
b00000000000000000000000011111011 A
|
||||
b00000000000000000000000000000100 B
|
||||
b00000000000000000000000000000100 C
|
||||
b00000000000000000000000000000101 D
|
||||
b00000000000000000000000000000101 E
|
||||
#45
|
||||
0!
|
||||
#50
|
||||
1!
|
||||
b00000000000000000000000000000101 E
|
||||
b00000000000000000000000000000101 D
|
||||
b00000000000000000000000000000101 C
|
||||
b00000000000000000000000000000101 B
|
||||
b00000000000000000000000011111010 A
|
||||
r1.5 @
|
||||
r1 ?
|
||||
r0.5 >
|
||||
1=
|
||||
1<
|
||||
1;
|
||||
1:
|
||||
b11 9
|
||||
b11 8
|
||||
11
|
||||
10
|
||||
1/
|
||||
1.
|
||||
b11 -
|
||||
b11 ,
|
||||
b11 +
|
||||
1*
|
||||
1)
|
||||
1(
|
||||
1'
|
||||
1&
|
||||
1%
|
||||
1$
|
||||
1#
|
||||
b00000000000000000000000000000101 "
|
||||
#55
|
||||
0!
|
||||
#60
|
||||
1!
|
||||
b00000000000000000000000000000110 "
|
||||
0#
|
||||
0$
|
||||
0%
|
||||
0&
|
||||
0'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
b00 +
|
||||
b00 ,
|
||||
b00 -
|
||||
0.
|
||||
0/
|
||||
00
|
||||
01
|
||||
b00 8
|
||||
b00 9
|
||||
0:
|
||||
0;
|
||||
0<
|
||||
0=
|
||||
r0.6 >
|
||||
r1.2 ?
|
||||
r1.8 @
|
||||
b00000000000000000000000011111001 A
|
||||
b00000000000000000000000000000110 B
|
||||
b00000000000000000000000000000110 C
|
||||
b00000000000000000000000000000101 D
|
||||
b00000000000000000000000000000101 E
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2009 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t_trace_complex.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--cc --trace-fst --trace-structs --no-trace-params'],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
fst2vcd($Self->trace_filename, "$Self->{obj_dir}/simx-fst2vcd.vcd");
|
||||
vcd_identical("$Self->{obj_dir}/simx-fst2vcd.vcd", "t/$Self->{name}.out");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -1,5 +1,5 @@
|
||||
$date
|
||||
Tue Aug 28 15:07:10 2018
|
||||
Fri Oct 5 18:38:03 2018
|
||||
$end
|
||||
$version
|
||||
lxt2vcd
|
||||
@@ -47,38 +47,39 @@ $scope module v_arru_strp(4) $end
|
||||
$var wire 1 9 b0 $end
|
||||
$var wire 1 : b1 $end
|
||||
$upscope $end
|
||||
$var real 1 ; v_real $end
|
||||
$var wire 32 ; v_enumed [31:0] $end
|
||||
$var real 1 < v_real $end
|
||||
$scope module v_str32x2(0) $end
|
||||
$var wire 32 < data [31:0] $end
|
||||
$upscope $end
|
||||
$scope module v_str32x2(1) $end
|
||||
$var wire 32 = data [31:0] $end
|
||||
$upscope $end
|
||||
$scope module v_str32x2(1) $end
|
||||
$var wire 32 > data [31:0] $end
|
||||
$upscope $end
|
||||
$scope module v_strp $end
|
||||
$var wire 1 > b0 $end
|
||||
$var wire 1 ? b1 $end
|
||||
$var wire 1 ? b0 $end
|
||||
$var wire 1 @ b1 $end
|
||||
$upscope $end
|
||||
$scope module v_strp_strp $end
|
||||
$scope module x0 $end
|
||||
$var wire 1 @ b0 $end
|
||||
$var wire 1 A b1 $end
|
||||
$var wire 1 A b0 $end
|
||||
$var wire 1 B b1 $end
|
||||
$upscope $end
|
||||
$scope module x1 $end
|
||||
$var wire 1 B b0 $end
|
||||
$var wire 1 C b1 $end
|
||||
$var wire 1 C b0 $end
|
||||
$var wire 1 D b1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module v_unip_strp $end
|
||||
$scope module x1 $end
|
||||
$var wire 1 D b0 $end
|
||||
$var wire 1 E b1 $end
|
||||
$var wire 1 E b0 $end
|
||||
$var wire 1 F b1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$var wire 1 " clk $end
|
||||
$scope module v_unip_strp $end
|
||||
$scope module x0 $end
|
||||
$var wire 1 D b0 $end
|
||||
$var wire 1 E b1 $end
|
||||
$var wire 1 E b0 $end
|
||||
$var wire 1 F b1 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
@@ -112,10 +113,10 @@ b0 2
|
||||
08
|
||||
09
|
||||
0:
|
||||
r0 ;
|
||||
b11111111 <
|
||||
b0 =
|
||||
0>
|
||||
b0 ;
|
||||
r0 <
|
||||
b11111111 =
|
||||
b0 >
|
||||
0?
|
||||
0@
|
||||
0A
|
||||
@@ -123,7 +124,9 @@ b0 =
|
||||
0C
|
||||
0D
|
||||
0E
|
||||
0F
|
||||
#10
|
||||
1F
|
||||
1E
|
||||
1D
|
||||
1C
|
||||
@@ -131,10 +134,10 @@ b0 =
|
||||
1A
|
||||
1@
|
||||
1?
|
||||
1>
|
||||
b1 =
|
||||
b11111110 <
|
||||
r0.1 ;
|
||||
b1 >
|
||||
b11111110 =
|
||||
r0.1 <
|
||||
b1 ;
|
||||
1:
|
||||
19
|
||||
18
|
||||
@@ -174,10 +177,10 @@ b0 2
|
||||
08
|
||||
09
|
||||
0:
|
||||
r0.2 ;
|
||||
b11111101 <
|
||||
b10 =
|
||||
0>
|
||||
b10 ;
|
||||
r0.2 <
|
||||
b11111101 =
|
||||
b10 >
|
||||
0?
|
||||
0@
|
||||
0A
|
||||
@@ -185,10 +188,12 @@ b10 =
|
||||
0C
|
||||
0D
|
||||
0E
|
||||
0F
|
||||
#25
|
||||
0"
|
||||
#30
|
||||
1"
|
||||
1F
|
||||
1E
|
||||
1D
|
||||
1C
|
||||
@@ -196,10 +201,10 @@ b10 =
|
||||
1A
|
||||
1@
|
||||
1?
|
||||
1>
|
||||
b11 =
|
||||
b11111100 <
|
||||
r0.3 ;
|
||||
b11 >
|
||||
b11111100 =
|
||||
r0.3 <
|
||||
b11 ;
|
||||
1:
|
||||
19
|
||||
18
|
||||
@@ -236,10 +241,10 @@ b0 2
|
||||
08
|
||||
09
|
||||
0:
|
||||
r0.4 ;
|
||||
b11111011 <
|
||||
b100 =
|
||||
0>
|
||||
b100 ;
|
||||
r0.4 <
|
||||
b11111011 =
|
||||
b100 >
|
||||
0?
|
||||
0@
|
||||
0A
|
||||
@@ -247,10 +252,12 @@ b100 =
|
||||
0C
|
||||
0D
|
||||
0E
|
||||
0F
|
||||
#45
|
||||
0"
|
||||
#50
|
||||
1"
|
||||
1F
|
||||
1E
|
||||
1D
|
||||
1C
|
||||
@@ -258,10 +265,10 @@ b100 =
|
||||
1A
|
||||
1@
|
||||
1?
|
||||
1>
|
||||
b101 =
|
||||
b11111010 <
|
||||
r0.5 ;
|
||||
b101 >
|
||||
b11111010 =
|
||||
r0.5 <
|
||||
b101 ;
|
||||
1:
|
||||
19
|
||||
18
|
||||
@@ -298,10 +305,10 @@ b0 2
|
||||
08
|
||||
09
|
||||
0:
|
||||
r0.6 ;
|
||||
b11111001 <
|
||||
b110 =
|
||||
0>
|
||||
b110 ;
|
||||
r0.6 <
|
||||
b11111001 =
|
||||
b110 >
|
||||
0?
|
||||
0@
|
||||
0A
|
||||
@@ -309,3 +316,4 @@ b110 =
|
||||
0C
|
||||
0D
|
||||
0E
|
||||
0F
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
# This file ONLY is placed into the Public Domain, for any use,
|
||||
# Author: Yu-Sheng Lin [email protected]
|
||||
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
|
||||
scenarios(vlt_all => 1);
|
||||
|
||||
compile(
|
||||
v_flags2 => ["--trace-fst"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
fst2vcd($Self->trace_filename, "$Self->{obj_dir}/simx-fst2vcd.vcd");
|
||||
vcd_identical("$Self->{obj_dir}/simx-fst2vcd.vcd", "t/$Self->{name}.out");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// Author: Yu-Sheng Lin [email protected]
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
state,
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
|
||||
int cyc;
|
||||
reg rstn;
|
||||
output [4:0] state;
|
||||
|
||||
parameter real fst_gparam_real = 1.23;
|
||||
localparam real fst_lparam_real = 4.56;
|
||||
real fst_real = 1.23;
|
||||
integer fst_integer;
|
||||
bit fst_bit;
|
||||
logic fst_logic;
|
||||
int fst_int;
|
||||
shortint fst_shortint;
|
||||
longint fst_longint;
|
||||
byte fst_byte;
|
||||
|
||||
parameter fst_parameter = 123;
|
||||
localparam fst_lparam = 456;
|
||||
supply0 fst_supply0;
|
||||
supply1 fst_supply1;
|
||||
tri0 fst_tri0;
|
||||
tri1 fst_tri1;
|
||||
tri fst_tri;
|
||||
wire fst_wire;
|
||||
|
||||
Test test (/*AUTOINST*/
|
||||
// Outputs
|
||||
.state (state[4:0]),
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.rstn (rstn));
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
rstn <= ~'1;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
rstn <= ~'1;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
rstn <= ~'0;
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module Test (
|
||||
input clk,
|
||||
input rstn,
|
||||
output logic [4:0] state
|
||||
);
|
||||
|
||||
logic [4:0] state_w;
|
||||
logic [4:0] state_array [3];
|
||||
assign state = state_array[0];
|
||||
|
||||
always_comb begin
|
||||
state_w[4] = state_array[2][0];
|
||||
state_w[3] = state_array[2][4];
|
||||
state_w[2] = state_array[2][3] ^ state_array[2][0];
|
||||
state_w[1] = state_array[2][2];
|
||||
state_w[0] = state_array[2][1];
|
||||
end
|
||||
|
||||
always_ff @(posedge clk or negedge rstn) begin
|
||||
if (!rstn) begin
|
||||
for (int i = 0; i < 3; i++)
|
||||
state_array[i] <= 'b1;
|
||||
end
|
||||
else begin
|
||||
for (int i = 0; i < 2; i++)
|
||||
state_array[i] <= state_array[i+1];
|
||||
state_array[2] <= state_w;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,45 @@
|
||||
$date
|
||||
Thu Oct 4 19:33:41 2018
|
||||
|
||||
$end
|
||||
$version
|
||||
fstWriter
|
||||
$end
|
||||
$timescale
|
||||
1ns
|
||||
$end
|
||||
$scope module top $end
|
||||
$var bit 1 ! clk $end
|
||||
$scope module t $end
|
||||
$var wire 1 ! clk $end
|
||||
$var int 32 " cnt $end
|
||||
$var parameter 96 # v(0) $end
|
||||
$var parameter 96 $ v(1) $end
|
||||
$var parameter 96 % v(2) $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$dumpvars
|
||||
0!
|
||||
b00000000000000000000000000000000 "
|
||||
b001100000000000000000000000000100011000000000000000000000000000100110000000000000000000000000000 #
|
||||
b001000000000000000000000000000100010000000000000000000000000000100100000000000000000000000000000 $
|
||||
b000100000000000000000000000000100001000000000000000000000000000100010000000000000000000000000000 %
|
||||
#10
|
||||
b00000000000000000000000000000001 "
|
||||
1!
|
||||
#15
|
||||
0!
|
||||
#20
|
||||
1!
|
||||
b00000000000000000000000000000010 "
|
||||
#25
|
||||
0!
|
||||
#30
|
||||
1!
|
||||
b00000000000000000000000000000011 "
|
||||
#35
|
||||
0!
|
||||
#40
|
||||
1!
|
||||
b00000000000000000000000000000011 "
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_trace_packed_struct.v");
|
||||
|
||||
compile(
|
||||
v_flags2 => ["--trace-fst"]
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
fst2vcd($Self->trace_filename, "$Self->{obj_dir}/simx-fst2vcd.vcd");
|
||||
vcd_identical("$Self->{obj_dir}/simx-fst2vcd.vcd", "t/$Self->{name}.out");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2013 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.
|
||||
|
||||
scenarios(vlt_all => 1);
|
||||
|
||||
top_filename("t/t_trace_param.v");
|
||||
|
||||
compile(
|
||||
v_flags2 => ["--trace-fst"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2013 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_trace_primitive.v");
|
||||
|
||||
compile(
|
||||
v_flags2 => ["--trace-fst"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_trace_string.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--cc --trace'],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -50,6 +50,7 @@ foreach my $file (sort keys %hit) {
|
||||
if (!$hit{$file}
|
||||
&& $file !~ /_sc/
|
||||
&& $file !~ /_lxt2/
|
||||
&& $file !~ /_fst/
|
||||
&& ($file !~ /_thread/ || $Self->cfg_with_threaded)) {
|
||||
error("Include file not covered by t_verilated_all test: ",$file);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user