# HG changeset patch # User Space Falcon # Date 1438484955 0 # Node ID 1d4c693b8f35914341d5ed351f9ae332854fb93e # Parent 52000ae7a6cf5c35471ed70c48518d926ecbeae9 unet-bind: sverp netlist reading implemented diff -r 52000ae7a6cf -r 1d4c693b8f35 ueda/sverp-bind/Makefile --- 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 diff -r 52000ae7a6cf -r 1d4c693b8f35 ueda/sverp-bind/main.c --- 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); diff -r 52000ae7a6cf -r 1d4c693b8f35 ueda/sverp-bind/readunet.c --- /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 +#include +#include +#include +#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); + } + } +}