changeset 19:1d4c693b8f35

unet-bind: sverp netlist reading implemented
author Space Falcon <falcon@ivan.Harhan.ORG>
date Sun, 02 Aug 2015 03:09:15 +0000
parents 52000ae7a6cf
children dda8e455c863
files ueda/sverp-bind/Makefile ueda/sverp-bind/main.c ueda/sverp-bind/readunet.c
diffstat 3 files changed, 238 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/ueda/sverp-bind/Makefile	Sun Aug 02 01:23:09 2015 +0000
+++ b/ueda/sverp-bind/Makefile	Sun Aug 02 03:09:15 2015 +0000
@@ -1,7 +1,7 @@
 CC=	gcc
 CFLAGS=	-O2
-OBJS=	enterinst.o insthash.o main.o outcomp.o starpoints.o
-LIBS=	../libueda/libueda.a
+OBJS=	enterinst.o insthash.o main.o outcomp.o readunet.o starpoints.o
+LIBS=	../libunet/libunet.a ../libueda/libueda.a
 PROG=	unet-bind
 BINDIR=	/usr/local/bin
 
--- a/ueda/sverp-bind/main.c	Sun Aug 02 01:23:09 2015 +0000
+++ b/ueda/sverp-bind/main.c	Sun Aug 02 03:09:15 2015 +0000
@@ -8,7 +8,7 @@
 
 char *input_filename, *output_filename;
 char *starpoints_file;
-int check_completeness;
+int check_completeness, unbound_instances;
 
 static void
 usage()
@@ -61,10 +61,17 @@
 	set_default_sympath();
 	read_pinouts();
 	init_outcomp_from_MCL();
-
 	/* do we have any star points? */
 	if (starpoints_file)
 		process_starpoints_file();
+	/* read the netlist from sverp */
+	process_input_unet();
+	if (unbound_instances) {
+		fprintf(stderr,
+		"error: %s input contains unbound instances, aborting\n",
+			input_filename);
+		exit(1);
+	}
 
 	/* remaining functionality remains to be implemented */
 	exit(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ueda/sverp-bind/readunet.c	Sun Aug 02 03:09:15 2015 +0000
@@ -0,0 +1,227 @@
+#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->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:
+			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);
+		}
+	}
+}