FreeCalypso > hg > ueda-linux
view ueda/unet-utils/unet-destar.c @ 80:df98a82b807e
ueda-mkbom refdes list output: refdes range detection implemented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 23 Feb 2017 18:54:47 +0000 |
parents | a93e4b07fdf3 |
children |
line wrap: on
line source
#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(); extern struct net *net_list_head; static char *input_filename, *output_filename; static struct unetrd_state rdstate; static struct unetrd_out rdout; static int total_input_nets, total_output_nets; static struct net *starpoint_head; static FILE *tempFILE, *outFILE; static int net_comment_column; 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: case UNETOBJ_ATTR: 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_ATTR: fprintf(tempFILE, " ATTR %s=%s\n", rdout.objname, rdout.attr_value); 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); } } } static void find_net_comment_column() { register struct net *n; register struct netextra *nx; register int len, maxlen; maxlen = 0; for (n = net_list_head; n; n = n->nextinlist) { nx = (struct netextra *)(n + 1); if (nx->squashed_to) continue; total_output_nets++; len = strlen(n->name); if (len > maxlen) maxlen = len; } maxlen += 4; do maxlen++; while (maxlen % 8); net_comment_column = maxlen; } static void output_nets() { register struct net *n; register struct netextra *nx; register int col; fprintf(outFILE, "\n# %d input nets reduced to %d joined nets:\n#\n", total_input_nets, total_output_nets); for (n = net_list_head; n; n = n->nextinlist) { nx = (struct netextra *)(n + 1); if (nx->squashed_to) continue; fprintf(outFILE, "NET %s", n->name); col = 4 + strlen(n->name); do { fputc('\t', outFILE); col += 8; col &= ~7; } while (col < net_comment_column); fprintf(outFILE, "# %d points\n", nx->npoints); } } static void generate_output() { if (output_filename) { outFILE = fopen(output_filename, "w"); if (!outFILE) { perror(output_filename); exit(1); } } else outFILE = stdout; fprintf(outFILE, "# This netlist has been generated by unet-destar from %s\n", input_filename); output_nets(); dump_tempfile(); if (outFILE != stdout) fclose(outFILE); } 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(); find_net_comment_column(); generate_output(); exit(0); }