FreeCalypso > hg > ueda-linux
diff ueda/uschem-utils/check.c @ 0:cd92449fdb51
initial import of ueda and ifctf-part-lib from ifctfvax CVS
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 20 Jul 2015 00:24:37 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ueda/uschem-utils/check.c Mon Jul 20 00:24:37 2015 +0000 @@ -0,0 +1,298 @@ +/* + * This program (uschem-check) reads a uschem schematic into core, exercising + * libuschem reading code. + * It then performs the most basic DRC, or more specifically, the check is + * focused on matching the graphical info with the netlist info - no attempt + * is made to guess the sensibility of the actual electrical circuit. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <strings.h> +#include "../libuschem/schemstruct.h" +#include "../libuschem/graphsym.h" + +extern int optind; +extern char *optarg; + +extern char *MCLfile; + +extern struct schem *read_schem(); + +struct schem *schem; +int domcl, dosymbols, checkhash, donets; + +main(argc, argv) + char **argv; +{ + register int c; + char **avp; + + while ((c = getopt(argc, argv, "hI:mM:s")) != EOF) + switch (c) { + case 'h': + checkhash++; + break; + case 'I': + add_symfile_dir(optarg); + break; + case 'm': + domcl++; + break; + case 'M': + MCLfile = optarg; + break; + case 's': + dosymbols++; + break; + default: +usage: fprintf(stderr, "usage: %s [-hImMs] schemfile...\n", + argv[0]); + exit(1); + } + if (!argv[optind]) + goto usage; + + if (domcl) { + read_MCL(); + hash_MCL(); + if (checkhash) + report_mclhash_quality(); + } + if (dosymbols) + set_default_sympath(); + + for (avp = argv + optind; *avp; avp++) { + schem = read_schem(*avp); + hash_component_instances(schem); + if (checkhash) + report_compinst_hash_quality(schem); + if (domcl) + match_schem_to_mcl(schem); + if (dosymbols) { + load_graphsyms(schem); + instantiate_graphsym_pins(schem, 1); + if (checkhash) + report_pininst_hash_quality(schem); + } + donets = 1; + check_schem_objects(); + if (preen_graphnets(schem, 1, dosymbols, 1, 0) < 0) + donets = 0; + if (donets && (!schem->is_graph || dosymbols)) + check_exclusive_nets(); + } + + report_exclusive_net_violations(); + if (checkhash && dosymbols) + report_graphsym_hash_quality(); + exit(0); +} + +check_schem_objects() +{ + register struct schemobj *obj; + + for (obj = schem->obj_next; obj != (struct schemobj *)schem; + obj = obj->obj_next) { + switch (obj->obj_type) { + case OBJTYPE_COMPINST: + if (obj->compobj_isgraph && !schem->is_graph) + fprintf(stderr, + "%s: line %d: graphical symbol used in a non-graphical schematic\n", + schem->orig_filename, obj->obj_lineno); + if (obj->compobj_isgraph && dosymbols && + obj->compobj_graphsym->gs_forcenets) + fprintf(stderr, +"%s: line %d: symbol \"%s\" on %s: forcenets won't have the desired effect\n", + schem->orig_filename, obj->obj_lineno, + obj->compobj_graph_symname, + obj->compobj_instname); + break; + case OBJTYPE_GRAPHSYM: + if (!schem->is_graph) + fprintf(stderr, + "%s: line %d: GraphSym object in a non-graphical schematic\n", + schem->orig_filename, obj->obj_lineno); + break; + case OBJTYPE_GRAPHNET: + if (!schem->is_graph) { + fprintf(stderr, + "%s: line %d: GraphNet object in a non-graphical schematic\n", + schem->orig_filename, obj->obj_lineno); + donets = 0; + } + break; + case OBJTYPE_NETLINE: + if (!schem->is_graph) + fprintf(stderr, + "%s: line %d: NetLine object in a non-graphical schematic\n", + schem->orig_filename, obj->obj_lineno); + break; + case OBJTYPE_BUSSEG: + if (!schem->is_graph) + fprintf(stderr, + "%s: line %d: BusSeg object in a non-graphical schematic\n", + schem->orig_filename, obj->obj_lineno); + break; + case OBJTYPE_GRAPHBLOCK: + if (!schem->is_graph) + fprintf(stderr, + "%s: line %d: graphics block in a non-graphical schematic\n", + schem->orig_filename, obj->obj_lineno); + break; + } + check_obj_decors(obj); + } +} + +check_obj_decors(obj) + register struct schemobj *obj; +{ + register struct decoration *decor; + + for (decor = obj->obj_decorations; decor; decor = decor->decor_next) + switch (decor->decor_type) { + case DECOR_TYPE_DISPLAYATTR: + if (!is_graphical_obj(obj)) + fprintf(stderr, + "%s: line %d: DisplayAttr on a non-graphical object\n", + schem->orig_filename, decor->decor_lineno); + continue; + case DECOR_TYPE_DISPLAYNETNAME: + if (obj->obj_type != OBJTYPE_GRAPHNET) + fprintf(stderr, + "%s: line %d: DisplayNetName invalid in objects other than GraphNet\n", + schem->orig_filename, decor->decor_lineno); + continue; + case DECOR_TYPE_GRAPHBLOCK: + if (!is_graphical_obj(obj)) + fprintf(stderr, + "%s: line %d: graphics block decoration on a non-graphical object\n", + schem->orig_filename, decor->decor_lineno); + break; + case DECOR_TYPE_PINTONET: + if (obj->obj_type != OBJTYPE_COMPINST) { + fprintf(stderr, + "%s: line %d: PinToNet invalid in objects other than components\n", + schem->orig_filename, decor->decor_lineno); + continue; + } + record_netname_reference(decor->decorpincon_netname, 0, + schem->orig_filename, + decor->decor_lineno); + if (obj->compobj_isgraph && dosymbols) + check_pintonet_graph(obj, decor); + continue; + case DECOR_TYPE_SYMONPIN: + if (obj->obj_type != OBJTYPE_COMPINST) { + fprintf(stderr, + "%s: line %d: SymOnPin invalid in objects other than components\n", + schem->orig_filename, decor->decor_lineno); + continue; + } + if (!obj->compobj_isgraph) { + fprintf(stderr, + "%s: line %d: SymOnPin invalid on a non-graphical component\n", + schem->orig_filename, decor->decor_lineno); + continue; + } + if (dosymbols) + check_symonpin(obj, decor); + } +} + +is_graphical_obj(obj) + register struct schemobj *obj; +{ + switch (obj->obj_type) { + case OBJTYPE_COMPINST: + return(obj->compobj_isgraph); + case OBJTYPE_GRAPHSYM: + case OBJTYPE_GRAPHNET: + case OBJTYPE_NETLINE: + case OBJTYPE_BUSSEG: + case OBJTYPE_GRAPHBLOCK: + return(1); + default: + return(0); + } +} + +check_pintonet_graph(obj, condec) + struct schemobj *obj; + register struct decoration *condec; +{ + register struct decoration *symdec; + + /* is this pin represented graphically? */ + if (!is_pin_graphical(obj->compobj_graphsym, condec->decorpincon_pin)) + return; + /* it is graphical -- look for matching SymOnPin */ + for (symdec = obj->obj_decorations; symdec; symdec = symdec->decor_next) + if (symdec->decor_type == DECOR_TYPE_SYMONPIN && + !strcmp(condec->decorpincon_pin, symdec->decorpinsym_pin)) + break; + if (!symdec) + fprintf(stderr, "%s: line %d: pin %s of %s is connected with PinToNet, but not marked with SymOnPin\n", + schem->orig_filename, condec->decor_lineno, + condec->decorpincon_pin, obj->compobj_instname); +} + +is_pin_graphical(gs, matchkey) + struct graphsym *gs; + register char *matchkey; +{ + int bynum; + register struct graphsym_pindef *pd; + register char *pinid; + + if (matchkey[0] == '#') { + bynum = 1; + matchkey++; + } else + bynum = 0; + for (pd = gs->gs_pins; pd; pd = pd->gspd_next) { + pinid = bynum ? pd->gspd_pinnumber : pd->gspd_pinname; + if (pinid && !strcmp(pinid, matchkey)) + return(1); + } + return(0); +} + +check_symonpin(obj, symdec) + struct schemobj *obj; + struct decoration *symdec; +{ + struct graphsym *gs; + struct graphsym_pindef *pindef; + register struct decoration *ndec; + + gs = symdec->decorpinsym_gs; + if (gs->gs_npins > 1) { + fprintf(stderr, + "%s: line %d: SymOnPin symbols may not have more than 1 pin\n", + schem->orig_filename, symdec->decor_lineno); + return; + } + pindef = gs->gs_pins; + if (!pindef->gspd_forcenet) + return; + /* look for matching PinToNet */ + for (ndec = obj->obj_decorations; ndec; ndec = ndec->decor_next) + if (ndec->decor_type == DECOR_TYPE_PINTONET && + !strcmp(ndec->decorpincon_pin, symdec->decorpinsym_pin)) + break; + if (!ndec) { + fprintf(stderr, +"%s: line %d: SymOnPin implies connection to %s, but no matching PinToNet\n", + schem->orig_filename, symdec->decor_lineno, + pindef->gspd_forcenet); + return; + } + if (strcmp(ndec->decorpincon_netname, pindef->gspd_forcenet)) + fprintf(stderr, +"%s: SymOnPin (line %d) and PinToNet (line %d) call for different nets!\n", + schem->orig_filename, symdec->decor_lineno, + ndec->decor_lineno); +}