diff ueda/unet-bind/readunet.c @ 101:ffab0a4424ad

ueda: unet-bind program moved into sensibly named unet-bind subdir
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 29 Sep 2019 22:42:41 +0000
parents ueda/sverp-bind/readunet.c@ce887659d12e
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ueda/unet-bind/readunet.c	Sun Sep 29 22:42:41 2019 +0000
@@ -0,0 +1,230 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "../libueda/xga.h"
+#include "../libunet/unetrd.h"
+#include "struct.h"
+
+extern char *pinname_to_pinnumber();
+extern struct net *find_net_by_name();
+extern struct instance *find_instance();
+
+extern char *input_filename;
+extern int unbound_instances;
+
+static struct unetrd_state rdstate;
+static struct unetrd_out rdout;
+
+static int
+resolve_pinnum_numeric(oc, pinnumstr)
+	struct outcomp *oc;
+	register char *pinnumstr;
+{
+	register int num;
+
+	if (!string_is_valid_decnum(pinnumstr)) {
+invnum:		fprintf(stderr,
+"%s line %d: component %s has numeric pins and \"%s\" is not a valid pin number\n",
+			input_filename, rdstate.lineno, oc->name, pinnumstr);
+		exit(1);
+	}
+	num = atoi(pinnumstr);
+	if (num < 1)
+		goto invnum;
+	if (num > oc->npins) {
+		fprintf(stderr,
+"%s line %d: attempting connection to pin %d on component %s that only has %d pins\n",
+			input_filename, rdstate.lineno, num, oc->name,
+			oc->npins);
+		exit(1);
+	}
+	return(num - 1);
+}
+
+static int
+resolve_pinnum_grid(oc, pinnumstr)
+	struct outcomp *oc;
+	char *pinnumstr;
+{
+	register struct grid_pkg_desc *xga = oc->grid_pkg;
+	struct xga_parsed_pinnum rowcol;
+	register int idx;
+
+	if (parse_xga_pinnumber(xga, pinnumstr, &rowcol) < 0) {
+		fprintf(stderr,
+	"%s line %d: \"%s\" is not a valid pin number for grid package %s\n",
+			input_filename, rdstate.lineno, pinnumstr, oc->name);
+		exit(1);
+	}
+	idx = rowcol.row_0based * xga->ncolumns + rowcol.col_0based;
+	if (xga->holes_array[idx]) {
+		fprintf(stderr,
+	"%s line %d: pin position %s is a hole in the grid package for %s\n",
+			input_filename, rdstate.lineno, pinnumstr, oc->name);
+		exit(1);
+	}
+	return(idx);
+}
+
+static int
+resolve_pinnum(oc, pinnumstr)
+	register struct outcomp *oc;
+	char *pinnumstr;
+{
+	if (oc->grid_pkg)
+		return resolve_pinnum_grid(oc, pinnumstr);
+	else
+		return resolve_pinnum_numeric(oc, pinnumstr);
+}
+
+static struct pinconn *
+create_pinconn()
+{
+	register struct pinconn *conn;
+	register struct net *net;
+
+	if (rdout.connect_to_net) {
+		net = find_net_by_name(rdout.connect_to_net);
+		conn = (struct pinconn *) malloc(sizeof(struct pinconn));
+		if (!conn) {
+			perror("malloc");
+			exit(1);
+		}
+		conn->net = net;
+		conn->nc_comment = 0;
+	} else {
+		conn = (struct pinconn *) malloc(sizeof(struct pinconn) +
+						 strlen(rdout.nc_comment) + 1);
+		if (!conn) {
+			perror("malloc");
+			exit(1);
+		}
+		conn->net = 0;
+		conn->nc_comment = (char *)(conn + 1);
+		strcpy(conn->nc_comment, rdout.nc_comment);
+	}
+	conn->input_lineno = rdstate.lineno;
+	return conn;
+}
+
+static void
+connect_pin(oc, pinnumstr)
+	register struct outcomp *oc;
+	char *pinnumstr;
+{
+	register int pinidx;
+
+	pinidx = resolve_pinnum(oc, pinnumstr);
+	if (oc->reverse_2pin)
+		pinidx = !pinidx;
+	if (oc->conn_array[pinidx]) {
+		fprintf(stderr,
+	"error: multiple connections to %s pin %s (input lines %d and %d)\n",
+			oc->name, pinnumstr,
+			oc->conn_array[pinidx]->input_lineno, rdstate.lineno);
+		exit(1);
+	}
+	oc->conn_array[pinidx] = create_pinconn();
+}
+
+static void
+process_pinmap(inst)
+	struct instance *inst;
+{
+	register struct outcomp *oc = inst->outcomp;
+	register char *pinnum;
+
+	if (!oc->mclcomp) {
+		fprintf(stderr,
+			"%s line %d: PINMAP is meaningless for starpoints\n",
+			input_filename, rdstate.lineno);
+		exit(1);
+	}
+	pinnum = pinname_to_pinnumber(oc->mclcomp, rdout.objname, inst->slot);
+	if (!pinnum) {
+		fprintf(stderr, "PINMAP error on %s line %d\n",
+			input_filename, rdstate.lineno);
+		exit(1);
+	}
+	connect_pin(oc, pinnum);
+}
+
+static void
+process_component()
+{
+	struct instance *inst;
+
+	inst = find_instance(rdout.objname);
+	if (!inst) {
+		fprintf(stderr, "%s line %d: instance %s not bound in MCL\n",
+			input_filename, rdstate.lineno, rdout.objname);
+		unbound_instances++;
+	} else {
+		if (inst->claimed) {
+			fprintf(stderr,
+			"%s line %d: instance %s appears more than once\n",
+				input_filename, rdstate.lineno, inst->name);
+			exit(1);
+		}
+		inst->claimed = 1;
+	}
+	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:
+		case UNETOBJ_ATTR:
+			continue;
+		case UNETOBJ_PIN:
+			if (inst)
+				connect_pin(inst->outcomp, rdout.objname);
+			continue;
+		case UNETOBJ_PINMAP:
+			if (inst)
+				process_pinmap(inst);
+			continue;
+		default:
+			fprintf(stderr,
+		"%s line %d: object type %s unexpected in component block\n",
+				input_filename, rdstate.lineno, rdout.keyword);
+			exit(1);
+		}
+	}
+}
+
+process_input_unet()
+{
+	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:
+			enter_net_object(rdout.objname, 0);
+			continue;
+		case UNETOBJ_COMPONENT:
+			process_component();
+			continue;
+		case UNETOBJ_STARPOINT:
+			fprintf(stderr,
+"error: STARPOINT objects not expected in unet-bind input (%s line %d)\n",
+				input_filename, rdstate.lineno);
+			exit(1);
+		default:
+			fprintf(stderr,
+				"%s line %d: unexpected object type %s\n",
+				input_filename, rdstate.lineno, rdout.keyword);
+			exit(1);
+		}
+	}
+}