Compare commits

...
24 Commits
Author SHA1 Message Date
Wilson Snyder 4333c201f1 Version bump 2018-10-06 09:51:57 -04:00
Wilson Snyder 1f5913a83c Internals: V3Simulate refactoring prep for future work. No functional change. 2018-10-05 20:26:54 -04:00
Wilson Snyder 159c653b4b Internals: V3Simulate refactoring prep for future work. No functional change. 2018-10-05 20:06:08 -04:00
Wilson Snyder 47a2e2aeb9 Commentary 2018-10-05 18:47:46 -04:00
Wilson Snyder 98b0d19363 Tests: Add enum to trace test. 2018-10-05 18:38:52 -04:00
Wilson Snyder 24a0873f6d Commentary 2018-10-05 06:47:18 -04:00
Wilson Snyder c5fee7c456 Fix flex warning 2018-10-04 20:51:20 -04:00
Wilson Snyder d11592cadd Support signal types in FST dumps, bug1358. 2018-10-04 20:24:41 -04:00
Wilson Snyder 8ef9ac7dba Support in/out directions in FST dumps, bug1358. 2018-10-03 19:51:05 -04:00
Sergi Granell a5aa0e2b0a Add GTKWave FST native tracing, bug1356.
Signed-off-by: Wilson Snyder <[email protected]>
2018-10-02 18:42:53 -04:00
Wilson Snyder f8ae08c0c2 Internals: Fix whitespace. 2018-10-02 06:31:11 -04:00
Wilson Snyder 72f5d39ace Rename include/lxt2 to include/gtkwave. 2018-10-01 18:29:04 -04:00
Sergi Granell 5c9801d42c Commentary
Signed-off-by: Wilson Snyder <[email protected]>
2018-09-30 17:34:47 -04:00
Wilson Snyder c9ee425ed5 Fix replication of 64-bit signal change detects. 2018-09-28 08:36:37 -04:00
Wilson Snyder 1871e2b541 Commentary 2018-09-27 19:58:17 -04:00
Wilson Snyder 3e39c55a97 Tests: Check mod-prefix subnames. 2018-09-27 19:58:13 -04:00
Wilson Snyder e4d6fa0e3b include: Update license from GTKWave upstream. 2018-09-27 19:55:00 -04:00
Wilson Snyder 9f8dbc91f2 Support restrict, bug1350. 2018-09-23 15:20:12 -04:00
Wilson Snyder 0e37747d2c Support $past. 2018-09-23 15:20:01 -04:00
Wilson Snyder a8519a7a53 Fix MinGW compile issues, msg2636. 2018-09-20 18:09:19 -04:00
Kevin Kiningham d4159811d2 configure: Fix test for c++03 etc. 2018-09-17 21:47:35 -04:00
Kevin Kiningham b2ca4995ab Fix Mac OSX 10.13.6 / LLVM 9.1 compile issues, bug1348. 2018-09-17 18:35:23 -04:00
Wilson Snyder 7876fe94ad Fix Mac OSX 10.13.6 / LLVM 9.1 compile issues, bug1348. 2018-09-17 06:39:43 -04:00
Wilson Snyder cc9f7d1ac3 devel release 2018-09-17 06:24:18 -04:00
80 changed files with 13673 additions and 380 deletions
+19
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+547
View File
@@ -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) */
+107
View File
@@ -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 */
+12
View File
@@ -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
+432
View File
@@ -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
+360
View File
@@ -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
+42
View File
@@ -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
-29
View File
@@ -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
-1
View File
@@ -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
View File
@@ -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
};
//=========================================================================
+226
View File
@@ -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:
+217
View File
@@ -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
+1 -1
View File
@@ -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>
+7 -7
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 {
+9
View File
@@ -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());
+2
View File
@@ -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",
+3
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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];
}
+13
View File
@@ -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)
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+20
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+2
View File
@@ -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);
+1 -1
View File
@@ -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/;
+1
View File
@@ -8,6 +8,7 @@ module t;
endmodule
module sub;
//verilator no_inline_module
string scope;
initial begin
scope = $sformatf("%m");
+20
View File
@@ -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;
+98
View File
@@ -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
+22
View File
@@ -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;
+14
View File
@@ -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
+21
View File
@@ -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;
+14
View File
@@ -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
+26
View File
@@ -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;
+38 -30
View File
@@ -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:
+4
View File
@@ -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];
+213
View File
@@ -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
+26
View File
@@ -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;
+41 -33
View File
@@ -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 <
+38 -30
View File
@@ -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
+26
View File
@@ -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;
+41 -33
View File
@@ -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 <
+33 -25
View File
@@ -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
View File
@@ -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;
+51 -43
View File
@@ -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
+22
View File
@@ -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;
+96
View File
@@ -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 "
+26
View File
@@ -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;
+23
View File
@@ -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;
+23
View File
@@ -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;
+23
View File
@@ -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;
+1
View File
@@ -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);
}