From 7ce1d1bc27999054c221fc9e97449fcb086e8e88 Mon Sep 17 00:00:00 2001 From: umarcor Date: Fri, 23 Apr 2021 23:22:46 +0200 Subject: ghw: rename 'ghwlib' to 'libghw' (#1741) --- Makefile.in | 20 +- doc/ghw/index.rst | 4 +- ghw/ghwdump.c | 2 +- ghw/ghwlib.c | 2240 ----------------------------------------------------- ghw/ghwlib.h | 471 ----------- ghw/libghw.c | 2240 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ghw/libghw.h | 471 +++++++++++ 7 files changed, 2724 insertions(+), 2724 deletions(-) delete mode 100644 ghw/ghwlib.c delete mode 100644 ghw/ghwlib.h create mode 100644 ghw/libghw.c create mode 100644 ghw/libghw.h diff --git a/Makefile.in b/Makefile.in index 561510bc5..082596174 100644 --- a/Makefile.in +++ b/Makefile.in @@ -472,33 +472,33 @@ libghdl-py.tgz: ################ ghwdump ################################################# -GHWDUMP_OBJS=ghwdump.o ghwlib.o +GHWDUMP_OBJS=ghwdump.o libghw.o ghwdump: ghwdump$(EXEEXT) ghwdump$(EXEEXT): $(GHWDUMP_OBJS) $(CC) -o $@ $(GHWDUMP_OBJS) -ghwlib$(SOEXT): ghwlib.o - $(CC) $(PIC_FLAGS) -shared -o lib/$@ ghwlib.o +libghw$(SOEXT): libghw.o + $(CC) $(PIC_FLAGS) -shared -o lib/$@ libghw.o -ghwdump.o: $(srcdir)/ghw/ghwdump.c $(srcdir)/ghw/ghwlib.h +ghwdump.o: $(srcdir)/ghw/ghwdump.c $(srcdir)/ghw/libghw.h $(CC) -c -o $@ $< $(OPT_FLAGS) $(WARN_CFLAGS) -ghwlib.o: $(srcdir)/ghw/ghwlib.c $(srcdir)/ghw/ghwlib.h +libghw.o: $(srcdir)/ghw/libghw.c $(srcdir)/ghw/libghw.h $(CC) $(PIC_FLAGS) -c -o $@ $< $(OPT_FLAGS) $(WARN_CFLAGS) -all.ghw: ghwdump$(EXEEXT) ghwlib$(SOEXT) +all.ghw: ghwdump$(EXEEXT) libghw$(SOEXT) install.ghw: $(INSTALL_PROGRAM) -p ghwdump$(EXEEXT) $(DESTDIR)$(bindir)/ - $(INSTALL_PROGRAM) -p lib/ghwlib$(SOEXT) $(DESTDIR)$(libdir)/ - $(INSTALL_DATA) -p $(srcdir)/ghw/ghwlib.h $(DESTDIR)$(incdir)/ghdl/ + $(INSTALL_PROGRAM) -p lib/libghw$(SOEXT) $(DESTDIR)$(libdir)/ + $(INSTALL_DATA) -p $(srcdir)/ghw/libghw.h $(DESTDIR)$(incdir)/ghdl/ uninstall.ghw: $(RM) $(DESTDIR)$(bindir)/ghwdump$(EXEEXT) - $(RM) $(DESTDIR)$(libdir)/ghwlib$(EXEEXT) - $(RM) -f $(DESTDIR)$(incdir)/ghdl/ghwlib.h + $(RM) $(DESTDIR)$(libdir)/libghw$(EXEEXT) + $(RM) -f $(DESTDIR)$(incdir)/ghdl/libghw.h ############### grt ##################################################### diff --git a/doc/ghw/index.rst b/doc/ghw/index.rst index af8a12384..bc3d7284f 100644 --- a/doc/ghw/index.rst +++ b/doc/ghw/index.rst @@ -13,7 +13,7 @@ However, VCD/EVCD cannot handle certain signal types from the VHDL language. There is neither any equivalent in the VHDL LRM. So, the author of GHDL, Tristan Gingold, implemented an alternative format named GHW, for allowing all VHDL types to be dumped. -He also contributed a reader to GTKWave based on ghwlib (see `gtkwave/gtkwave/search?q=ghwlib `__ and `gtkwave/gtkwave: gtkwave3/src/ghw.c `__), +He also contributed a reader to GTKWave based on libghw (see `gtkwave/gtkwave/search?q=libghw `__ and `gtkwave/gtkwave: gtkwave3/src/ghw.c `__), which allows visualizing GHW waves . The GHW format is not completely fixed, and it might change slightly as new language features are implemented in GHDL @@ -24,7 +24,7 @@ Nevertheless, the GHDL codebase (:ghdlsrc:`grt/grt-waves.adb In `nturley/ghw-notes `__, there is some work for defining the GHW format as a Kaitai Struct (see `kaitai.io `__). -ghwlib +libghw ====== GHW reading features are provided as a shared library, which is built and installed with GHDL by default. diff --git a/ghw/ghwdump.c b/ghw/ghwdump.c index 2acb0cab5..fe74e5f9a 100644 --- a/ghw/ghwdump.c +++ b/ghw/ghwdump.c @@ -22,7 +22,7 @@ #include #include -#include "ghwlib.h" +#include "libghw.h" static const char *progname; void diff --git a/ghw/ghwlib.c b/ghw/ghwlib.c deleted file mode 100644 index cb90fbcdf..000000000 --- a/ghw/ghwlib.c +++ /dev/null @@ -1,2240 +0,0 @@ -/* GHDL Wavefile reader library. - Copyright (C) 2005 Tristan Gingold - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program 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. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include -#include -#include -#include -#include - -#include "ghwlib.h" - -/* Reopen H through decompressor DECOMP. */ - -static int -ghw_openz (struct ghw_handler *h, const char *decomp, const char *filename) -{ - int plen = strlen (decomp) + 1 + strlen (filename) + 1; - char *p = malloc (plen); - - snprintf (p, plen, "%s %s", decomp, filename); - fclose (h->stream); - h->stream = popen (p, "r"); - free (p); - - if (h->stream == NULL) - return -1; - - h->stream_ispipe = 1; - - return 0; -} - -int -ghw_open (struct ghw_handler *h, const char *filename) -{ - char hdr[16]; - - h->stream = fopen (filename, "rb"); - if (h->stream == NULL) - return -1; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - - /* Check compression layer. */ - if (!memcmp (hdr, "\x1f\x8b", 2)) - { - if (ghw_openz (h, "gzip -cd", filename) < 0) - return -1; - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - } - else if (!memcmp (hdr, "BZ", 2)) - { - if (ghw_openz (h, "bzip2 -cd", filename) < 0) - return -1; - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - } - else - { - h->stream_ispipe = 0; - } - - /* Check magic. */ - if (memcmp (hdr, "GHDLwave\n", 9) != 0) - return -2; - /* Check version. */ - if (hdr[9] != 16 || hdr[10] != 0) - return -2; - h->version = hdr[11]; - if (h->version > 1) - return -3; - if (hdr[12] == 1) - h->word_be = 0; - else if (hdr[12] == 2) - h->word_be = 1; - else - return -4; -#if 0 - /* Endianness. */ - { - int endian; - union - { - unsigned char b[4]; - uint32_t i; - } v; - v.i = 0x11223344; - if (v.b[0] == 0x11) - endian = 2; - else if (v.b[0] == 0x44) - endian = 1; - else - return -3; - - if (hdr[12] != 1 && hdr[12] != 2) - return -3; - if (hdr[12] != endian) - h->swap_word = 1; - else - h->swap_word = 0; - } -#endif - h->word_len = hdr[13]; - h->off_len = hdr[14]; - - if (hdr[15] != 0) - return -5; - - h->hie = NULL; - return 0; -} - -int32_t -ghw_get_i32 (struct ghw_handler *h, unsigned char *b) -{ - if (h->word_be) - return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3] << 0); - else - return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0] << 0); -} - -int64_t -ghw_get_i64 (struct ghw_handler *ghw_h, unsigned char *b) -{ - int l, h; - - if (ghw_h->word_be) - { - h = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3] << 0); - l = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7] << 0); - } - else - { - l = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0] << 0); - h = (b[7] << 24) | (b[6] << 16) | (b[5] << 8) | (b[4] << 0); - } - return (((int64_t) h) << 32) | l; -} - -int -ghw_read_byte (struct ghw_handler *h, unsigned char *res) -{ - int v; - - v = fgetc (h->stream); - if (v == EOF) - return -1; - *res = v; - return 0; -} - -int -ghw_read_uleb128 (struct ghw_handler *h, uint32_t * res) -{ - uint32_t r = 0; - unsigned int off = 0; - - while (1) - { - int v = fgetc (h->stream); - if (v == EOF) - return -1; - r |= (v & 0x7f) << off; - if ((v & 0x80) == 0) - break; - off += 7; - } - *res = r; - return 0; -} - -int -ghw_read_sleb128 (struct ghw_handler *h, int32_t * res) -{ - int32_t r = 0; - unsigned int off = 0; - - while (1) - { - int v = fgetc (h->stream); - if (v == EOF) - return -1; - r |= ((int32_t) (v & 0x7f)) << off; - off += 7; - if ((v & 0x80) == 0) - { - if ((v & 0x40) && off < 32) - r |= ~0U << off; - break; - } - } - *res = r; - return 0; -} - -int -ghw_read_lsleb128 (struct ghw_handler *h, int64_t * res) -{ - static const int64_t r_mask = -1; - int64_t r = 0; - unsigned int off = 0; - - while (1) - { - int v = fgetc (h->stream); - if (v == EOF) - return -1; - r |= ((int64_t) (v & 0x7f)) << off; - off += 7; - if ((v & 0x80) == 0) - { - if ((v & 0x40) && off < 64) - r |= r_mask << off; - break; - } - } - *res = r; - return 0; -} - -int -ghw_read_f64 (struct ghw_handler *h, double *res) -{ - /* FIXME: handle byte order. */ - if (fread (res, sizeof (*res), 1, h->stream) != 1) - return -1; - return 0; -} - -const char * -ghw_read_strid (struct ghw_handler *h) -{ - uint32_t id; - - if (ghw_read_uleb128 (h, &id) != 0) - return NULL; - return h->str_table[id]; -} - -union ghw_type * -ghw_read_typeid (struct ghw_handler *h) -{ - uint32_t id; - - if (ghw_read_uleb128 (h, &id) != 0) - return NULL; - return h->types[id - 1]; -} - -union ghw_range * -ghw_read_range (struct ghw_handler *h) -{ - int t = fgetc (h->stream); - if (t == EOF) - return NULL; - switch (t & 0x7f) - { - case ghdl_rtik_type_b2: - { - struct ghw_range_b2 *r; - r = malloc (sizeof (struct ghw_range_b2)); - r->kind = t & 0x7f; - r->dir = (t & 0x80) != 0; - if (ghw_read_byte (h, &r->left) != 0) - goto err_b2; - if (ghw_read_byte (h, &r->right) != 0) - goto err_b2; - return (union ghw_range *) r; - err_b2: - free (r); - return NULL; - } - case ghdl_rtik_type_e8: - { - struct ghw_range_e8 *r; - r = malloc (sizeof (struct ghw_range_e8)); - r->kind = t & 0x7f; - r->dir = (t & 0x80) != 0; - if (ghw_read_byte (h, &r->left) != 0) - goto err_e8; - if (ghw_read_byte (h, &r->right) != 0) - goto err_e8; - return (union ghw_range *) r; - err_e8: - free (r); - return NULL; - } - case ghdl_rtik_type_i32: - case ghdl_rtik_type_p32: - { - struct ghw_range_i32 *r; - r = malloc (sizeof (struct ghw_range_i32)); - r->kind = t & 0x7f; - r->dir = (t & 0x80) != 0; - if (ghw_read_sleb128 (h, &r->left) != 0) - goto err_i32; - if (ghw_read_sleb128 (h, &r->right) != 0) - goto err_i32; - return (union ghw_range *) r; - err_i32: - free (r); - return NULL; - } - case ghdl_rtik_type_i64: - case ghdl_rtik_type_p64: - { - struct ghw_range_i64 *r; - r = malloc (sizeof (struct ghw_range_i64)); - r->kind = t & 0x7f; - r->dir = (t & 0x80) != 0; - if (ghw_read_lsleb128 (h, &r->left) != 0) - goto err_i64; - if (ghw_read_lsleb128 (h, &r->right) != 0) - goto err_i64; - return (union ghw_range *) r; - err_i64: - free (r); - return NULL; - } - case ghdl_rtik_type_f64: - { - struct ghw_range_f64 *r; - r = malloc (sizeof (struct ghw_range_f64)); - r->kind = t & 0x7f; - r->dir = (t & 0x80) != 0; - if (ghw_read_f64 (h, &r->left) != 0) - goto err_f64; - if (ghw_read_f64 (h, &r->right) != 0) - goto err_f64; - return (union ghw_range *) r; - err_f64: - free (r); - return NULL; - } - default: - fprintf (stderr, "ghw_read_range: type %d unhandled\n", t & 0x7f); - return NULL; - } -} - -int -ghw_read_str (struct ghw_handler *h) -{ - unsigned char hdr[12]; - unsigned i; - char *p; - int prev_len; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - - if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) - return -1; - h->nbr_str = ghw_get_i32 (h, &hdr[4]); - h->nbr_str++; - h->str_size = ghw_get_i32 (h, &hdr[8]); - h->str_table = (char **) malloc ((h->nbr_str + 1) * sizeof (char *)); - h->str_content = (char *) malloc (h->str_size + h->nbr_str + 1); - - if (h->flag_verbose) - { - printf ("Number of strings: %u\n", h->nbr_str - 1); - printf ("String table size: %u\n", h->str_size); - } - - h->str_table[0] = ""; - p = h->str_content; - prev_len = 0; - for (i = 1; i < h->nbr_str; i++) - { - int j; - int c; - char *prev; - int sh; - - h->str_table[i] = p; - prev = h->str_table[i - 1]; - for (j = 0; j < prev_len; j++) - *p++ = prev[j]; - - while (1) - { - c = fgetc (h->stream); - if (c == EOF) - return -1; - if ((c >= 0 && c <= 31) || (c >= 128 && c <= 159)) - break; - *p++ = c; - } - *p++ = 0; - - if (h->flag_verbose > 1) - printf (" string %u (pl=%d): %s\n", i, prev_len, h->str_table[i]); - - prev_len = c & 0x1f; - sh = 5; - while (c >= 128) - { - c = fgetc (h->stream); - if (c == EOF) - return -1; - prev_len |= (c & 0x1f) << sh; - sh += 5; - } - } - if (fread (hdr, 4, 1, h->stream) != 1) - return -1; - if (memcmp (hdr, "EOS", 4) != 0) - return -1; - return 0; -} - -union ghw_type * -ghw_get_base_type (union ghw_type *t) -{ - switch (t->kind) - { - case ghdl_rtik_type_b2: - case ghdl_rtik_type_e8: - case ghdl_rtik_type_e32: - case ghdl_rtik_type_i32: - case ghdl_rtik_type_i64: - case ghdl_rtik_type_f64: - case ghdl_rtik_type_p32: - case ghdl_rtik_type_p64: - case ghdl_rtik_type_array: - return t; - case ghdl_rtik_subtype_scalar: - return t->ss.base; - case ghdl_rtik_subtype_array: - return t->sa.base; - case ghdl_rtik_subtype_unbounded_array: - return t->sua.base; - default: - fprintf (stderr, "ghw_get_base_type: cannot handle type %d\n", t->kind); - abort (); - } -} - -/* Return -1 for unbounded types. */ -static int -get_nbr_elements (union ghw_type *t) -{ - switch (t->kind) - { - case ghdl_rtik_type_b2: - case ghdl_rtik_type_e8: - case ghdl_rtik_type_e32: - case ghdl_rtik_type_i32: - case ghdl_rtik_type_i64: - case ghdl_rtik_type_f64: - case ghdl_rtik_type_p32: - case ghdl_rtik_type_p64: - case ghdl_rtik_subtype_scalar: - return 1; - case ghdl_rtik_type_array: - return -1; - case ghdl_rtik_subtype_array: - return t->sa.nbr_scalars; - case ghdl_rtik_type_record: - return t->rec.nbr_scalars; - case ghdl_rtik_subtype_record: - return t->sr.nbr_scalars; - case ghdl_rtik_subtype_unbounded_record: - case ghdl_rtik_subtype_unbounded_array: - return -1; - default: - fprintf (stderr, "get_nbr_elements: unhandled type %d\n", t->kind); - abort (); - } -} - -int -ghw_get_range_length (union ghw_range *rng) -{ - int res; - - assert (rng != NULL); - - switch (rng->kind) - { - case ghdl_rtik_type_i32: - if (rng->i32.dir) - res = rng->i32.left - rng->i32.right + 1; - else - res = rng->i32.right - rng->i32.left + 1; - break; - case ghdl_rtik_type_b2: - if (rng->b2.dir) - res = rng->b2.left - rng->b2.right + 1; - else - res = rng->b2.right - rng->b2.left + 1; - break; - case ghdl_rtik_type_e8: - if (rng->e8.dir) - res = rng->e8.left - rng->e8.right + 1; - else - res = rng->e8.right - rng->e8.left + 1; - break; - default: - fprintf (stderr, "get_range_length: unhandled kind %d\n", rng->kind); - abort (); - } - /* The length of a null range is 0. */ - return (res <= 0) ? 0 : res; -} - -static union ghw_type *ghw_read_type_bounds (struct ghw_handler *h, - union ghw_type *base); - -/* Create an array subtype using BASE and ranges read from H. */ - -struct ghw_subtype_array * -ghw_read_array_subtype (struct ghw_handler *h, union ghw_type *base) -{ - struct ghw_type_array *arr = - (struct ghw_type_array *) ghw_get_base_type (base); - struct ghw_subtype_array *sa; - unsigned j; - int nbr_scalars; - int nbr_els; - - sa = malloc (sizeof (struct ghw_subtype_array)); - sa->kind = ghdl_rtik_subtype_array; - sa->name = NULL; - sa->base = base; - nbr_els = get_nbr_elements (arr->el); - nbr_scalars = 1; - sa->rngs = malloc (arr->nbr_dim * sizeof (union ghw_range *)); - for (j = 0; j < arr->nbr_dim; j++) - { - sa->rngs[j] = ghw_read_range (h); - nbr_scalars *= ghw_get_range_length (sa->rngs[j]); - } - if (nbr_els >= 0) - { - /* Element type is bounded. */ - sa->el = arr->el; - } - else - { - /* Read bounds for the elements. */ - sa->el = ghw_read_type_bounds (h, arr->el); - nbr_els = get_nbr_elements (sa->el); - } - sa->nbr_scalars = nbr_scalars * nbr_els; - return sa; -} - -struct ghw_subtype_record * -ghw_read_record_subtype (struct ghw_handler *h, struct ghw_type_record *base) -{ - struct ghw_subtype_record *sr; - - sr = malloc (sizeof (struct ghw_subtype_record)); - sr->kind = ghdl_rtik_subtype_record; - sr->name = NULL; - sr->base = base; - if (base->nbr_scalars >= 0) - { - /* Record base type is bounded. */ - sr->nbr_scalars = base->nbr_scalars; - sr->els = base->els; - } - else - { - /* Read subtypes. */ - unsigned j; - int nbr_scalars; - - sr->els = - malloc (base->nbr_fields * sizeof (struct ghw_record_element)); - nbr_scalars = 0; - for (j = 0; j < base->nbr_fields; j++) - { - union ghw_type *btype = base->els[j].type; - int el_nbr_scalars = get_nbr_elements (btype); - - sr->els[j].name = base->els[j].name; - if (el_nbr_scalars >= 0) - { - /* Element is constrained. */ - sr->els[j].type = btype; - } - else - { - sr->els[j].type = ghw_read_type_bounds (h, btype); - el_nbr_scalars = get_nbr_elements (sr->els[j].type); - } - nbr_scalars += el_nbr_scalars; - } - sr->nbr_scalars = nbr_scalars; - } - return sr; -} - -/* Read bounds for BASE and create a subtype. */ - -static union ghw_type * -ghw_read_type_bounds (struct ghw_handler *h, union ghw_type *base) -{ - switch (base->kind) - { - case ghdl_rtik_type_array: - case ghdl_rtik_subtype_unbounded_array: - return (union ghw_type *) ghw_read_array_subtype (h, base); - break; - case ghdl_rtik_type_record: - case ghdl_rtik_subtype_unbounded_record: - return (union ghw_type *) ghw_read_record_subtype (h, &base->rec); - break; - default: - fprintf (stderr, "ghw_read_type_bounds: unhandled kind %d\n", - base->kind); - return NULL; - } -} - -int -ghw_read_type (struct ghw_handler *h) -{ - unsigned char hdr[8]; - unsigned i; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - - if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) - return -1; - h->nbr_types = ghw_get_i32 (h, &hdr[4]); - h->types = - (union ghw_type **) malloc (h->nbr_types * sizeof (union ghw_type *)); - - for (i = 0; i < h->nbr_types; i++) - { - int t; - - t = fgetc (h->stream); - if (t == EOF) - return -1; - if (h->flag_verbose > 1) - printf ("type[%d]= %d\n", i, t); - switch (t) - { - case ghdl_rtik_type_b2: - case ghdl_rtik_type_e8: - { - struct ghw_type_enum *e; - unsigned j; - - e = malloc (sizeof (struct ghw_type_enum)); - e->kind = t; - e->wkt = ghw_wkt_unknown; - e->name = ghw_read_strid (h); - if (ghw_read_uleb128 (h, &e->nbr) != 0) - goto err_b2; - e->lits = (const char **) malloc (e->nbr * sizeof (char *)); - if (h->flag_verbose > 1) - printf ("enum %s:", e->name); - for (j = 0; j < e->nbr; j++) - { - e->lits[j] = ghw_read_strid (h); - if (h->flag_verbose > 1) - printf (" %s", e->lits[j]); - } - if (h->flag_verbose > 1) - printf ("\n"); - h->types[i] = (union ghw_type *) e; - break; - err_b2: - free (e); - return -1; - } - break; - case ghdl_rtik_type_i32: - case ghdl_rtik_type_i64: - case ghdl_rtik_type_f64: - { - struct ghw_type_scalar *sc; - - sc = malloc (sizeof (struct ghw_type_scalar)); - sc->kind = t; - sc->name = ghw_read_strid (h); - if (h->flag_verbose > 1) - printf ("scalar: %s\n", sc->name); - h->types[i] = (union ghw_type *) sc; - } break; - case ghdl_rtik_type_p32: - case ghdl_rtik_type_p64: - { - struct ghw_type_physical *ph; - - ph = malloc (sizeof (struct ghw_type_physical)); - ph->kind = t; - ph->name = ghw_read_strid (h); - ph->units = NULL; - if (h->version == 0) - ph->nbr_units = 0; - else - { - unsigned j; - - if (ghw_read_uleb128 (h, &ph->nbr_units) != 0) - goto err_p32; - ph->units = malloc (ph->nbr_units * sizeof (struct ghw_unit)); - for (j = 0; j < ph->nbr_units; j++) - { - ph->units[j].name = ghw_read_strid (h); - if (ghw_read_lsleb128 (h, &ph->units[j].val) < 0) - goto err_p32; - } - } - if (h->flag_verbose > 1) - printf ("physical: %s\n", ph->name); - h->types[i] = (union ghw_type *) ph; - break; - err_p32: - free (ph->units); - free (ph); - return -1; - } - break; - case ghdl_rtik_subtype_scalar: - { - struct ghw_subtype_scalar *ss; - - ss = malloc (sizeof (struct ghw_subtype_scalar)); - ss->kind = t; - ss->name = ghw_read_strid (h); - ss->base = ghw_read_typeid (h); - ss->rng = ghw_read_range (h); - if (h->flag_verbose > 1) - printf ("subtype scalar: %s\n", ss->name); - h->types[i] = (union ghw_type *) ss; - } break; - case ghdl_rtik_type_array: - { - struct ghw_type_array *arr; - unsigned j; - - arr = malloc (sizeof (struct ghw_type_array)); - arr->kind = t; - arr->name = ghw_read_strid (h); - arr->el = ghw_read_typeid (h); - if (ghw_read_uleb128 (h, &arr->nbr_dim) != 0) - goto err_array; - arr->dims = - (union ghw_type **) malloc (arr->nbr_dim * - sizeof (union ghw_type *)); - for (j = 0; j < arr->nbr_dim; j++) - arr->dims[j] = ghw_read_typeid (h); - if (h->flag_verbose > 1) - printf ("array: %s (ndim=%u) of %s\n", arr->name, arr->nbr_dim, - arr->el->common.name); - h->types[i] = (union ghw_type *) arr; - break; - err_array: - free (arr); - return -1; - } - break; - case ghdl_rtik_subtype_array: - { - struct ghw_subtype_array *sa; - const char *name; - union ghw_type *base; - - name = ghw_read_strid (h); - base = ghw_read_typeid (h); - - sa = ghw_read_array_subtype (h, base); - sa->name = name; - h->types[i] = (union ghw_type *) sa; - if (h->flag_verbose > 1) - printf ("subtype array: %s (nbr_scalars=%d)\n", sa->name, - sa->nbr_scalars); - } - break; - case ghdl_rtik_subtype_unbounded_array: - { - struct ghw_subtype_unbounded_array *sua; - - sua = malloc (sizeof (struct ghw_subtype_unbounded_array)); - sua->kind = t; - sua->name = ghw_read_strid (h); - sua->base = ghw_read_typeid (h); - h->types[i] = (union ghw_type *) sua; - if (h->flag_verbose > 1) - printf ("subtype unbounded array: %s\n", sua->name); - } - break; - case ghdl_rtik_type_record: - { - struct ghw_type_record *rec; - unsigned j; - int nbr_scalars; - - rec = malloc (sizeof (struct ghw_type_record)); - rec->kind = t; - rec->name = ghw_read_strid (h); - rec->els = NULL; - if (ghw_read_uleb128 (h, &rec->nbr_fields) != 0) - goto err_record; - rec->els = - malloc (rec->nbr_fields * sizeof (struct ghw_record_element)); - nbr_scalars = 0; - for (j = 0; j < rec->nbr_fields; j++) - { - rec->els[j].name = ghw_read_strid (h); - rec->els[j].type = ghw_read_typeid (h); - if (nbr_scalars != -1) - { - int field_nbr_scalars = - get_nbr_elements (rec->els[j].type); - if (field_nbr_scalars == -1) - nbr_scalars = -1; - else - nbr_scalars += field_nbr_scalars; - } - } - rec->nbr_scalars = nbr_scalars; - if (h->flag_verbose > 1) - printf ("record type: %s (nbr_scalars=%d)\n", rec->name, - rec->nbr_scalars); - h->types[i] = (union ghw_type *) rec; - break; - err_record: - free (rec->els); - free (rec); - return -1; - } - break; - case ghdl_rtik_subtype_record: - { - struct ghw_subtype_record *sr; - const char *name; - struct ghw_type_record *base; - - name = ghw_read_strid (h); - base = (struct ghw_type_record *) ghw_read_typeid (h); - - sr = ghw_read_record_subtype (h, base); - sr->name = name; - h->types[i] = (union ghw_type *) sr; - if (h->flag_verbose > 1) - printf ("subtype record: %s (nbr_scalars=%d)\n", sr->name, - sr->nbr_scalars); - } - break; - case ghdl_rtik_subtype_unbounded_record: - { - struct ghw_subtype_unbounded_record *sur; - - sur = malloc (sizeof (struct ghw_subtype_unbounded_record)); - sur->kind = t; - sur->name = ghw_read_strid (h); - sur->base = (struct ghw_type_record *) ghw_read_typeid (h); - h->types[i] = (union ghw_type *) sur; - if (h->flag_verbose > 1) - printf ("subtype unbounded record: %s\n", sur->name); - } - break; - default: - fprintf (stderr, "ghw_read_type: unknown type %d\n", t); - return -1; - } - } - if (fgetc (h->stream) != 0) - return -1; - return 0; -} - -int -ghw_read_wk_types (struct ghw_handler *h) -{ - char hdr[4]; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - - if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) - return -1; - - while (1) - { - int t; - union ghw_type *tid; - - t = fgetc (h->stream); - if (t == EOF) - return -1; - else if (t == 0) - break; - - tid = ghw_read_typeid (h); - if (tid->kind == ghdl_rtik_type_b2 || tid->kind == ghdl_rtik_type_e8) - { - if (h->flag_verbose > 0) - printf ("%s: wkt=%d\n", tid->en.name, t); - tid->en.wkt = t; - } - } - return 0; -} - -void -ghw_disp_typename (struct ghw_handler *h, union ghw_type *t) -{ - (void) h; - printf ("%s", t->common.name); -} - -/* Read a signal composed of severals elements. - Return 0 for success. */ -int -ghw_read_signal (struct ghw_handler *h, unsigned int *sigs, union ghw_type *t) -{ - switch (t->kind) - { - case ghdl_rtik_type_b2: - case ghdl_rtik_type_e8: - case ghdl_rtik_type_e32: - case ghdl_rtik_subtype_scalar: - { - unsigned int sig_el; - - if (ghw_read_uleb128 (h, &sig_el) < 0) - return -1; - *sigs = sig_el; - if (sig_el == 0 || sig_el >= h->nbr_sigs) - return -1; - if (h->sigs[sig_el].type == NULL) - h->sigs[sig_el].type = ghw_get_base_type (t); - } - return 0; - case ghdl_rtik_subtype_array: - { - int i; - int stride; - int len; - - len = t->sa.nbr_scalars; - stride = get_nbr_elements (t->sa.el); - - for (i = 0; i < len; i += stride) - if (ghw_read_signal (h, &sigs[i], t->sa.el) < 0) - return -1; - } - return 0; - case ghdl_rtik_type_record: - { - struct ghw_type_record *r = &t->rec; - int nbr_fields = r->nbr_fields; - int i; - int off; - - off = 0; - for (i = 0; i < nbr_fields; i++) - { - if (ghw_read_signal (h, &sigs[off], r->els[i].type) < 0) - return -1; - off += get_nbr_elements (r->els[i].type); - } - } - return 0; - case ghdl_rtik_subtype_record: - { - struct ghw_subtype_record *sr = &t->sr; - int nbr_fields = sr->base->nbr_fields; - int i; - int off; - - off = 0; - for (i = 0; i < nbr_fields; i++) - { - if (ghw_read_signal (h, &sigs[off], sr->els[i].type) < 0) - return -1; - off += get_nbr_elements (sr->els[i].type); - } - } - return 0; - default: - fprintf (stderr, "ghw_read_signal: type kind %d unhandled\n", t->kind); - abort (); - } -} - -int -ghw_read_value (struct ghw_handler *h, union ghw_val *val, - union ghw_type *type) -{ - switch (ghw_get_base_type (type)->kind) - { - case ghdl_rtik_type_b2: - { - int v; - v = fgetc (h->stream); - if (v == EOF) - return -1; - val->b2 = v; - } - break; - case ghdl_rtik_type_e8: - { - int v; - v = fgetc (h->stream); - if (v == EOF) - return -1; - val->e8 = v; - } - break; - case ghdl_rtik_type_i32: - case ghdl_rtik_type_p32: - { - int32_t v; - if (ghw_read_sleb128 (h, &v) < 0) - return -1; - val->i32 = v; - } - break; - case ghdl_rtik_type_f64: - { - double v; - if (ghw_read_f64 (h, &v) < 0) - return -1; - val->f64 = v; - } - break; - case ghdl_rtik_type_p64: - { - int64_t v; - if (ghw_read_lsleb128 (h, &v) < 0) - return -1; - val->i64 = v; - } - break; - default: - fprintf (stderr, "read_value: cannot handle format %d\n", type->kind); - abort (); - } - return 0; -} - -int -ghw_read_hie (struct ghw_handler *h) -{ - unsigned char hdr[16]; - int nbr_scopes; - int nbr_sigs; - unsigned i; - struct ghw_hie *blk; - struct ghw_hie **last; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - - if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) - return -1; - nbr_scopes = ghw_get_i32 (h, &hdr[4]); - /* Number of declared signals (which may be composite). */ - nbr_sigs = ghw_get_i32 (h, &hdr[8]); - /* Number of basic signals. */ - h->nbr_sigs = ghw_get_i32 (h, &hdr[12]); - - if (h->flag_verbose) - printf ("%u scopes, %u signals, %u signal elements\n", nbr_scopes, - nbr_sigs, h->nbr_sigs); - - blk = (struct ghw_hie *) malloc (sizeof (struct ghw_hie)); - blk->kind = ghw_hie_design; - blk->name = NULL; - blk->parent = NULL; - blk->brother = NULL; - blk->u.blk.child = NULL; - - last = &blk->u.blk.child; - h->hie = blk; - - h->nbr_sigs++; - h->skip_sigs = NULL; - h->flag_full_names = 0; - h->sigs = (struct ghw_sig *) malloc (h->nbr_sigs * sizeof (struct ghw_sig)); - memset (h->sigs, 0, h->nbr_sigs * sizeof (struct ghw_sig)); - - while (1) - { - int t; - struct ghw_hie *el; - unsigned int str; - - t = fgetc (h->stream); - if (t == EOF) - return -1; - if (t == 0) - break; - - if (t == ghw_hie_eos) - { - blk = blk->parent; - if (blk->u.blk.child == NULL) - last = &blk->u.blk.child; - else - { - struct ghw_hie *l = blk->u.blk.child; - while (l->brother != NULL) - l = l->brother; - last = &l->brother; - } - - continue; - } - - el = (struct ghw_hie *) malloc (sizeof (struct ghw_hie)); - el->kind = t; - el->parent = blk; - el->brother = NULL; - - /* Link. */ - *last = el; - last = &el->brother; - - /* Read name. */ - if (ghw_read_uleb128 (h, &str) != 0) - return -1; - el->name = h->str_table[str]; - - switch (t) - { - case ghw_hie_eoh: - case ghw_hie_design: - case ghw_hie_eos: - /* Should not be here. */ - abort (); - case ghw_hie_process: - el->u.blk.child = NULL; - break; - case ghw_hie_block: - case ghw_hie_generate_if: - case ghw_hie_generate_for: - case ghw_hie_instance: - case ghw_hie_generic: - case ghw_hie_package: - /* Create a block. */ - el->u.blk.child = NULL; - - if (t == ghw_hie_generate_for) - { - el->u.blk.iter_type = ghw_read_typeid (h); - el->u.blk.iter_value = malloc (sizeof (union ghw_val)); - if (ghw_read_value - (h, el->u.blk.iter_value, el->u.blk.iter_type) < 0) - return -1; - } - blk = el; - last = &el->u.blk.child; - break; - case ghw_hie_signal: - case ghw_hie_port_in: - case ghw_hie_port_out: - case ghw_hie_port_inout: - case ghw_hie_port_buffer: - case ghw_hie_port_linkage: - /* For a signal, read type. */ - { - int nbr_el; - unsigned int *sigs; - - el->u.sig.type = ghw_read_typeid (h); - nbr_el = get_nbr_elements (el->u.sig.type); - if (nbr_el < 0) - return -1; - sigs = - (unsigned int *) malloc ((nbr_el + 1) * sizeof (unsigned int)); - el->u.sig.sigs = sigs; - /* Last element is NULL. */ - sigs[nbr_el] = 0; - - if (h->flag_verbose > 1) - printf ("signal %s: %d el [", el->name, nbr_el); - if (ghw_read_signal (h, sigs, el->u.sig.type) < 0) - return -1; - if (h->flag_verbose > 1) - { - int j; - for (j = 0; j < nbr_el; j++) - printf (" #%u", sigs[j]); - printf ("]\n"); - } - } - break; - default: - fprintf (stderr, "ghw_read_hie: unhandled kind %d\n", t); - abort (); - } - } - - /* Allocate values. */ - for (i = 0; i < h->nbr_sigs; i++) - if (h->sigs[i].type != NULL) - h->sigs[i].val = (union ghw_val *) malloc (sizeof (union ghw_val)); - return 0; -} - -const char * -ghw_get_hie_name (struct ghw_hie *h) -{ - switch (h->kind) - { - case ghw_hie_eoh: - return "eoh"; - case ghw_hie_design: - return "design"; - case ghw_hie_block: - return "block"; - case ghw_hie_generate_if: - return "generate-if"; - case ghw_hie_generate_for: - return "generate-for"; - case ghw_hie_instance: - return "instance"; - case ghw_hie_package: - return "package"; - case ghw_hie_process: - return "process"; - case ghw_hie_generic: - return "generic"; - case ghw_hie_eos: - return "eos"; - case ghw_hie_signal: - return "signal"; - case ghw_hie_port_in: - return "port-in"; - case ghw_hie_port_out: - return "port-out"; - case ghw_hie_port_inout: - return "port-inout"; - case ghw_hie_port_buffer: - return "port-buffer"; - case ghw_hie_port_linkage: - return "port-linkage"; - default: - return "??"; - } -} - -void ghw_disp_value (union ghw_val *val, union ghw_type *type); - -static void -print_name (struct ghw_hie *hie, int full_names) -{ - int i; - int depth; - struct ghw_hie *p; - struct ghw_hie **buf; - struct ghw_hie **end; - - /* HIE must be valid. */ - assert (hie->name != NULL); - - if (0 == full_names) - { - printf (" %s: ", hie->name); - return; - } - - p = hie; - depth = 0; - while (p && p->name) - { - p = p->parent; - ++depth; - } - buf = (struct ghw_hie **) malloc (depth * sizeof (struct ghw_hie *)); - - p = hie; - end = depth + buf; - while (p && p->name) - { - *(--end) = p; - p = p->parent; - } - - putchar (' '); - putchar ('/'); - for (i = 0; i < depth; ++i) - { - printf ("%s%s", i ? "/" : "", buf[i]->name); - if (ghw_hie_generate_for == buf[i]->kind) - { - putchar ('('); - ghw_disp_value (buf[i]->u.blk.iter_value, buf[i]->u.blk.iter_type); - putchar (')'); - } - } - putchar (':'); - putchar (' '); - free (buf); -} - -void -ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top) -{ - int i; - int indent; - struct ghw_hie *hie; - struct ghw_hie *n; - - hie = top; - indent = 0; - - while (1) - { - if (0 == h->flag_full_names) - for (i = 0; i < indent; i++) - fputc (' ', stdout); - printf ("%s", ghw_get_hie_name (hie)); - - switch (hie->kind) - { - case ghw_hie_design: - case ghw_hie_block: - case ghw_hie_generate_if: - case ghw_hie_generate_for: - case ghw_hie_instance: - case ghw_hie_process: - case ghw_hie_package: - if (hie->name) - print_name (hie, h->flag_full_names); - if (hie->kind == ghw_hie_generate_for) - { - printf ("("); - ghw_disp_value (hie->u.blk.iter_value, hie->u.blk.iter_type); - printf (")"); - } - n = hie->u.blk.child; - if (n == NULL) - n = hie->brother; - else - indent++; - break; - case ghw_hie_generic: - case ghw_hie_eos: - abort (); - case ghw_hie_signal: - case ghw_hie_port_in: - case ghw_hie_port_out: - case ghw_hie_port_inout: - case ghw_hie_port_buffer: - case ghw_hie_port_linkage: - { - unsigned int *sigs = hie->u.sig.sigs; - unsigned int k, num; - - print_name (hie, h->flag_full_names); - ghw_disp_subtype_indication (h, hie->u.sig.type); - printf (":"); - k = 0; - /* There can be 0-length signals. */ - while (sigs[k] != GHW_NO_SIG) - { - /* First signal of the range. */ - printf (" #%u", sigs[k]); - for (num = 1; sigs[k + num] != GHW_NO_SIG; num++) - if (sigs[k + num] != sigs[k + num - 1] + 1) - break; - if (num > 1) - printf ("-#%u", sigs[k + num - 1]); - k += num; - } - n = hie->brother; - } - break; - default: - abort (); - } - printf ("\n"); - - while (n == NULL) - { - if (hie->parent == NULL) - return; - hie = hie->parent; - indent--; - n = hie->brother; - } - hie = n; - } -} - -int -ghw_read_eoh (struct ghw_handler *h) -{ - (void) h; - return 0; -} - -int -ghw_read_base (struct ghw_handler *h) -{ - unsigned char hdr[4]; - int res; - - while (1) - { - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - if (memcmp (hdr, "STR", 4) == 0) - res = ghw_read_str (h); - else if (memcmp (hdr, "HIE", 4) == 0) - res = ghw_read_hie (h); - else if (memcmp (hdr, "TYP", 4) == 0) - res = ghw_read_type (h); - else if (memcmp (hdr, "WKT", 4) == 0) - res = ghw_read_wk_types (h); - else if (memcmp (hdr, "EOH", 4) == 0) - return 0; - else - { - fprintf (stderr, "ghw_read_base: unknown GHW section %c%c%c%c\n", - hdr[0], hdr[1], hdr[2], hdr[3]); - return -1; - } - if (res != 0) - { - fprintf (stderr, "ghw_read_base: error in section %s\n", hdr); - return res; - } - } -} - -int -ghw_read_signal_value (struct ghw_handler *h, struct ghw_sig *s) -{ - return ghw_read_value (h, s->val, s->type); -} - -int -ghw_read_snapshot (struct ghw_handler *h) -{ - unsigned char hdr[12]; - unsigned i; - struct ghw_sig *s; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - - if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) - return -1; - h->snap_time = ghw_get_i64 (h, &hdr[4]); - if (h->flag_verbose > 1) - printf ("Time is " GHWPRI64 " fs\n", h->snap_time); - - for (i = 0; i < h->nbr_sigs; i++) - { - s = &h->sigs[i]; - if (s->type != NULL) - { - if (h->flag_verbose > 1) - printf ("read type %d for sig %u\n", s->type->kind, i); - if (ghw_read_signal_value (h, s) < 0) - return -1; - } - } - if (fread (hdr, 4, 1, h->stream) != 1) - return -1; - - if (memcmp (hdr, "ESN", 4)) - return -1; - - return 0; -} - -void ghw_disp_values (struct ghw_handler *h); - -int -ghw_read_cycle_start (struct ghw_handler *h) -{ - unsigned char hdr[8]; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - - h->snap_time = ghw_get_i64 (h, hdr); - return 0; -} - -int -ghw_read_cycle_cont (struct ghw_handler *h, int *list) -{ - int i; - int *list_p; - - i = 0; - list_p = list; - while (1) - { - uint32_t d; - - /* Read delta to next signal. */ - if (ghw_read_uleb128 (h, &d) < 0) - return -1; - if (d == 0) - { - /* Last signal reached. */ - break; - } - - /* Find next signal. */ - while (d > 0) - { - i++; - if (h->sigs[i].type != NULL) - d--; - } - - if (ghw_read_signal_value (h, &h->sigs[i]) < 0) - return -1; - if (list_p) - *list_p++ = i; - } - - if (list_p) - *list_p = 0; - return 0; -} - -int -ghw_read_cycle_next (struct ghw_handler *h) -{ - int64_t d_time; - - if (ghw_read_lsleb128 (h, &d_time) < 0) - return -1; - if (d_time == -1) - return 0; - h->snap_time += d_time; - return 1; -} - -int -ghw_read_cycle_end (struct ghw_handler *h) -{ - char hdr[4]; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - if (memcmp (hdr, "ECY", 4)) - return -1; - - return 0; -} - -static const char * -ghw_get_lit (union ghw_type *type, unsigned e) -{ - if (e >= type->en.nbr) - return "??"; - else - return type->en.lits[e]; -} - -static void -ghw_disp_lit (union ghw_type *type, unsigned e) -{ - printf ("%s (%u)", ghw_get_lit (type, e), e); -} - -void -ghw_disp_value (union ghw_val *val, union ghw_type *type) -{ - switch (ghw_get_base_type (type)->kind) - { - case ghdl_rtik_type_b2: - ghw_disp_lit (type, val->b2); - break; - case ghdl_rtik_type_e8: - ghw_disp_lit (type, val->e8); - break; - case ghdl_rtik_type_i32: - printf (GHWPRI32, val->i32); - break; - case ghdl_rtik_type_p64: - printf (GHWPRI64, val->i64); - break; - case ghdl_rtik_type_f64: - printf ("%g", val->f64); - break; - default: - fprintf (stderr, "ghw_disp_value: cannot handle type %d\n", type->kind); - abort (); - } -} - -/* Put the ASCII representation of VAL into BUF, whose size if LEN. - A NUL is always written to BUF. -*/ -void -ghw_get_value (char *buf, int len, union ghw_val *val, union ghw_type *type) -{ - union ghw_type *base = ghw_get_base_type (type); - - switch (base->kind) - { - case ghdl_rtik_type_b2: - if (val->b2 <= 1) - { - strncpy (buf, base->en.lits[val->b2], len - 1); - buf[len - 1] = 0; - } - else - { - snprintf (buf, len, "?%d", val->b2); - } - break; - case ghdl_rtik_type_e8: - if (val->b2 <= base->en.nbr) - { - strncpy (buf, base->en.lits[val->e8], len - 1); - buf[len - 1] = 0; - } - else - { - snprintf (buf, len, "?%d", val->e8); - } - break; - case ghdl_rtik_type_i32: - snprintf (buf, len, GHWPRI32, val->i32); - break; - case ghdl_rtik_type_p64: - snprintf (buf, len, GHWPRI64, val->i64); - break; - case ghdl_rtik_type_f64: - snprintf (buf, len, "%g", val->f64); - break; - default: - snprintf (buf, len, "?bad type %d?", type->kind); - } -} - -static char -is_skip_signal (int *signals_to_keep, int nb_signals_to_keep, int signal) -{ - int i; - for (i = 0; i < nb_signals_to_keep; ++i) - { - if (signal == signals_to_keep[i]) - { - return 0; - } - } - return 1; -} - -void -ghw_filter_signals (struct ghw_handler *h, int *signals_to_keep, - int nb_signals_to_keep) -{ - unsigned i; - - if (0 < nb_signals_to_keep && 0 != signals_to_keep) - { - if (0 == h->skip_sigs) - { - h->skip_sigs = (char *) malloc (sizeof (char) * h->nbr_sigs); - } - for (i = 0; i < h->nbr_sigs; ++i) - { - h->skip_sigs[i] = - is_skip_signal (signals_to_keep, nb_signals_to_keep, i); - } - } - else - { - if (0 != h->skip_sigs) - { - free (h->skip_sigs); - h->skip_sigs = 0; - } - } -} - -void -ghw_disp_values (struct ghw_handler *h) -{ - unsigned i; - for (i = 0; i < h->nbr_sigs; i++) - { - struct ghw_sig *s = &h->sigs[i]; - int skip = (0 != h->skip_sigs && (0 != h->skip_sigs[i])); - if (s->type != NULL && !skip) - { - printf ("#%u: ", i); - ghw_disp_value (s->val, s->type); - printf ("\n"); - } - } -} - -int -ghw_read_directory (struct ghw_handler *h) -{ - unsigned char hdr[8]; - int nbr_entries; - int i; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - - nbr_entries = ghw_get_i32 (h, &hdr[4]); - - if (h->flag_verbose) - printf ("Directory (%d entries):\n", nbr_entries); - - for (i = 0; i < nbr_entries; i++) - { - unsigned char ent[8]; - int pos; - - if (fread (ent, sizeof (ent), 1, h->stream) != 1) - return -1; - - pos = ghw_get_i32 (h, &ent[4]); - if (h->flag_verbose) - printf (" %s at %d\n", ent, pos); - } - - if (fread (hdr, 4, 1, h->stream) != 1) - return -1; - if (memcmp (hdr, "EOD", 4)) - return -1; - return 0; -} - -int -ghw_read_tailer (struct ghw_handler *h) -{ - unsigned char hdr[8]; - int pos; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - return -1; - - pos = ghw_get_i32 (h, &hdr[4]); - - if (h->flag_verbose) - printf ("Tailer: directory at %d\n", pos); - return 0; -} - -enum ghw_res -ghw_read_sm_hdr (struct ghw_handler *h, int *list) -{ - unsigned char hdr[4]; - int res; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - { - if (feof (h->stream)) - return ghw_res_eof; - else - return ghw_res_error; - } - if (memcmp (hdr, "SNP", 4) == 0) - { - res = ghw_read_snapshot (h); - if (res < 0) - return res; - return ghw_res_snapshot; - } - else if (memcmp (hdr, "CYC", 4) == 0) - { - res = ghw_read_cycle_start (h); - if (res < 0) - return res; - res = ghw_read_cycle_cont (h, list); - if (res < 0) - return res; - - return ghw_res_cycle; - } - else if (memcmp (hdr, "DIR", 4) == 0) - { - res = ghw_read_directory (h); - } - else if (memcmp (hdr, "TAI", 4) == 0) - { - res = ghw_read_tailer (h); - } - else - { - fprintf (stderr, "unknown GHW section %c%c%c%c\n", hdr[0], hdr[1], - hdr[2], hdr[3]); - return -1; - } - if (res != 0) - return res; - return ghw_res_other; -} - -int -ghw_read_sm (struct ghw_handler *h, enum ghw_sm_type *sm) -{ - int res; - - while (1) - { - /* printf ("sm: state = %d\n", *sm); */ - switch (*sm) - { - case ghw_sm_init: - case ghw_sm_sect: - res = ghw_read_sm_hdr (h, NULL); - switch (res) - { - case ghw_res_other: - break; - case ghw_res_snapshot: - *sm = ghw_sm_sect; - return res; - case ghw_res_cycle: - *sm = ghw_sm_cycle; - return res; - default: - return res; - } - break; - case ghw_sm_cycle: - if (0) - printf ("Time is " GHWPRI64 " fs\n", h->snap_time); - if (0) - ghw_disp_values (h); - - res = ghw_read_cycle_next (h); - if (res < 0) - return res; - if (res == 1) - { - res = ghw_read_cycle_cont (h, NULL); - if (res < 0) - return res; - return ghw_res_cycle; - } - res = ghw_read_cycle_end (h); - if (res < 0) - return res; - *sm = ghw_sm_sect; - break; - } - } -} - -int -ghw_read_cycle (struct ghw_handler *h) -{ - int res; - - res = ghw_read_cycle_start (h); - if (res < 0) - return res; - while (1) - { - res = ghw_read_cycle_cont (h, NULL); - if (res < 0) - return res; - - if (0) - printf ("Time is " GHWPRI64 " fs\n", h->snap_time); - if (0) - ghw_disp_values (h); - - res = ghw_read_cycle_next (h); - if (res < 0) - return res; - if (res == 0) - break; - } - res = ghw_read_cycle_end (h); - return res; -} - -int -ghw_read_dump (struct ghw_handler *h) -{ - unsigned char hdr[4]; - int res; - - while (1) - { - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - { - if (feof (h->stream)) - return 0; - else - return -1; - } - if (memcmp (hdr, "SNP", 4) == 0) - { - res = ghw_read_snapshot (h); - if (0 && res >= 0) - ghw_disp_values (h); - } - else if (memcmp (hdr, "CYC", 4) == 0) - { - res = ghw_read_cycle (h); - } - else if (memcmp (hdr, "DIR", 4) == 0) - { - res = ghw_read_directory (h); - } - else if (memcmp (hdr, "TAI", 4) == 0) - { - res = ghw_read_tailer (h); - } - else - { - fprintf (stderr, "unknown GHW section %c%c%c%c\n", hdr[0], hdr[1], - hdr[2], hdr[3]); - return -1; - } - if (res != 0) - return res; - } -} - -struct ghw_section ghw_sections[] = { {"\0\0\0", NULL}, -{"STR", ghw_read_str}, -{"HIE", ghw_read_hie}, -{"TYP", ghw_read_type}, -{"WKT", ghw_read_wk_types}, -{"EOH", ghw_read_eoh}, -{"SNP", ghw_read_snapshot}, -{"CYC", ghw_read_cycle}, -{"DIR", ghw_read_directory}, -{"TAI", ghw_read_tailer} -}; - -int -ghw_read_section (struct ghw_handler *h) -{ - unsigned char hdr[4]; - unsigned i; - - if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) - { - if (feof (h->stream)) - return -2; - else - return -1; - } - - for (i = 1; i < sizeof (ghw_sections) / sizeof (*ghw_sections); i++) - if (memcmp (hdr, ghw_sections[i].name, 4) == 0) - return i; - - fprintf (stderr, "ghw_read_section: unknown GHW section %c%c%c%c\n", hdr[0], - hdr[1], hdr[2], hdr[3]); - return 0; -} - -void -ghw_close (struct ghw_handler *h) -{ - if (h->stream) - { - if (h->stream_ispipe) - pclose (h->stream); - else - fclose (h->stream); - - h->stream = NULL; - } -} - -const char * -ghw_get_dir (int is_downto) -{ - return is_downto ? "downto" : "to"; -} - -void -ghw_disp_range (union ghw_type *type, union ghw_range *rng) -{ - switch (rng->kind) - { - case ghdl_rtik_type_b2: - printf ("%s %s %s", ghw_get_lit (type, rng->b2.left), - ghw_get_dir (rng->b2.dir), ghw_get_lit (type, rng->b2.right)); - break; - case ghdl_rtik_type_e8: - printf ("%s %s %s", ghw_get_lit (type, rng->e8.left), - ghw_get_dir (rng->e8.dir), ghw_get_lit (type, rng->e8.right)); - break; - case ghdl_rtik_type_i32: - case ghdl_rtik_type_p32: - printf (GHWPRI32 " %s " GHWPRI32, rng->i32.left, - ghw_get_dir (rng->i32.dir), rng->i32.right); - break; - case ghdl_rtik_type_i64: - case ghdl_rtik_type_p64: - printf (GHWPRI64 " %s " GHWPRI64, rng->i64.left, - ghw_get_dir (rng->i64.dir), rng->i64.right); - break; - case ghdl_rtik_type_f64: - printf ("%g %s %g", rng->f64.left, ghw_get_dir (rng->f64.dir), - rng->f64.right); - break; - default: - printf ("?(%d)", rng->kind); - } -} - -static void -ghw_disp_array_subtype_bounds (struct ghw_subtype_array *a) -{ - unsigned i; - struct ghw_type_array *base = - (struct ghw_type_array *) ghw_get_base_type (a->base); - - printf (" ("); - for (i = 0; i < base->nbr_dim; i++) - { - if (i != 0) - printf (", "); - ghw_disp_range (base->dims[i], a->rngs[i]); - } - printf (")"); -} - -static void -ghw_disp_record_subtype_bounds (struct ghw_subtype_record *sr) -{ - struct ghw_type_record *base = sr->base; - int is_first = 1; - unsigned i; - - for (i = 0; i < base->nbr_fields; i++) - { - if (sr->els[i].type != base->els[i].type) - { - if (is_first) - { - printf ("("); - is_first = 0; - } - else - printf (", "); - printf ("%s", base->els[i].name); - switch (sr->els[i].type->kind) - { - case ghdl_rtik_subtype_array: - ghw_disp_array_subtype_bounds (&sr->els[i].type->sa); - break; - case ghdl_rtik_subtype_record: - ghw_disp_record_subtype_bounds (&sr->els[i].type->sr); - break; - default: - printf ("??? (%d)", sr->els[i].type->kind); - } - } - } - if (!is_first) - printf (")"); -} - -static void -ghw_disp_subtype_definition (struct ghw_handler *h, union ghw_type *t) -{ - switch (t->kind) - { - case ghdl_rtik_subtype_scalar: - { - struct ghw_subtype_scalar *s = &t->ss; - ghw_disp_typename (h, s->base); - printf (" range "); - ghw_disp_range (s->base, s->rng); - } break; - case ghdl_rtik_subtype_array: - { - struct ghw_subtype_array *a = &t->sa; - - ghw_disp_typename (h, (union ghw_type *) a->base); - ghw_disp_array_subtype_bounds (a); - } break; - case ghdl_rtik_subtype_record: - { - struct ghw_subtype_record *sr = &t->sr; - - ghw_disp_typename (h, (union ghw_type *) sr->base); - ghw_disp_record_subtype_bounds (sr); - } break; - case ghdl_rtik_subtype_unbounded_array: - case ghdl_rtik_subtype_unbounded_record: - { - struct ghw_subtype_unbounded_record *sur = &t->sur; - - ghw_disp_typename (h, (union ghw_type *) sur->base); - } break; - default: - printf ("ghw_disp_subtype_definition: unhandled type kind %d\n", - t->kind); - } -} - -static int -ghw_is_anonymous_type (struct ghw_handler *h, union ghw_type *t) -{ - return t->common.name == h->str_table[0]; -} - -void -ghw_disp_subtype_indication (struct ghw_handler *h, union ghw_type *t) -{ - if (ghw_is_anonymous_type (h, t)) - { - /* Anonymous subtype. */ - ghw_disp_subtype_definition (h, t); - } - else - ghw_disp_typename (h, t); -} - -void -ghw_disp_type (struct ghw_handler *h, union ghw_type *t) -{ - switch (t->kind) - { - case ghdl_rtik_type_b2: - case ghdl_rtik_type_e8: - { - struct ghw_type_enum *e = &t->en; - unsigned i; - - printf ("type %s is (", e->name); - for (i = 0; i < e->nbr; i++) - { - if (i != 0) - printf (", "); - printf ("%s", e->lits[i]); - } - printf (");"); - if (e->wkt != ghw_wkt_unknown) - printf (" -- WKT:%d", e->wkt); - printf ("\n"); - } - break; - case ghdl_rtik_type_i32: - case ghdl_rtik_type_f64: - { - struct ghw_type_scalar *s = &t->sc; - printf ("type %s is range <>;\n", s->name); - } break; - case ghdl_rtik_type_p32: - case ghdl_rtik_type_p64: - { - unsigned i; - - struct ghw_type_physical *p = &t->ph; - printf ("type %s is range <> units\n", p->name); - for (i = 0; i < p->nbr_units; i++) - { - struct ghw_unit *u = &p->units[i]; - printf (" %s = " GHWPRI64 " %s;\n", u->name, u->val, - p->units[0].name); - } - printf ("end units\n"); - } break; - case ghdl_rtik_type_array: - { - struct ghw_type_array *a = &t->ar; - unsigned i; - - printf ("type %s is array (", a->name); - for (i = 0; i < a->nbr_dim; i++) - { - if (i != 0) - printf (", "); - ghw_disp_typename (h, a->dims[i]); - printf (" range <>"); - } - printf (") of "); - ghw_disp_subtype_indication (h, a->el); - printf (";\n"); - } - break; - case ghdl_rtik_type_record: - { - struct ghw_type_record *r = &t->rec; - unsigned i; - - printf ("type %s is record\n", r->name); - for (i = 0; i < r->nbr_fields; i++) - { - printf (" %s: ", r->els[i].name); - ghw_disp_subtype_indication (h, r->els[i].type); - printf (";\n"); - } - printf ("end record;\n"); - } - break; - case ghdl_rtik_subtype_array: - case ghdl_rtik_subtype_scalar: - case ghdl_rtik_subtype_record: - case ghdl_rtik_subtype_unbounded_array: - case ghdl_rtik_subtype_unbounded_record: - { - struct ghw_type_common *c = &t->common; - printf ("subtype %s is ", c->name); - ghw_disp_subtype_definition (h, t); - printf (";\n"); - } break; - default: - printf ("ghw_disp_type: unhandled type kind %d\n", t->kind); - } -} - -void -ghw_disp_types (struct ghw_handler *h) -{ - unsigned i; - - for (i = 0; i < h->nbr_types; i++) - if (h->flag_verbose || !ghw_is_anonymous_type (h, h->types[i])) - ghw_disp_type (h, h->types[i]); -} diff --git a/ghw/ghwlib.h b/ghw/ghwlib.h deleted file mode 100644 index 3efa65721..000000000 --- a/ghw/ghwlib.h +++ /dev/null @@ -1,471 +0,0 @@ -/* GHDL Wavefile reader library. - Copyright (C) 2005-2017 Tristan Gingold - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This program 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. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef _GHWLIB_H_ -#define _GHWLIB_H_ - -#include -#include - -/* To be libraries friendly. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* The ghwlib uses the standard c99 int32_t and int64_t. They are declared - in stdint.h. Header inttypes.h includes stdint.h and provides macro for - printf and co specifiers. Use it if known to be available. */ - -#if defined(__cplusplus) || \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - defined(HAVE_INTTYPES_H) -/* Use C99 standard header. */ -#include -#define GHWPRI64 "%" PRId64 -#define GHWPRI32 "%" PRId32 -#else -#include -#define GHWPRI64 "%lld" -#define GHWPRI32 "%d" -#endif - -enum ghdl_rtik -{ - ghdl_rtik_top, /* 0 */ - ghdl_rtik_library, - ghdl_rtik_package, - ghdl_rtik_package_body, - ghdl_rtik_entity, - ghdl_rtik_architecture, /* 5 */ - ghdl_rtik_process, - ghdl_rtik_block, - ghdl_rtik_if_generate, - ghdl_rtik_for_generate, - ghdl_rtik_instance, - ghdl_rtik_constant, - ghdl_rtik_iterator, - ghdl_rtik_variable, - ghdl_rtik_signal, - ghdl_rtik_file, - ghdl_rtik_port, - ghdl_rtik_generic, - ghdl_rtik_alias, - ghdl_rtik_guard, - ghdl_rtik_component, - ghdl_rtik_attribute, - ghdl_rtik_type_b2, /* 22 */ - ghdl_rtik_type_e8, - ghdl_rtik_type_e32, - ghdl_rtik_type_i32, /* 25 */ - ghdl_rtik_type_i64, - ghdl_rtik_type_f64, - ghdl_rtik_type_p32, - ghdl_rtik_type_p64, - ghdl_rtik_type_access, /* 30 */ - ghdl_rtik_type_array, - ghdl_rtik_type_record, - ghdl_rtik_type_file, - ghdl_rtik_subtype_scalar, - ghdl_rtik_subtype_array, /* 35 */ - ghdl_rtik_subtype_array_ptr, /* Obsolete. */ - ghdl_rtik_subtype_unbounded_array, - ghdl_rtik_subtype_record, - ghdl_rtik_subtype_unbounded_record, -#if 0 - ghdl_rtik_subtype_access, /* 40 */ - ghdl_rtik_type_protected, - ghdl_rtik_element, - ghdl_rtik_unit, - ghdl_rtik_attribute_transaction, - ghdl_rtik_attribute_quiet, - ghdl_rtik_attribute_stable, -#endif - ghdl_rtik_error -}; - -/* Well-known types. */ -enum ghw_wkt_type -{ - ghw_wkt_unknown, - ghw_wkt_boolean, - ghw_wkt_bit, - ghw_wkt_std_ulogic -}; - -struct ghw_range_b2 -{ - enum ghdl_rtik kind:8; - int dir:8; /* 0: to, !0: downto. */ - unsigned char left; - unsigned char right; -}; - -struct ghw_range_e8 -{ - enum ghdl_rtik kind:8; - int dir:8; /* 0: to, !0: downto. */ - unsigned char left; - unsigned char right; -}; - -struct ghw_range_i32 -{ - enum ghdl_rtik kind:8; - int dir:8; /* 0: to, !0: downto. */ - int32_t left; - int32_t right; -}; - -struct ghw_range_i64 -{ - enum ghdl_rtik kind:8; - int dir:8; - int64_t left; - int64_t right; -}; - -struct ghw_range_f64 -{ - enum ghdl_rtik kind:8; - int dir:8; - double left; - double right; -}; - -union ghw_range -{ - enum ghdl_rtik kind:8; - struct ghw_range_b2 b2; - struct ghw_range_e8 e8; - struct ghw_range_i32 i32; - struct ghw_range_i64 i64; - struct ghw_range_f64 f64; -}; - -/* Note: the first two fields must be kind and name. */ -union ghw_type; - -struct ghw_type_common -{ - enum ghdl_rtik kind; - const char *name; -}; - -struct ghw_type_enum -{ - enum ghdl_rtik kind; - const char *name; - - enum ghw_wkt_type wkt; - unsigned int nbr; - const char **lits; -}; - -struct ghw_type_scalar -{ - enum ghdl_rtik kind; - const char *name; -}; - -struct ghw_unit -{ - const char *name; - int64_t val; -}; - -struct ghw_type_physical -{ - enum ghdl_rtik kind; - const char *name; - uint32_t nbr_units; - struct ghw_unit *units; -}; - -struct ghw_type_array -{ - enum ghdl_rtik kind; - const char *name; - - unsigned int nbr_dim; - union ghw_type *el; - union ghw_type **dims; -}; - -struct ghw_subtype_unbounded_array -{ - enum ghdl_rtik kind; - const char *name; - - union ghw_type *base; -}; - -struct ghw_subtype_array -{ - enum ghdl_rtik kind; - const char *name; - - union ghw_type *base; - int nbr_scalars; - union ghw_range **rngs; - union ghw_type *el; -}; - -struct ghw_subtype_scalar -{ - enum ghdl_rtik kind; - const char *name; - - union ghw_type *base; - union ghw_range *rng; -}; - -struct ghw_record_element -{ - const char *name; - union ghw_type *type; -}; - -struct ghw_type_record -{ - enum ghdl_rtik kind; - const char *name; - - unsigned int nbr_fields; - int nbr_scalars; /* Number of scalar elements (ie nbr of signals). */ - struct ghw_record_element *els; -}; - -struct ghw_subtype_record -{ - enum ghdl_rtik kind; - const char *name; - - struct ghw_type_record *base; - int nbr_scalars; /* Number of scalar elements (ie nbr of signals). */ - struct ghw_record_element *els; -}; - -struct ghw_subtype_unbounded_record -{ - enum ghdl_rtik kind; - const char *name; - - struct ghw_type_record *base; -}; - -union ghw_type -{ - enum ghdl_rtik kind; - struct ghw_type_common common; - struct ghw_type_enum en; - struct ghw_type_scalar sc; - struct ghw_type_physical ph; - struct ghw_subtype_scalar ss; - struct ghw_type_array ar; - struct ghw_type_record rec; - struct ghw_subtype_array sa; - struct ghw_subtype_unbounded_array sua; - struct ghw_subtype_record sr; - struct ghw_subtype_unbounded_record sur; -}; - -union ghw_val -{ - unsigned char b2; - unsigned char e8; - int32_t i32; - int64_t i64; - double f64; -}; - -/* A non-composite signal. */ -struct ghw_sig -{ - union ghw_type *type; - union ghw_val *val; -}; - -enum ghw_hie_kind -{ - ghw_hie_eoh = 0, - ghw_hie_design = 1, - ghw_hie_block = 3, - ghw_hie_generate_if = 4, - ghw_hie_generate_for = 5, - ghw_hie_instance = 6, - ghw_hie_package = 7, - ghw_hie_process = 13, - ghw_hie_generic = 14, - ghw_hie_eos = 15, - ghw_hie_signal = 16, - ghw_hie_port_in = 17, - ghw_hie_port_out = 18, - ghw_hie_port_inout = 19, - ghw_hie_port_buffer = 20, - ghw_hie_port_linkage = 21 -}; - -#define GHW_NO_SIG 0 - -struct ghw_hie -{ - enum ghw_hie_kind kind; - struct ghw_hie *parent; - const char *name; - struct ghw_hie *brother; - union - { - struct - { - struct ghw_hie *child; - union ghw_type *iter_type; - union ghw_val *iter_value; - } blk; - struct - { - union ghw_type *type; - /* Array of signal elements. - Last element is GHW_NO_SIG (0). */ - unsigned int *sigs; - } sig; - } u; -}; - -struct ghw_handler -{ - FILE *stream; - /* True if STREAM was popen, else was fopen. */ - unsigned char stream_ispipe; - /* True if words are big-endian. */ - unsigned char word_be; - unsigned char word_len; - unsigned char off_len; - /* Minor version. */ - int version; - - /* Set by user. */ - int flag_verbose; - - /* String table. */ - /* Number of strings. */ - unsigned nbr_str; - /* Size of the strings (without nul). */ - unsigned str_size; - /* String table. */ - char **str_table; - /* Array containing strings. */ - char *str_content; - - /* Type table. */ - unsigned nbr_types; - union ghw_type **types; - - /* Non-composite (or basic) signals. */ - unsigned nbr_sigs; - char *skip_sigs; - int flag_full_names; - struct ghw_sig *sigs; - - /* Hierarchy. */ - struct ghw_hie *hie; - - /* Time of the next cycle. */ - int64_t snap_time; -}; - -/* Open a GHW file with H. - Return < 0 in case of error. */ -int ghw_open (struct ghw_handler *h, const char *filename); - -/* Return base type of T. */ -union ghw_type *ghw_get_base_type (union ghw_type *t); - -/* Return length of RNG. */ -int ghw_get_range_length (union ghw_range *rng); - -/* Put the ASCII representation of VAL into BUF, whose size if LEN. - A NUL is always written to BUF. */ -void ghw_get_value (char *buf, int len, union ghw_val *val, - union ghw_type *type); - -const char *ghw_get_hie_name (struct ghw_hie *h); - -void ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top); - -int ghw_read_base (struct ghw_handler *h); - -void ghw_filter_signals (struct ghw_handler *h, int *signals_to_keep, - int nb_signals_to_keep); - -void ghw_disp_values (struct ghw_handler *h); - -int ghw_read_cycle_start (struct ghw_handler *h); - -int ghw_read_cycle_cont (struct ghw_handler *h, int *list); - -int ghw_read_cycle_next (struct ghw_handler *h); - -int ghw_read_cycle_end (struct ghw_handler *h); - -enum ghw_sm_type -{ - /* At init; - Read section name. */ - ghw_sm_init = 0, - ghw_sm_sect = 1, - ghw_sm_cycle = 2 -}; - -enum ghw_res -{ - ghw_res_error = -1, - ghw_res_eof = -2, - ghw_res_ok = 0, - ghw_res_snapshot = 1, - ghw_res_cycle = 2, - ghw_res_other = 3 -}; - -enum ghw_res ghw_read_sm_hdr (struct ghw_handler *h, int *list); - -int ghw_read_sm (struct ghw_handler *h, enum ghw_sm_type *sm); - -int ghw_read_dump (struct ghw_handler *h); - -struct ghw_section -{ - const char name[4]; - int (*handler) (struct ghw_handler * h); -}; - -extern struct ghw_section ghw_sections[]; - -int ghw_read_section (struct ghw_handler *h); - -void ghw_close (struct ghw_handler *h); - -const char *ghw_get_dir (int is_downto); - -void ghw_disp_subtype_indication (struct ghw_handler *h, union ghw_type *t); - -/* Note: TYPE must be a base type (used only to display literals). */ -void ghw_disp_range (union ghw_type *type, union ghw_range *rng); - -void ghw_disp_type (struct ghw_handler *h, union ghw_type *t); - -void ghw_disp_types (struct ghw_handler *h); -#endif /* _GHWLIB_H_ */ diff --git a/ghw/libghw.c b/ghw/libghw.c new file mode 100644 index 000000000..eabc31cba --- /dev/null +++ b/ghw/libghw.c @@ -0,0 +1,2240 @@ +/* GHDL Wavefile reader library. + Copyright (C) 2005 Tristan Gingold + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include + +#include "libghw.h" + +/* Reopen H through decompressor DECOMP. */ + +static int +ghw_openz (struct ghw_handler *h, const char *decomp, const char *filename) +{ + int plen = strlen (decomp) + 1 + strlen (filename) + 1; + char *p = malloc (plen); + + snprintf (p, plen, "%s %s", decomp, filename); + fclose (h->stream); + h->stream = popen (p, "r"); + free (p); + + if (h->stream == NULL) + return -1; + + h->stream_ispipe = 1; + + return 0; +} + +int +ghw_open (struct ghw_handler *h, const char *filename) +{ + char hdr[16]; + + h->stream = fopen (filename, "rb"); + if (h->stream == NULL) + return -1; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + + /* Check compression layer. */ + if (!memcmp (hdr, "\x1f\x8b", 2)) + { + if (ghw_openz (h, "gzip -cd", filename) < 0) + return -1; + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + } + else if (!memcmp (hdr, "BZ", 2)) + { + if (ghw_openz (h, "bzip2 -cd", filename) < 0) + return -1; + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + } + else + { + h->stream_ispipe = 0; + } + + /* Check magic. */ + if (memcmp (hdr, "GHDLwave\n", 9) != 0) + return -2; + /* Check version. */ + if (hdr[9] != 16 || hdr[10] != 0) + return -2; + h->version = hdr[11]; + if (h->version > 1) + return -3; + if (hdr[12] == 1) + h->word_be = 0; + else if (hdr[12] == 2) + h->word_be = 1; + else + return -4; +#if 0 + /* Endianness. */ + { + int endian; + union + { + unsigned char b[4]; + uint32_t i; + } v; + v.i = 0x11223344; + if (v.b[0] == 0x11) + endian = 2; + else if (v.b[0] == 0x44) + endian = 1; + else + return -3; + + if (hdr[12] != 1 && hdr[12] != 2) + return -3; + if (hdr[12] != endian) + h->swap_word = 1; + else + h->swap_word = 0; + } +#endif + h->word_len = hdr[13]; + h->off_len = hdr[14]; + + if (hdr[15] != 0) + return -5; + + h->hie = NULL; + return 0; +} + +int32_t +ghw_get_i32 (struct ghw_handler *h, unsigned char *b) +{ + if (h->word_be) + return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3] << 0); + else + return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0] << 0); +} + +int64_t +ghw_get_i64 (struct ghw_handler *ghw_h, unsigned char *b) +{ + int l, h; + + if (ghw_h->word_be) + { + h = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3] << 0); + l = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7] << 0); + } + else + { + l = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0] << 0); + h = (b[7] << 24) | (b[6] << 16) | (b[5] << 8) | (b[4] << 0); + } + return (((int64_t) h) << 32) | l; +} + +int +ghw_read_byte (struct ghw_handler *h, unsigned char *res) +{ + int v; + + v = fgetc (h->stream); + if (v == EOF) + return -1; + *res = v; + return 0; +} + +int +ghw_read_uleb128 (struct ghw_handler *h, uint32_t * res) +{ + uint32_t r = 0; + unsigned int off = 0; + + while (1) + { + int v = fgetc (h->stream); + if (v == EOF) + return -1; + r |= (v & 0x7f) << off; + if ((v & 0x80) == 0) + break; + off += 7; + } + *res = r; + return 0; +} + +int +ghw_read_sleb128 (struct ghw_handler *h, int32_t * res) +{ + int32_t r = 0; + unsigned int off = 0; + + while (1) + { + int v = fgetc (h->stream); + if (v == EOF) + return -1; + r |= ((int32_t) (v & 0x7f)) << off; + off += 7; + if ((v & 0x80) == 0) + { + if ((v & 0x40) && off < 32) + r |= ~0U << off; + break; + } + } + *res = r; + return 0; +} + +int +ghw_read_lsleb128 (struct ghw_handler *h, int64_t * res) +{ + static const int64_t r_mask = -1; + int64_t r = 0; + unsigned int off = 0; + + while (1) + { + int v = fgetc (h->stream); + if (v == EOF) + return -1; + r |= ((int64_t) (v & 0x7f)) << off; + off += 7; + if ((v & 0x80) == 0) + { + if ((v & 0x40) && off < 64) + r |= r_mask << off; + break; + } + } + *res = r; + return 0; +} + +int +ghw_read_f64 (struct ghw_handler *h, double *res) +{ + /* FIXME: handle byte order. */ + if (fread (res, sizeof (*res), 1, h->stream) != 1) + return -1; + return 0; +} + +const char * +ghw_read_strid (struct ghw_handler *h) +{ + uint32_t id; + + if (ghw_read_uleb128 (h, &id) != 0) + return NULL; + return h->str_table[id]; +} + +union ghw_type * +ghw_read_typeid (struct ghw_handler *h) +{ + uint32_t id; + + if (ghw_read_uleb128 (h, &id) != 0) + return NULL; + return h->types[id - 1]; +} + +union ghw_range * +ghw_read_range (struct ghw_handler *h) +{ + int t = fgetc (h->stream); + if (t == EOF) + return NULL; + switch (t & 0x7f) + { + case ghdl_rtik_type_b2: + { + struct ghw_range_b2 *r; + r = malloc (sizeof (struct ghw_range_b2)); + r->kind = t & 0x7f; + r->dir = (t & 0x80) != 0; + if (ghw_read_byte (h, &r->left) != 0) + goto err_b2; + if (ghw_read_byte (h, &r->right) != 0) + goto err_b2; + return (union ghw_range *) r; + err_b2: + free (r); + return NULL; + } + case ghdl_rtik_type_e8: + { + struct ghw_range_e8 *r; + r = malloc (sizeof (struct ghw_range_e8)); + r->kind = t & 0x7f; + r->dir = (t & 0x80) != 0; + if (ghw_read_byte (h, &r->left) != 0) + goto err_e8; + if (ghw_read_byte (h, &r->right) != 0) + goto err_e8; + return (union ghw_range *) r; + err_e8: + free (r); + return NULL; + } + case ghdl_rtik_type_i32: + case ghdl_rtik_type_p32: + { + struct ghw_range_i32 *r; + r = malloc (sizeof (struct ghw_range_i32)); + r->kind = t & 0x7f; + r->dir = (t & 0x80) != 0; + if (ghw_read_sleb128 (h, &r->left) != 0) + goto err_i32; + if (ghw_read_sleb128 (h, &r->right) != 0) + goto err_i32; + return (union ghw_range *) r; + err_i32: + free (r); + return NULL; + } + case ghdl_rtik_type_i64: + case ghdl_rtik_type_p64: + { + struct ghw_range_i64 *r; + r = malloc (sizeof (struct ghw_range_i64)); + r->kind = t & 0x7f; + r->dir = (t & 0x80) != 0; + if (ghw_read_lsleb128 (h, &r->left) != 0) + goto err_i64; + if (ghw_read_lsleb128 (h, &r->right) != 0) + goto err_i64; + return (union ghw_range *) r; + err_i64: + free (r); + return NULL; + } + case ghdl_rtik_type_f64: + { + struct ghw_range_f64 *r; + r = malloc (sizeof (struct ghw_range_f64)); + r->kind = t & 0x7f; + r->dir = (t & 0x80) != 0; + if (ghw_read_f64 (h, &r->left) != 0) + goto err_f64; + if (ghw_read_f64 (h, &r->right) != 0) + goto err_f64; + return (union ghw_range *) r; + err_f64: + free (r); + return NULL; + } + default: + fprintf (stderr, "ghw_read_range: type %d unhandled\n", t & 0x7f); + return NULL; + } +} + +int +ghw_read_str (struct ghw_handler *h) +{ + unsigned char hdr[12]; + unsigned i; + char *p; + int prev_len; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + + if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) + return -1; + h->nbr_str = ghw_get_i32 (h, &hdr[4]); + h->nbr_str++; + h->str_size = ghw_get_i32 (h, &hdr[8]); + h->str_table = (char **) malloc ((h->nbr_str + 1) * sizeof (char *)); + h->str_content = (char *) malloc (h->str_size + h->nbr_str + 1); + + if (h->flag_verbose) + { + printf ("Number of strings: %u\n", h->nbr_str - 1); + printf ("String table size: %u\n", h->str_size); + } + + h->str_table[0] = ""; + p = h->str_content; + prev_len = 0; + for (i = 1; i < h->nbr_str; i++) + { + int j; + int c; + char *prev; + int sh; + + h->str_table[i] = p; + prev = h->str_table[i - 1]; + for (j = 0; j < prev_len; j++) + *p++ = prev[j]; + + while (1) + { + c = fgetc (h->stream); + if (c == EOF) + return -1; + if ((c >= 0 && c <= 31) || (c >= 128 && c <= 159)) + break; + *p++ = c; + } + *p++ = 0; + + if (h->flag_verbose > 1) + printf (" string %u (pl=%d): %s\n", i, prev_len, h->str_table[i]); + + prev_len = c & 0x1f; + sh = 5; + while (c >= 128) + { + c = fgetc (h->stream); + if (c == EOF) + return -1; + prev_len |= (c & 0x1f) << sh; + sh += 5; + } + } + if (fread (hdr, 4, 1, h->stream) != 1) + return -1; + if (memcmp (hdr, "EOS", 4) != 0) + return -1; + return 0; +} + +union ghw_type * +ghw_get_base_type (union ghw_type *t) +{ + switch (t->kind) + { + case ghdl_rtik_type_b2: + case ghdl_rtik_type_e8: + case ghdl_rtik_type_e32: + case ghdl_rtik_type_i32: + case ghdl_rtik_type_i64: + case ghdl_rtik_type_f64: + case ghdl_rtik_type_p32: + case ghdl_rtik_type_p64: + case ghdl_rtik_type_array: + return t; + case ghdl_rtik_subtype_scalar: + return t->ss.base; + case ghdl_rtik_subtype_array: + return t->sa.base; + case ghdl_rtik_subtype_unbounded_array: + return t->sua.base; + default: + fprintf (stderr, "ghw_get_base_type: cannot handle type %d\n", t->kind); + abort (); + } +} + +/* Return -1 for unbounded types. */ +static int +get_nbr_elements (union ghw_type *t) +{ + switch (t->kind) + { + case ghdl_rtik_type_b2: + case ghdl_rtik_type_e8: + case ghdl_rtik_type_e32: + case ghdl_rtik_type_i32: + case ghdl_rtik_type_i64: + case ghdl_rtik_type_f64: + case ghdl_rtik_type_p32: + case ghdl_rtik_type_p64: + case ghdl_rtik_subtype_scalar: + return 1; + case ghdl_rtik_type_array: + return -1; + case ghdl_rtik_subtype_array: + return t->sa.nbr_scalars; + case ghdl_rtik_type_record: + return t->rec.nbr_scalars; + case ghdl_rtik_subtype_record: + return t->sr.nbr_scalars; + case ghdl_rtik_subtype_unbounded_record: + case ghdl_rtik_subtype_unbounded_array: + return -1; + default: + fprintf (stderr, "get_nbr_elements: unhandled type %d\n", t->kind); + abort (); + } +} + +int +ghw_get_range_length (union ghw_range *rng) +{ + int res; + + assert (rng != NULL); + + switch (rng->kind) + { + case ghdl_rtik_type_i32: + if (rng->i32.dir) + res = rng->i32.left - rng->i32.right + 1; + else + res = rng->i32.right - rng->i32.left + 1; + break; + case ghdl_rtik_type_b2: + if (rng->b2.dir) + res = rng->b2.left - rng->b2.right + 1; + else + res = rng->b2.right - rng->b2.left + 1; + break; + case ghdl_rtik_type_e8: + if (rng->e8.dir) + res = rng->e8.left - rng->e8.right + 1; + else + res = rng->e8.right - rng->e8.left + 1; + break; + default: + fprintf (stderr, "get_range_length: unhandled kind %d\n", rng->kind); + abort (); + } + /* The length of a null range is 0. */ + return (res <= 0) ? 0 : res; +} + +static union ghw_type *ghw_read_type_bounds (struct ghw_handler *h, + union ghw_type *base); + +/* Create an array subtype using BASE and ranges read from H. */ + +struct ghw_subtype_array * +ghw_read_array_subtype (struct ghw_handler *h, union ghw_type *base) +{ + struct ghw_type_array *arr = + (struct ghw_type_array *) ghw_get_base_type (base); + struct ghw_subtype_array *sa; + unsigned j; + int nbr_scalars; + int nbr_els; + + sa = malloc (sizeof (struct ghw_subtype_array)); + sa->kind = ghdl_rtik_subtype_array; + sa->name = NULL; + sa->base = base; + nbr_els = get_nbr_elements (arr->el); + nbr_scalars = 1; + sa->rngs = malloc (arr->nbr_dim * sizeof (union ghw_range *)); + for (j = 0; j < arr->nbr_dim; j++) + { + sa->rngs[j] = ghw_read_range (h); + nbr_scalars *= ghw_get_range_length (sa->rngs[j]); + } + if (nbr_els >= 0) + { + /* Element type is bounded. */ + sa->el = arr->el; + } + else + { + /* Read bounds for the elements. */ + sa->el = ghw_read_type_bounds (h, arr->el); + nbr_els = get_nbr_elements (sa->el); + } + sa->nbr_scalars = nbr_scalars * nbr_els; + return sa; +} + +struct ghw_subtype_record * +ghw_read_record_subtype (struct ghw_handler *h, struct ghw_type_record *base) +{ + struct ghw_subtype_record *sr; + + sr = malloc (sizeof (struct ghw_subtype_record)); + sr->kind = ghdl_rtik_subtype_record; + sr->name = NULL; + sr->base = base; + if (base->nbr_scalars >= 0) + { + /* Record base type is bounded. */ + sr->nbr_scalars = base->nbr_scalars; + sr->els = base->els; + } + else + { + /* Read subtypes. */ + unsigned j; + int nbr_scalars; + + sr->els = + malloc (base->nbr_fields * sizeof (struct ghw_record_element)); + nbr_scalars = 0; + for (j = 0; j < base->nbr_fields; j++) + { + union ghw_type *btype = base->els[j].type; + int el_nbr_scalars = get_nbr_elements (btype); + + sr->els[j].name = base->els[j].name; + if (el_nbr_scalars >= 0) + { + /* Element is constrained. */ + sr->els[j].type = btype; + } + else + { + sr->els[j].type = ghw_read_type_bounds (h, btype); + el_nbr_scalars = get_nbr_elements (sr->els[j].type); + } + nbr_scalars += el_nbr_scalars; + } + sr->nbr_scalars = nbr_scalars; + } + return sr; +} + +/* Read bounds for BASE and create a subtype. */ + +static union ghw_type * +ghw_read_type_bounds (struct ghw_handler *h, union ghw_type *base) +{ + switch (base->kind) + { + case ghdl_rtik_type_array: + case ghdl_rtik_subtype_unbounded_array: + return (union ghw_type *) ghw_read_array_subtype (h, base); + break; + case ghdl_rtik_type_record: + case ghdl_rtik_subtype_unbounded_record: + return (union ghw_type *) ghw_read_record_subtype (h, &base->rec); + break; + default: + fprintf (stderr, "ghw_read_type_bounds: unhandled kind %d\n", + base->kind); + return NULL; + } +} + +int +ghw_read_type (struct ghw_handler *h) +{ + unsigned char hdr[8]; + unsigned i; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + + if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) + return -1; + h->nbr_types = ghw_get_i32 (h, &hdr[4]); + h->types = + (union ghw_type **) malloc (h->nbr_types * sizeof (union ghw_type *)); + + for (i = 0; i < h->nbr_types; i++) + { + int t; + + t = fgetc (h->stream); + if (t == EOF) + return -1; + if (h->flag_verbose > 1) + printf ("type[%d]= %d\n", i, t); + switch (t) + { + case ghdl_rtik_type_b2: + case ghdl_rtik_type_e8: + { + struct ghw_type_enum *e; + unsigned j; + + e = malloc (sizeof (struct ghw_type_enum)); + e->kind = t; + e->wkt = ghw_wkt_unknown; + e->name = ghw_read_strid (h); + if (ghw_read_uleb128 (h, &e->nbr) != 0) + goto err_b2; + e->lits = (const char **) malloc (e->nbr * sizeof (char *)); + if (h->flag_verbose > 1) + printf ("enum %s:", e->name); + for (j = 0; j < e->nbr; j++) + { + e->lits[j] = ghw_read_strid (h); + if (h->flag_verbose > 1) + printf (" %s", e->lits[j]); + } + if (h->flag_verbose > 1) + printf ("\n"); + h->types[i] = (union ghw_type *) e; + break; + err_b2: + free (e); + return -1; + } + break; + case ghdl_rtik_type_i32: + case ghdl_rtik_type_i64: + case ghdl_rtik_type_f64: + { + struct ghw_type_scalar *sc; + + sc = malloc (sizeof (struct ghw_type_scalar)); + sc->kind = t; + sc->name = ghw_read_strid (h); + if (h->flag_verbose > 1) + printf ("scalar: %s\n", sc->name); + h->types[i] = (union ghw_type *) sc; + } break; + case ghdl_rtik_type_p32: + case ghdl_rtik_type_p64: + { + struct ghw_type_physical *ph; + + ph = malloc (sizeof (struct ghw_type_physical)); + ph->kind = t; + ph->name = ghw_read_strid (h); + ph->units = NULL; + if (h->version == 0) + ph->nbr_units = 0; + else + { + unsigned j; + + if (ghw_read_uleb128 (h, &ph->nbr_units) != 0) + goto err_p32; + ph->units = malloc (ph->nbr_units * sizeof (struct ghw_unit)); + for (j = 0; j < ph->nbr_units; j++) + { + ph->units[j].name = ghw_read_strid (h); + if (ghw_read_lsleb128 (h, &ph->units[j].val) < 0) + goto err_p32; + } + } + if (h->flag_verbose > 1) + printf ("physical: %s\n", ph->name); + h->types[i] = (union ghw_type *) ph; + break; + err_p32: + free (ph->units); + free (ph); + return -1; + } + break; + case ghdl_rtik_subtype_scalar: + { + struct ghw_subtype_scalar *ss; + + ss = malloc (sizeof (struct ghw_subtype_scalar)); + ss->kind = t; + ss->name = ghw_read_strid (h); + ss->base = ghw_read_typeid (h); + ss->rng = ghw_read_range (h); + if (h->flag_verbose > 1) + printf ("subtype scalar: %s\n", ss->name); + h->types[i] = (union ghw_type *) ss; + } break; + case ghdl_rtik_type_array: + { + struct ghw_type_array *arr; + unsigned j; + + arr = malloc (sizeof (struct ghw_type_array)); + arr->kind = t; + arr->name = ghw_read_strid (h); + arr->el = ghw_read_typeid (h); + if (ghw_read_uleb128 (h, &arr->nbr_dim) != 0) + goto err_array; + arr->dims = + (union ghw_type **) malloc (arr->nbr_dim * + sizeof (union ghw_type *)); + for (j = 0; j < arr->nbr_dim; j++) + arr->dims[j] = ghw_read_typeid (h); + if (h->flag_verbose > 1) + printf ("array: %s (ndim=%u) of %s\n", arr->name, arr->nbr_dim, + arr->el->common.name); + h->types[i] = (union ghw_type *) arr; + break; + err_array: + free (arr); + return -1; + } + break; + case ghdl_rtik_subtype_array: + { + struct ghw_subtype_array *sa; + const char *name; + union ghw_type *base; + + name = ghw_read_strid (h); + base = ghw_read_typeid (h); + + sa = ghw_read_array_subtype (h, base); + sa->name = name; + h->types[i] = (union ghw_type *) sa; + if (h->flag_verbose > 1) + printf ("subtype array: %s (nbr_scalars=%d)\n", sa->name, + sa->nbr_scalars); + } + break; + case ghdl_rtik_subtype_unbounded_array: + { + struct ghw_subtype_unbounded_array *sua; + + sua = malloc (sizeof (struct ghw_subtype_unbounded_array)); + sua->kind = t; + sua->name = ghw_read_strid (h); + sua->base = ghw_read_typeid (h); + h->types[i] = (union ghw_type *) sua; + if (h->flag_verbose > 1) + printf ("subtype unbounded array: %s\n", sua->name); + } + break; + case ghdl_rtik_type_record: + { + struct ghw_type_record *rec; + unsigned j; + int nbr_scalars; + + rec = malloc (sizeof (struct ghw_type_record)); + rec->kind = t; + rec->name = ghw_read_strid (h); + rec->els = NULL; + if (ghw_read_uleb128 (h, &rec->nbr_fields) != 0) + goto err_record; + rec->els = + malloc (rec->nbr_fields * sizeof (struct ghw_record_element)); + nbr_scalars = 0; + for (j = 0; j < rec->nbr_fields; j++) + { + rec->els[j].name = ghw_read_strid (h); + rec->els[j].type = ghw_read_typeid (h); + if (nbr_scalars != -1) + { + int field_nbr_scalars = + get_nbr_elements (rec->els[j].type); + if (field_nbr_scalars == -1) + nbr_scalars = -1; + else + nbr_scalars += field_nbr_scalars; + } + } + rec->nbr_scalars = nbr_scalars; + if (h->flag_verbose > 1) + printf ("record type: %s (nbr_scalars=%d)\n", rec->name, + rec->nbr_scalars); + h->types[i] = (union ghw_type *) rec; + break; + err_record: + free (rec->els); + free (rec); + return -1; + } + break; + case ghdl_rtik_subtype_record: + { + struct ghw_subtype_record *sr; + const char *name; + struct ghw_type_record *base; + + name = ghw_read_strid (h); + base = (struct ghw_type_record *) ghw_read_typeid (h); + + sr = ghw_read_record_subtype (h, base); + sr->name = name; + h->types[i] = (union ghw_type *) sr; + if (h->flag_verbose > 1) + printf ("subtype record: %s (nbr_scalars=%d)\n", sr->name, + sr->nbr_scalars); + } + break; + case ghdl_rtik_subtype_unbounded_record: + { + struct ghw_subtype_unbounded_record *sur; + + sur = malloc (sizeof (struct ghw_subtype_unbounded_record)); + sur->kind = t; + sur->name = ghw_read_strid (h); + sur->base = (struct ghw_type_record *) ghw_read_typeid (h); + h->types[i] = (union ghw_type *) sur; + if (h->flag_verbose > 1) + printf ("subtype unbounded record: %s\n", sur->name); + } + break; + default: + fprintf (stderr, "ghw_read_type: unknown type %d\n", t); + return -1; + } + } + if (fgetc (h->stream) != 0) + return -1; + return 0; +} + +int +ghw_read_wk_types (struct ghw_handler *h) +{ + char hdr[4]; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + + if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) + return -1; + + while (1) + { + int t; + union ghw_type *tid; + + t = fgetc (h->stream); + if (t == EOF) + return -1; + else if (t == 0) + break; + + tid = ghw_read_typeid (h); + if (tid->kind == ghdl_rtik_type_b2 || tid->kind == ghdl_rtik_type_e8) + { + if (h->flag_verbose > 0) + printf ("%s: wkt=%d\n", tid->en.name, t); + tid->en.wkt = t; + } + } + return 0; +} + +void +ghw_disp_typename (struct ghw_handler *h, union ghw_type *t) +{ + (void) h; + printf ("%s", t->common.name); +} + +/* Read a signal composed of severals elements. + Return 0 for success. */ +int +ghw_read_signal (struct ghw_handler *h, unsigned int *sigs, union ghw_type *t) +{ + switch (t->kind) + { + case ghdl_rtik_type_b2: + case ghdl_rtik_type_e8: + case ghdl_rtik_type_e32: + case ghdl_rtik_subtype_scalar: + { + unsigned int sig_el; + + if (ghw_read_uleb128 (h, &sig_el) < 0) + return -1; + *sigs = sig_el; + if (sig_el == 0 || sig_el >= h->nbr_sigs) + return -1; + if (h->sigs[sig_el].type == NULL) + h->sigs[sig_el].type = ghw_get_base_type (t); + } + return 0; + case ghdl_rtik_subtype_array: + { + int i; + int stride; + int len; + + len = t->sa.nbr_scalars; + stride = get_nbr_elements (t->sa.el); + + for (i = 0; i < len; i += stride) + if (ghw_read_signal (h, &sigs[i], t->sa.el) < 0) + return -1; + } + return 0; + case ghdl_rtik_type_record: + { + struct ghw_type_record *r = &t->rec; + int nbr_fields = r->nbr_fields; + int i; + int off; + + off = 0; + for (i = 0; i < nbr_fields; i++) + { + if (ghw_read_signal (h, &sigs[off], r->els[i].type) < 0) + return -1; + off += get_nbr_elements (r->els[i].type); + } + } + return 0; + case ghdl_rtik_subtype_record: + { + struct ghw_subtype_record *sr = &t->sr; + int nbr_fields = sr->base->nbr_fields; + int i; + int off; + + off = 0; + for (i = 0; i < nbr_fields; i++) + { + if (ghw_read_signal (h, &sigs[off], sr->els[i].type) < 0) + return -1; + off += get_nbr_elements (sr->els[i].type); + } + } + return 0; + default: + fprintf (stderr, "ghw_read_signal: type kind %d unhandled\n", t->kind); + abort (); + } +} + +int +ghw_read_value (struct ghw_handler *h, union ghw_val *val, + union ghw_type *type) +{ + switch (ghw_get_base_type (type)->kind) + { + case ghdl_rtik_type_b2: + { + int v; + v = fgetc (h->stream); + if (v == EOF) + return -1; + val->b2 = v; + } + break; + case ghdl_rtik_type_e8: + { + int v; + v = fgetc (h->stream); + if (v == EOF) + return -1; + val->e8 = v; + } + break; + case ghdl_rtik_type_i32: + case ghdl_rtik_type_p32: + { + int32_t v; + if (ghw_read_sleb128 (h, &v) < 0) + return -1; + val->i32 = v; + } + break; + case ghdl_rtik_type_f64: + { + double v; + if (ghw_read_f64 (h, &v) < 0) + return -1; + val->f64 = v; + } + break; + case ghdl_rtik_type_p64: + { + int64_t v; + if (ghw_read_lsleb128 (h, &v) < 0) + return -1; + val->i64 = v; + } + break; + default: + fprintf (stderr, "read_value: cannot handle format %d\n", type->kind); + abort (); + } + return 0; +} + +int +ghw_read_hie (struct ghw_handler *h) +{ + unsigned char hdr[16]; + int nbr_scopes; + int nbr_sigs; + unsigned i; + struct ghw_hie *blk; + struct ghw_hie **last; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + + if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) + return -1; + nbr_scopes = ghw_get_i32 (h, &hdr[4]); + /* Number of declared signals (which may be composite). */ + nbr_sigs = ghw_get_i32 (h, &hdr[8]); + /* Number of basic signals. */ + h->nbr_sigs = ghw_get_i32 (h, &hdr[12]); + + if (h->flag_verbose) + printf ("%u scopes, %u signals, %u signal elements\n", nbr_scopes, + nbr_sigs, h->nbr_sigs); + + blk = (struct ghw_hie *) malloc (sizeof (struct ghw_hie)); + blk->kind = ghw_hie_design; + blk->name = NULL; + blk->parent = NULL; + blk->brother = NULL; + blk->u.blk.child = NULL; + + last = &blk->u.blk.child; + h->hie = blk; + + h->nbr_sigs++; + h->skip_sigs = NULL; + h->flag_full_names = 0; + h->sigs = (struct ghw_sig *) malloc (h->nbr_sigs * sizeof (struct ghw_sig)); + memset (h->sigs, 0, h->nbr_sigs * sizeof (struct ghw_sig)); + + while (1) + { + int t; + struct ghw_hie *el; + unsigned int str; + + t = fgetc (h->stream); + if (t == EOF) + return -1; + if (t == 0) + break; + + if (t == ghw_hie_eos) + { + blk = blk->parent; + if (blk->u.blk.child == NULL) + last = &blk->u.blk.child; + else + { + struct ghw_hie *l = blk->u.blk.child; + while (l->brother != NULL) + l = l->brother; + last = &l->brother; + } + + continue; + } + + el = (struct ghw_hie *) malloc (sizeof (struct ghw_hie)); + el->kind = t; + el->parent = blk; + el->brother = NULL; + + /* Link. */ + *last = el; + last = &el->brother; + + /* Read name. */ + if (ghw_read_uleb128 (h, &str) != 0) + return -1; + el->name = h->str_table[str]; + + switch (t) + { + case ghw_hie_eoh: + case ghw_hie_design: + case ghw_hie_eos: + /* Should not be here. */ + abort (); + case ghw_hie_process: + el->u.blk.child = NULL; + break; + case ghw_hie_block: + case ghw_hie_generate_if: + case ghw_hie_generate_for: + case ghw_hie_instance: + case ghw_hie_generic: + case ghw_hie_package: + /* Create a block. */ + el->u.blk.child = NULL; + + if (t == ghw_hie_generate_for) + { + el->u.blk.iter_type = ghw_read_typeid (h); + el->u.blk.iter_value = malloc (sizeof (union ghw_val)); + if (ghw_read_value + (h, el->u.blk.iter_value, el->u.blk.iter_type) < 0) + return -1; + } + blk = el; + last = &el->u.blk.child; + break; + case ghw_hie_signal: + case ghw_hie_port_in: + case ghw_hie_port_out: + case ghw_hie_port_inout: + case ghw_hie_port_buffer: + case ghw_hie_port_linkage: + /* For a signal, read type. */ + { + int nbr_el; + unsigned int *sigs; + + el->u.sig.type = ghw_read_typeid (h); + nbr_el = get_nbr_elements (el->u.sig.type); + if (nbr_el < 0) + return -1; + sigs = + (unsigned int *) malloc ((nbr_el + 1) * sizeof (unsigned int)); + el->u.sig.sigs = sigs; + /* Last element is NULL. */ + sigs[nbr_el] = 0; + + if (h->flag_verbose > 1) + printf ("signal %s: %d el [", el->name, nbr_el); + if (ghw_read_signal (h, sigs, el->u.sig.type) < 0) + return -1; + if (h->flag_verbose > 1) + { + int j; + for (j = 0; j < nbr_el; j++) + printf (" #%u", sigs[j]); + printf ("]\n"); + } + } + break; + default: + fprintf (stderr, "ghw_read_hie: unhandled kind %d\n", t); + abort (); + } + } + + /* Allocate values. */ + for (i = 0; i < h->nbr_sigs; i++) + if (h->sigs[i].type != NULL) + h->sigs[i].val = (union ghw_val *) malloc (sizeof (union ghw_val)); + return 0; +} + +const char * +ghw_get_hie_name (struct ghw_hie *h) +{ + switch (h->kind) + { + case ghw_hie_eoh: + return "eoh"; + case ghw_hie_design: + return "design"; + case ghw_hie_block: + return "block"; + case ghw_hie_generate_if: + return "generate-if"; + case ghw_hie_generate_for: + return "generate-for"; + case ghw_hie_instance: + return "instance"; + case ghw_hie_package: + return "package"; + case ghw_hie_process: + return "process"; + case ghw_hie_generic: + return "generic"; + case ghw_hie_eos: + return "eos"; + case ghw_hie_signal: + return "signal"; + case ghw_hie_port_in: + return "port-in"; + case ghw_hie_port_out: + return "port-out"; + case ghw_hie_port_inout: + return "port-inout"; + case ghw_hie_port_buffer: + return "port-buffer"; + case ghw_hie_port_linkage: + return "port-linkage"; + default: + return "??"; + } +} + +void ghw_disp_value (union ghw_val *val, union ghw_type *type); + +static void +print_name (struct ghw_hie *hie, int full_names) +{ + int i; + int depth; + struct ghw_hie *p; + struct ghw_hie **buf; + struct ghw_hie **end; + + /* HIE must be valid. */ + assert (hie->name != NULL); + + if (0 == full_names) + { + printf (" %s: ", hie->name); + return; + } + + p = hie; + depth = 0; + while (p && p->name) + { + p = p->parent; + ++depth; + } + buf = (struct ghw_hie **) malloc (depth * sizeof (struct ghw_hie *)); + + p = hie; + end = depth + buf; + while (p && p->name) + { + *(--end) = p; + p = p->parent; + } + + putchar (' '); + putchar ('/'); + for (i = 0; i < depth; ++i) + { + printf ("%s%s", i ? "/" : "", buf[i]->name); + if (ghw_hie_generate_for == buf[i]->kind) + { + putchar ('('); + ghw_disp_value (buf[i]->u.blk.iter_value, buf[i]->u.blk.iter_type); + putchar (')'); + } + } + putchar (':'); + putchar (' '); + free (buf); +} + +void +ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top) +{ + int i; + int indent; + struct ghw_hie *hie; + struct ghw_hie *n; + + hie = top; + indent = 0; + + while (1) + { + if (0 == h->flag_full_names) + for (i = 0; i < indent; i++) + fputc (' ', stdout); + printf ("%s", ghw_get_hie_name (hie)); + + switch (hie->kind) + { + case ghw_hie_design: + case ghw_hie_block: + case ghw_hie_generate_if: + case ghw_hie_generate_for: + case ghw_hie_instance: + case ghw_hie_process: + case ghw_hie_package: + if (hie->name) + print_name (hie, h->flag_full_names); + if (hie->kind == ghw_hie_generate_for) + { + printf ("("); + ghw_disp_value (hie->u.blk.iter_value, hie->u.blk.iter_type); + printf (")"); + } + n = hie->u.blk.child; + if (n == NULL) + n = hie->brother; + else + indent++; + break; + case ghw_hie_generic: + case ghw_hie_eos: + abort (); + case ghw_hie_signal: + case ghw_hie_port_in: + case ghw_hie_port_out: + case ghw_hie_port_inout: + case ghw_hie_port_buffer: + case ghw_hie_port_linkage: + { + unsigned int *sigs = hie->u.sig.sigs; + unsigned int k, num; + + print_name (hie, h->flag_full_names); + ghw_disp_subtype_indication (h, hie->u.sig.type); + printf (":"); + k = 0; + /* There can be 0-length signals. */ + while (sigs[k] != GHW_NO_SIG) + { + /* First signal of the range. */ + printf (" #%u", sigs[k]); + for (num = 1; sigs[k + num] != GHW_NO_SIG; num++) + if (sigs[k + num] != sigs[k + num - 1] + 1) + break; + if (num > 1) + printf ("-#%u", sigs[k + num - 1]); + k += num; + } + n = hie->brother; + } + break; + default: + abort (); + } + printf ("\n"); + + while (n == NULL) + { + if (hie->parent == NULL) + return; + hie = hie->parent; + indent--; + n = hie->brother; + } + hie = n; + } +} + +int +ghw_read_eoh (struct ghw_handler *h) +{ + (void) h; + return 0; +} + +int +ghw_read_base (struct ghw_handler *h) +{ + unsigned char hdr[4]; + int res; + + while (1) + { + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + if (memcmp (hdr, "STR", 4) == 0) + res = ghw_read_str (h); + else if (memcmp (hdr, "HIE", 4) == 0) + res = ghw_read_hie (h); + else if (memcmp (hdr, "TYP", 4) == 0) + res = ghw_read_type (h); + else if (memcmp (hdr, "WKT", 4) == 0) + res = ghw_read_wk_types (h); + else if (memcmp (hdr, "EOH", 4) == 0) + return 0; + else + { + fprintf (stderr, "ghw_read_base: unknown GHW section %c%c%c%c\n", + hdr[0], hdr[1], hdr[2], hdr[3]); + return -1; + } + if (res != 0) + { + fprintf (stderr, "ghw_read_base: error in section %s\n", hdr); + return res; + } + } +} + +int +ghw_read_signal_value (struct ghw_handler *h, struct ghw_sig *s) +{ + return ghw_read_value (h, s->val, s->type); +} + +int +ghw_read_snapshot (struct ghw_handler *h) +{ + unsigned char hdr[12]; + unsigned i; + struct ghw_sig *s; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + + if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) + return -1; + h->snap_time = ghw_get_i64 (h, &hdr[4]); + if (h->flag_verbose > 1) + printf ("Time is " GHWPRI64 " fs\n", h->snap_time); + + for (i = 0; i < h->nbr_sigs; i++) + { + s = &h->sigs[i]; + if (s->type != NULL) + { + if (h->flag_verbose > 1) + printf ("read type %d for sig %u\n", s->type->kind, i); + if (ghw_read_signal_value (h, s) < 0) + return -1; + } + } + if (fread (hdr, 4, 1, h->stream) != 1) + return -1; + + if (memcmp (hdr, "ESN", 4)) + return -1; + + return 0; +} + +void ghw_disp_values (struct ghw_handler *h); + +int +ghw_read_cycle_start (struct ghw_handler *h) +{ + unsigned char hdr[8]; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + + h->snap_time = ghw_get_i64 (h, hdr); + return 0; +} + +int +ghw_read_cycle_cont (struct ghw_handler *h, int *list) +{ + int i; + int *list_p; + + i = 0; + list_p = list; + while (1) + { + uint32_t d; + + /* Read delta to next signal. */ + if (ghw_read_uleb128 (h, &d) < 0) + return -1; + if (d == 0) + { + /* Last signal reached. */ + break; + } + + /* Find next signal. */ + while (d > 0) + { + i++; + if (h->sigs[i].type != NULL) + d--; + } + + if (ghw_read_signal_value (h, &h->sigs[i]) < 0) + return -1; + if (list_p) + *list_p++ = i; + } + + if (list_p) + *list_p = 0; + return 0; +} + +int +ghw_read_cycle_next (struct ghw_handler *h) +{ + int64_t d_time; + + if (ghw_read_lsleb128 (h, &d_time) < 0) + return -1; + if (d_time == -1) + return 0; + h->snap_time += d_time; + return 1; +} + +int +ghw_read_cycle_end (struct ghw_handler *h) +{ + char hdr[4]; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + if (memcmp (hdr, "ECY", 4)) + return -1; + + return 0; +} + +static const char * +ghw_get_lit (union ghw_type *type, unsigned e) +{ + if (e >= type->en.nbr) + return "??"; + else + return type->en.lits[e]; +} + +static void +ghw_disp_lit (union ghw_type *type, unsigned e) +{ + printf ("%s (%u)", ghw_get_lit (type, e), e); +} + +void +ghw_disp_value (union ghw_val *val, union ghw_type *type) +{ + switch (ghw_get_base_type (type)->kind) + { + case ghdl_rtik_type_b2: + ghw_disp_lit (type, val->b2); + break; + case ghdl_rtik_type_e8: + ghw_disp_lit (type, val->e8); + break; + case ghdl_rtik_type_i32: + printf (GHWPRI32, val->i32); + break; + case ghdl_rtik_type_p64: + printf (GHWPRI64, val->i64); + break; + case ghdl_rtik_type_f64: + printf ("%g", val->f64); + break; + default: + fprintf (stderr, "ghw_disp_value: cannot handle type %d\n", type->kind); + abort (); + } +} + +/* Put the ASCII representation of VAL into BUF, whose size if LEN. + A NUL is always written to BUF. +*/ +void +ghw_get_value (char *buf, int len, union ghw_val *val, union ghw_type *type) +{ + union ghw_type *base = ghw_get_base_type (type); + + switch (base->kind) + { + case ghdl_rtik_type_b2: + if (val->b2 <= 1) + { + strncpy (buf, base->en.lits[val->b2], len - 1); + buf[len - 1] = 0; + } + else + { + snprintf (buf, len, "?%d", val->b2); + } + break; + case ghdl_rtik_type_e8: + if (val->b2 <= base->en.nbr) + { + strncpy (buf, base->en.lits[val->e8], len - 1); + buf[len - 1] = 0; + } + else + { + snprintf (buf, len, "?%d", val->e8); + } + break; + case ghdl_rtik_type_i32: + snprintf (buf, len, GHWPRI32, val->i32); + break; + case ghdl_rtik_type_p64: + snprintf (buf, len, GHWPRI64, val->i64); + break; + case ghdl_rtik_type_f64: + snprintf (buf, len, "%g", val->f64); + break; + default: + snprintf (buf, len, "?bad type %d?", type->kind); + } +} + +static char +is_skip_signal (int *signals_to_keep, int nb_signals_to_keep, int signal) +{ + int i; + for (i = 0; i < nb_signals_to_keep; ++i) + { + if (signal == signals_to_keep[i]) + { + return 0; + } + } + return 1; +} + +void +ghw_filter_signals (struct ghw_handler *h, int *signals_to_keep, + int nb_signals_to_keep) +{ + unsigned i; + + if (0 < nb_signals_to_keep && 0 != signals_to_keep) + { + if (0 == h->skip_sigs) + { + h->skip_sigs = (char *) malloc (sizeof (char) * h->nbr_sigs); + } + for (i = 0; i < h->nbr_sigs; ++i) + { + h->skip_sigs[i] = + is_skip_signal (signals_to_keep, nb_signals_to_keep, i); + } + } + else + { + if (0 != h->skip_sigs) + { + free (h->skip_sigs); + h->skip_sigs = 0; + } + } +} + +void +ghw_disp_values (struct ghw_handler *h) +{ + unsigned i; + for (i = 0; i < h->nbr_sigs; i++) + { + struct ghw_sig *s = &h->sigs[i]; + int skip = (0 != h->skip_sigs && (0 != h->skip_sigs[i])); + if (s->type != NULL && !skip) + { + printf ("#%u: ", i); + ghw_disp_value (s->val, s->type); + printf ("\n"); + } + } +} + +int +ghw_read_directory (struct ghw_handler *h) +{ + unsigned char hdr[8]; + int nbr_entries; + int i; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + + nbr_entries = ghw_get_i32 (h, &hdr[4]); + + if (h->flag_verbose) + printf ("Directory (%d entries):\n", nbr_entries); + + for (i = 0; i < nbr_entries; i++) + { + unsigned char ent[8]; + int pos; + + if (fread (ent, sizeof (ent), 1, h->stream) != 1) + return -1; + + pos = ghw_get_i32 (h, &ent[4]); + if (h->flag_verbose) + printf (" %s at %d\n", ent, pos); + } + + if (fread (hdr, 4, 1, h->stream) != 1) + return -1; + if (memcmp (hdr, "EOD", 4)) + return -1; + return 0; +} + +int +ghw_read_tailer (struct ghw_handler *h) +{ + unsigned char hdr[8]; + int pos; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + return -1; + + pos = ghw_get_i32 (h, &hdr[4]); + + if (h->flag_verbose) + printf ("Tailer: directory at %d\n", pos); + return 0; +} + +enum ghw_res +ghw_read_sm_hdr (struct ghw_handler *h, int *list) +{ + unsigned char hdr[4]; + int res; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + { + if (feof (h->stream)) + return ghw_res_eof; + else + return ghw_res_error; + } + if (memcmp (hdr, "SNP", 4) == 0) + { + res = ghw_read_snapshot (h); + if (res < 0) + return res; + return ghw_res_snapshot; + } + else if (memcmp (hdr, "CYC", 4) == 0) + { + res = ghw_read_cycle_start (h); + if (res < 0) + return res; + res = ghw_read_cycle_cont (h, list); + if (res < 0) + return res; + + return ghw_res_cycle; + } + else if (memcmp (hdr, "DIR", 4) == 0) + { + res = ghw_read_directory (h); + } + else if (memcmp (hdr, "TAI", 4) == 0) + { + res = ghw_read_tailer (h); + } + else + { + fprintf (stderr, "unknown GHW section %c%c%c%c\n", hdr[0], hdr[1], + hdr[2], hdr[3]); + return -1; + } + if (res != 0) + return res; + return ghw_res_other; +} + +int +ghw_read_sm (struct ghw_handler *h, enum ghw_sm_type *sm) +{ + int res; + + while (1) + { + /* printf ("sm: state = %d\n", *sm); */ + switch (*sm) + { + case ghw_sm_init: + case ghw_sm_sect: + res = ghw_read_sm_hdr (h, NULL); + switch (res) + { + case ghw_res_other: + break; + case ghw_res_snapshot: + *sm = ghw_sm_sect; + return res; + case ghw_res_cycle: + *sm = ghw_sm_cycle; + return res; + default: + return res; + } + break; + case ghw_sm_cycle: + if (0) + printf ("Time is " GHWPRI64 " fs\n", h->snap_time); + if (0) + ghw_disp_values (h); + + res = ghw_read_cycle_next (h); + if (res < 0) + return res; + if (res == 1) + { + res = ghw_read_cycle_cont (h, NULL); + if (res < 0) + return res; + return ghw_res_cycle; + } + res = ghw_read_cycle_end (h); + if (res < 0) + return res; + *sm = ghw_sm_sect; + break; + } + } +} + +int +ghw_read_cycle (struct ghw_handler *h) +{ + int res; + + res = ghw_read_cycle_start (h); + if (res < 0) + return res; + while (1) + { + res = ghw_read_cycle_cont (h, NULL); + if (res < 0) + return res; + + if (0) + printf ("Time is " GHWPRI64 " fs\n", h->snap_time); + if (0) + ghw_disp_values (h); + + res = ghw_read_cycle_next (h); + if (res < 0) + return res; + if (res == 0) + break; + } + res = ghw_read_cycle_end (h); + return res; +} + +int +ghw_read_dump (struct ghw_handler *h) +{ + unsigned char hdr[4]; + int res; + + while (1) + { + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + { + if (feof (h->stream)) + return 0; + else + return -1; + } + if (memcmp (hdr, "SNP", 4) == 0) + { + res = ghw_read_snapshot (h); + if (0 && res >= 0) + ghw_disp_values (h); + } + else if (memcmp (hdr, "CYC", 4) == 0) + { + res = ghw_read_cycle (h); + } + else if (memcmp (hdr, "DIR", 4) == 0) + { + res = ghw_read_directory (h); + } + else if (memcmp (hdr, "TAI", 4) == 0) + { + res = ghw_read_tailer (h); + } + else + { + fprintf (stderr, "unknown GHW section %c%c%c%c\n", hdr[0], hdr[1], + hdr[2], hdr[3]); + return -1; + } + if (res != 0) + return res; + } +} + +struct ghw_section ghw_sections[] = { {"\0\0\0", NULL}, +{"STR", ghw_read_str}, +{"HIE", ghw_read_hie}, +{"TYP", ghw_read_type}, +{"WKT", ghw_read_wk_types}, +{"EOH", ghw_read_eoh}, +{"SNP", ghw_read_snapshot}, +{"CYC", ghw_read_cycle}, +{"DIR", ghw_read_directory}, +{"TAI", ghw_read_tailer} +}; + +int +ghw_read_section (struct ghw_handler *h) +{ + unsigned char hdr[4]; + unsigned i; + + if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) + { + if (feof (h->stream)) + return -2; + else + return -1; + } + + for (i = 1; i < sizeof (ghw_sections) / sizeof (*ghw_sections); i++) + if (memcmp (hdr, ghw_sections[i].name, 4) == 0) + return i; + + fprintf (stderr, "ghw_read_section: unknown GHW section %c%c%c%c\n", hdr[0], + hdr[1], hdr[2], hdr[3]); + return 0; +} + +void +ghw_close (struct ghw_handler *h) +{ + if (h->stream) + { + if (h->stream_ispipe) + pclose (h->stream); + else + fclose (h->stream); + + h->stream = NULL; + } +} + +const char * +ghw_get_dir (int is_downto) +{ + return is_downto ? "downto" : "to"; +} + +void +ghw_disp_range (union ghw_type *type, union ghw_range *rng) +{ + switch (rng->kind) + { + case ghdl_rtik_type_b2: + printf ("%s %s %s", ghw_get_lit (type, rng->b2.left), + ghw_get_dir (rng->b2.dir), ghw_get_lit (type, rng->b2.right)); + break; + case ghdl_rtik_type_e8: + printf ("%s %s %s", ghw_get_lit (type, rng->e8.left), + ghw_get_dir (rng->e8.dir), ghw_get_lit (type, rng->e8.right)); + break; + case ghdl_rtik_type_i32: + case ghdl_rtik_type_p32: + printf (GHWPRI32 " %s " GHWPRI32, rng->i32.left, + ghw_get_dir (rng->i32.dir), rng->i32.right); + break; + case ghdl_rtik_type_i64: + case ghdl_rtik_type_p64: + printf (GHWPRI64 " %s " GHWPRI64, rng->i64.left, + ghw_get_dir (rng->i64.dir), rng->i64.right); + break; + case ghdl_rtik_type_f64: + printf ("%g %s %g", rng->f64.left, ghw_get_dir (rng->f64.dir), + rng->f64.right); + break; + default: + printf ("?(%d)", rng->kind); + } +} + +static void +ghw_disp_array_subtype_bounds (struct ghw_subtype_array *a) +{ + unsigned i; + struct ghw_type_array *base = + (struct ghw_type_array *) ghw_get_base_type (a->base); + + printf (" ("); + for (i = 0; i < base->nbr_dim; i++) + { + if (i != 0) + printf (", "); + ghw_disp_range (base->dims[i], a->rngs[i]); + } + printf (")"); +} + +static void +ghw_disp_record_subtype_bounds (struct ghw_subtype_record *sr) +{ + struct ghw_type_record *base = sr->base; + int is_first = 1; + unsigned i; + + for (i = 0; i < base->nbr_fields; i++) + { + if (sr->els[i].type != base->els[i].type) + { + if (is_first) + { + printf ("("); + is_first = 0; + } + else + printf (", "); + printf ("%s", base->els[i].name); + switch (sr->els[i].type->kind) + { + case ghdl_rtik_subtype_array: + ghw_disp_array_subtype_bounds (&sr->els[i].type->sa); + break; + case ghdl_rtik_subtype_record: + ghw_disp_record_subtype_bounds (&sr->els[i].type->sr); + break; + default: + printf ("??? (%d)", sr->els[i].type->kind); + } + } + } + if (!is_first) + printf (")"); +} + +static void +ghw_disp_subtype_definition (struct ghw_handler *h, union ghw_type *t) +{ + switch (t->kind) + { + case ghdl_rtik_subtype_scalar: + { + struct ghw_subtype_scalar *s = &t->ss; + ghw_disp_typename (h, s->base); + printf (" range "); + ghw_disp_range (s->base, s->rng); + } break; + case ghdl_rtik_subtype_array: + { + struct ghw_subtype_array *a = &t->sa; + + ghw_disp_typename (h, (union ghw_type *) a->base); + ghw_disp_array_subtype_bounds (a); + } break; + case ghdl_rtik_subtype_record: + { + struct ghw_subtype_record *sr = &t->sr; + + ghw_disp_typename (h, (union ghw_type *) sr->base); + ghw_disp_record_subtype_bounds (sr); + } break; + case ghdl_rtik_subtype_unbounded_array: + case ghdl_rtik_subtype_unbounded_record: + { + struct ghw_subtype_unbounded_record *sur = &t->sur; + + ghw_disp_typename (h, (union ghw_type *) sur->base); + } break; + default: + printf ("ghw_disp_subtype_definition: unhandled type kind %d\n", + t->kind); + } +} + +static int +ghw_is_anonymous_type (struct ghw_handler *h, union ghw_type *t) +{ + return t->common.name == h->str_table[0]; +} + +void +ghw_disp_subtype_indication (struct ghw_handler *h, union ghw_type *t) +{ + if (ghw_is_anonymous_type (h, t)) + { + /* Anonymous subtype. */ + ghw_disp_subtype_definition (h, t); + } + else + ghw_disp_typename (h, t); +} + +void +ghw_disp_type (struct ghw_handler *h, union ghw_type *t) +{ + switch (t->kind) + { + case ghdl_rtik_type_b2: + case ghdl_rtik_type_e8: + { + struct ghw_type_enum *e = &t->en; + unsigned i; + + printf ("type %s is (", e->name); + for (i = 0; i < e->nbr; i++) + { + if (i != 0) + printf (", "); + printf ("%s", e->lits[i]); + } + printf (");"); + if (e->wkt != ghw_wkt_unknown) + printf (" -- WKT:%d", e->wkt); + printf ("\n"); + } + break; + case ghdl_rtik_type_i32: + case ghdl_rtik_type_f64: + { + struct ghw_type_scalar *s = &t->sc; + printf ("type %s is range <>;\n", s->name); + } break; + case ghdl_rtik_type_p32: + case ghdl_rtik_type_p64: + { + unsigned i; + + struct ghw_type_physical *p = &t->ph; + printf ("type %s is range <> units\n", p->name); + for (i = 0; i < p->nbr_units; i++) + { + struct ghw_unit *u = &p->units[i]; + printf (" %s = " GHWPRI64 " %s;\n", u->name, u->val, + p->units[0].name); + } + printf ("end units\n"); + } break; + case ghdl_rtik_type_array: + { + struct ghw_type_array *a = &t->ar; + unsigned i; + + printf ("type %s is array (", a->name); + for (i = 0; i < a->nbr_dim; i++) + { + if (i != 0) + printf (", "); + ghw_disp_typename (h, a->dims[i]); + printf (" range <>"); + } + printf (") of "); + ghw_disp_subtype_indication (h, a->el); + printf (";\n"); + } + break; + case ghdl_rtik_type_record: + { + struct ghw_type_record *r = &t->rec; + unsigned i; + + printf ("type %s is record\n", r->name); + for (i = 0; i < r->nbr_fields; i++) + { + printf (" %s: ", r->els[i].name); + ghw_disp_subtype_indication (h, r->els[i].type); + printf (";\n"); + } + printf ("end record;\n"); + } + break; + case ghdl_rtik_subtype_array: + case ghdl_rtik_subtype_scalar: + case ghdl_rtik_subtype_record: + case ghdl_rtik_subtype_unbounded_array: + case ghdl_rtik_subtype_unbounded_record: + { + struct ghw_type_common *c = &t->common; + printf ("subtype %s is ", c->name); + ghw_disp_subtype_definition (h, t); + printf (";\n"); + } break; + default: + printf ("ghw_disp_type: unhandled type kind %d\n", t->kind); + } +} + +void +ghw_disp_types (struct ghw_handler *h) +{ + unsigned i; + + for (i = 0; i < h->nbr_types; i++) + if (h->flag_verbose || !ghw_is_anonymous_type (h, h->types[i])) + ghw_disp_type (h, h->types[i]); +} diff --git a/ghw/libghw.h b/ghw/libghw.h new file mode 100644 index 000000000..3efa65721 --- /dev/null +++ b/ghw/libghw.h @@ -0,0 +1,471 @@ +/* GHDL Wavefile reader library. + Copyright (C) 2005-2017 Tristan Gingold + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _GHWLIB_H_ +#define _GHWLIB_H_ + +#include +#include + +/* To be libraries friendly. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* The ghwlib uses the standard c99 int32_t and int64_t. They are declared + in stdint.h. Header inttypes.h includes stdint.h and provides macro for + printf and co specifiers. Use it if known to be available. */ + +#if defined(__cplusplus) || \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + defined(HAVE_INTTYPES_H) +/* Use C99 standard header. */ +#include +#define GHWPRI64 "%" PRId64 +#define GHWPRI32 "%" PRId32 +#else +#include +#define GHWPRI64 "%lld" +#define GHWPRI32 "%d" +#endif + +enum ghdl_rtik +{ + ghdl_rtik_top, /* 0 */ + ghdl_rtik_library, + ghdl_rtik_package, + ghdl_rtik_package_body, + ghdl_rtik_entity, + ghdl_rtik_architecture, /* 5 */ + ghdl_rtik_process, + ghdl_rtik_block, + ghdl_rtik_if_generate, + ghdl_rtik_for_generate, + ghdl_rtik_instance, + ghdl_rtik_constant, + ghdl_rtik_iterator, + ghdl_rtik_variable, + ghdl_rtik_signal, + ghdl_rtik_file, + ghdl_rtik_port, + ghdl_rtik_generic, + ghdl_rtik_alias, + ghdl_rtik_guard, + ghdl_rtik_component, + ghdl_rtik_attribute, + ghdl_rtik_type_b2, /* 22 */ + ghdl_rtik_type_e8, + ghdl_rtik_type_e32, + ghdl_rtik_type_i32, /* 25 */ + ghdl_rtik_type_i64, + ghdl_rtik_type_f64, + ghdl_rtik_type_p32, + ghdl_rtik_type_p64, + ghdl_rtik_type_access, /* 30 */ + ghdl_rtik_type_array, + ghdl_rtik_type_record, + ghdl_rtik_type_file, + ghdl_rtik_subtype_scalar, + ghdl_rtik_subtype_array, /* 35 */ + ghdl_rtik_subtype_array_ptr, /* Obsolete. */ + ghdl_rtik_subtype_unbounded_array, + ghdl_rtik_subtype_record, + ghdl_rtik_subtype_unbounded_record, +#if 0 + ghdl_rtik_subtype_access, /* 40 */ + ghdl_rtik_type_protected, + ghdl_rtik_element, + ghdl_rtik_unit, + ghdl_rtik_attribute_transaction, + ghdl_rtik_attribute_quiet, + ghdl_rtik_attribute_stable, +#endif + ghdl_rtik_error +}; + +/* Well-known types. */ +enum ghw_wkt_type +{ + ghw_wkt_unknown, + ghw_wkt_boolean, + ghw_wkt_bit, + ghw_wkt_std_ulogic +}; + +struct ghw_range_b2 +{ + enum ghdl_rtik kind:8; + int dir:8; /* 0: to, !0: downto. */ + unsigned char left; + unsigned char right; +}; + +struct ghw_range_e8 +{ + enum ghdl_rtik kind:8; + int dir:8; /* 0: to, !0: downto. */ + unsigned char left; + unsigned char right; +}; + +struct ghw_range_i32 +{ + enum ghdl_rtik kind:8; + int dir:8; /* 0: to, !0: downto. */ + int32_t left; + int32_t right; +}; + +struct ghw_range_i64 +{ + enum ghdl_rtik kind:8; + int dir:8; + int64_t left; + int64_t right; +}; + +struct ghw_range_f64 +{ + enum ghdl_rtik kind:8; + int dir:8; + double left; + double right; +}; + +union ghw_range +{ + enum ghdl_rtik kind:8; + struct ghw_range_b2 b2; + struct ghw_range_e8 e8; + struct ghw_range_i32 i32; + struct ghw_range_i64 i64; + struct ghw_range_f64 f64; +}; + +/* Note: the first two fields must be kind and name. */ +union ghw_type; + +struct ghw_type_common +{ + enum ghdl_rtik kind; + const char *name; +}; + +struct ghw_type_enum +{ + enum ghdl_rtik kind; + const char *name; + + enum ghw_wkt_type wkt; + unsigned int nbr; + const char **lits; +}; + +struct ghw_type_scalar +{ + enum ghdl_rtik kind; + const char *name; +}; + +struct ghw_unit +{ + const char *name; + int64_t val; +}; + +struct ghw_type_physical +{ + enum ghdl_rtik kind; + const char *name; + uint32_t nbr_units; + struct ghw_unit *units; +}; + +struct ghw_type_array +{ + enum ghdl_rtik kind; + const char *name; + + unsigned int nbr_dim; + union ghw_type *el; + union ghw_type **dims; +}; + +struct ghw_subtype_unbounded_array +{ + enum ghdl_rtik kind; + const char *name; + + union ghw_type *base; +}; + +struct ghw_subtype_array +{ + enum ghdl_rtik kind; + const char *name; + + union ghw_type *base; + int nbr_scalars; + union ghw_range **rngs; + union ghw_type *el; +}; + +struct ghw_subtype_scalar +{ + enum ghdl_rtik kind; + const char *name; + + union ghw_type *base; + union ghw_range *rng; +}; + +struct ghw_record_element +{ + const char *name; + union ghw_type *type; +}; + +struct ghw_type_record +{ + enum ghdl_rtik kind; + const char *name; + + unsigned int nbr_fields; + int nbr_scalars; /* Number of scalar elements (ie nbr of signals). */ + struct ghw_record_element *els; +}; + +struct ghw_subtype_record +{ + enum ghdl_rtik kind; + const char *name; + + struct ghw_type_record *base; + int nbr_scalars; /* Number of scalar elements (ie nbr of signals). */ + struct ghw_record_element *els; +}; + +struct ghw_subtype_unbounded_record +{ + enum ghdl_rtik kind; + const char *name; + + struct ghw_type_record *base; +}; + +union ghw_type +{ + enum ghdl_rtik kind; + struct ghw_type_common common; + struct ghw_type_enum en; + struct ghw_type_scalar sc; + struct ghw_type_physical ph; + struct ghw_subtype_scalar ss; + struct ghw_type_array ar; + struct ghw_type_record rec; + struct ghw_subtype_array sa; + struct ghw_subtype_unbounded_array sua; + struct ghw_subtype_record sr; + struct ghw_subtype_unbounded_record sur; +}; + +union ghw_val +{ + unsigned char b2; + unsigned char e8; + int32_t i32; + int64_t i64; + double f64; +}; + +/* A non-composite signal. */ +struct ghw_sig +{ + union ghw_type *type; + union ghw_val *val; +}; + +enum ghw_hie_kind +{ + ghw_hie_eoh = 0, + ghw_hie_design = 1, + ghw_hie_block = 3, + ghw_hie_generate_if = 4, + ghw_hie_generate_for = 5, + ghw_hie_instance = 6, + ghw_hie_package = 7, + ghw_hie_process = 13, + ghw_hie_generic = 14, + ghw_hie_eos = 15, + ghw_hie_signal = 16, + ghw_hie_port_in = 17, + ghw_hie_port_out = 18, + ghw_hie_port_inout = 19, + ghw_hie_port_buffer = 20, + ghw_hie_port_linkage = 21 +}; + +#define GHW_NO_SIG 0 + +struct ghw_hie +{ + enum ghw_hie_kind kind; + struct ghw_hie *parent; + const char *name; + struct ghw_hie *brother; + union + { + struct + { + struct ghw_hie *child; + union ghw_type *iter_type; + union ghw_val *iter_value; + } blk; + struct + { + union ghw_type *type; + /* Array of signal elements. + Last element is GHW_NO_SIG (0). */ + unsigned int *sigs; + } sig; + } u; +}; + +struct ghw_handler +{ + FILE *stream; + /* True if STREAM was popen, else was fopen. */ + unsigned char stream_ispipe; + /* True if words are big-endian. */ + unsigned char word_be; + unsigned char word_len; + unsigned char off_len; + /* Minor version. */ + int version; + + /* Set by user. */ + int flag_verbose; + + /* String table. */ + /* Number of strings. */ + unsigned nbr_str; + /* Size of the strings (without nul). */ + unsigned str_size; + /* String table. */ + char **str_table; + /* Array containing strings. */ + char *str_content; + + /* Type table. */ + unsigned nbr_types; + union ghw_type **types; + + /* Non-composite (or basic) signals. */ + unsigned nbr_sigs; + char *skip_sigs; + int flag_full_names; + struct ghw_sig *sigs; + + /* Hierarchy. */ + struct ghw_hie *hie; + + /* Time of the next cycle. */ + int64_t snap_time; +}; + +/* Open a GHW file with H. + Return < 0 in case of error. */ +int ghw_open (struct ghw_handler *h, const char *filename); + +/* Return base type of T. */ +union ghw_type *ghw_get_base_type (union ghw_type *t); + +/* Return length of RNG. */ +int ghw_get_range_length (union ghw_range *rng); + +/* Put the ASCII representation of VAL into BUF, whose size if LEN. + A NUL is always written to BUF. */ +void ghw_get_value (char *buf, int len, union ghw_val *val, + union ghw_type *type); + +const char *ghw_get_hie_name (struct ghw_hie *h); + +void ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top); + +int ghw_read_base (struct ghw_handler *h); + +void ghw_filter_signals (struct ghw_handler *h, int *signals_to_keep, + int nb_signals_to_keep); + +void ghw_disp_values (struct ghw_handler *h); + +int ghw_read_cycle_start (struct ghw_handler *h); + +int ghw_read_cycle_cont (struct ghw_handler *h, int *list); + +int ghw_read_cycle_next (struct ghw_handler *h); + +int ghw_read_cycle_end (struct ghw_handler *h); + +enum ghw_sm_type +{ + /* At init; + Read section name. */ + ghw_sm_init = 0, + ghw_sm_sect = 1, + ghw_sm_cycle = 2 +}; + +enum ghw_res +{ + ghw_res_error = -1, + ghw_res_eof = -2, + ghw_res_ok = 0, + ghw_res_snapshot = 1, + ghw_res_cycle = 2, + ghw_res_other = 3 +}; + +enum ghw_res ghw_read_sm_hdr (struct ghw_handler *h, int *list); + +int ghw_read_sm (struct ghw_handler *h, enum ghw_sm_type *sm); + +int ghw_read_dump (struct ghw_handler *h); + +struct ghw_section +{ + const char name[4]; + int (*handler) (struct ghw_handler * h); +}; + +extern struct ghw_section ghw_sections[]; + +int ghw_read_section (struct ghw_handler *h); + +void ghw_close (struct ghw_handler *h); + +const char *ghw_get_dir (int is_downto); + +void ghw_disp_subtype_indication (struct ghw_handler *h, union ghw_type *t); + +/* Note: TYPE must be a base type (used only to display literals). */ +void ghw_disp_range (union ghw_type *type, union ghw_range *rng); + +void ghw_disp_type (struct ghw_handler *h, union ghw_type *t); + +void ghw_disp_types (struct ghw_handler *h); +#endif /* _GHWLIB_H_ */ -- cgit v1.2.3