changeset 136:65f87111090c

netdiff: tedax2donl written
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 07 Sep 2020 03:02:42 +0000
parents 25634b3977a9
children 6f528e2a9e23
files .hgignore netdiff/convert/Makefile netdiff/convert/tedax2donl.c
diffstat 3 files changed, 208 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Mon Sep 07 01:22:36 2020 +0000
+++ b/.hgignore	Mon Sep 07 03:02:42 2020 +0000
@@ -18,5 +18,6 @@
 
 ^netdiff/convert/pads2donl$
 ^netdiff/convert/protel2donl$
+^netdiff/convert/tedax2donl$
 
 ^pads2gpcb/pads2gpcb$
--- a/netdiff/convert/Makefile	Mon Sep 07 01:22:36 2020 +0000
+++ b/netdiff/convert/Makefile	Mon Sep 07 03:02:42 2020 +0000
@@ -1,6 +1,6 @@
 CC=	gcc
 CFLAGS=	-O2
-PROGS=	pads2donl protel2donl
+PROGS=	pads2donl protel2donl tedax2donl
 BINDIR=	/usr/local/bin
 
 all:	${PROGS}
@@ -16,3 +16,4 @@
 
 pads2donl:	pads2donl.c
 protel2donl:	protel2donl.c
+tedax2donl:	tedax2donl.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netdiff/convert/tedax2donl.c	Mon Sep 07 03:02:42 2020 +0000
@@ -0,0 +1,205 @@
+/*
+ * This program converts a tEDAx netlist into our
+ * Diff-Oriented Netlist (DONL) format.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#define	MAX_FIELDS	32
+
+static char *infname;
+static FILE *inf;
+static char linebuf[512];
+static int lineno;
+static char *fields[MAX_FIELDS];
+static unsigned nfields;
+
+static
+get_line()
+{
+	if (!fgets(linebuf, sizeof linebuf, inf))
+		return(0);
+	lineno++;
+	if (!index(linebuf, '\n')) {
+		fprintf(stderr, "%s line %d: missing newline\n",
+			infname, lineno);
+		exit(1);
+	}
+	return(1);
+}
+
+static void
+parse_into_fields()
+{
+	char *cp;
+
+	nfields = 0;
+	for (cp = linebuf; ; ) {
+		while (isspace(*cp))
+			cp++;
+		if (*cp == '\0' || *cp == '#')
+			break;
+		if (nfields >= MAX_FIELDS) {
+			fprintf(stderr, "%s line %d: too many fields\n",
+				infname, lineno);
+			exit(1);
+		}
+		fields[nfields++] = cp;
+		while (*cp) {
+			if (isspace(*cp)) {
+				*cp++ = '\0';
+				break;
+			}
+			if (*cp++ != '\\')
+				continue;
+			switch (*cp++) {
+			case '\\':
+			case 'n':
+			case 'r':
+			case 't':
+			case ' ':
+			case '\t':
+				continue;
+			default:
+				fprintf(stderr, "%s line %d: invalid escape\n",
+					infname, lineno);
+				exit(1);
+			}
+		}
+	}
+}
+
+static void
+get_tedax_header()
+{
+	do {
+		if (!get_line()) {
+			fprintf(stderr, "%s: EOF before tEDAx header\n",
+				infname);
+			exit(1);
+		}
+		parse_into_fields();
+	} while (!nfields);
+	if (strcmp(fields[0], "tEDAx")) {
+		fprintf(stderr, "%s line %d: expected tEDAx header\n",
+			infname, lineno);
+		exit(1);
+	}
+	if (nfields != 2 || strcmp(fields[1], "v1")) {
+		fprintf(stderr, "%s line %d: expected tEDAx v1\n",
+			infname, lineno);
+		exit(1);
+	}
+}
+
+static void
+skip_wrong_block()
+{
+	for (;;) {
+		if (!get_line()) {
+			fprintf(stderr,
+				"%s: EOF in the middle of a skip block\n",
+				infname, lineno);
+			exit(1);
+		}
+		if (!nfields)
+			continue;
+		if (!strcmp(fields[0], "begin")) {
+			fprintf(stderr, "%s line %d: nested block beginning\n",
+				infname, lineno);
+			exit(1);
+		}
+		if (!strcmp(fields[0], "end"))
+			return;
+	}
+}
+
+static void
+find_begin_netlist()
+{
+	for (;;) {
+		do {
+			if (!get_line()) {
+				fprintf(stderr,
+				"%s: EOF before beginning of netlist block\n",
+					infname);
+				exit(1);
+			}
+			parse_into_fields();
+		} while (!nfields);
+		if (strcmp(fields[0], "begin")) {
+			fprintf(stderr, "%s line %d: expected begin line\n",
+				infname, lineno);
+			exit(1);
+		}
+		if (nfields != 4) {
+			fprintf(stderr,
+			"%s line %d: begin line has wrong number of fields\n",
+				infname, lineno);
+			exit(1);
+		}
+		if (!strcmp(fields[1], "netlist"))
+			break;
+		skip_wrong_block();
+	}
+	if (strcmp(fields[2], "v1")) {
+		fprintf(stderr,
+			"%s line %d: netlist block has wrong version\n",
+			infname, lineno);
+		exit(1);
+	}
+}
+
+static void
+process_netlist_block()
+{
+	for (;;) {
+		if (!get_line()) {
+			fprintf(stderr,
+				"%s: EOF in the middle of the netlist block\n",
+				infname, lineno);
+			exit(1);
+		}
+		if (!nfields)
+			continue;
+		if (!strcmp(fields[0], "begin")) {
+			fprintf(stderr, "%s line %d: nested block beginning\n",
+				infname, lineno);
+			exit(1);
+		}
+		if (!strcmp(fields[0], "end"))
+			return;
+		if (strcmp(fields[0], "conn"))
+			continue;
+		if (nfields != 4) {
+			fprintf(stderr,
+			"%s line %d: conn line has wrong number of fields\n",
+				infname, lineno);
+			exit(1);
+		}
+		printf("%s\t%s.%s\n", fields[1], fields[2], fields[3]);
+	}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	if (argc != 2) {
+		fprintf(stderr, "usage: %s tedax-netlist-file\n", argv[0]);
+		exit(1);
+	}
+	infname = argv[1];
+	inf = fopen(infname, "r");
+	if (!inf) {
+		perror(infname);
+		exit(1);
+	}
+	get_tedax_header();
+	find_begin_netlist();
+	process_netlist_block();
+	exit(0);
+}