Add GTKWave FST native tracing, bug1356.
Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
parent
f8ae08c0c2
commit
a5aa0e2b0a
3
Changes
3
Changes
|
@ -2,8 +2,11 @@ Revision history for Verilator
|
|||
|
||||
The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
|
||||
* Verilator 4.003 devel
|
||||
|
||||
** Add GTKWave FST native tracing, bug1356. [Sergi Granell]
|
||||
|
||||
*** Support $past. [Dan Gisselquist]
|
||||
|
||||
*** Support restrict, bug1350. [Clifford Wolf]
|
||||
|
|
|
@ -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 LXT2 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>,
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
@ -4127,6 +4134,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.
|
||||
|
@ -4146,10 +4170,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?
|
||||
|
||||
|
|
|
@ -0,0 +1,547 @@
|
|||
/*
|
||||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
||||
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
|
||||
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "fastlz.h"
|
||||
|
||||
#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
|
||||
|
||||
/*
|
||||
* Always check for bound when decompressing.
|
||||
* Generally it is best to leave it defined.
|
||||
*/
|
||||
#define FASTLZ_SAFE
|
||||
|
||||
|
||||
/*
|
||||
* Give hints to the compiler for branch prediction optimization.
|
||||
*/
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2)
|
||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
|
||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
|
||||
#else
|
||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
|
||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use inlined functions for supported systems.
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
|
||||
#define FASTLZ_INLINE inline
|
||||
#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
|
||||
#define FASTLZ_INLINE __inline
|
||||
#else
|
||||
#define FASTLZ_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prevent accessing more than 8-bit at once, except on x86 architectures.
|
||||
*/
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
#define FASTLZ_STRICT_ALIGN
|
||||
#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__amd64) /* GNU C */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(_M_IX86) /* Intel, MSVC */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__386)
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(_X86_) /* MinGW */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__I86__) /* Digital Mars */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* prototypes */
|
||||
int fastlz_compress(const void* input, int length, void* output);
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
|
||||
#define MAX_COPY 32
|
||||
#define MAX_LEN 264 /* 256 + 8 */
|
||||
#define MAX_DISTANCE 8192
|
||||
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
#define FASTLZ_READU16(p) *((const flzuint16*)(p))
|
||||
#else
|
||||
#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
|
||||
#endif
|
||||
|
||||
#define HASH_LOG 13
|
||||
#define HASH_SIZE (1<< HASH_LOG)
|
||||
#define HASH_MASK (HASH_SIZE-1)
|
||||
#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
|
||||
|
||||
#undef FASTLZ_LEVEL
|
||||
#define FASTLZ_LEVEL 1
|
||||
|
||||
#undef FASTLZ_COMPRESSOR
|
||||
#undef FASTLZ_DECOMPRESSOR
|
||||
#define FASTLZ_COMPRESSOR fastlz1_compress
|
||||
#define FASTLZ_DECOMPRESSOR fastlz1_decompress
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
|
||||
#include "fastlz.c"
|
||||
|
||||
#undef FASTLZ_LEVEL
|
||||
#define FASTLZ_LEVEL 2
|
||||
|
||||
#undef MAX_DISTANCE
|
||||
#define MAX_DISTANCE 8191
|
||||
#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
|
||||
|
||||
#undef FASTLZ_COMPRESSOR
|
||||
#undef FASTLZ_DECOMPRESSOR
|
||||
#define FASTLZ_COMPRESSOR fastlz2_compress
|
||||
#define FASTLZ_DECOMPRESSOR fastlz2_decompress
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
|
||||
#include "fastlz.c"
|
||||
|
||||
int fastlz_compress(const void* input, int length, void* output)
|
||||
{
|
||||
/* for short block, choose fastlz1 */
|
||||
if(length < 65536)
|
||||
return fastlz1_compress(input, length, output);
|
||||
|
||||
/* else... */
|
||||
return fastlz2_compress(input, length, output);
|
||||
}
|
||||
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout)
|
||||
{
|
||||
/* magic identifier for compression level */
|
||||
int level = ((*(const flzuint8*)input) >> 5) + 1;
|
||||
|
||||
if(level == 1)
|
||||
return fastlz1_decompress(input, length, output, maxout);
|
||||
if(level == 2)
|
||||
return fastlz2_decompress(input, length, output, maxout);
|
||||
|
||||
/* unknown level, trigger error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output)
|
||||
{
|
||||
if(level == 1)
|
||||
return fastlz1_compress(input, length, output);
|
||||
if(level == 2)
|
||||
return fastlz2_compress(input, length, output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
|
||||
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
|
||||
{
|
||||
const flzuint8* ip = (const flzuint8*) input;
|
||||
const flzuint8* ip_bound = ip + length - 2;
|
||||
const flzuint8* ip_limit = ip + length - 12;
|
||||
flzuint8* op = (flzuint8*) output;
|
||||
|
||||
const flzuint8* htab[HASH_SIZE];
|
||||
const flzuint8** hslot;
|
||||
flzuint32 hval;
|
||||
|
||||
flzuint32 copy;
|
||||
|
||||
/* sanity check */
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
|
||||
{
|
||||
if(length)
|
||||
{
|
||||
/* create literal copy only */
|
||||
*op++ = length-1;
|
||||
ip_bound++;
|
||||
while(ip <= ip_bound)
|
||||
*op++ = *ip++;
|
||||
return length+1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initializes hash table */
|
||||
for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
|
||||
*hslot = ip;
|
||||
|
||||
/* we start with literal copy */
|
||||
copy = 2;
|
||||
*op++ = MAX_COPY-1;
|
||||
*op++ = *ip++;
|
||||
*op++ = *ip++;
|
||||
|
||||
/* main loop */
|
||||
while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
|
||||
{
|
||||
const flzuint8* ref;
|
||||
flzuint32 distance;
|
||||
|
||||
/* minimum match length */
|
||||
flzuint32 len = 3;
|
||||
|
||||
/* comparison starting-point */
|
||||
const flzuint8* anchor = ip;
|
||||
|
||||
/* check for a run */
|
||||
#if FASTLZ_LEVEL==2
|
||||
if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
|
||||
{
|
||||
distance = 1;
|
||||
/* ip += 3; */ /* scan-build, never used */
|
||||
ref = anchor - 1 + 3;
|
||||
goto match;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* find potential match */
|
||||
HASH_FUNCTION(hval,ip);
|
||||
hslot = htab + hval;
|
||||
ref = htab[hval];
|
||||
|
||||
/* calculate distance to the match */
|
||||
distance = anchor - ref;
|
||||
|
||||
/* update hash table */
|
||||
*hslot = anchor;
|
||||
|
||||
/* is this a match? check the first 3 bytes */
|
||||
if(distance==0 ||
|
||||
#if FASTLZ_LEVEL==1
|
||||
(distance >= MAX_DISTANCE) ||
|
||||
#else
|
||||
(distance >= MAX_FARDISTANCE) ||
|
||||
#endif
|
||||
*ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
|
||||
goto literal;
|
||||
|
||||
#if FASTLZ_LEVEL==2
|
||||
/* far, needs at least 5-byte match */
|
||||
if(distance >= MAX_DISTANCE)
|
||||
{
|
||||
if(*ip++ != *ref++ || *ip++!= *ref++)
|
||||
goto literal;
|
||||
len += 2;
|
||||
}
|
||||
|
||||
match:
|
||||
#endif
|
||||
|
||||
/* last matched byte */
|
||||
ip = anchor + len;
|
||||
|
||||
/* distance is biased */
|
||||
distance--;
|
||||
|
||||
if(!distance)
|
||||
{
|
||||
/* zero distance means a run */
|
||||
flzuint8 x = ip[-1];
|
||||
while(ip < ip_bound)
|
||||
if(*ref++ != x) break; else ip++;
|
||||
}
|
||||
else
|
||||
for(;;)
|
||||
{
|
||||
/* safe because the outer check against ip limit */
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
while(ip < ip_bound)
|
||||
if(*ref++ != *ip++) break;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if we have copied something, adjust the copy count */
|
||||
if(copy)
|
||||
/* copy is biased, '0' means 1 byte copy */
|
||||
*(op-copy-1) = copy-1;
|
||||
else
|
||||
/* back, to overwrite the copy count */
|
||||
op--;
|
||||
|
||||
/* reset literal counter */
|
||||
copy = 0;
|
||||
|
||||
/* length is biased, '1' means a match of 3 bytes */
|
||||
ip -= 3;
|
||||
len = ip - anchor;
|
||||
|
||||
/* encode the match */
|
||||
#if FASTLZ_LEVEL==2
|
||||
if(distance < MAX_DISTANCE)
|
||||
{
|
||||
if(len < 7)
|
||||
{
|
||||
*op++ = (len << 5) + (distance >> 8);
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
for(len-=7; len >= 255; len-= 255)
|
||||
*op++ = 255;
|
||||
*op++ = len;
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* far away, but not yet in the another galaxy... */
|
||||
if(len < 7)
|
||||
{
|
||||
distance -= MAX_DISTANCE;
|
||||
*op++ = (len << 5) + 31;
|
||||
*op++ = 255;
|
||||
*op++ = distance >> 8;
|
||||
*op++ = distance & 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance -= MAX_DISTANCE;
|
||||
*op++ = (7 << 5) + 31;
|
||||
for(len-=7; len >= 255; len-= 255)
|
||||
*op++ = 255;
|
||||
*op++ = len;
|
||||
*op++ = 255;
|
||||
*op++ = distance >> 8;
|
||||
*op++ = distance & 255;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
|
||||
while(len > MAX_LEN-2)
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
*op++ = MAX_LEN - 2 - 7 -2;
|
||||
*op++ = (distance & 255);
|
||||
len -= MAX_LEN-2;
|
||||
}
|
||||
|
||||
if(len < 7)
|
||||
{
|
||||
*op++ = (len << 5) + (distance >> 8);
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
*op++ = len - 7;
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* update the hash at match boundary */
|
||||
HASH_FUNCTION(hval,ip);
|
||||
htab[hval] = ip++;
|
||||
HASH_FUNCTION(hval,ip);
|
||||
htab[hval] = ip++;
|
||||
|
||||
/* assuming literal copy */
|
||||
*op++ = MAX_COPY-1;
|
||||
|
||||
continue;
|
||||
|
||||
literal:
|
||||
*op++ = *anchor++;
|
||||
ip = anchor;
|
||||
copy++;
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
|
||||
{
|
||||
copy = 0;
|
||||
*op++ = MAX_COPY-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* left-over as literal copy */
|
||||
ip_bound++;
|
||||
while(ip <= ip_bound)
|
||||
{
|
||||
*op++ = *ip++;
|
||||
copy++;
|
||||
if(copy == MAX_COPY)
|
||||
{
|
||||
copy = 0;
|
||||
*op++ = MAX_COPY-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we have copied something, adjust the copy length */
|
||||
if(copy)
|
||||
*(op-copy-1) = copy-1;
|
||||
else
|
||||
op--;
|
||||
|
||||
#if FASTLZ_LEVEL==2
|
||||
/* marker for fastlz2 */
|
||||
*(flzuint8*)output |= (1 << 5);
|
||||
#endif
|
||||
|
||||
return op - (flzuint8*)output;
|
||||
}
|
||||
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
|
||||
{
|
||||
const flzuint8* ip = (const flzuint8*) input;
|
||||
const flzuint8* ip_limit = ip + length;
|
||||
flzuint8* op = (flzuint8*) output;
|
||||
flzuint8* op_limit = op + maxout;
|
||||
flzuint32 ctrl = (*ip++) & 31;
|
||||
int loop = 1;
|
||||
|
||||
do
|
||||
{
|
||||
const flzuint8* ref = op;
|
||||
flzuint32 len = ctrl >> 5;
|
||||
flzuint32 ofs = (ctrl & 31) << 8;
|
||||
|
||||
if(ctrl >= 32)
|
||||
{
|
||||
#if FASTLZ_LEVEL==2
|
||||
flzuint8 code;
|
||||
#endif
|
||||
len--;
|
||||
ref -= ofs;
|
||||
if (len == 7-1)
|
||||
#if FASTLZ_LEVEL==1
|
||||
len += *ip++;
|
||||
ref -= *ip++;
|
||||
#else
|
||||
do
|
||||
{
|
||||
code = *ip++;
|
||||
len += code;
|
||||
} while (code==255);
|
||||
code = *ip++;
|
||||
ref -= code;
|
||||
|
||||
/* match from 16-bit distance */
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
|
||||
if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
|
||||
{
|
||||
ofs = (*ip++) << 8;
|
||||
ofs += *ip++;
|
||||
ref = op - ofs - MAX_DISTANCE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FASTLZ_SAFE
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
|
||||
return 0;
|
||||
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
|
||||
ctrl = *ip++;
|
||||
else
|
||||
loop = 0;
|
||||
|
||||
if(ref == op)
|
||||
{
|
||||
/* optimize copy for a run */
|
||||
flzuint8 b = ref[-1];
|
||||
*op++ = b;
|
||||
*op++ = b;
|
||||
*op++ = b;
|
||||
for(; len; --len)
|
||||
*op++ = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
const flzuint16* p;
|
||||
flzuint16* q;
|
||||
#endif
|
||||
/* copy from reference */
|
||||
ref--;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
/* copy a byte, so that now it's word aligned */
|
||||
if(len & 1)
|
||||
{
|
||||
*op++ = *ref++;
|
||||
len--;
|
||||
}
|
||||
|
||||
/* copy 16-bit at once */
|
||||
q = (flzuint16*) op;
|
||||
op += len;
|
||||
p = (const flzuint16*) ref;
|
||||
for(len>>=1; len > 4; len-=4)
|
||||
{
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
}
|
||||
for(; len; --len)
|
||||
*q++ = *p++;
|
||||
#else
|
||||
for(; len; --len)
|
||||
*op++ = *ref++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl++;
|
||||
#ifdef FASTLZ_SAFE
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
|
||||
return 0;
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
*op++ = *ip++;
|
||||
for(--ctrl; ctrl; ctrl--)
|
||||
*op++ = *ip++;
|
||||
|
||||
loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
|
||||
if(loop)
|
||||
ctrl = *ip++;
|
||||
}
|
||||
}
|
||||
while(FASTLZ_EXPECT_CONDITIONAL(loop));
|
||||
|
||||
return op - (flzuint8*)output;
|
||||
}
|
||||
|
||||
#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
||||
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
|
||||
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FASTLZ_H
|
||||
#define FASTLZ_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define flzuint8 uint8_t
|
||||
#define flzuint16 uint16_t
|
||||
#define flzuint32 uint32_t
|
||||
|
||||
|
||||
#define FASTLZ_VERSION 0x000100
|
||||
|
||||
#define FASTLZ_VERSION_MAJOR 0
|
||||
#define FASTLZ_VERSION_MINOR 0
|
||||
#define FASTLZ_VERSION_REVISION 0
|
||||
|
||||
#define FASTLZ_VERSION_STRING "0.1.0"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
minimum input buffer size is 16.
|
||||
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
and can not be smaller than 66 bytes.
|
||||
|
||||
If the input is not compressible, the return value might be larger than
|
||||
length (input buffer size).
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
*/
|
||||
|
||||
int fastlz_compress(const void* input, int length, void* output);
|
||||
|
||||
/**
|
||||
Decompress a block of compressed data and returns the size of the
|
||||
decompressed block. If error occurs, e.g. the compressed data is
|
||||
corrupted or the output buffer is not large enough, then 0 (zero)
|
||||
will be returned instead.
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
|
||||
Decompression is memory safe and guaranteed not to write the output buffer
|
||||
more than what is specified in maxout.
|
||||
*/
|
||||
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
|
||||
/**
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
minimum input buffer size is 16.
|
||||
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
and can not be smaller than 66 bytes.
|
||||
|
||||
If the input is not compressible, the return value might be larger than
|
||||
length (input buffer size).
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
|
||||
Compression level can be specified in parameter level. At the moment,
|
||||
only level 1 and level 2 are supported.
|
||||
Level 1 is the fastest compression and generally useful for short data.
|
||||
Level 2 is slightly slower but it gives better compression ratio.
|
||||
|
||||
Note that the compressed data, regardless of the level, can always be
|
||||
decompressed using the function fastlz_decompress above.
|
||||
*/
|
||||
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FASTLZ_H */
|
|
@ -0,0 +1,12 @@
|
|||
/* This file specifically for FST usage */
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#define HAVE_ALLOCA 1
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#define HAVE_ALLOCA_H 1
|
||||
|
||||
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
|
||||
#define HAVE_FSEEKO 1
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2017 Tony Bybell.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FST_API_H
|
||||
#define FST_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <zlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#define FST_RDLOAD "FSTLOAD | "
|
||||
|
||||
typedef uint32_t fstHandle;
|
||||
|
||||
enum fstWriterPackType {
|
||||
FST_WR_PT_ZLIB = 0,
|
||||
FST_WR_PT_FASTLZ = 1,
|
||||
FST_WR_PT_LZ4 = 2
|
||||
};
|
||||
|
||||
enum fstFileType {
|
||||
FST_FT_MIN = 0,
|
||||
|
||||
FST_FT_VERILOG = 0,
|
||||
FST_FT_VHDL = 1,
|
||||
FST_FT_VERILOG_VHDL = 2,
|
||||
|
||||
FST_FT_MAX = 2
|
||||
};
|
||||
|
||||
enum fstBlockType {
|
||||
FST_BL_HDR = 0,
|
||||
FST_BL_VCDATA = 1,
|
||||
FST_BL_BLACKOUT = 2,
|
||||
FST_BL_GEOM = 3,
|
||||
FST_BL_HIER = 4,
|
||||
FST_BL_VCDATA_DYN_ALIAS = 5,
|
||||
FST_BL_HIER_LZ4 = 6,
|
||||
FST_BL_HIER_LZ4DUO = 7,
|
||||
FST_BL_VCDATA_DYN_ALIAS2 = 8,
|
||||
|
||||
FST_BL_ZWRAPPER = 254, /* indicates that whole trace is gz wrapped */
|
||||
FST_BL_SKIP = 255 /* used while block is being written */
|
||||
};
|
||||
|
||||
enum fstScopeType {
|
||||
FST_ST_MIN = 0,
|
||||
|
||||
FST_ST_VCD_MODULE = 0,
|
||||
FST_ST_VCD_TASK = 1,
|
||||
FST_ST_VCD_FUNCTION = 2,
|
||||
FST_ST_VCD_BEGIN = 3,
|
||||
FST_ST_VCD_FORK = 4,
|
||||
FST_ST_VCD_GENERATE = 5,
|
||||
FST_ST_VCD_STRUCT = 6,
|
||||
FST_ST_VCD_UNION = 7,
|
||||
FST_ST_VCD_CLASS = 8,
|
||||
FST_ST_VCD_INTERFACE = 9,
|
||||
FST_ST_VCD_PACKAGE = 10,
|
||||
FST_ST_VCD_PROGRAM = 11,
|
||||
|
||||
FST_ST_VHDL_ARCHITECTURE = 12,
|
||||
FST_ST_VHDL_PROCEDURE = 13,
|
||||
FST_ST_VHDL_FUNCTION = 14,
|
||||
FST_ST_VHDL_RECORD = 15,
|
||||
FST_ST_VHDL_PROCESS = 16,
|
||||
FST_ST_VHDL_BLOCK = 17,
|
||||
FST_ST_VHDL_FOR_GENERATE = 18,
|
||||
FST_ST_VHDL_IF_GENERATE = 19,
|
||||
FST_ST_VHDL_GENERATE = 20,
|
||||
FST_ST_VHDL_PACKAGE = 21,
|
||||
|
||||
FST_ST_MAX = 21,
|
||||
|
||||
FST_ST_GEN_ATTRBEGIN = 252,
|
||||
FST_ST_GEN_ATTREND = 253,
|
||||
|
||||
FST_ST_VCD_SCOPE = 254,
|
||||
FST_ST_VCD_UPSCOPE = 255
|
||||
};
|
||||
|
||||
enum fstVarType {
|
||||
FST_VT_MIN = 0, /* start of vartypes */
|
||||
|
||||
FST_VT_VCD_EVENT = 0,
|
||||
FST_VT_VCD_INTEGER = 1,
|
||||
FST_VT_VCD_PARAMETER = 2,
|
||||
FST_VT_VCD_REAL = 3,
|
||||
FST_VT_VCD_REAL_PARAMETER = 4,
|
||||
FST_VT_VCD_REG = 5,
|
||||
FST_VT_VCD_SUPPLY0 = 6,
|
||||
FST_VT_VCD_SUPPLY1 = 7,
|
||||
FST_VT_VCD_TIME = 8,
|
||||
FST_VT_VCD_TRI = 9,
|
||||
FST_VT_VCD_TRIAND = 10,
|
||||
FST_VT_VCD_TRIOR = 11,
|
||||
FST_VT_VCD_TRIREG = 12,
|
||||
FST_VT_VCD_TRI0 = 13,
|
||||
FST_VT_VCD_TRI1 = 14,
|
||||
FST_VT_VCD_WAND = 15,
|
||||
FST_VT_VCD_WIRE = 16,
|
||||
FST_VT_VCD_WOR = 17,
|
||||
FST_VT_VCD_PORT = 18,
|
||||
FST_VT_VCD_SPARRAY = 19, /* used to define the rownum (index) port for a sparse array */
|
||||
FST_VT_VCD_REALTIME = 20,
|
||||
|
||||
FST_VT_GEN_STRING = 21, /* generic string type (max len is defined dynamically via fstWriterEmitVariableLengthValueChange) */
|
||||
|
||||
FST_VT_SV_BIT = 22,
|
||||
FST_VT_SV_LOGIC = 23,
|
||||
FST_VT_SV_INT = 24, /* declare as size = 32 */
|
||||
FST_VT_SV_SHORTINT = 25, /* declare as size = 16 */
|
||||
FST_VT_SV_LONGINT = 26, /* declare as size = 64 */
|
||||
FST_VT_SV_BYTE = 27, /* declare as size = 8 */
|
||||
FST_VT_SV_ENUM = 28, /* declare as appropriate type range */
|
||||
FST_VT_SV_SHORTREAL = 29, /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */
|
||||
|
||||
FST_VT_MAX = 29 /* end of vartypes */
|
||||
};
|
||||
|
||||
enum fstVarDir {
|
||||
FST_VD_MIN = 0,
|
||||
|
||||
FST_VD_IMPLICIT = 0,
|
||||
FST_VD_INPUT = 1,
|
||||
FST_VD_OUTPUT = 2,
|
||||
FST_VD_INOUT = 3,
|
||||
FST_VD_BUFFER = 4,
|
||||
FST_VD_LINKAGE = 5,
|
||||
|
||||
FST_VD_MAX = 5
|
||||
};
|
||||
|
||||
enum fstHierType {
|
||||
FST_HT_MIN = 0,
|
||||
|
||||
FST_HT_SCOPE = 0,
|
||||
FST_HT_UPSCOPE = 1,
|
||||
FST_HT_VAR = 2,
|
||||
FST_HT_ATTRBEGIN = 3,
|
||||
FST_HT_ATTREND = 4,
|
||||
|
||||
/* FST_HT_TREEBEGIN and FST_HT_TREEEND are not yet used by FST but are currently used when fstHier bridges other formats */
|
||||
FST_HT_TREEBEGIN = 5,
|
||||
FST_HT_TREEEND = 6,
|
||||
|
||||
FST_HT_MAX = 6
|
||||
};
|
||||
|
||||
enum fstAttrType {
|
||||
FST_AT_MIN = 0,
|
||||
|
||||
FST_AT_MISC = 0, /* self-contained: does not need matching FST_HT_ATTREND */
|
||||
FST_AT_ARRAY = 1,
|
||||
FST_AT_ENUM = 2,
|
||||
FST_AT_PACK = 3,
|
||||
|
||||
FST_AT_MAX = 3
|
||||
};
|
||||
|
||||
enum fstMiscType {
|
||||
FST_MT_MIN = 0,
|
||||
|
||||
FST_MT_COMMENT = 0, /* use fstWriterSetComment() to emit */
|
||||
FST_MT_ENVVAR = 1, /* use fstWriterSetEnvVar() to emit */
|
||||
FST_MT_SUPVAR = 2, /* use fstWriterCreateVar2() to emit */
|
||||
FST_MT_PATHNAME = 3, /* reserved for fstWriterSetSourceStem() string -> number management */
|
||||
FST_MT_SOURCESTEM = 4, /* use fstWriterSetSourceStem() to emit */
|
||||
FST_MT_SOURCEISTEM = 5, /* use fstWriterSetSourceInstantiationStem() to emit */
|
||||
FST_MT_VALUELIST = 6, /* use fstWriterSetValueList() to emit, followed by fstWriterCreateVar*() */
|
||||
FST_MT_UNKNOWN = 7,
|
||||
|
||||
FST_MT_MAX = 7
|
||||
};
|
||||
|
||||
enum fstArrayType {
|
||||
FST_AR_MIN = 0,
|
||||
|
||||
FST_AR_NONE = 0,
|
||||
FST_AR_UNPACKED = 1,
|
||||
FST_AR_PACKED = 2,
|
||||
FST_AR_SPARSE = 3,
|
||||
|
||||
FST_AR_MAX = 3
|
||||
};
|
||||
|
||||
enum fstEnumValueType {
|
||||
FST_EV_SV_INTEGER = 0,
|
||||
FST_EV_SV_BIT = 1,
|
||||
FST_EV_SV_LOGIC = 2,
|
||||
FST_EV_SV_INT = 3,
|
||||
FST_EV_SV_SHORTINT = 4,
|
||||
FST_EV_SV_LONGINT = 5,
|
||||
FST_EV_SV_BYTE = 6,
|
||||
FST_EV_SV_UNSIGNED_INTEGER = 7,
|
||||
FST_EV_SV_UNSIGNED_BIT = 8,
|
||||
FST_EV_SV_UNSIGNED_LOGIC = 9,
|
||||
FST_EV_SV_UNSIGNED_INT = 10,
|
||||
FST_EV_SV_UNSIGNED_SHORTINT = 11,
|
||||
FST_EV_SV_UNSIGNED_LONGINT = 12,
|
||||
FST_EV_SV_UNSIGNED_BYTE = 13,
|
||||
|
||||
FST_EV_MAX = 13
|
||||
};
|
||||
|
||||
enum fstPackType {
|
||||
FST_PT_NONE = 0,
|
||||
FST_PT_UNPACKED = 1,
|
||||
FST_PT_PACKED = 2,
|
||||
FST_PT_TAGGED_PACKED = 3,
|
||||
|
||||
FST_PT_MAX = 3
|
||||
};
|
||||
|
||||
enum fstSupplementalVarType {
|
||||
FST_SVT_MIN = 0,
|
||||
|
||||
FST_SVT_NONE = 0,
|
||||
|
||||
FST_SVT_VHDL_SIGNAL = 1,
|
||||
FST_SVT_VHDL_VARIABLE = 2,
|
||||
FST_SVT_VHDL_CONSTANT = 3,
|
||||
FST_SVT_VHDL_FILE = 4,
|
||||
FST_SVT_VHDL_MEMORY = 5,
|
||||
|
||||
FST_SVT_MAX = 5
|
||||
};
|
||||
|
||||
enum fstSupplementalDataType {
|
||||
FST_SDT_MIN = 0,
|
||||
|
||||
FST_SDT_NONE = 0,
|
||||
|
||||
FST_SDT_VHDL_BOOLEAN = 1,
|
||||
FST_SDT_VHDL_BIT = 2,
|
||||
FST_SDT_VHDL_BIT_VECTOR = 3,
|
||||
FST_SDT_VHDL_STD_ULOGIC = 4,
|
||||
FST_SDT_VHDL_STD_ULOGIC_VECTOR = 5,
|
||||
FST_SDT_VHDL_STD_LOGIC = 6,
|
||||
FST_SDT_VHDL_STD_LOGIC_VECTOR = 7,
|
||||
FST_SDT_VHDL_UNSIGNED = 8,
|
||||
FST_SDT_VHDL_SIGNED = 9,
|
||||
FST_SDT_VHDL_INTEGER = 10,
|
||||
FST_SDT_VHDL_REAL = 11,
|
||||
FST_SDT_VHDL_NATURAL = 12,
|
||||
FST_SDT_VHDL_POSITIVE = 13,
|
||||
FST_SDT_VHDL_TIME = 14,
|
||||
FST_SDT_VHDL_CHARACTER = 15,
|
||||
FST_SDT_VHDL_STRING = 16,
|
||||
|
||||
FST_SDT_MAX = 16,
|
||||
|
||||
FST_SDT_SVT_SHIFT_COUNT = 10, /* FST_SVT_* is ORed in by fstWriterCreateVar2() to the left after shifting FST_SDT_SVT_SHIFT_COUNT */
|
||||
FST_SDT_ABS_MAX = ((1<<(FST_SDT_SVT_SHIFT_COUNT))-1)
|
||||
};
|
||||
|
||||
|
||||
struct fstHier
|
||||
{
|
||||
unsigned char htyp;
|
||||
|
||||
union {
|
||||
/* if htyp == FST_HT_SCOPE */
|
||||
struct fstHierScope {
|
||||
unsigned char typ; /* FST_ST_MIN ... FST_ST_MAX */
|
||||
const char *name;
|
||||
const char *component;
|
||||
uint32_t name_length; /* strlen(u.scope.name) */
|
||||
uint32_t component_length; /* strlen(u.scope.component) */
|
||||
} scope;
|
||||
|
||||
/* if htyp == FST_HT_VAR */
|
||||
struct fstHierVar {
|
||||
unsigned char typ; /* FST_VT_MIN ... FST_VT_MAX */
|
||||
unsigned char direction; /* FST_VD_MIN ... FST_VD_MAX */
|
||||
unsigned char svt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
unsigned char sdt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
unsigned int sxt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
const char *name;
|
||||
uint32_t length;
|
||||
fstHandle handle;
|
||||
uint32_t name_length; /* strlen(u.var.name) */
|
||||
unsigned is_alias : 1;
|
||||
} var;
|
||||
|
||||
/* if htyp == FST_HT_ATTRBEGIN */
|
||||
struct fstHierAttr {
|
||||
unsigned char typ; /* FST_AT_MIN ... FST_AT_MAX */
|
||||
unsigned char subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */
|
||||
const char *name;
|
||||
uint64_t arg; /* number of array elements, struct members, or some other payload (possibly ignored) */
|
||||
uint64_t arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */
|
||||
uint32_t name_length; /* strlen(u.attr.name) */
|
||||
} attr;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* writer functions
|
||||
*/
|
||||
void fstWriterClose(void *ctx);
|
||||
void * fstWriterCreate(const char *nam, int use_compressed_hier);
|
||||
/* used for Verilog/SV */
|
||||
fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle);
|
||||
/* future expansion for VHDL and other languages. The variable type, data type, etc map onto
|
||||
the current Verilog/SV one. The "type" string is optional for a more verbose or custom description */
|
||||
fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle,
|
||||
const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt);
|
||||
void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val);
|
||||
void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len);
|
||||
void fstWriterEmitDumpActive(void *ctx, int enable);
|
||||
void fstWriterEmitTimeChange(void *ctx, uint64_t tim);
|
||||
void fstWriterFlushContext(void *ctx);
|
||||
int fstWriterGetDumpSizeLimitReached(void *ctx);
|
||||
int fstWriterGetFseekFailed(void *ctx);
|
||||
void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype,
|
||||
const char *attrname, uint64_t arg);
|
||||
void fstWriterSetAttrEnd(void *ctx);
|
||||
void fstWriterSetComment(void *ctx, const char *comm);
|
||||
void fstWriterSetDate(void *ctx, const char *dat);
|
||||
void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes);
|
||||
void fstWriterSetEnvVar(void *ctx, const char *envvar);
|
||||
void fstWriterSetFileType(void *ctx, enum fstFileType filetype);
|
||||
void fstWriterSetPackType(void *ctx, enum fstWriterPackType typ);
|
||||
void fstWriterSetParallelMode(void *ctx, int enable);
|
||||
void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */
|
||||
void fstWriterSetScope(void *ctx, enum fstScopeType scopetype,
|
||||
const char *scopename, const char *scopecomp);
|
||||
void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
|
||||
void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
|
||||
void fstWriterSetTimescale(void *ctx, int ts);
|
||||
void fstWriterSetTimescaleFromString(void *ctx, const char *s);
|
||||
void fstWriterSetTimezero(void *ctx, int64_t tim);
|
||||
void fstWriterSetUpscope(void *ctx);
|
||||
void fstWriterSetValueList(void *ctx, const char *vl);
|
||||
void fstWriterSetVersion(void *ctx, const char *vers);
|
||||
|
||||
|
||||
/*
|
||||
* reader functions
|
||||
*/
|
||||
void fstReaderClose(void *ctx);
|
||||
void fstReaderClrFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderClrFacProcessMaskAll(void *ctx);
|
||||
uint64_t fstReaderGetAliasCount(void *ctx);
|
||||
const char * fstReaderGetCurrentFlatScope(void *ctx);
|
||||
void * fstReaderGetCurrentScopeUserInfo(void *ctx);
|
||||
int fstReaderGetCurrentScopeLen(void *ctx);
|
||||
const char * fstReaderGetDateString(void *ctx);
|
||||
int fstReaderGetDoubleEndianMatchState(void *ctx);
|
||||
uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx);
|
||||
unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx);
|
||||
uint64_t fstReaderGetEndTime(void *ctx);
|
||||
int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx);
|
||||
int fstReaderGetFileType(void *ctx);
|
||||
int fstReaderGetFseekFailed(void *ctx);
|
||||
fstHandle fstReaderGetMaxHandle(void *ctx);
|
||||
uint64_t fstReaderGetMemoryUsedByWriter(void *ctx);
|
||||
uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx);
|
||||
uint64_t fstReaderGetScopeCount(void *ctx);
|
||||
uint64_t fstReaderGetStartTime(void *ctx);
|
||||
signed char fstReaderGetTimescale(void *ctx);
|
||||
int64_t fstReaderGetTimezero(void *ctx);
|
||||
uint64_t fstReaderGetValueChangeSectionCount(void *ctx);
|
||||
char * fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf);
|
||||
uint64_t fstReaderGetVarCount(void *ctx);
|
||||
const char * fstReaderGetVersionString(void *ctx);
|
||||
struct fstHier *fstReaderIterateHier(void *ctx);
|
||||
int fstReaderIterateHierRewind(void *ctx);
|
||||
int fstReaderIterBlocks(void *ctx,
|
||||
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
|
||||
void *user_callback_data_pointer, FILE *vcdhandle);
|
||||
int fstReaderIterBlocks2(void *ctx,
|
||||
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
|
||||
void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len),
|
||||
void *user_callback_data_pointer, FILE *vcdhandle);
|
||||
void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable);
|
||||
void * fstReaderOpen(const char *nam);
|
||||
void * fstReaderOpenForUtilitiesOnly(void);
|
||||
const char * fstReaderPopScope(void *ctx);
|
||||
int fstReaderProcessHier(void *ctx, FILE *vcdhandle);
|
||||
const char * fstReaderPushScope(void *ctx, const char *nam, void *user_info);
|
||||
void fstReaderResetScope(void *ctx);
|
||||
void fstReaderSetFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderSetFacProcessMaskAll(void *ctx);
|
||||
void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time);
|
||||
void fstReaderSetUnlimitedTimeRange(void *ctx);
|
||||
void fstReaderSetVcdExtensions(void *ctx, int enable);
|
||||
|
||||
|
||||
/*
|
||||
* utility functions
|
||||
*/
|
||||
int fstUtilityBinToEsc(unsigned char *d, unsigned char *s, int len);
|
||||
int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -27,6 +27,7 @@
|
|||
#include "lxt2_config.h"
|
||||
#include "lxt2_write.h"
|
||||
|
||||
|
||||
static char *lxt2_wr_vcd_truncate_bitvec(char *s)
|
||||
{
|
||||
char l, r;
|
||||
|
@ -96,7 +97,7 @@ if (lo<hi)
|
|||
|
||||
static void wave_msort(struct lxt2_wr_symbol **a, int num)
|
||||
{
|
||||
struct lxt2_wr_symbol **b = (lxt2_wr_symbol**)malloc(((num/2)+1) * sizeof(struct lxt2_wr_symbol *));
|
||||
struct lxt2_wr_symbol **b = (struct lxt2_wr_symbol**)malloc(((num/2)+1) * sizeof(struct lxt2_wr_symbol *));
|
||||
|
||||
wave_mergesort(a, b, 0, num-1);
|
||||
|
||||
|
@ -582,7 +583,7 @@ unsigned int i;
|
|||
if((lt)&&(lt->numfacs))
|
||||
{
|
||||
struct lxt2_wr_symbol *s = lt->symchain;
|
||||
struct lxt2_wr_symbol **aliascache = (lxt2_wr_symbol**)calloc(lt->numalias ? lt->numalias : 1, sizeof(struct lxt2_wr_symbol *));
|
||||
struct lxt2_wr_symbol **aliascache = (struct lxt2_wr_symbol**)calloc(lt->numalias ? lt->numalias : 1, sizeof(struct lxt2_wr_symbol *));
|
||||
unsigned int aliases_encountered, facs_encountered;
|
||||
|
||||
lt->sorted_facs = (struct lxt2_wr_symbol **)calloc(lt->numfacs, sizeof(struct lxt2_wr_symbol *));
|
||||
|
@ -2100,7 +2101,7 @@ if((lt)&&(lt->blackout))
|
|||
{
|
||||
if((!(s->flags&LXT2_WR_SYM_F_ALIAS))&&(s->rows<2))
|
||||
{
|
||||
char tmp[16]; // To get rid of the warning
|
||||
char tmp[16]; /* To get rid of the warning */
|
||||
if(!(s->flags&(LXT2_WR_SYM_F_DOUBLE|LXT2_WR_SYM_F_STRING)))
|
||||
{
|
||||
strcpy(tmp, "x");
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
LZ4 - Fast LZ compression algorithm
|
||||
Header File
|
||||
Copyright (C) 2011-2015, Yann Collet.
|
||||
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 source repository : https://github.com/Cyan4973/lz4
|
||||
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* lz4.h provides block compression functions, and gives full buffer control to programmer.
|
||||
* If you need to generate inter-operable compressed data (respecting LZ4 frame specification),
|
||||
* and can let the library handle its own memory, please use lz4frame.h instead.
|
||||
*/
|
||||
|
||||
/**************************************
|
||||
* Version
|
||||
**************************************/
|
||||
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
|
||||
#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */
|
||||
#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */
|
||||
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
|
||||
int LZ4_versionNumber (void);
|
||||
|
||||
/**************************************
|
||||
* Tuning parameter
|
||||
**************************************/
|
||||
/*
|
||||
* LZ4_MEMORY_USAGE :
|
||||
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
|
||||
* Increasing memory usage improves compression ratio
|
||||
* Reduced memory usage can improve speed, due to cache effect
|
||||
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
|
||||
*/
|
||||
#define LZ4_MEMORY_USAGE 14
|
||||
|
||||
|
||||
/**************************************
|
||||
* Simple Functions
|
||||
**************************************/
|
||||
|
||||
int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize);
|
||||
int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
|
||||
|
||||
/*
|
||||
LZ4_compress_default() :
|
||||
Compresses 'sourceSize' bytes from buffer 'source'
|
||||
into already allocated 'dest' buffer of size 'maxDestSize'.
|
||||
Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize).
|
||||
It also runs faster, so it's a recommended setting.
|
||||
If the function cannot compress 'source' into a more limited 'dest' budget,
|
||||
compression stops *immediately*, and the function result is zero.
|
||||
As a consequence, 'dest' content is not valid.
|
||||
This function never writes outside 'dest' buffer, nor read outside 'source' buffer.
|
||||
sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE
|
||||
maxDestSize : full or partial size of buffer 'dest' (which must be already allocated)
|
||||
return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize)
|
||||
or 0 if compression fails
|
||||
|
||||
LZ4_decompress_safe() :
|
||||
compressedSize : is the precise full size of the compressed block.
|
||||
maxDecompressedSize : is the size of destination buffer, which must be already allocated.
|
||||
return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize)
|
||||
If destination buffer is not large enough, decoding will stop and output an error code (<0).
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
This function is protected against buffer overflow exploits, including malicious data packets.
|
||||
It never writes outside output buffer, nor reads outside input buffer.
|
||||
*/
|
||||
|
||||
|
||||
/**************************************
|
||||
* Advanced Functions
|
||||
**************************************/
|
||||
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
|
||||
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
|
||||
|
||||
/*
|
||||
LZ4_compressBound() :
|
||||
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
|
||||
This function is primarily useful for memory allocation purposes (destination buffer size).
|
||||
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
|
||||
Note that LZ4_compress_default() compress faster when dest buffer size is >= LZ4_compressBound(srcSize)
|
||||
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
|
||||
return : maximum output size in a "worst case" scenario
|
||||
or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
|
||||
*/
|
||||
int LZ4_compressBound(int inputSize);
|
||||
|
||||
/*
|
||||
LZ4_compress_fast() :
|
||||
Same as LZ4_compress_default(), but allows to select an "acceleration" factor.
|
||||
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
|
||||
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
|
||||
An acceleration value of "1" is the same as regular LZ4_compress_default()
|
||||
Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1.
|
||||
*/
|
||||
int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration);
|
||||
|
||||
|
||||
/*
|
||||
LZ4_compress_fast_extState() :
|
||||
Same compression function, just using an externally allocated memory space to store compression state.
|
||||
Use LZ4_sizeofState() to know how much memory must be allocated,
|
||||
and allocate it on 8-bytes boundaries (using malloc() typically).
|
||||
Then, provide it as 'void* state' to compression function.
|
||||
*/
|
||||
int LZ4_sizeofState(void);
|
||||
int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration);
|
||||
|
||||
|
||||
/*
|
||||
LZ4_compress_destSize() :
|
||||
Reverse the logic, by compressing as much data as possible from 'source' buffer
|
||||
into already allocated buffer 'dest' of size 'targetDestSize'.
|
||||
This function either compresses the entire 'source' content into 'dest' if it's large enough,
|
||||
or fill 'dest' buffer completely with as much data as possible from 'source'.
|
||||
*sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'.
|
||||
New value is necessarily <= old value.
|
||||
return : Nb bytes written into 'dest' (necessarily <= targetDestSize)
|
||||
or 0 if compression fails
|
||||
*/
|
||||
int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize);
|
||||
|
||||
|
||||
/*
|
||||
LZ4_decompress_fast() :
|
||||
originalSize : is the original and therefore uncompressed size
|
||||
return : the number of bytes read from the source buffer (in other words, the compressed size)
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes.
|
||||
note : This function fully respect memory boundaries for properly formed compressed data.
|
||||
It is a bit faster than LZ4_decompress_safe().
|
||||
However, it does not provide any protection against intentionally modified data stream (malicious input).
|
||||
Use this function in trusted environment only (data to decode comes from a trusted source).
|
||||
*/
|
||||
int LZ4_decompress_fast (const char* source, char* dest, int originalSize);
|
||||
|
||||
/*
|
||||
LZ4_decompress_safe_partial() :
|
||||
This function decompress a compressed block of size 'compressedSize' at position 'source'
|
||||
into destination buffer 'dest' of size 'maxDecompressedSize'.
|
||||
The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached,
|
||||
reducing decompression time.
|
||||
return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize)
|
||||
Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller.
|
||||
Always control how many bytes were decoded.
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets
|
||||
*/
|
||||
int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize);
|
||||
|
||||
|
||||
/***********************************************
|
||||
* Streaming Compression Functions
|
||||
***********************************************/
|
||||
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
|
||||
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long))
|
||||
/*
|
||||
* LZ4_stream_t
|
||||
* information structure to track an LZ4 stream.
|
||||
* important : init this structure content before first use !
|
||||
* note : only allocated directly the structure if you are statically linking LZ4
|
||||
* If you are using liblz4 as a DLL, please use below construction methods instead.
|
||||
*/
|
||||
typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t;
|
||||
|
||||
/*
|
||||
* LZ4_resetStream
|
||||
* Use this function to init an allocated LZ4_stream_t structure
|
||||
*/
|
||||
void LZ4_resetStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*
|
||||
* LZ4_createStream will allocate and initialize an LZ4_stream_t structure
|
||||
* LZ4_freeStream releases its memory.
|
||||
* In the context of a DLL (liblz4), please use these methods rather than the static struct.
|
||||
* They are more future proof, in case of a change of LZ4_stream_t size.
|
||||
*/
|
||||
LZ4_stream_t* LZ4_createStream(void);
|
||||
int LZ4_freeStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*
|
||||
* LZ4_loadDict
|
||||
* Use this function to load a static dictionary into LZ4_stream.
|
||||
* Any previous data will be forgotten, only 'dictionary' will remain in memory.
|
||||
* Loading a size of 0 is allowed.
|
||||
* Return : dictionary size, in bytes (necessarily <= 64 KB)
|
||||
*/
|
||||
int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
|
||||
|
||||
/*
|
||||
* LZ4_compress_fast_continue
|
||||
* Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio.
|
||||
* Important : Previous data blocks are assumed to still be present and unmodified !
|
||||
* 'dst' buffer must be already allocated.
|
||||
* If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
|
||||
* If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero.
|
||||
*/
|
||||
int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration);
|
||||
|
||||
/*
|
||||
* LZ4_saveDict
|
||||
* If previously compressed data block is not guaranteed to remain available at its memory location
|
||||
* save it into a safer place (char* safeBuffer)
|
||||
* Note : you don't need to call LZ4_loadDict() afterwards,
|
||||
* dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue()
|
||||
* Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error
|
||||
*/
|
||||
int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize);
|
||||
|
||||
|
||||
/************************************************
|
||||
* Streaming Decompression Functions
|
||||
************************************************/
|
||||
|
||||
#define LZ4_STREAMDECODESIZE_U64 4
|
||||
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
|
||||
typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t;
|
||||
/*
|
||||
* LZ4_streamDecode_t
|
||||
* information structure to track an LZ4 stream.
|
||||
* init this structure content using LZ4_setStreamDecode or memset() before first use !
|
||||
*
|
||||
* In the context of a DLL (liblz4) please prefer usage of construction methods below.
|
||||
* They are more future proof, in case of a change of LZ4_streamDecode_t size in the future.
|
||||
* LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure
|
||||
* LZ4_freeStreamDecode releases its memory.
|
||||
*/
|
||||
LZ4_streamDecode_t* LZ4_createStreamDecode(void);
|
||||
int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
|
||||
|
||||
/*
|
||||
* LZ4_setStreamDecode
|
||||
* Use this function to instruct where to find the dictionary.
|
||||
* Setting a size of 0 is allowed (same effect as reset).
|
||||
* Return : 1 if OK, 0 if error
|
||||
*/
|
||||
int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
|
||||
|
||||
/*
|
||||
*_continue() :
|
||||
These decoding functions allow decompression of multiple blocks in "streaming" mode.
|
||||
Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB)
|
||||
In the case of a ring buffers, decoding buffer must be either :
|
||||
- Exactly same size as encoding buffer, with same update rule (block boundaries at same positions)
|
||||
In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB).
|
||||
- Larger than encoding buffer, by a minimum of maxBlockSize more bytes.
|
||||
maxBlockSize is implementation dependent. It's the maximum size you intend to compress into a single block.
|
||||
In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
and encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||
- _At least_ 64 KB + 8 bytes + maxBlockSize.
|
||||
In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
and encoding ring buffer can have any size, including larger than decoding buffer.
|
||||
Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer,
|
||||
and indicate where it is saved using LZ4_setStreamDecode()
|
||||
*/
|
||||
int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize);
|
||||
int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize);
|
||||
|
||||
|
||||
/*
|
||||
Advanced decoding functions :
|
||||
*_usingDict() :
|
||||
These decoding functions work the same as
|
||||
a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue()
|
||||
They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure.
|
||||
*/
|
||||
int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize);
|
||||
int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize);
|
||||
|
||||
|
||||
|
||||
/**************************************
|
||||
* Obsolete Functions
|
||||
**************************************/
|
||||
/* Deprecate Warnings */
|
||||
/* Should these warnings messages be a problem,
|
||||
it is generally possible to disable them,
|
||||
with -Wno-deprecated-declarations for gcc
|
||||
or _CRT_SECURE_NO_WARNINGS in Visual for example.
|
||||
You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */
|
||||
#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK
|
||||
# define LZ4_DEPRECATE_WARNING_DEFBLOCK
|
||||
# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||
# if (LZ4_GCC_VERSION >= 405) || defined(__clang__)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
# elif (LZ4_GCC_VERSION >= 301)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
|
||||
# elif defined(_MSC_VER)
|
||||
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
|
||||
# else
|
||||
# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
|
||||
# define LZ4_DEPRECATED(message)
|
||||
# endif
|
||||
#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */
|
||||
|
||||
/* Obsolete compression functions */
|
||||
/* These functions are planned to start generate warnings by r131 approximately */
|
||||
int LZ4_compress (const char* source, char* dest, int sourceSize);
|
||||
int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
|
||||
int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
|
||||
int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
|
||||
int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
|
||||
/* Obsolete decompression functions */
|
||||
/* These function names are completely deprecated and must no longer be used.
|
||||
They are only provided here for compatibility with older programs.
|
||||
- LZ4_uncompress is the same as LZ4_decompress_fast
|
||||
- LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe
|
||||
These function prototypes are now disabled; uncomment them only if you really need them.
|
||||
It is highly recommended to stop using these prototypes and migrate to maintained ones */
|
||||
/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */
|
||||
/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */
|
||||
|
||||
/* Obsolete streaming functions; use new streaming interface whenever possible */
|
||||
LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer);
|
||||
LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void);
|
||||
LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer);
|
||||
LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state);
|
||||
|
||||
/* Obsolete streaming decoding functions */
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
|
||||
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
|
@ -81,6 +81,8 @@ class VerilatedVcd;
|
|||
class VerilatedVcdC;
|
||||
class VerilatedLxt2;
|
||||
class VerilatedLxt2C;
|
||||
class VerilatedFst;
|
||||
class VerilatedFstC;
|
||||
|
||||
enum VerilatedVarType {
|
||||
VLVT_UNKNOWN=0,
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
// -*- 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, int arraynum, uint32_t len, enum fstVarType vartype) {
|
||||
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, FST_VD_IMPLICIT, len, name_str.c_str(), 0);
|
||||
assert(p.first->second);
|
||||
} else { // Alias
|
||||
fstWriterCreateVar(m_fst, vartype, FST_VD_IMPLICIT, len, name_str.c_str(), p.first->second);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Callbacks
|
||||
|
||||
void VerilatedFst::addCallback(
|
||||
VerilatedFstCallback_t initcb, VerilatedFstCallback_t fullcb,
|
||||
VerilatedFstCallback_t changecb, void* userthis) VL_MT_UNSAFE_ONE {
|
||||
m_assertOne.check();
|
||||
if (VL_UNLIKELY(isOpen())) {
|
||||
std::string msg = std::string("Internal: ")+__FILE__+"::"+__FUNCTION__+" called with already open file";
|
||||
VL_FATAL_MT(__FILE__,__LINE__,"",msg.c_str());
|
||||
}
|
||||
VerilatedFstCallInfo* vci = new VerilatedFstCallInfo(initcb, fullcb, changecb, userthis, 1);
|
||||
m_callbacks.push_back(vci);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Dumping
|
||||
|
||||
void VerilatedFst::dump(vluint64_t timeui) {
|
||||
if (!isOpen()) return;
|
||||
if (VL_UNLIKELY(m_fullDump)) {
|
||||
m_fullDump = false; // No need for more full dumps
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
||||
VerilatedFstCallInfo* cip = m_callbacks[ent];
|
||||
(cip->m_fullcb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
return;
|
||||
}
|
||||
fstWriterEmitTimeChange(m_fst, timeui);
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
||||
VerilatedFstCallInfo* cip = m_callbacks[ent];
|
||||
(cip->m_changecb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Helpers
|
||||
|
||||
char* VerilatedFst::word2Str(vluint32_t newval, int bits) {
|
||||
m_valueStrBuffer.resize(bits+1);
|
||||
char* s = m_valueStrBuffer.data();
|
||||
for (int i = 0; i < bits; ++i) {
|
||||
*s = '0' + ((newval>>(bits-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
*s = '\0';
|
||||
return m_valueStrBuffer.data();
|
||||
}
|
||||
|
||||
char* VerilatedFst::quad2Str(vluint64_t newval, int bits) {
|
||||
m_valueStrBuffer.resize(bits+1);
|
||||
char* s = m_valueStrBuffer.data();
|
||||
for (int i = 0; i < bits; ++i) {
|
||||
*s = '0' + ((newval>>(bits-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
*s = '\0';
|
||||
return m_valueStrBuffer.data();
|
||||
}
|
||||
|
||||
char* VerilatedFst::array2Str(const vluint32_t* newval, int bits) {
|
||||
int bq = bits/32, br = bits%32;
|
||||
m_valueStrBuffer.resize(bits+1);
|
||||
char* s = m_valueStrBuffer.data();
|
||||
for (int w = bq-1; w >= 0; --w) {
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
*s = '0' + ((newval[w]>>(32-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < br; ++i) {
|
||||
*s = '0' + ((newval[bq]>>(br-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
*s = '\0';
|
||||
return m_valueStrBuffer.data();
|
||||
}
|
||||
|
||||
//********************************************************************
|
||||
// Local Variables:
|
||||
// End:
|
|
@ -0,0 +1,209 @@
|
|||
// -*- 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, int arraynum, uint32_t len, fstVarType vartype);
|
||||
// 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, int arraynum) {
|
||||
this->declSymbol(code, name, arraynum, 1, FST_VT_VCD_WIRE);
|
||||
}
|
||||
void declBus(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
|
||||
this->declSymbol(code, name, arraynum, msb - lsb + 1, FST_VT_VCD_WIRE);
|
||||
}
|
||||
void declDouble(vluint32_t code, const char* name, int arraynum) {
|
||||
this->declSymbol(code, name, arraynum, 2, FST_VT_VCD_REAL);
|
||||
}
|
||||
void declFloat(vluint32_t code, const char* name, int arraynum) {
|
||||
this->declSymbol(code, name, arraynum, 1, FST_VT_SV_SHORTREAL);
|
||||
}
|
||||
void declQuad(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
|
||||
this->declSymbol(code, name, arraynum, msb - lsb + 1, FST_VT_VCD_WIRE);
|
||||
}
|
||||
void declArray(vluint32_t code, const char* name, int arraynum, int msb, int lsb) {
|
||||
this->declSymbol(code, name, arraynum, msb - lsb + 1, FST_VT_VCD_WIRE);
|
||||
}
|
||||
|
||||
/// 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
|
|
@ -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; }
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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,";
|
||||
|
|
|
@ -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,9 +1254,10 @@ 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) {
|
||||
|
@ -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 !~ /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;
|
||||
|
@ -1620,7 +1642,6 @@ sub lxt2vcd {
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub _vcd_read {
|
||||
my $self = (ref $_[0]? shift : $Self);
|
||||
my $filename = shift;
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
$date
|
||||
Tue Aug 28 17:08:13 2018
|
||||
$end
|
||||
$version
|
||||
lxt2vcd
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
$scope module top $end
|
||||
$var wire 1 ! clk $end
|
||||
$scope module t $end
|
||||
$scope module biggie $end
|
||||
$var wire 1048577 " d [1048576:0] $end
|
||||
$upscope $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$var wire 1 ! clk $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
$dumpvars
|
||||
#0
|
||||
0!
|
||||
b0 "
|
||||
b0 #
|
||||
#10
|
||||
b1 #
|
||||
b111111101110110111111010110011100 "
|
||||
1!
|
||||
#15
|
||||
0!
|
||||
#20
|
||||
1!
|
||||
b1111111011101101111110101100111000 "
|
||||
b10 #
|
||||
#25
|
||||
0!
|
||||
#30
|
||||
1!
|
||||
b11 #
|
||||
b11111110111011011111101011001110000 "
|
||||
#35
|
||||
0!
|
||||
#40
|
||||
1!
|
||||
b111111101110110111111010110011100000 "
|
||||
b100 #
|
||||
#45
|
||||
0!
|
||||
#50
|
||||
1!
|
||||
b101 #
|
||||
b1111111011101101111110101100111000000 "
|
||||
#55
|
||||
0!
|
||||
#60
|
||||
1!
|
||||
b11111110111011011111101011001110000000 "
|
||||
b110 #
|
|
@ -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;
|
|
@ -0,0 +1,205 @@
|
|||
$date
|
||||
Tue Oct 2 18:35:11 2018
|
||||
|
||||
$end
|
||||
$version
|
||||
fstWriter
|
||||
$end
|
||||
$timescale
|
||||
1ns
|
||||
$end
|
||||
$scope module top $end
|
||||
$var wire 1 ! clk $end
|
||||
$scope module t $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc $end
|
||||
$var wire 2 # v_strp $end
|
||||
$var wire 4 $ v_strp_strp $end
|
||||
$var wire 2 % v_unip_strp $end
|
||||
$var wire 2 & v_arrp $end
|
||||
$var wire 4 ' v_arrp_arrp $end
|
||||
$var wire 4 ( v_arrp_strp $end
|
||||
$var wire 1 ) v_arru(1) $end
|
||||
$var wire 1 * v_arru(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_arrp(3) $end
|
||||
$var wire 2 0 v_arru_arrp(4) $end
|
||||
$var wire 2 1 v_arru_strp(3) $end
|
||||
$var wire 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 wire 64 6 v_str32x2 $end
|
||||
$scope module unnamedblk1 $end
|
||||
$var wire 32 7 b $end
|
||||
$scope module unnamedblk2 $end
|
||||
$var wire 32 8 a $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module p2 $end
|
||||
$var wire 32 9 PARAM $end
|
||||
$upscope $end
|
||||
$scope module p3 $end
|
||||
$var wire 32 : PARAM $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module $unit $end
|
||||
$var wire 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
|
||||
b00000000000000000000000000000010 9
|
||||
b00000000000000000000000000000011 :
|
||||
1;
|
||||
#10
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 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
|
||||
b00000000000000000000000000000101 7
|
||||
b00000000000000000000000000000101 8
|
||||
#25
|
||||
0!
|
||||
#30
|
||||
1!
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 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
|
||||
b00000000000000000000000000000101 7
|
||||
b00000000000000000000000000000101 8
|
||||
#45
|
||||
0!
|
||||
#50
|
||||
1!
|
||||
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
|
||||
b00000000000000000000000000000101 7
|
||||
b00000000000000000000000000000101 8
|
|
@ -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;
|
|
@ -0,0 +1,205 @@
|
|||
$date
|
||||
Tue Oct 2 18:35:13 2018
|
||||
|
||||
$end
|
||||
$version
|
||||
fstWriter
|
||||
$end
|
||||
$timescale
|
||||
1ns
|
||||
$end
|
||||
$scope module top $end
|
||||
$var wire 1 ! clk $end
|
||||
$scope module t $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc $end
|
||||
$var wire 2 # v_strp $end
|
||||
$var wire 4 $ v_strp_strp $end
|
||||
$var wire 2 % v_unip_strp $end
|
||||
$var wire 2 & v_arrp $end
|
||||
$var wire 4 ' v_arrp_arrp $end
|
||||
$var wire 4 ( v_arrp_strp $end
|
||||
$var wire 1 ) v_arru(1) $end
|
||||
$var wire 1 * v_arru(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_arrp(3) $end
|
||||
$var wire 2 0 v_arru_arrp(4) $end
|
||||
$var wire 2 1 v_arru_strp(3) $end
|
||||
$var wire 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 wire 64 6 v_str32x2 $end
|
||||
$scope module unnamedblk1 $end
|
||||
$var wire 32 7 b $end
|
||||
$scope module unnamedblk2 $end
|
||||
$var wire 32 8 a $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module p2 $end
|
||||
$var wire 32 9 PARAM $end
|
||||
$upscope $end
|
||||
$scope module p3 $end
|
||||
$var wire 32 : PARAM $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module $unit $end
|
||||
$var wire 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
|
||||
b00000000000000000000000000000010 9
|
||||
b00000000000000000000000000000011 :
|
||||
1;
|
||||
#10
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 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
|
||||
b00000000000000000000000000000101 7
|
||||
b00000000000000000000000000000101 8
|
||||
#25
|
||||
0!
|
||||
#30
|
||||
1!
|
||||
b00000000000000000000000000000101 8
|
||||
b00000000000000000000000000000101 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
|
||||
b00000000000000000000000000000101 7
|
||||
b00000000000000000000000000000101 8
|
||||
#45
|
||||
0!
|
||||
#50
|
||||
1!
|
||||
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
|
||||
b00000000000000000000000000000101 7
|
||||
b00000000000000000000000000000101 8
|
|
@ -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;
|
|
@ -0,0 +1,321 @@
|
|||
$date
|
||||
Tue Oct 2 18:35:16 2018
|
||||
|
||||
$end
|
||||
$version
|
||||
fstWriter
|
||||
$end
|
||||
$timescale
|
||||
1ns
|
||||
$end
|
||||
$scope module top $end
|
||||
$var wire 1 ! clk $end
|
||||
$scope module t $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc $end
|
||||
$scope module v_strp $end
|
||||
$var wire 1 # b1 $end
|
||||
$var wire 1 $ b0 $end
|
||||
$upscope $end
|
||||
$scope module v_strp_strp $end
|
||||
$scope module x1 $end
|
||||
$var wire 1 % b1 $end
|
||||
$var wire 1 & b0 $end
|
||||
$upscope $end
|
||||
$scope module x0 $end
|
||||
$var wire 1 ' b1 $end
|
||||
$var wire 1 ( b0 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module v_unip_strp $end
|
||||
$scope module x1 $end
|
||||
$var wire 1 ) b1 $end
|
||||
$var wire 1 * b0 $end
|
||||
$upscope $end
|
||||
$scope module x0 $end
|
||||
$var wire 1 ) b1 $end
|
||||
$var wire 1 * b0 $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$var wire 2 + v_arrp $end
|
||||
$var wire 2 , v_arrp_arrp(3) $end
|
||||
$var wire 2 - v_arrp_arrp(4) $end
|
||||
$scope module v_arrp_strp(3) $end
|
||||
$var wire 1 . b1 $end
|
||||
$var wire 1 / b0 $end
|
||||
$upscope $end
|
||||
$scope module v_arrp_strp(4) $end
|
||||
$var wire 1 0 b1 $end
|
||||
$var wire 1 1 b0 $end
|
||||
$upscope $end
|
||||
$var wire 1 2 v_arru(1) $end
|
||||
$var wire 1 3 v_arru(2) $end
|
||||
$var wire 1 4 v_arru_arru(3)(1) $end
|
||||
$var wire 1 5 v_arru_arru(3)(2) $end
|
||||
$var wire 1 6 v_arru_arru(4)(1) $end
|
||||
$var wire 1 7 v_arru_arru(4)(2) $end
|
||||
$var wire 2 8 v_arru_arrp(3) $end
|
||||
$var wire 2 9 v_arru_arrp(4) $end
|
||||
$scope module v_arru_strp(3) $end
|
||||
$var wire 1 : b1 $end
|
||||
$var wire 1 ; b0 $end
|
||||
$upscope $end
|
||||
$scope module v_arru_strp(4) $end
|
||||
$var wire 1 < b1 $end
|
||||
$var wire 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 wire 32 A data $end
|
||||
$upscope $end
|
||||
$scope module v_str32x2(1) $end
|
||||
$var wire 32 B data $end
|
||||
$upscope $end
|
||||
$scope module unnamedblk1 $end
|
||||
$var wire 32 C b $end
|
||||
$scope module unnamedblk2 $end
|
||||
$var wire 32 D a $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module $unit $end
|
||||
$var wire 1 E 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
|
||||
1E
|
||||
#10
|
||||
b00000000000000000000000000000101 D
|
||||
b00000000000000000000000000000101 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
|
||||
b00000000000000000000000000000101 C
|
||||
b00000000000000000000000000000101 D
|
||||
#25
|
||||
0!
|
||||
#30
|
||||
1!
|
||||
b00000000000000000000000000000101 D
|
||||
b00000000000000000000000000000101 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
|
||||
b00000000000000000000000000000101 C
|
||||
b00000000000000000000000000000101 D
|
||||
#45
|
||||
0!
|
||||
#50
|
||||
1!
|
||||
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
|
||||
b00000000000000000000000000000101 C
|
||||
b00000000000000000000000000000101 D
|
|
@ -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;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/perl
|
||||
# This file ONLY is placed into the Public Domain, for any use,
|
||||
# Author: Yu-Sheng Lin johnjohnlys@media.ee.ntu.edu.tw
|
||||
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
|
||||
scenarios(vlt_all => 1);
|
||||
|
||||
compile(
|
||||
v_flags2 => ["--trace-fst"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
fst2vcd($Self->trace_filename, "$Self->{obj_dir}/simx-fst2vcd.vcd");
|
||||
vcd_identical("$Self->{obj_dir}/simx-fst2vcd.vcd", "t/$Self->{name}.out");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// Author: Yu-Sheng Lin johnjohnlys@media.ee.ntu.edu.tw
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
state,
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
|
||||
int cyc;
|
||||
reg rstn;
|
||||
output [4:0] state;
|
||||
|
||||
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
|
||||
Tue Oct 2 18:35:19 2018
|
||||
|
||||
$end
|
||||
$version
|
||||
fstWriter
|
||||
$end
|
||||
$timescale
|
||||
1ns
|
||||
$end
|
||||
$scope module top $end
|
||||
$var wire 1 ! clk $end
|
||||
$scope module t $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cnt $end
|
||||
$var wire 96 # v(0) $end
|
||||
$var wire 96 $ v(1) $end
|
||||
$var wire 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 "
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_trace_string.v");
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ['--cc --trace'],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
|
@ -50,6 +50,7 @@ foreach my $file (sort keys %hit) {
|
|||
if (!$hit{$file}
|
||||
&& $file !~ /_sc/
|
||||
&& $file !~ /_lxt2/
|
||||
&& $file !~ /_fst/
|
||||
&& ($file !~ /_thread/ || $Self->cfg_with_threaded)) {
|
||||
error("Include file not covered by t_verilated_all test: ",$file);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue