From fc7d604eec94ff376fb934dbf4d1be3b93120a7f Mon Sep 17 00:00:00 2001 From: Cary R Date: Wed, 1 Jan 2020 19:57:54 -0800 Subject: [PATCH] Update to the latest fstapi files from GTKWave --- vpi/fstapi.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++----- vpi/fstapi.h | 8 +++ 2 files changed, 164 insertions(+), 14 deletions(-) diff --git a/vpi/fstapi.c b/vpi/fstapi.c index c1353347c..720116ba8 100644 --- a/vpi/fstapi.c +++ b/vpi/fstapi.c @@ -37,7 +37,10 @@ * */ -#include +#ifndef FST_CONFIG_INCLUDE +# define FST_CONFIG_INCLUDE +#endif +#include FST_CONFIG_INCLUDE #include "fstapi.h" #include "fastlz.h" @@ -129,6 +132,16 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3 #include #endif +#ifdef __GNUC__ +/* Boolean expression more often true than false */ +#define FST_LIKELY(x) __builtin_expect(!!(x), 1) +/* Boolean expression more often false than true */ +#define FST_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define FST_LIKELY(x) (!!(x)) +#define FST_UNLIKELY(x) (!!(x)) +#endif + #define FST_APIMESS "FSTAPI | " /***********************/ @@ -724,6 +737,9 @@ off_t hier_file_len; uint32_t *valpos_mem; unsigned char *curval_mem; +unsigned char *outval_mem; /* for two-state / Verilator-style value changes */ +uint32_t outval_alloc_siz; + char *filename; fstHandle maxhandle; @@ -1913,7 +1929,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush) xc->skip_writing_section_hdr = 1; if(!xc->size_limit_locked) { - if(xc->is_initial_time) /* simulation time never advanced so mock up the changes as time zero ones */ + if(FST_UNLIKELY(xc->is_initial_time)) /* simulation time never advanced so mock up the changes as time zero ones */ { fstHandle dupe_idx; @@ -1931,6 +1947,11 @@ if(xc && !xc->already_in_close && !xc->already_in_flush) } } fstDestroyMmaps(xc, 1); + if(xc->outval_mem) + { + free(xc->outval_mem); xc->outval_mem = NULL; + xc->outval_alloc_siz = 0; + } /* write out geom section */ fflush(xc->geom_handle); @@ -2875,12 +2896,12 @@ const unsigned char *buf = (const unsigned char *)val; uint32_t offs; int len; -if((xc) && (handle <= xc->maxhandle)) +if(FST_LIKELY((xc) && (handle <= xc->maxhandle))) { uint32_t fpos; uint32_t *vm4ip; - if(!xc->valpos_mem) + if(FST_UNLIKELY(!xc->valpos_mem)) { xc->vc_emitted = 1; fstWriterCreateMmaps(xc); @@ -2890,17 +2911,17 @@ if((xc) && (handle <= xc->maxhandle)) vm4ip = &(xc->valpos_mem[4*handle]); len = vm4ip[1]; - if(len) /* len of zero = variable length, use fstWriterEmitVariableLengthValueChange */ + if(FST_LIKELY(len)) /* len of zero = variable length, use fstWriterEmitVariableLengthValueChange */ { - if(!xc->is_initial_time) + if(FST_LIKELY(!xc->is_initial_time)) { fpos = xc->vchg_siz; - if((fpos + len + 10) > xc->vchg_alloc_siz) + if(FST_UNLIKELY((fpos + len + 10) > xc->vchg_alloc_siz)) { xc->vchg_alloc_siz += (xc->fst_break_add_size + len); /* +len added in the case of extremely long vectors and small break add sizes */ xc->vchg_mem = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz); - if(!xc->vchg_mem) + if(FST_UNLIKELY(!xc->vchg_mem)) { fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitValueChange, exiting.\n"); exit(255); @@ -2985,18 +3006,139 @@ if((xc) && (handle <= xc->maxhandle)) } } +void fstWriterEmitValueChange32(void *ctx, fstHandle handle, + uint32_t bits, uint32_t val) { + char buf[32]; + char *s = buf; + uint32_t i; + for (i = 0; i < bits; ++i) + { + *s++ = '0' + ((val >> (bits - i - 1)) & 1); + } + fstWriterEmitValueChange(ctx, handle, buf); +} +void fstWriterEmitValueChange64(void *ctx, fstHandle handle, + uint32_t bits, uint64_t val) { + char buf[64]; + char *s = buf; + uint32_t i; + for (i = 0; i < bits; ++i) + { + *s++ = '0' + ((val >> (bits - i - 1)) & 1); + } + fstWriterEmitValueChange(ctx, handle, buf); +} +void fstWriterEmitValueChangeVec32(void *ctx, fstHandle handle, + uint32_t bits, const uint32_t *val) { + struct fstWriterContext *xc = (struct fstWriterContext *)ctx; + if (FST_UNLIKELY(bits <= 32)) + { + fstWriterEmitValueChange32(ctx, handle, bits, val[0]); + } + else if(FST_LIKELY(xc)) + { + int bq = bits / 32; + int br = bits & 31; + int i; + int w; + uint32_t v; + unsigned char* s; + if (FST_UNLIKELY(bits > xc->outval_alloc_siz)) + { + xc->outval_alloc_siz = bits*2 + 1; + xc->outval_mem = (unsigned char*)realloc(xc->outval_mem, xc->outval_alloc_siz); + if (FST_UNLIKELY(!xc->outval_mem)) + { + fprintf(stderr, + FST_APIMESS "Could not realloc() in fstWriterEmitValueChangeVec32, exiting.\n"); + exit(255); + } + } + s = xc->outval_mem; + { + w = bq; + v = val[w]; + for (i = 0; i < br; ++i) + { + *s++ = '0' + ((v >> (br - i - 1)) & 1); + } + } + for (w = bq - 1; w >= 0; --w) + { + v = val[w]; + for (i = (32 - 4); i >= 0; i -= 4) { + s[0] = '0' + ((v >> (i + 3)) & 1); + s[1] = '0' + ((v >> (i + 2)) & 1); + s[2] = '0' + ((v >> (i + 1)) & 1); + s[3] = '0' + ((v >> (i + 0)) & 1); + s += 4; + } + } + fstWriterEmitValueChange(ctx, handle, xc->outval_mem); + } +} +void fstWriterEmitValueChangeVec64(void *ctx, fstHandle handle, + uint32_t bits, const uint64_t *val) { + struct fstWriterContext *xc = (struct fstWriterContext *)ctx; + if (FST_UNLIKELY(bits <= 64)) + { + fstWriterEmitValueChange64(ctx, handle, bits, val[0]); + } + else if(FST_LIKELY(xc)) + { + int bq = bits / 64; + int br = bits & 63; + int i; + int w; + uint32_t v; + unsigned char* s; + if (FST_UNLIKELY(bits > xc->outval_alloc_siz)) + { + xc->outval_alloc_siz = bits*2 + 1; + xc->outval_mem = (unsigned char*)realloc(xc->outval_mem, xc->outval_alloc_siz); + if (FST_UNLIKELY(!xc->outval_mem)) + { + fprintf(stderr, + FST_APIMESS "Could not realloc() in fstWriterEmitValueChangeVec64, exiting.\n"); + exit(255); + } + } + s = xc->outval_mem; + { + w = bq; + v = val[w]; + for (i = 0; i < br; ++i) + { + *s++ = '0' + ((v >> (br - i - 1)) & 1); + } + } + for (w = bq - 1; w >= 0; --w) { + v = val[w]; + for (i = (64 - 4); i >= 0; i -= 4) + { + s[0] = '0' + ((v >> (i + 3)) & 1); + s[1] = '0' + ((v >> (i + 2)) & 1); + s[2] = '0' + ((v >> (i + 1)) & 1); + s[3] = '0' + ((v >> (i + 0)) & 1); + s += 4; + } + } + fstWriterEmitValueChange(ctx, handle, xc->outval_mem); + } +} + void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; const unsigned char *buf = (const unsigned char *)val; -if((xc) && (handle <= xc->maxhandle)) +if(FST_LIKELY((xc) && (handle <= xc->maxhandle))) { uint32_t fpos; uint32_t *vm4ip; - if(!xc->valpos_mem) + if(FST_UNLIKELY(!xc->valpos_mem)) { xc->vc_emitted = 1; fstWriterCreateMmaps(xc); @@ -3006,15 +3148,15 @@ if((xc) && (handle <= xc->maxhandle)) vm4ip = &(xc->valpos_mem[4*handle]); /* there is no initial time dump for variable length value changes */ - if(!vm4ip[1]) /* len of zero = variable length */ + if(FST_LIKELY(!vm4ip[1])) /* len of zero = variable length */ { fpos = xc->vchg_siz; - if((fpos + len + 10 + 5) > xc->vchg_alloc_siz) + if(FST_UNLIKELY((fpos + len + 10 + 5) > xc->vchg_alloc_siz)) { xc->vchg_alloc_siz += (xc->fst_break_add_size + len + 5); /* +len added in the case of extremely long vectors and small break add sizes */ xc->vchg_mem = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz); - if(!xc->vchg_mem) + if(FST_UNLIKELY(!xc->vchg_mem)) { fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitVariableLengthValueChange, exiting.\n"); exit(255); @@ -3036,7 +3178,7 @@ unsigned int i; int skip = 0; if(xc) { - if(xc->is_initial_time) + if(FST_UNLIKELY(xc->is_initial_time)) { if(xc->size_limit_locked) /* this resets xc->is_initial_time to one */ { diff --git a/vpi/fstapi.h b/vpi/fstapi.h index aef6de23b..bbc82c278 100644 --- a/vpi/fstapi.h +++ b/vpi/fstapi.h @@ -355,6 +355,14 @@ fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDi void fstWriterEmitDumpActive(void *ctx, int enable); void fstWriterEmitEnumTableRef(void *ctx, fstEnumHandle handle); void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val); +void fstWriterEmitValueChange32(void *ctx, fstHandle handle, + uint32_t bits, uint32_t val); +void fstWriterEmitValueChange64(void *ctx, fstHandle handle, + uint32_t bits, uint64_t val); +void fstWriterEmitValueChangeVec32(void *ctx, fstHandle handle, + uint32_t bits, const uint32_t *val); +void fstWriterEmitValueChangeVec64(void *ctx, fstHandle handle, + uint32_t bits, const uint64_t *val); void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len); void fstWriterEmitTimeChange(void *ctx, uint64_t tim); void fstWriterFlushContext(void *ctx);