Update lxt, lxt2 and fst files to latest from GTKWave

This commit is contained in:
Cary R 2012-08-16 14:55:02 -07:00
parent 34bb00144f
commit e8b40e14b9
7 changed files with 457 additions and 49 deletions

View File

@ -1,7 +1,7 @@
#ifndef __config_H /* -*- c++ -*- */ #ifndef __config_H /* -*- c++ -*- */
#define __config_H #define __config_H
/* /*
* Copyright (c) 2001-2010 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -52,6 +52,8 @@
/* These two are needed by the lxt and lxt2 files (copied from GTKWave). */ /* These two are needed by the lxt and lxt2 files (copied from GTKWave). */
# undef HAVE_ALLOCA_H # undef HAVE_ALLOCA_H
# undef HAVE_FSEEKO # undef HAVE_FSEEKO
/* And this is needed by the fst files (copied from GTKWave). */
# undef HAVE_LIBPTHREAD
/* /*
* Define this if you want to compile vvp with memory freeing and * Define this if you want to compile vvp with memory freeing and

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2011 Tony Bybell. * Copyright (c) 2009-2012 Tony Bybell.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,13 @@
#include "fstapi.h" #include "fstapi.h"
#include "fastlz.h" #include "fastlz.h"
#ifndef HAVE_LIBPTHREAD
#undef FST_WRITER_PARALLEL
#endif
#ifdef FST_WRITER_PARALLEL
#include <pthread.h>
#endif
/* this define is to force writer backward compatibility with old readers */ /* this define is to force writer backward compatibility with old readers */
#ifndef FST_DYNAMIC_ALIAS_DISABLE #ifndef FST_DYNAMIC_ALIAS_DISABLE
@ -47,13 +54,17 @@ void **JenkinsIns(void *base_i, unsigned char *mem, uint32_t length, uint32_t ha
#undef FST_DEBUG #undef FST_DEBUG
#define FST_BREAK_SIZE (128 * 1024 * 1024) #define FST_BREAK_SIZE (1UL << 27)
#define FST_BREAK_ADD_SIZE (4 * 1024 * 1024) #define FST_BREAK_ADD_SIZE (1UL << 22)
#define FST_BREAK_SIZE_MAX (1UL << 31)
#define FST_ACTIVATE_HUGE_BREAK (2000000)
#define FST_ACTIVATE_HUGE_INC (2000000)
#define FST_WRITER_STR "fstWriter" #define FST_WRITER_STR "fstWriter"
#define FST_ID_NAM_SIZ (512) #define FST_ID_NAM_SIZ (512)
#define FST_DOUBLE_ENDTEST (2.7182818284590452354) #define FST_DOUBLE_ENDTEST (2.7182818284590452354)
#define FST_HDR_SIM_VERSION_SIZE (128) #define FST_HDR_SIM_VERSION_SIZE (128)
#define FST_HDR_DATE_SIZE (128) #define FST_HDR_DATE_SIZE (120)
#define FST_GZIO_LEN (32768) #define FST_GZIO_LEN (32768)
#if defined(__i386__) || defined(__x86_64__) || defined(_AIX) #if defined(__i386__) || defined(__x86_64__) || defined(_AIX)
@ -73,8 +84,8 @@ void **JenkinsIns(void *base_i, unsigned char *mem, uint32_t length, uint32_t ha
#ifdef __MINGW32__ #ifdef __MINGW32__
#include <io.h> #include <io.h>
#define ftello ftell /* #define ftello ftell */
#define fseeko fseek /* #define fseeko fseek */
#endif #endif
@ -480,6 +491,7 @@ unsigned vc_emitted : 1;
unsigned is_initial_time : 1; unsigned is_initial_time : 1;
unsigned fastpack : 1; unsigned fastpack : 1;
int64_t timezero;
off_t section_header_truncpos; off_t section_header_truncpos;
uint32_t tchn_cnt, tchn_idx; uint32_t tchn_cnt, tchn_idx;
uint64_t curtime; uint64_t curtime;
@ -506,10 +518,29 @@ unsigned skip_writing_section_hdr : 1;
unsigned size_limit_locked : 1; unsigned size_limit_locked : 1;
unsigned section_header_only : 1; unsigned section_header_only : 1;
unsigned flush_context_pending : 1; unsigned flush_context_pending : 1;
unsigned parallel_enabled : 1;
unsigned parallel_was_enabled : 1;
/* should really be semaphores, but are bytes to cut down on read-modify-write window size */ /* should really be semaphores, but are bytes to cut down on read-modify-write window size */
unsigned char already_in_flush; /* in case control-c handlers interrupt */ unsigned char already_in_flush; /* in case control-c handlers interrupt */
unsigned char already_in_close; /* in case control-c handlers interrupt */ unsigned char already_in_close; /* in case control-c handlers interrupt */
#ifdef FST_WRITER_PARALLEL
pthread_mutex_t mutex;
pthread_t thread;
pthread_attr_t thread_attr;
struct fstWriterContext *xc_parent;
#endif
size_t fst_orig_break_size;
size_t fst_orig_break_add_size;
size_t fst_break_size;
size_t fst_break_add_size;
size_t fst_huge_break_size;
fstHandle next_huge_break;
}; };
@ -603,7 +634,7 @@ fstWriterUint64(xc->handle, 0); /* +17 end time */
fstFwrite(&endtest, 8, 1, xc->handle); /* +25 endian test for reals */ fstFwrite(&endtest, 8, 1, xc->handle); /* +25 endian test for reals */
#define FST_HDR_OFFS_MEM_USED (FST_HDR_OFFS_ENDIAN_TEST + 8) #define FST_HDR_OFFS_MEM_USED (FST_HDR_OFFS_ENDIAN_TEST + 8)
fstWriterUint64(xc->handle, FST_BREAK_SIZE); /* +33 memory used by writer */ fstWriterUint64(xc->handle, xc->fst_break_size);/* +33 memory used by writer */
#define FST_HDR_OFFS_NUM_SCOPES (FST_HDR_OFFS_MEM_USED + 8) #define FST_HDR_OFFS_NUM_SCOPES (FST_HDR_OFFS_MEM_USED + 8)
fstWriterUint64(xc->handle, 0); /* +41 scope creation count */ fstWriterUint64(xc->handle, 0); /* +41 scope creation count */
@ -631,7 +662,12 @@ time(&walltime);
strcpy(dbuf, asctime(localtime(&walltime))); strcpy(dbuf, asctime(localtime(&walltime)));
fstFwrite(dbuf, FST_HDR_DATE_SIZE, 1, xc->handle); /* +202 date */ fstFwrite(dbuf, FST_HDR_DATE_SIZE, 1, xc->handle); /* +202 date */
#define FST_HDR_LENGTH (FST_HDR_OFFS_DATE + FST_HDR_DATE_SIZE) /* date size is deliberately overspecified at 120 bytes in order to provide backfill for new args */
#define FST_HDR_OFFS_TIMEZERO (FST_HDR_OFFS_DATE + FST_HDR_DATE_SIZE)
fstWriterUint64(xc->handle, xc->timezero); /* +322 timezero */
#define FST_HDR_LENGTH (FST_HDR_OFFS_TIMEZERO + 8)
/* +330 next section starts here */ /* +330 next section starts here */
fflush(xc->handle); fflush(xc->handle);
} }
@ -703,6 +739,79 @@ xc->curval_mem = NULL;
} }
/*
* set up large and small memory usages
* crossover point in model is FST_ACTIVATE_HUGE_BREAK number of signals
*/
static void fstDetermineBreakSize(struct fstWriterContext *xc)
{
#if defined(__linux__) || defined(FST_MACOSX)
#ifdef __linux__
FILE *f = fopen("/proc/meminfo", "rb");
#else
FILE *f = popen("system_profiler", "r");
#endif
int was_set = 0;
if(f)
{
char buf[257];
char *s;
while(!feof(f))
{
buf[0] = 0;
s = fgets(buf, 256, f);
if(s && *s)
{
#ifdef __linux__
if(!strncmp(s, "MemTotal:", 9))
{
size_t v = atol(s+10);
v *= 1024; /* convert to bytes */
#else
if((s=strstr(s, "Memory:")))
{
size_t v = atol(s+7);
v <<= 30; /* convert GB to bytes */
#endif
v /= 8; /* chop down to 1/8 physical memory */
if(v > FST_BREAK_SIZE)
{
if(v > FST_BREAK_SIZE_MAX)
{
v = FST_BREAK_SIZE_MAX;
}
xc->fst_huge_break_size = v;
was_set = 1;
break;
}
}
}
}
#ifdef __linux__
fclose(f);
#else
pclose(f);
#endif
}
if(!was_set)
#endif
{
xc->fst_huge_break_size = FST_BREAK_SIZE;
}
xc->fst_break_size = xc->fst_orig_break_size = FST_BREAK_SIZE;
xc->fst_break_add_size = xc->fst_orig_break_add_size = FST_BREAK_ADD_SIZE;
xc->next_huge_break = FST_ACTIVATE_HUGE_BREAK;
}
/* /*
* file creation and close * file creation and close
*/ */
@ -711,6 +820,7 @@ void *fstWriterCreate(const char *nam, int use_compressed_hier)
struct fstWriterContext *xc = calloc(1, sizeof(struct fstWriterContext)); struct fstWriterContext *xc = calloc(1, sizeof(struct fstWriterContext));
xc->compress_hier = use_compressed_hier; xc->compress_hier = use_compressed_hier;
fstDetermineBreakSize(xc);
if((!nam)||(!(xc->handle=unlink_fopen(nam, "w+b")))) if((!nam)||(!(xc->handle=unlink_fopen(nam, "w+b"))))
{ {
@ -730,7 +840,7 @@ if((!nam)||(!(xc->handle=unlink_fopen(nam, "w+b"))))
xc->valpos_handle = tmpfile(); /* .offs */ xc->valpos_handle = tmpfile(); /* .offs */
xc->curval_handle = tmpfile(); /* .bits */ xc->curval_handle = tmpfile(); /* .bits */
xc->tchn_handle = tmpfile(); /* .tchn */ xc->tchn_handle = tmpfile(); /* .tchn */
xc->vchg_alloc_siz = FST_BREAK_SIZE + FST_BREAK_ADD_SIZE; xc->vchg_alloc_siz = xc->fst_break_size + xc->fst_break_add_size;
xc->vchg_mem = malloc(xc->vchg_alloc_siz); xc->vchg_mem = malloc(xc->vchg_alloc_siz);
free(hf); free(hf);
@ -741,6 +851,11 @@ if((!nam)||(!(xc->handle=unlink_fopen(nam, "w+b"))))
fstWriterEmitHdrBytes(xc); fstWriterEmitHdrBytes(xc);
xc->nan = strtod("NaN", NULL); xc->nan = strtod("NaN", NULL);
#ifdef FST_WRITER_PARALLEL
pthread_mutex_init(&xc->mutex, NULL);
pthread_attr_init(&xc->thread_attr);
pthread_attr_setdetachstate(&xc->thread_attr, PTHREAD_CREATE_DETACHED);
#endif
} }
else else
{ {
@ -778,6 +893,9 @@ if(xc)
fputc(FST_BL_SKIP, xc->handle); /* temporarily tag the section, use FST_BL_VCDATA on finalize */ fputc(FST_BL_SKIP, xc->handle); /* temporarily tag the section, use FST_BL_VCDATA on finalize */
xc->section_start = ftello(xc->handle); xc->section_start = ftello(xc->handle);
#ifdef FST_WRITER_PARALLEL
if(xc->xc_parent) xc->xc_parent->section_start = xc->section_start;
#endif
xc->section_header_only = 1; /* indicates truncate might be needed */ xc->section_header_only = 1; /* indicates truncate might be needed */
fstWriterUint64(xc->handle, 0); /* placeholder = section length */ fstWriterUint64(xc->handle, 0); /* placeholder = section length */
fstWriterUint64(xc->handle, xc->is_initial_time ? xc->firsttime : xc->curtime); /* begin time of section */ fstWriterUint64(xc->handle, xc->is_initial_time ? xc->firsttime : xc->curtime); /* begin time of section */
@ -813,7 +931,11 @@ if(xc)
* only to be called directly by fst code...otherwise must * only to be called directly by fst code...otherwise must
* be synced up with time changes * be synced up with time changes
*/ */
#ifdef FST_WRITER_PARALLEL
static void fstWriterFlushContextPrivate2(void *ctx)
#else
static void fstWriterFlushContextPrivate(void *ctx) static void fstWriterFlushContextPrivate(void *ctx)
#endif
{ {
#ifdef FST_DEBUG #ifdef FST_DEBUG
int cnt = 0; int cnt = 0;
@ -833,6 +955,11 @@ unsigned char *packmem;
unsigned int packmemlen; unsigned int packmemlen;
uint32_t *vm4ip; uint32_t *vm4ip;
struct fstWriterContext *xc = (struct fstWriterContext *)ctx; struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
#ifdef FST_WRITER_PARALLEL
struct fstWriterContext *xc2 = xc->xc_parent;
#else
struct fstWriterContext *xc2 = xc;
#endif
#ifndef FST_DYNAMIC_ALIAS_DISABLE #ifndef FST_DYNAMIC_ALIAS_DISABLE
Pvoid_t PJHSArray = (Pvoid_t) NULL; Pvoid_t PJHSArray = (Pvoid_t) NULL;
@ -880,8 +1007,9 @@ for(i=0;i<xc->maxhandle;i++)
if(vm4ip[1] == 1) if(vm4ip[1] == 1)
{ {
wrlen = fstGetVarint32Length(vchg_mem + offs + 4); /* used to advance and determine wrlen */ wrlen = fstGetVarint32Length(vchg_mem + offs + 4); /* used to advance and determine wrlen */
#ifndef FST_REMOVE_DUPLICATE_VC
xc->curval_mem[vm4ip[0]] = vchg_mem[offs + 4 + wrlen]; /* checkpoint variable */ xc->curval_mem[vm4ip[0]] = vchg_mem[offs + 4 + wrlen]; /* checkpoint variable */
#endif
while(offs) while(offs)
{ {
unsigned char val; unsigned char val;
@ -941,8 +1069,9 @@ for(i=0;i<xc->maxhandle;i++)
else else
{ {
wrlen = fstGetVarint32Length(vchg_mem + offs + 4); /* used to advance and determine wrlen */ wrlen = fstGetVarint32Length(vchg_mem + offs + 4); /* used to advance and determine wrlen */
#ifndef FST_REMOVE_DUPLICATE_VC
memcpy(xc->curval_mem + vm4ip[0], vchg_mem + offs + 4 + wrlen, vm4ip[1]); /* checkpoint variable */ memcpy(xc->curval_mem + vm4ip[0], vchg_mem + offs + 4 + wrlen, vm4ip[1]); /* checkpoint variable */
#endif
while(offs) while(offs)
{ {
int idx; int idx;
@ -1137,7 +1266,7 @@ for(i=0;i<xc->maxhandle;i++)
#endif #endif
} }
vm4ip[3] = 0; /* vm4ip[3] = 0; ...redundant with clearing below */
#ifdef FST_DEBUG #ifdef FST_DEBUG
cnt++; cnt++;
#endif #endif
@ -1253,21 +1382,21 @@ fflush(xc->handle);
fseeko(xc->handle, endpos, SEEK_SET); /* seek to end of file */ fseeko(xc->handle, endpos, SEEK_SET); /* seek to end of file */
xc->section_header_truncpos = endpos; /* cache in case of need to truncate */ xc2->section_header_truncpos = endpos; /* cache in case of need to truncate */
if(xc->dump_size_limit) if(xc->dump_size_limit)
{ {
if(endpos >= xc->dump_size_limit) if(endpos >= xc->dump_size_limit)
{ {
xc->skip_writing_section_hdr = 1; xc2->skip_writing_section_hdr = 1;
xc->size_limit_locked = 1; xc2->size_limit_locked = 1;
xc->is_initial_time = 1; /* to trick emit value and emit time change */ xc2->is_initial_time = 1; /* to trick emit value and emit time change */
#ifdef FST_DEBUG #ifdef FST_DEBUG
printf("<< dump file size limit reached, stopping dumping >>\n"); printf("<< dump file size limit reached, stopping dumping >>\n");
#endif #endif
} }
} }
if(!xc->skip_writing_section_hdr) if(!xc2->skip_writing_section_hdr)
{ {
fstWriterEmitSectionHeader(xc); /* emit next section header */ fstWriterEmitSectionHeader(xc); /* emit next section header */
} }
@ -1277,6 +1406,89 @@ xc->already_in_flush = 0;
} }
#ifdef FST_WRITER_PARALLEL
static void *fstWriterFlushContextPrivate1(void *ctx)
{
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
fstWriterFlushContextPrivate2(xc);
pthread_mutex_unlock(&(xc->xc_parent->mutex));
#ifdef FST_REMOVE_DUPLICATE_VC
free(xc->curval_mem);
#endif
free(xc->valpos_mem);
free(xc->vchg_mem);
fclose(xc->tchn_handle);
free(xc);
return(NULL);
}
static void fstWriterFlushContextPrivate(void *ctx)
{
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
if(xc->parallel_enabled)
{
struct fstWriterContext *xc2 = malloc(sizeof(struct fstWriterContext));
int i;
pthread_mutex_lock(&xc->mutex);
pthread_mutex_unlock(&xc->mutex);
xc->xc_parent = xc;
memcpy(xc2, xc, sizeof(struct fstWriterContext));
xc2->valpos_mem = malloc(xc->maxhandle * 4 * sizeof(uint32_t));
memcpy(xc2->valpos_mem, xc->valpos_mem, xc->maxhandle * 4 * sizeof(uint32_t));
/* curval mem is updated in the thread */
#ifdef FST_REMOVE_DUPLICATE_VC
xc2->curval_mem = malloc(xc->maxvalpos);
memcpy(xc2->curval_mem, xc->curval_mem, xc->maxvalpos);
#endif
xc->vchg_mem = malloc(xc->vchg_alloc_siz);
xc->vchg_mem[0] = '!';
xc->vchg_siz = 1;
for(i=0;i<xc->maxhandle;i++)
{
uint32_t *vm4ip = &(xc->valpos_mem[4*i]);
vm4ip[2] = 0; /* zero out offset val */
vm4ip[3] = 0; /* zero out last time change val */
}
xc->tchn_cnt = xc->tchn_idx = 0;
xc->tchn_handle = tmpfile();
fseeko(xc->tchn_handle, 0, SEEK_SET);
fstFtruncate(fileno(xc->tchn_handle), 0);
xc->section_header_only = 0;
xc->secnum++;
pthread_mutex_lock(&xc->mutex);
pthread_create(&xc->thread, &xc->thread_attr, fstWriterFlushContextPrivate1, xc2);
}
else
{
if(xc->parallel_was_enabled) /* conservatively block */
{
pthread_mutex_lock(&xc->mutex);
pthread_mutex_unlock(&xc->mutex);
}
xc->xc_parent = xc;
fstWriterFlushContextPrivate2(xc);
}
}
#endif
/* /*
* queues up a flush context operation * queues up a flush context operation
*/ */
@ -1299,6 +1511,15 @@ if(xc)
void fstWriterClose(void *ctx) void fstWriterClose(void *ctx)
{ {
struct fstWriterContext *xc = (struct fstWriterContext *)ctx; struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
#ifdef FST_WRITER_PARALLEL
if(xc)
{
pthread_mutex_lock(&xc->mutex);
pthread_mutex_unlock(&xc->mutex);
}
#endif
if(xc && !xc->already_in_close && !xc->already_in_flush) if(xc && !xc->already_in_close && !xc->already_in_flush)
{ {
unsigned char *tmem; unsigned char *tmem;
@ -1328,6 +1549,10 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
} }
} }
fstWriterFlushContextPrivate(xc); fstWriterFlushContextPrivate(xc);
#ifdef FST_WRITER_PARALLEL
pthread_mutex_lock(&xc->mutex);
pthread_mutex_unlock(&xc->mutex);
#endif
} }
} }
fstDestroyMmaps(xc, 1); fstDestroyMmaps(xc, 1);
@ -1556,6 +1781,11 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
} }
#endif #endif
#ifdef FST_WRITER_PARALLEL
pthread_mutex_destroy(&xc->mutex);
pthread_attr_destroy(&xc->thread_attr);
#endif
free(xc->filename); xc->filename = NULL; free(xc->filename); xc->filename = NULL;
free(xc); free(xc);
} }
@ -1661,6 +1891,20 @@ if(xc && s)
} }
void fstWriterSetTimezero(void *ctx, int64_t tim)
{
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
if(xc)
{
off_t fpos = ftello(xc->handle);
fseeko(xc->handle, FST_HDR_OFFS_TIMEZERO, SEEK_SET);
fstWriterUint64(xc->handle, (xc->timezero = tim));
fflush(xc->handle);
fseeko(xc->handle, fpos, SEEK_SET);
}
}
void fstWriterSetPackType(void *ctx, int typ) void fstWriterSetPackType(void *ctx, int typ)
{ {
struct fstWriterContext *xc = (struct fstWriterContext *)ctx; struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
@ -1681,6 +1925,24 @@ if(xc)
} }
void fstWriterSetParallelMode(void *ctx, int enable)
{
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
if(xc)
{
xc->parallel_was_enabled |= xc->parallel_enabled; /* make sticky */
xc->parallel_enabled = (enable != 0);
#ifndef FST_WRITER_PARALLEL
if(xc->parallel_enabled)
{
fprintf(stderr, "ERROR: fstWriterSetParallelMode(), FST_WRITER_PARALLEL not enabled during compile, exiting.\n");
exit(255);
}
#endif
}
}
void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes) void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes)
{ {
struct fstWriterContext *xc = (struct fstWriterContext *)ctx; struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
@ -1745,6 +2007,22 @@ if(xc && nam)
if(aliasHandle > xc->maxhandle) aliasHandle = 0; if(aliasHandle > xc->maxhandle) aliasHandle = 0;
xc->hier_file_len += fstWriterVarint(xc->hier_handle, aliasHandle); xc->hier_file_len += fstWriterVarint(xc->hier_handle, aliasHandle);
xc->numsigs++; xc->numsigs++;
if(xc->numsigs == xc->next_huge_break)
{
if(xc->fst_break_size < xc->fst_huge_break_size)
{
xc->next_huge_break += FST_ACTIVATE_HUGE_INC;
xc->fst_break_size += xc->fst_orig_break_size;
xc->fst_break_add_size += xc->fst_orig_break_add_size;
xc->vchg_alloc_siz = xc->fst_break_size + xc->fst_break_add_size;
if(xc->vchg_mem)
{
xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz);
}
}
}
if(!aliasHandle) if(!aliasHandle)
{ {
uint32_t zero = 0; uint32_t zero = 0;
@ -1863,7 +2141,7 @@ if((xc) && (handle <= xc->maxhandle))
if((fpos + len + 10) > xc->vchg_alloc_siz) if((fpos + len + 10) > xc->vchg_alloc_siz)
{ {
xc->vchg_alloc_siz += (FST_BREAK_ADD_SIZE + len); /* +len added in the case of extremely long vectors and small break add sizes */ 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 = realloc(xc->vchg_mem, xc->vchg_alloc_siz); xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz);
if(!xc->vchg_mem) if(!xc->vchg_mem)
{ {
@ -1871,7 +2149,72 @@ if((xc) && (handle <= xc->maxhandle))
exit(255); exit(255);
} }
} }
#ifdef FST_REMOVE_DUPLICATE_VC
offs = vm4ip[0];
if(len != 1)
{
if((vm4ip[3]==xc->tchn_idx)&&(vm4ip[2]))
{
unsigned char *old_value = xc->vchg_mem + vm4ip[2] + 4; /* the +4 skips old vm4ip[2] value */
while(*(old_value++) & 0x80) { /* skips over varint encoded "xc->tchn_idx - vm4ip[3]" */ }
memcpy(old_value, buf, len); /* overlay new value */
memcpy(xc->curval_mem + offs, buf, len);
return;
}
else
{
if(!memcmp(xc->curval_mem + offs, buf, len))
{
if(!xc->curtime)
{
int i;
for(i=0;i<len;i++)
{
if(buf[i]!='x') break;
}
if(i<len) return;
}
else
{
return;
}
}
}
memcpy(xc->curval_mem + offs, buf, len);
}
else
{
if((vm4ip[3]==xc->tchn_idx)&&(vm4ip[2]))
{
unsigned char *old_value = xc->vchg_mem + vm4ip[2] + 4; /* the +4 skips old vm4ip[2] value */
while(*(old_value++) & 0x80) { /* skips over varint encoded "xc->tchn_idx - vm4ip[3]" */ }
*old_value = *buf; /* overlay new value */
*(xc->curval_mem + offs) = *buf;
return;
}
else
{
if((*(xc->curval_mem + offs)) == (*buf))
{
if(!xc->curtime)
{
if(*buf != 'x') return;
}
else
{
return;
}
}
}
*(xc->curval_mem + offs) = *buf;
}
#endif
xc->vchg_siz += fstWriterUint32WithVarint32(xc, &vm4ip[2], xc->tchn_idx - vm4ip[3], buf, len); /* do one fwrite op only */ xc->vchg_siz += fstWriterUint32WithVarint32(xc, &vm4ip[2], xc->tchn_idx - vm4ip[3], buf, len); /* do one fwrite op only */
vm4ip[3] = xc->tchn_idx; vm4ip[3] = xc->tchn_idx;
vm4ip[2] = fpos; vm4ip[2] = fpos;
@ -1912,7 +2255,7 @@ if((xc) && (handle <= xc->maxhandle))
if((fpos + len + 10 + 5) > xc->vchg_alloc_siz) if((fpos + len + 10 + 5) > xc->vchg_alloc_siz)
{ {
xc->vchg_alloc_siz += (FST_BREAK_ADD_SIZE + len + 5); /* +len added in the case of extremely long vectors and small break add sizes */ 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 = realloc(xc->vchg_mem, xc->vchg_alloc_siz); xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz);
if(!xc->vchg_mem) if(!xc->vchg_mem)
{ {
@ -1964,7 +2307,7 @@ if(xc)
} }
else else
{ {
if((xc->vchg_siz >= FST_BREAK_SIZE) || (xc->flush_context_pending)) if((xc->vchg_siz >= xc->fst_break_size) || (xc->flush_context_pending))
{ {
xc->flush_context_pending = 0; xc->flush_context_pending = 0;
fstWriterFlushContextPrivate(xc); fstWriterFlushContextPrivate(xc);
@ -2044,9 +2387,6 @@ struct fstReaderContext
/* common entries */ /* common entries */
FILE *f, *fh; FILE *f, *fh;
#ifdef __MINGW32__
char *fh_name;
#endif
uint64_t start_time, end_time; uint64_t start_time, end_time;
uint64_t mem_used_by_writer; uint64_t mem_used_by_writer;
@ -2071,6 +2411,7 @@ unsigned limit_range_valid : 1; /* valid for limit_range_start, limit_range_end
char version[FST_HDR_SIM_VERSION_SIZE + 1]; char version[FST_HDR_SIM_VERSION_SIZE + 1];
char date[FST_HDR_DATE_SIZE + 1]; char date[FST_HDR_DATE_SIZE + 1];
int64_t timezero;
char *filename, *filename_unpacked; char *filename, *filename_unpacked;
off_t hier_pos; off_t hier_pos;
@ -2410,6 +2751,12 @@ struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
return(xc ? xc->date : NULL); return(xc ? xc->date : NULL);
} }
int64_t fstReaderGetTimezero(void *ctx)
{
struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
return(xc ? xc->timezero : 0);
}
uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx) uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx)
{ {
@ -2562,8 +2909,10 @@ if(!xc->fh)
return(0); return(0);
} }
#ifndef __MINGW32__
xc->fh = fopen(fnam, "w+b"); xc->fh = fopen(fnam, "w+b");
if(!xc->fh) if(!xc->fh)
#endif
{ {
xc->fh = tmpfile(); xc->fh = tmpfile();
free(fnam); fnam = NULL; free(fnam); fnam = NULL;
@ -2599,12 +2948,7 @@ if(!xc->fh)
} }
gzclose(zhandle); gzclose(zhandle);
free(mem); free(mem);
#ifndef __MINGW32__
free(fnam); free(fnam);
#else
xc->fh_name = fnam;
#endif
fseeko(xc->f, offs_cache, SEEK_SET); fseeko(xc->f, offs_cache, SEEK_SET);
} }
@ -2784,10 +3128,13 @@ if(fv)
fprintf(fv, "$date\n\t%s\n$end\n", xc->date); fprintf(fv, "$date\n\t%s\n$end\n", xc->date);
fprintf(fv, "$version\n\t%s\n$end\n", xc->version); fprintf(fv, "$version\n\t%s\n$end\n", xc->version);
if(xc->timezero) fprintf(fv, "$timezero\n\t%"PRId64"\n$end\n", xc->timezero);
switch(xc->timescale) switch(xc->timescale)
{ {
case 0: break; case 2: time_scale = 100; time_dimension[0] = ' '; break;
case 1: time_scale = 10;
case 0: time_dimension[0] = ' '; break;
case -1: time_scale = 100; time_dimension[0] = 'm'; break; case -1: time_scale = 100; time_dimension[0] = 'm'; break;
case -2: time_scale = 10; case -2: time_scale = 10;
@ -3117,6 +3464,7 @@ if(gzread_pass_status)
xc->version[FST_HDR_SIM_VERSION_SIZE] = 0; xc->version[FST_HDR_SIM_VERSION_SIZE] = 0;
fstFread(xc->date, FST_HDR_DATE_SIZE, 1, xc->f); fstFread(xc->date, FST_HDR_DATE_SIZE, 1, xc->f);
xc->date[FST_HDR_DATE_SIZE] = 0; xc->date[FST_HDR_DATE_SIZE] = 0;
xc->timezero = fstReaderUint64(xc->f);
} }
} }
else if((sectype == FST_BL_VCDATA) || (sectype == FST_BL_VCDATA_DYN_ALIAS)) else if((sectype == FST_BL_VCDATA) || (sectype == FST_BL_VCDATA_DYN_ALIAS))
@ -3254,6 +3602,14 @@ return(hdr_seen);
} }
void *fstReaderOpenForUtilitiesOnly(void)
{
struct fstReaderContext *xc = calloc(1, sizeof(struct fstReaderContext));
return(xc);
}
void *fstReaderOpen(const char *nam) void *fstReaderOpen(const char *nam)
{ {
struct fstReaderContext *xc = calloc(1, sizeof(struct fstReaderContext)); struct fstReaderContext *xc = calloc(1, sizeof(struct fstReaderContext));
@ -3334,13 +3690,6 @@ if(xc)
if(xc->fh) if(xc->fh)
{ {
fclose(xc->fh); xc->fh = NULL; fclose(xc->fh); xc->fh = NULL;
#ifdef __MINGW32__
if(xc->fh_name)
{
unlink(xc->fh_name);
free(xc->fh_name); xc->fh_name = NULL;
}
#endif
} }
if(xc->f) if(xc->f)
@ -5042,6 +5391,7 @@ int fstUtilityBinToEsc(unsigned char *d, unsigned char *s, int len)
{ {
unsigned char *src = s; unsigned char *src = s;
unsigned char *dst = d; unsigned char *dst = d;
unsigned char val;
int i; int i;
for(i=0;i<len;i++) for(i=0;i<len;i++)
@ -5065,10 +5415,11 @@ for(i=0;i<len;i++)
} }
else else
{ {
val = src[i];
*(dst++) = '\\'; *(dst++) = '\\';
*(dst++) = (src[i]/64) + '0'; src[i] = src[i] & 63; *(dst++) = (val/64) + '0'; val = val & 63;
*(dst++) = (src[i]/8) + '0'; src[i] = src[i] & 7; *(dst++) = (val/8) + '0'; val = val & 7;
*(dst++) = (src[i]) + '0'; *(dst++) = (val) + '0';
} }
break; break;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2010 Tony Bybell. * Copyright (c) 2009-2012 Tony Bybell.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -148,6 +148,7 @@ fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
void fstWriterSetPackType(void *ctx, int typ); /* type = 0 (libz), 1 (fastlz) */ void fstWriterSetPackType(void *ctx, int typ); /* type = 0 (libz), 1 (fastlz) */
void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */ void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */
void fstWriterSetParallelMode(void *ctx, int enable);
void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes); void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes);
int fstWriterGetDumpSizeLimitReached(void *ctx); int fstWriterGetDumpSizeLimitReached(void *ctx);
@ -157,6 +158,7 @@ void fstWriterSetDate(void *ctx, const char *dat);
void fstWriterSetVersion(void *ctx, const char *vers); void fstWriterSetVersion(void *ctx, const char *vers);
void fstWriterSetTimescale(void *ctx, int ts); void fstWriterSetTimescale(void *ctx, int ts);
void fstWriterSetTimescaleFromString(void *ctx, const char *s); void fstWriterSetTimescaleFromString(void *ctx, const char *s);
void fstWriterSetTimezero(void *ctx, int64_t tim);
void fstWriterSetScope(void *ctx, enum fstScopeType scopetype, void fstWriterSetScope(void *ctx, enum fstScopeType scopetype,
const char *scopename, const char *scopecomp); const char *scopename, const char *scopecomp);
void fstWriterSetUpscope(void *ctx); void fstWriterSetUpscope(void *ctx);
@ -170,6 +172,7 @@ void fstWriterFlushContext(void *ctx);
* reader functions * reader functions
*/ */
void *fstReaderOpen(const char *nam); void *fstReaderOpen(const char *nam);
void *fstReaderOpenForUtilitiesOnly(void);
void fstReaderClose(void *ctx); void fstReaderClose(void *ctx);
int fstReaderProcessHier(void *ctx, FILE *vcdhandle); int fstReaderProcessHier(void *ctx, FILE *vcdhandle);
@ -184,6 +187,7 @@ void *fstReaderGetCurrentScopeUserInfo(void *ctx);
int fstReaderGetCurrentScopeLen(void *ctx); int fstReaderGetCurrentScopeLen(void *ctx);
signed char fstReaderGetTimescale(void *ctx); signed char fstReaderGetTimescale(void *ctx);
int64_t fstReaderGetTimezero(void *ctx);
uint64_t fstReaderGetStartTime(void *ctx); uint64_t fstReaderGetStartTime(void *ctx);
uint64_t fstReaderGetEndTime(void *ctx); uint64_t fstReaderGetEndTime(void *ctx);
uint64_t fstReaderGetMemoryUsedByWriter(void *ctx); uint64_t fstReaderGetMemoryUsedByWriter(void *ctx);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003-2008 Tony Bybell. * Copyright (c) 2003-2012 Tony Bybell.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -663,11 +663,24 @@ if((lt)&&(lt->numfacs))
lt->sorted_facs[i]->facnum = i; lt->sorted_facs[i]->facnum = i;
} }
lt->facname_offset=lt->position; if(!lt->timezero)
{
lxt2_wr_emit_u32(lt, lt->numfacs); /* uncompressed */
}
else
{
lxt2_wr_emit_u32(lt, 0); /* uncompressed, flag to insert extra parameters */
lxt2_wr_emit_u32(lt, 8); /* uncompressed 8 counts timezero and on */
lxt2_wr_emit_u32(lt, lt->numfacs); /* uncompressed */
lxt2_wr_emit_u64(lt, (lt->timezero >> 32) & 0xffffffffL, lt->timezero & 0xffffffffL); /* uncompressed */
}
lxt2_wr_emit_u32(lt, lt->numfacs); /* uncompressed */
lxt2_wr_emit_u32(lt, lt->numfacbytes); /* uncompressed */ lxt2_wr_emit_u32(lt, lt->numfacbytes); /* uncompressed */
lxt2_wr_emit_u32(lt, lt->longestname); /* uncompressed */ lxt2_wr_emit_u32(lt, lt->longestname); /* uncompressed */
lt->facname_offset=lt->position;
lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacnamesize */ lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacnamesize */
lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacname_predec_size */ lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacname_predec_size */
lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacgeometrysize */ lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacgeometrysize */
@ -720,7 +733,7 @@ if((lt)&&(lt->numfacs))
lt->break_header_size = lt->position; /* in case we need to emit multiple lxt2s with same header */ lt->break_header_size = lt->position; /* in case we need to emit multiple lxt2s with same header */
lt->zfacgeometry_size = lt->position - lt->facgeometry_offset; lt->zfacgeometry_size = lt->position - lt->facgeometry_offset;
fseeko(lt->handle, lt->facname_offset + 12, SEEK_SET); fseeko(lt->handle, lt->facname_offset, SEEK_SET);
lxt2_wr_emit_u32(lt, lt->zfacname_size); /* backpatch sizes... */ lxt2_wr_emit_u32(lt, lt->zfacname_size); /* backpatch sizes... */
lxt2_wr_emit_u32(lt, lt->zfacname_predec_size); lxt2_wr_emit_u32(lt, lt->zfacname_predec_size);
lxt2_wr_emit_u32(lt, lt->zfacgeometry_size); lxt2_wr_emit_u32(lt, lt->zfacgeometry_size);
@ -2178,3 +2191,15 @@ if(lt)
} }
} }
/*
* time zero offset
*/
void lxt2_wr_set_timezero(struct lxt2_wr_trace *lt, lxtstime_t timeval)
{
if(lt)
{
lt->timezero = timeval;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003-2010 Tony Bybell. * Copyright (c) 2003-2012 Tony Bybell.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -60,6 +60,7 @@ extern "C" {
#define LXT2_WR_SYMPRIME 500009 #define LXT2_WR_SYMPRIME 500009
typedef uint64_t lxttime_t; typedef uint64_t lxttime_t;
typedef int64_t lxtstime_t;
#ifndef _MSC_VER #ifndef _MSC_VER
@ -170,6 +171,7 @@ int numsections, numblock;
off_t facname_offset, facgeometry_offset; off_t facname_offset, facgeometry_offset;
lxttime_t mintime, maxtime; lxttime_t mintime, maxtime;
lxtstime_t timezero;
unsigned int timegranule; unsigned int timegranule;
int timescale; int timescale;
int timepos; int timepos;
@ -291,6 +293,7 @@ void lxt2_wr_set_maxgranule(struct lxt2_wr_trace *lt, unsigned int maxgranule
/* time ops */ /* time ops */
void lxt2_wr_set_timescale(struct lxt2_wr_trace *lt, int timescale); void lxt2_wr_set_timescale(struct lxt2_wr_trace *lt, int timescale);
void lxt2_wr_set_timezero(struct lxt2_wr_trace *lt, lxtstime_t timeval);
int lxt2_wr_set_time(struct lxt2_wr_trace *lt, unsigned int timeval); int lxt2_wr_set_time(struct lxt2_wr_trace *lt, unsigned int timeval);
int lxt2_wr_inc_time_by_delta(struct lxt2_wr_trace *lt, unsigned int timeval); int lxt2_wr_inc_time_by_delta(struct lxt2_wr_trace *lt, unsigned int timeval);
int lxt2_wr_set_time64(struct lxt2_wr_trace *lt, lxttime_t timeval); int lxt2_wr_set_time64(struct lxt2_wr_trace *lt, lxttime_t timeval);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-9 Tony Bybell. * Copyright (c) 2001-2012 Tony Bybell.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -1208,6 +1208,12 @@ if(lt)
lt->dumpoffcount = 0; lt->dumpoffcount = 0;
} }
if(lt->timezero)
{
lt->timezero_offset = lt->position;
lt_emit_u64(lt, (int)((lt->timezero)>>32), (int)lt->timezero);
}
/* prefix */ /* prefix */
lt_emit_u8(lt, LT_SECTION_END); lt_emit_u8(lt, LT_SECTION_END);
@ -1237,6 +1243,9 @@ if(lt)
/* Version 5 adds */ /* Version 5 adds */
if(lt->exclude_offset) { lt_emit_u32(lt, lt->exclude_offset); lt_emit_u8(lt, LT_SECTION_EXCLUDE_TABLE); lt->exclude_offset = 0; } if(lt->exclude_offset) { lt_emit_u32(lt, lt->exclude_offset); lt_emit_u8(lt, LT_SECTION_EXCLUDE_TABLE); lt->exclude_offset = 0; }
/* Version 6 adds */
if(lt->timezero_offset) { lt_emit_u32(lt, lt->timezero_offset); lt_emit_u8(lt, LT_SECTION_TIMEZERO); lt->timezero_offset = 0; }
/* suffix */ /* suffix */
lt_emit_u8(lt, LT_TRLID); lt_emit_u8(lt, LT_TRLID);
@ -2808,3 +2817,11 @@ if((lt)&&(lt->dumpoff_active))
} }
} }
void lt_set_timezero(struct lt_trace *lt, lxtotime_t timeval)
{
if(lt)
{
lt->timezero = timeval;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-3 Tony Bybell. * Copyright (c) 2001-2012 Tony Bybell.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -72,9 +72,11 @@ enum lt_zmode_types { LT_ZMODE_NONE, LT_ZMODE_GZIP, LT_ZMODE_BZIP2 };
#ifndef _MSC_VER #ifndef _MSC_VER
typedef uint64_t lxttime_t; typedef uint64_t lxttime_t;
#define ULLDescriptor(x) x##ULL #define ULLDescriptor(x) x##ULL
typedef int64_t lxtotime_t;
#else #else
typedef unsigned __int64 lxttime_t; typedef unsigned __int64 lxttime_t;
#define ULLDescriptor(x) x##i64 #define ULLDescriptor(x) x##i64
typedef __int64 lxtotime_t;
#endif #endif
@ -108,6 +110,7 @@ unsigned int position;
#define LT_SECTION_ZDICTIONARY (17) #define LT_SECTION_ZDICTIONARY (17)
#define LT_SECTION_ZDICTIONARY_SIZE (18) #define LT_SECTION_ZDICTIONARY_SIZE (18)
#define LT_SECTION_EXCLUDE_TABLE (19) #define LT_SECTION_EXCLUDE_TABLE (19)
#define LT_SECTION_TIMEZERO (20)
struct lt_trace struct lt_trace
{ {
@ -164,11 +167,13 @@ unsigned int timescale_offset;
unsigned int double_test_offset; unsigned int double_test_offset;
unsigned int dictionary_offset; unsigned int dictionary_offset;
unsigned int exclude_offset; unsigned int exclude_offset;
unsigned int timezero_offset;
char *compress_fac_str; char *compress_fac_str;
int compress_fac_len; int compress_fac_len;
lxttime_t timeval; /* for clock induction, current time */ lxttime_t timeval; /* for clock induction, current time */
lxtotime_t timezero; /* for allowing negative values */
unsigned dumpoff_active : 1; /* when set we're not dumping */ unsigned dumpoff_active : 1; /* when set we're not dumping */
unsigned double_used : 1; unsigned double_used : 1;
@ -234,6 +239,7 @@ void lt_set_clock_compress(struct lt_trace *lt);
void lt_set_dict_compress(struct lt_trace *lt, unsigned int minwidth); void lt_set_dict_compress(struct lt_trace *lt, unsigned int minwidth);
void lt_set_initial_value(struct lt_trace *lt, char value); void lt_set_initial_value(struct lt_trace *lt, char value);
void lt_set_timescale(struct lt_trace *lt, int timescale); void lt_set_timescale(struct lt_trace *lt, int timescale);
void lt_set_timezero(struct lt_trace *lt, lxtotime_t timeval);
int lt_set_time(struct lt_trace *lt, unsigned int timeval); int lt_set_time(struct lt_trace *lt, unsigned int timeval);
int lt_inc_time_by_delta(struct lt_trace *lt, unsigned int timeval); int lt_inc_time_by_delta(struct lt_trace *lt, unsigned int timeval);