aboutsummaryrefslogtreecommitdiffstats
path: root/ghw/ghwdump.c
diff options
context:
space:
mode:
authorumarcor <unai.martinezcorral@ehu.eus>2021-04-23 01:06:14 +0200
committertgingold <tgingold@users.noreply.github.com>2021-04-23 05:34:09 +0200
commit8136add60a289d1195817b0ba4e002e38e7e7263 (patch)
tree125995aad6bf67bb8933ecaba20ae64d1991cf8b /ghw/ghwdump.c
parentdc2542b1faef1817d7166458fd51dd2c001f45af (diff)
downloadghdl-8136add60a289d1195817b0ba4e002e38e7e7263.tar.gz
ghdl-8136add60a289d1195817b0ba4e002e38e7e7263.tar.bz2
ghdl-8136add60a289d1195817b0ba4e002e38e7e7263.zip
move ghwlib and ghwdump sources to subdir 'ghw'
Diffstat (limited to 'ghw/ghwdump.c')
-rw-r--r--ghw/ghwdump.c320
1 files changed, 320 insertions, 0 deletions
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 <gnu.org/licenses>.
+*/
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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 <lst> 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;
+}