diff ueda/unet-utils/unet-destar.c @ 24:7e8a2cb54b6b

started implementing unet-destar
author Space Falcon <falcon@ivan.Harhan.ORG>
date Thu, 06 Aug 2015 20:20:11 +0000
parents
children b2b60ec8d9ca
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ueda/unet-utils/unet-destar.c	Thu Aug 06 20:20:11 2015 +0000
@@ -0,0 +1,274 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "../libunet/unetrd.h"
+#include "../libunet/nethash.h"
+
+extern struct net *enter_net_object();
+extern struct net *find_net_by_name();
+
+static char *input_filename, *output_filename;
+static struct unetrd_state rdstate;
+static struct unetrd_out rdout;
+static int total_input_nets;
+static struct net *starpoint_head;
+static FILE *tempFILE, *outFILE;
+
+struct netextra {
+	struct	net *squashed_to;
+	int	npoints;
+};
+
+static FILE *
+tempfile()
+{
+	char template[16];
+	register int fd;
+	register FILE *f;
+
+	strcpy(template, "/tmp/uedaXXXXXX");
+	fd = mkstemp(template);
+	if (fd < 0) {
+		perror("mkstemp");
+		exit(1);
+	}
+	unlink(template);
+	f = fdopen(fd, "r+w");
+	if (!f) {
+		perror("fdopen");
+		exit(1);
+	}
+	return(f);
+}
+
+static void
+dump_tempfile()
+{
+	register FILE *inf = tempFILE;
+	register FILE *outf = outFILE;
+	register int c;
+
+	rewind(inf);
+	while ((c = getc(inf)) != EOF)
+		putc(c, outf);
+	fclose(inf);
+}
+
+static void
+process_starpoint_head()
+{
+	register struct net *n;
+	register struct netextra *nx;
+
+	n = find_net_by_name(rdout.connect_to_net);
+	for (;;) {
+		nx = (struct netextra *)(n + 1);
+		if (!nx->squashed_to)
+			break;
+		n = nx->squashed_to;
+	}
+	starpoint_head = n;
+}
+
+static void
+process_starpoint_arm()
+{
+	register struct net *n;
+	register struct netextra *nx;
+
+	n = find_net_by_name(rdout.connect_to_net);
+	if (n == starpoint_head) {
+		fprintf(stderr,
+			"%s line %d: starpoint between net %s and itself!\n",
+			input_filename, rdstate.lineno, n->name);
+		exit(1);
+	}
+	nx = (struct netextra *)(n + 1);
+	if (nx->squashed_to) {
+		fprintf(stderr,
+			"%s line %d: net %s has already been squashed\n",
+			input_filename, rdstate.lineno, n->name);
+		exit(1);
+	}
+	nx->squashed_to = starpoint_head;
+}
+
+static void
+process_starpoint()
+{
+	starpoint_head = 0;
+	for (;;) {
+		if (!read_unet_line(&rdstate, &rdout)) {
+			fprintf(stderr, "%s error: EOF in STARPOINT block\n",
+				input_filename);
+			exit(1);
+		}
+		if (rdout.typecode == UNETOBJ_CLOSINGBRACE)
+			break;
+		switch(rdout.typecode) {
+		case UNETOBJ_PRIMITIVE:
+		case UNETOBJ_ALTNAME:
+			continue;
+		case UNETOBJ_PIN:
+			if (!rdout.connect_to_net) {
+				fprintf(stderr,
+		"%s line %d: no-connect is meaningless for a starpoint arm\n",
+					input_filename, rdstate.lineno);
+				exit(1);
+			}
+			if (!starpoint_head)
+				process_starpoint_head();
+			else
+				process_starpoint_arm();
+			continue;
+		case UNETOBJ_PINMAP:
+			fprintf(stderr,
+			"%s line %d: PINMAP meaningless in a STARPOINT block\n",
+				input_filename, rdstate.lineno);
+			exit(1);
+		default:
+			fprintf(stderr,
+		"%s line %d: object type %s unexpected in STARPOINT block\n",
+				input_filename, rdstate.lineno, rdout.keyword);
+			exit(1);
+		}
+	}
+}
+
+static void
+process_component_pin()
+{
+	register struct net *n;
+	register struct netextra *nx;
+
+	if (!rdout.connect_to_net) {
+		fprintf(tempFILE, "  %s %s = NC (%s)\n", rdout.keyword,
+			rdout.objname, rdout.nc_comment);
+		return;
+	}
+	n = find_net_by_name(rdout.connect_to_net);
+	for (;;) {
+		nx = (struct netextra *)(n + 1);
+		if (!nx->squashed_to)
+			break;
+		n = nx->squashed_to;
+	}
+	fprintf(tempFILE, "  %s %s = NET %s\n", rdout.keyword, rdout.objname,
+		n->name);
+	nx->npoints++;
+}
+
+static void
+process_component()
+{
+	fprintf(tempFILE, "\nCOMPONENT %s {\n", rdout.objname);
+	for (;;) {
+		if (!read_unet_line(&rdstate, &rdout)) {
+			fprintf(stderr, "%s error: EOF in COMPONENT block\n",
+				input_filename);
+			exit(1);
+		}
+		if (rdout.typecode == UNETOBJ_CLOSINGBRACE)
+			break;
+		switch(rdout.typecode) {
+		case UNETOBJ_PRIMITIVE:
+		case UNETOBJ_ALTNAME:
+			fprintf(tempFILE, "  %s %s\n", rdout.keyword,
+				rdout.objname);
+			continue;
+		case UNETOBJ_PIN:
+		case UNETOBJ_PINMAP:
+			process_component_pin();
+			continue;
+		default:
+			fprintf(stderr,
+		"%s line %d: object type %s unexpected in COMPONENT block\n",
+				input_filename, rdstate.lineno, rdout.keyword);
+			exit(1);
+		}
+	}
+	fputs("}\n", tempFILE);
+}
+
+static void
+process_input_unet()
+{
+	struct net *n;
+	int state = 0;
+
+	open_unet_input_file(input_filename, &rdstate);
+	while (read_unet_line(&rdstate, &rdout)) {
+		switch(rdout.typecode) {
+		case UNETOBJ_CLOSINGBRACE:
+			fprintf(stderr,
+		"%s line %d: unexpected '}' outside of component block\n",
+				input_filename, rdstate.lineno);
+			exit(1);
+		case UNETOBJ_NET:
+			if (state == 0)
+				state = 1;
+			else if (state > 1) {
+				fprintf(stderr,
+"error: all input nets must precede all starpoints and components (%s line %d)\n",
+					input_filename, rdstate.lineno);
+				exit(1);
+			}
+			n = enter_net_object(rdout.objname,
+						sizeof(struct netextra));
+			bzero(n + 1, sizeof(struct netextra));
+			total_input_nets++;
+			continue;
+		case UNETOBJ_STARPOINT:
+			if (state < 1) {
+				fprintf(stderr,
+		"error (%s line %d): STARPOINT without any preceding NETs\n",
+					input_filename, rdstate.lineno);
+				exit(1);
+			}
+			if (state > 2) {
+				fprintf(stderr,
+	"error: all STARPOINTs must precede all COMPONENTs (%s line %d)\n",
+					input_filename, rdstate.lineno);
+				exit(1);
+			}
+			state = 2;
+			process_starpoint();
+			continue;
+		case UNETOBJ_COMPONENT:
+			if (state < 1) {
+				fprintf(stderr,
+		"error (%s line %d): COMPONENT without any preceding NETs\n",
+					input_filename, rdstate.lineno);
+				exit(1);
+			}
+			if (state < 3) {
+				tempFILE = tempfile();
+				state = 3;
+			}
+			process_component();
+			continue;
+		default:
+			fprintf(stderr,
+				"%s line %d: unexpected object type %s\n",
+				input_filename, rdstate.lineno, rdout.keyword);
+			exit(1);
+		}
+	}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	if (argc < 2 || argc > 3) {
+		fprintf(stderr, "usage: %s input.unet [output.unet]\n",
+			argv[0]);
+		exit(1);
+	}
+	input_filename = argv[1];
+	output_filename = argv[2];
+	process_input_unet();
+	/* output remains to be implemented */
+	exit(0);
+}