view ueda/uschem-netlist/pinconn.c @ 31:61272ee5aadc

unet-bind: implemented -a option for specifying wanted attributes
author Space Falcon <falcon@ivan.Harhan.ORG>
date Sat, 08 Aug 2015 21:44:10 +0000
parents cd92449fdb51
children
line wrap: on
line source

/*
 * Recording of pin connections
 */

#include <stdio.h>
#include <strings.h>
#include "../libueda/mcl.h"
#include "netlist.h"

extern char *malloc();

int total_pin_connections;
int total_expl_noconnects;

extern struct net noconnect_pseudo_net;

struct pinconn *
alloc_pinconn()
{
	register struct pinconn *pc;

	pc = (struct pinconn *) malloc(sizeof(struct pinconn));
	if (!pc) {
		perror("malloc");
		exit(1);
	}
	bzero(pc, sizeof(struct pinconn));
	return(pc);
}

static
report_connection(pc)
	register struct pinconn *pc;
{
	register struct net *n;

	n = pc->net;
	if (n->netname)
		fprintf(stderr, "assigned to net %s by %s line %d\n",
			n->netname, pc->origin_file, pc->origin_line);
	else
		fprintf(stderr, "assigned to an unnamed net by %s line %d\n",
			pc->origin_file, pc->origin_line);
}

record_pin_connection(pc)
	register struct pinconn *pc;
{
	register struct nlcomp *nlc;
	register struct net *n;
	int stat;

	nlc = pc->comp;
	if (nlc->npins)
		stat = record_pin_connection_tab(pc);
	else
		stat = record_pin_connection_chain(pc);
	if (stat)
		return(stat);
	n = pc->net;
	pc->next_in_net = n->pins;
	n->pins = pc;
	n->npoints++;
	if (n != &noconnect_pseudo_net) {
		nlc->nconnects++;
		total_pin_connections++;
	} else
		total_expl_noconnects++;
	return(0);
}

static
record_pin_connection_tab(pc)
	register struct pinconn *pc;
{
	register struct nlcomp *nlc;
	register int n;

	nlc = pc->comp;
	n = atoi(pc->pinnum);
	if (n < 1 || n > nlc->npins) {
		fprintf(stderr, "%s: line %d: %s pin number %s is invalid\n",
			pc->origin_file, pc->origin_line, nlc->mclcomp->name,
			pc->pinnum);
		exit(1);
	}
	n--;
	if (nlc->pintab[n]) {
		if (nlc->pintab[n]->net == pc->net) /* same pin to same net? */
			return(1);		    /* redundant but harmless */
		fprintf(stderr,
			"%s pin %s is connected to more than one net:\n",
			nlc->mclcomp->name, pc->pinnum);
		report_connection(nlc->pintab[n]);
		report_connection(pc);
		exit(1);
	}
	nlc->pintab[n] = pc;
	return(0);
}

static
record_pin_connection_chain(pc)
	register struct pinconn *pc;
{
	struct nlcomp *nlc;
	struct component *comp;
	register struct pinconn *s, **sp;

	nlc = pc->comp;
	comp = nlc->mclcomp;
	for (sp = &nlc->pinchain; s = *sp; sp = &s->next_in_comp)
		if (!strcmp(s->pinnum, pc->pinnum)) {
			if (s->net == pc->net)	/* same pin to same net? */
				return(1);	/* redundant but harmless */
			fprintf(stderr,
			"%s pin %s is connected to more than one net:\n",
				comp->name, pc->pinnum);
			report_connection(s);
			report_connection(pc);
			exit(1);
		}
	*sp = pc;
	return(0);
}