From 8136add60a289d1195817b0ba4e002e38e7e7263 Mon Sep 17 00:00:00 2001 From: umarcor Date: Fri, 23 Apr 2021 01:06:14 +0200 Subject: move ghwlib and ghwdump sources to subdir 'ghw' --- Makefile.in | 4 +- ghw/ghwdump.c | 320 ++++++++ ghw/ghwlib.c | 2235 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ghw/ghwlib.h | 465 +++++++++++ src/grt/ghwdump.c | 320 -------- src/grt/ghwlib.c | 2235 ----------------------------------------------------- src/grt/ghwlib.h | 465 ----------- 7 files changed, 3022 insertions(+), 3022 deletions(-) create mode 100644 ghw/ghwdump.c create mode 100644 ghw/ghwlib.c create mode 100644 ghw/ghwlib.h delete mode 100644 src/grt/ghwdump.c delete mode 100644 src/grt/ghwlib.c delete mode 100644 src/grt/ghwlib.h diff --git a/Makefile.in b/Makefile.in index 378241e4e..db9d9ecab 100644 --- a/Makefile.in +++ b/Makefile.in @@ -479,10 +479,10 @@ ghwdump: ghwdump$(EXEEXT) ghwdump$(EXEEXT): $(GHWDUMP_OBJS) $(CC) -o $@ $(GHWDUMP_OBJS) -ghwdump.o: $(srcdir)/src/grt/ghwdump.c $(srcdir)/src/grt/ghwlib.h +ghwdump.o: $(srcdir)/ghw/ghwdump.c $(srcdir)/ghw/ghwlib.h $(CC) -c -o $@ $< $(OPT_FLAGS) $(WARN_CFLAGS) -ghwlib.o: $(srcdir)/src/grt/ghwlib.c $(srcdir)/src/grt/ghwlib.h +ghwlib.o: $(srcdir)/ghw/ghwlib.c $(srcdir)/ghw/ghwlib.h $(CC) -c -o $@ $< $(OPT_FLAGS) $(WARN_CFLAGS) all.ghw: ghwdump$(EXEEXT) diff --git a/ghw/ghwdump.c b/ghw/ghwdump.c new file mode 100644 index 000000000..d6e2d247d --- /dev/null +++ b/ghw/ghwdump.c @@ -0,0 +1,320 @@ +/* Display a GHDL Wavefile for debugging. + 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 + +#include "ghwlib.h" + +static const char *progname; +void +usage (void) +{ + printf ("usage: %s [OPTIONS] FILEs...\n", progname); + printf ("Options are:\n" + " -t display types\n" + " -h display hierarchy\n" + " -H display hierarchy with full pathnames\n" + " -T display time\n" + " -s display signals (and time)\n" + " -S display strings\n" + " -f list of signals to display (default: all, example: -f 1,3,5-7,21-33)\n" + " -l display list of sections\n" + " -v verbose\n"); +} + +static void +add_single_signal (int **signalSet, int *nbSignals, int signal) +{ + assert (NULL != signalSet); + assert (NULL != nbSignals); + assert (0 <= nbSignals[0]); + assert (0 <= signal); + + int newSize = (1 + nbSignals[0]); + /*printf("adding signal %6d set of signals to display\n", signal); */ + signalSet[0] = (int *) realloc (signalSet[0], newSize * sizeof (int)); + signalSet[0][nbSignals[0]] = signal; + nbSignals[0] = newSize; +} + +static void +add_signal_range (int **signalSet, + int *nbSignals, const char *s, const char *e) +{ + + int i; + int rangeSize; + int rangeEnd = -1; + int rangeStart = -1; + int bytesMatched = -1; + int expected = ((e - s) - 1); + int itemsMatched = sscanf (s, + "%d-%d%n", + &rangeStart, + &rangeEnd, + &bytesMatched); + if (2 == itemsMatched && expected == bytesMatched) + { + if (rangeEnd < rangeStart) + { + int t = rangeEnd; + rangeEnd = rangeStart; + rangeStart = t; + } + } + else + { + itemsMatched = sscanf (s, "%d%n", &rangeStart, &bytesMatched); + if (1 == itemsMatched && expected == bytesMatched) + { + if (0 <= rangeStart) + { + rangeEnd = rangeStart; + } + } + } + + rangeSize = (rangeEnd - rangeStart); + if (rangeEnd < 0 || rangeStart < 0 || rangeSize < 0) + { + fprintf (stderr, + "incorrect signal range specification\"%s\" found in command line, aborting\n", + s); + exit (1); + } + + for (i = rangeStart; i <= rangeEnd; ++i) + { + add_single_signal (signalSet, nbSignals, i); + } +} + +static void +add_signals (int **signalSet, int *nbSignals, const char *arg) +{ + int c = -1; + const char *e; + const char *s = e = arg; + while (0 != c) + { + c = *(e++); + if (',' == c || 0 == c) + { + add_signal_range (signalSet, nbSignals, s, e); + s = e; + } + } +} + +static void +disp_string_table (struct ghw_handler *hp) +{ + int i; + printf ("String table:\n"); + + for (i = 1; i < hp->nbr_str; i++) + printf (" %s\n", hp->str_table[i]); +} + +int +main (int argc, char **argv) +{ + int i; + int flag_disp_types; + int flag_disp_hierarchy; + int flag_disp_time; + int flag_disp_signals; + int flag_disp_strings; + int flag_full_names; + int flag_list; + int flag_verbose; + int nb_signals; + int *signal_set; + int filter_done; + int eof; + enum ghw_sm_type sm; + + progname = argv[0]; + flag_disp_types = 0; + flag_disp_hierarchy = 0; + flag_full_names = 0; + flag_disp_time = 0; + flag_disp_signals = 0; + flag_disp_strings = 0; + flag_list = 0; + flag_verbose = 0; + nb_signals = 0; + signal_set = NULL; + filter_done = 0; + + while (1) + { + int c; + + c = getopt (argc, argv, "thHTsSlvf:"); + if (c == -1) + break; + switch (c) + { + case 't': + flag_disp_types = 1; + break; + case 'h': + flag_disp_hierarchy = 1; + break; + case 'H': + flag_disp_hierarchy = 1; + flag_full_names = 1; + break; + case 'T': + flag_disp_time = 1; + break; + case 's': + flag_disp_signals = 1; + flag_disp_time = 1; + break; + case 'S': + flag_disp_strings = 1; + break; + case 'f': + add_signals (&signal_set, &nb_signals, optarg); + break; + case 'l': + flag_list = 1; + break; + case 'v': + flag_verbose++; + break; + default: + usage (); + exit (2); + } + } + + if (optind >= argc) + { + usage (); + return 1; + } + + for (i = optind; i < argc; i++) + { + struct ghw_handler h; + struct ghw_handler *hp = &h; + + hp->flag_verbose = flag_verbose; + + if (ghw_open (hp, argv[i]) != 0) + { + fprintf (stderr, "cannot open ghw file %s\n", argv[i]); + return 1; + } + if (flag_list) + { + while (1) + { + const char *section_name; + int section; + + section = ghw_read_section (hp); + if (section == -2) + { + printf ("eof of file\n"); + break; + } + else if (section < 0) + { + printf ("Error in file\n"); + break; + } + else if (section == 0) + { + printf ("Unknown section\n"); + break; + } + section_name = ghw_sections[section].name; + printf ("Section %s\n", section_name); + if ((*ghw_sections[section].handler)(hp) < 0) + break; + + if (flag_disp_strings && strcmp (section_name, "STR") == 0) + disp_string_table (hp); + else if (flag_disp_types && strcmp (section_name, "TYP") == 0) + ghw_disp_types (hp); + } + } + else + { + if (ghw_read_base (hp) < 0) + { + fprintf (stderr, "cannot read ghw file\n"); + return 2; + } + if (flag_disp_types) + ghw_disp_types (hp); + if (flag_disp_hierarchy) + { + hp->flag_full_names = flag_full_names; + ghw_disp_hie (hp, hp->hie); + } + +#if 1 + sm = ghw_sm_init; + eof = 0; + while (!eof) + { + switch (ghw_read_sm (hp, &sm)) + { + case ghw_res_snapshot: + case ghw_res_cycle: + if (flag_disp_time) + printf ("Time is %lld fs\n", hp->snap_time); + if (flag_disp_signals) + { + if (!filter_done) + { + ghw_filter_signals (hp, signal_set, nb_signals); + filter_done = 1; + } + ghw_disp_values (hp); + } + break; + case ghw_res_eof: + eof = 1; + break; + default: + abort (); + } + } + +#else + if (ghw_read_dump (hp) < 0) + { + fprintf (stderr, "error in ghw dump\n"); + return 3; + } +#endif + } + ghw_close (&h); + } + return 0; +} diff --git a/ghw/ghwlib.c b/ghw/ghwlib.c new file mode 100644 index 000000000..7c406fda2 --- /dev/null +++ b/ghw/ghwlib.c @@ -0,0 +1,2235 @@ +/* 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; + 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: + { + 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: + { + 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 new file mode 100644 index 000000000..df3c20a54 --- /dev/null +++ b/ghw/ghwlib.h @@ -0,0 +1,465 @@ +/* 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/src/grt/ghwdump.c b/src/grt/ghwdump.c deleted file mode 100644 index d6e2d247d..000000000 --- a/src/grt/ghwdump.c +++ /dev/null @@ -1,320 +0,0 @@ -/* Display a GHDL Wavefile for debugging. - 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 - -#include "ghwlib.h" - -static const char *progname; -void -usage (void) -{ - printf ("usage: %s [OPTIONS] FILEs...\n", progname); - printf ("Options are:\n" - " -t display types\n" - " -h display hierarchy\n" - " -H display hierarchy with full pathnames\n" - " -T display time\n" - " -s display signals (and time)\n" - " -S display strings\n" - " -f list of signals to display (default: all, example: -f 1,3,5-7,21-33)\n" - " -l display list of sections\n" - " -v verbose\n"); -} - -static void -add_single_signal (int **signalSet, int *nbSignals, int signal) -{ - assert (NULL != signalSet); - assert (NULL != nbSignals); - assert (0 <= nbSignals[0]); - assert (0 <= signal); - - int newSize = (1 + nbSignals[0]); - /*printf("adding signal %6d set of signals to display\n", signal); */ - signalSet[0] = (int *) realloc (signalSet[0], newSize * sizeof (int)); - signalSet[0][nbSignals[0]] = signal; - nbSignals[0] = newSize; -} - -static void -add_signal_range (int **signalSet, - int *nbSignals, const char *s, const char *e) -{ - - int i; - int rangeSize; - int rangeEnd = -1; - int rangeStart = -1; - int bytesMatched = -1; - int expected = ((e - s) - 1); - int itemsMatched = sscanf (s, - "%d-%d%n", - &rangeStart, - &rangeEnd, - &bytesMatched); - if (2 == itemsMatched && expected == bytesMatched) - { - if (rangeEnd < rangeStart) - { - int t = rangeEnd; - rangeEnd = rangeStart; - rangeStart = t; - } - } - else - { - itemsMatched = sscanf (s, "%d%n", &rangeStart, &bytesMatched); - if (1 == itemsMatched && expected == bytesMatched) - { - if (0 <= rangeStart) - { - rangeEnd = rangeStart; - } - } - } - - rangeSize = (rangeEnd - rangeStart); - if (rangeEnd < 0 || rangeStart < 0 || rangeSize < 0) - { - fprintf (stderr, - "incorrect signal range specification\"%s\" found in command line, aborting\n", - s); - exit (1); - } - - for (i = rangeStart; i <= rangeEnd; ++i) - { - add_single_signal (signalSet, nbSignals, i); - } -} - -static void -add_signals (int **signalSet, int *nbSignals, const char *arg) -{ - int c = -1; - const char *e; - const char *s = e = arg; - while (0 != c) - { - c = *(e++); - if (',' == c || 0 == c) - { - add_signal_range (signalSet, nbSignals, s, e); - s = e; - } - } -} - -static void -disp_string_table (struct ghw_handler *hp) -{ - int i; - printf ("String table:\n"); - - for (i = 1; i < hp->nbr_str; i++) - printf (" %s\n", hp->str_table[i]); -} - -int -main (int argc, char **argv) -{ - int i; - int flag_disp_types; - int flag_disp_hierarchy; - int flag_disp_time; - int flag_disp_signals; - int flag_disp_strings; - int flag_full_names; - int flag_list; - int flag_verbose; - int nb_signals; - int *signal_set; - int filter_done; - int eof; - enum ghw_sm_type sm; - - progname = argv[0]; - flag_disp_types = 0; - flag_disp_hierarchy = 0; - flag_full_names = 0; - flag_disp_time = 0; - flag_disp_signals = 0; - flag_disp_strings = 0; - flag_list = 0; - flag_verbose = 0; - nb_signals = 0; - signal_set = NULL; - filter_done = 0; - - while (1) - { - int c; - - c = getopt (argc, argv, "thHTsSlvf:"); - if (c == -1) - break; - switch (c) - { - case 't': - flag_disp_types = 1; - break; - case 'h': - flag_disp_hierarchy = 1; - break; - case 'H': - flag_disp_hierarchy = 1; - flag_full_names = 1; - break; - case 'T': - flag_disp_time = 1; - break; - case 's': - flag_disp_signals = 1; - flag_disp_time = 1; - break; - case 'S': - flag_disp_strings = 1; - break; - case 'f': - add_signals (&signal_set, &nb_signals, optarg); - break; - case 'l': - flag_list = 1; - break; - case 'v': - flag_verbose++; - break; - default: - usage (); - exit (2); - } - } - - if (optind >= argc) - { - usage (); - return 1; - } - - for (i = optind; i < argc; i++) - { - struct ghw_handler h; - struct ghw_handler *hp = &h; - - hp->flag_verbose = flag_verbose; - - if (ghw_open (hp, argv[i]) != 0) - { - fprintf (stderr, "cannot open ghw file %s\n", argv[i]); - return 1; - } - if (flag_list) - { - while (1) - { - const char *section_name; - int section; - - section = ghw_read_section (hp); - if (section == -2) - { - printf ("eof of file\n"); - break; - } - else if (section < 0) - { - printf ("Error in file\n"); - break; - } - else if (section == 0) - { - printf ("Unknown section\n"); - break; - } - section_name = ghw_sections[section].name; - printf ("Section %s\n", section_name); - if ((*ghw_sections[section].handler)(hp) < 0) - break; - - if (flag_disp_strings && strcmp (section_name, "STR") == 0) - disp_string_table (hp); - else if (flag_disp_types && strcmp (section_name, "TYP") == 0) - ghw_disp_types (hp); - } - } - else - { - if (ghw_read_base (hp) < 0) - { - fprintf (stderr, "cannot read ghw file\n"); - return 2; - } - if (flag_disp_types) - ghw_disp_types (hp); - if (flag_disp_hierarchy) - { - hp->flag_full_names = flag_full_names; - ghw_disp_hie (hp, hp->hie); - } - -#if 1 - sm = ghw_sm_init; - eof = 0; - while (!eof) - { - switch (ghw_read_sm (hp, &sm)) - { - case ghw_res_snapshot: - case ghw_res_cycle: - if (flag_disp_time) - printf ("Time is %lld fs\n", hp->snap_time); - if (flag_disp_signals) - { - if (!filter_done) - { - ghw_filter_signals (hp, signal_set, nb_signals); - filter_done = 1; - } - ghw_disp_values (hp); - } - break; - case ghw_res_eof: - eof = 1; - break; - default: - abort (); - } - } - -#else - if (ghw_read_dump (hp) < 0) - { - fprintf (stderr, "error in ghw dump\n"); - return 3; - } -#endif - } - ghw_close (&h); - } - return 0; -} diff --git a/src/grt/ghwlib.c b/src/grt/ghwlib.c deleted file mode 100644 index 7c406fda2..000000000 --- a/src/grt/ghwlib.c +++ /dev/null @@ -1,2235 +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; - 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: - { - 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: - { - 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/src/grt/ghwlib.h b/src/grt/ghwlib.h deleted file mode 100644 index df3c20a54..000000000 --- a/src/grt/ghwlib.h +++ /dev/null @@ -1,465 +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_ */ -- cgit v1.2.3