comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:cd92449fdb51
1 /*
2 * This program (uschem-check) reads a uschem schematic into core, exercising
3 * libuschem reading code.
4 * It then performs the most basic DRC, or more specifically, the check is
5 * focused on matching the graphical info with the netlist info - no attempt
6 * is made to guess the sensibility of the actual electrical circuit.
7 */
8
9 #include <sys/types.h>
10 #include <stdio.h>
11 #include <strings.h>
12 #include "../libuschem/schemstruct.h"
13 #include "../libuschem/graphsym.h"
14
15 extern int optind;
16 extern char *optarg;
17
18 extern char *MCLfile;
19
20 extern struct schem *read_schem();
21
22 struct schem *schem;
23 int domcl, dosymbols, checkhash, donets;
24
25 main(argc, argv)
26 char **argv;
27 {
28 register int c;
29 char **avp;
30
31 while ((c = getopt(argc, argv, "hI:mM:s")) != EOF)
32 switch (c) {
33 case 'h':
34 checkhash++;
35 break;
36 case 'I':
37 add_symfile_dir(optarg);
38 break;
39 case 'm':
40 domcl++;
41 break;
42 case 'M':
43 MCLfile = optarg;
44 break;
45 case 's':
46 dosymbols++;
47 break;
48 default:
49 usage: fprintf(stderr, "usage: %s [-hImMs] schemfile...\n",
50 argv[0]);
51 exit(1);
52 }
53 if (!argv[optind])
54 goto usage;
55
56 if (domcl) {
57 read_MCL();
58 hash_MCL();
59 if (checkhash)
60 report_mclhash_quality();
61 }
62 if (dosymbols)
63 set_default_sympath();
64
65 for (avp = argv + optind; *avp; avp++) {
66 schem = read_schem(*avp);
67 hash_component_instances(schem);
68 if (checkhash)
69 report_compinst_hash_quality(schem);
70 if (domcl)
71 match_schem_to_mcl(schem);
72 if (dosymbols) {
73 load_graphsyms(schem);
74 instantiate_graphsym_pins(schem, 1);
75 if (checkhash)
76 report_pininst_hash_quality(schem);
77 }
78 donets = 1;
79 check_schem_objects();
80 if (preen_graphnets(schem, 1, dosymbols, 1, 0) < 0)
81 donets = 0;
82 if (donets && (!schem->is_graph || dosymbols))
83 check_exclusive_nets();
84 }
85
86 report_exclusive_net_violations();
87 if (checkhash && dosymbols)
88 report_graphsym_hash_quality();
89 exit(0);
90 }
91
92 check_schem_objects()
93 {
94 register struct schemobj *obj;
95
96 for (obj = schem->obj_next; obj != (struct schemobj *)schem;
97 obj = obj->obj_next) {
98 switch (obj->obj_type) {
99 case OBJTYPE_COMPINST:
100 if (obj->compobj_isgraph && !schem->is_graph)
101 fprintf(stderr,
102 "%s: line %d: graphical symbol used in a non-graphical schematic\n",
103 schem->orig_filename, obj->obj_lineno);
104 if (obj->compobj_isgraph && dosymbols &&
105 obj->compobj_graphsym->gs_forcenets)
106 fprintf(stderr,
107 "%s: line %d: symbol \"%s\" on %s: forcenets won't have the desired effect\n",
108 schem->orig_filename, obj->obj_lineno,
109 obj->compobj_graph_symname,
110 obj->compobj_instname);
111 break;
112 case OBJTYPE_GRAPHSYM:
113 if (!schem->is_graph)
114 fprintf(stderr,
115 "%s: line %d: GraphSym object in a non-graphical schematic\n",
116 schem->orig_filename, obj->obj_lineno);
117 break;
118 case OBJTYPE_GRAPHNET:
119 if (!schem->is_graph) {
120 fprintf(stderr,
121 "%s: line %d: GraphNet object in a non-graphical schematic\n",
122 schem->orig_filename, obj->obj_lineno);
123 donets = 0;
124 }
125 break;
126 case OBJTYPE_NETLINE:
127 if (!schem->is_graph)
128 fprintf(stderr,
129 "%s: line %d: NetLine object in a non-graphical schematic\n",
130 schem->orig_filename, obj->obj_lineno);
131 break;
132 case OBJTYPE_BUSSEG:
133 if (!schem->is_graph)
134 fprintf(stderr,
135 "%s: line %d: BusSeg object in a non-graphical schematic\n",
136 schem->orig_filename, obj->obj_lineno);
137 break;
138 case OBJTYPE_GRAPHBLOCK:
139 if (!schem->is_graph)
140 fprintf(stderr,
141 "%s: line %d: graphics block in a non-graphical schematic\n",
142 schem->orig_filename, obj->obj_lineno);
143 break;
144 }
145 check_obj_decors(obj);
146 }
147 }
148
149 check_obj_decors(obj)
150 register struct schemobj *obj;
151 {
152 register struct decoration *decor;
153
154 for (decor = obj->obj_decorations; decor; decor = decor->decor_next)
155 switch (decor->decor_type) {
156 case DECOR_TYPE_DISPLAYATTR:
157 if (!is_graphical_obj(obj))
158 fprintf(stderr,
159 "%s: line %d: DisplayAttr on a non-graphical object\n",
160 schem->orig_filename, decor->decor_lineno);
161 continue;
162 case DECOR_TYPE_DISPLAYNETNAME:
163 if (obj->obj_type != OBJTYPE_GRAPHNET)
164 fprintf(stderr,
165 "%s: line %d: DisplayNetName invalid in objects other than GraphNet\n",
166 schem->orig_filename, decor->decor_lineno);
167 continue;
168 case DECOR_TYPE_GRAPHBLOCK:
169 if (!is_graphical_obj(obj))
170 fprintf(stderr,
171 "%s: line %d: graphics block decoration on a non-graphical object\n",
172 schem->orig_filename, decor->decor_lineno);
173 break;
174 case DECOR_TYPE_PINTONET:
175 if (obj->obj_type != OBJTYPE_COMPINST) {
176 fprintf(stderr,
177 "%s: line %d: PinToNet invalid in objects other than components\n",
178 schem->orig_filename, decor->decor_lineno);
179 continue;
180 }
181 record_netname_reference(decor->decorpincon_netname, 0,
182 schem->orig_filename,
183 decor->decor_lineno);
184 if (obj->compobj_isgraph && dosymbols)
185 check_pintonet_graph(obj, decor);
186 continue;
187 case DECOR_TYPE_SYMONPIN:
188 if (obj->obj_type != OBJTYPE_COMPINST) {
189 fprintf(stderr,
190 "%s: line %d: SymOnPin invalid in objects other than components\n",
191 schem->orig_filename, decor->decor_lineno);
192 continue;
193 }
194 if (!obj->compobj_isgraph) {
195 fprintf(stderr,
196 "%s: line %d: SymOnPin invalid on a non-graphical component\n",
197 schem->orig_filename, decor->decor_lineno);
198 continue;
199 }
200 if (dosymbols)
201 check_symonpin(obj, decor);
202 }
203 }
204
205 is_graphical_obj(obj)
206 register struct schemobj *obj;
207 {
208 switch (obj->obj_type) {
209 case OBJTYPE_COMPINST:
210 return(obj->compobj_isgraph);
211 case OBJTYPE_GRAPHSYM:
212 case OBJTYPE_GRAPHNET:
213 case OBJTYPE_NETLINE:
214 case OBJTYPE_BUSSEG:
215 case OBJTYPE_GRAPHBLOCK:
216 return(1);
217 default:
218 return(0);
219 }
220 }
221
222 check_pintonet_graph(obj, condec)
223 struct schemobj *obj;
224 register struct decoration *condec;
225 {
226 register struct decoration *symdec;
227
228 /* is this pin represented graphically? */
229 if (!is_pin_graphical(obj->compobj_graphsym, condec->decorpincon_pin))
230 return;
231 /* it is graphical -- look for matching SymOnPin */
232 for (symdec = obj->obj_decorations; symdec; symdec = symdec->decor_next)
233 if (symdec->decor_type == DECOR_TYPE_SYMONPIN &&
234 !strcmp(condec->decorpincon_pin, symdec->decorpinsym_pin))
235 break;
236 if (!symdec)
237 fprintf(stderr, "%s: line %d: pin %s of %s is connected with PinToNet, but not marked with SymOnPin\n",
238 schem->orig_filename, condec->decor_lineno,
239 condec->decorpincon_pin, obj->compobj_instname);
240 }
241
242 is_pin_graphical(gs, matchkey)
243 struct graphsym *gs;
244 register char *matchkey;
245 {
246 int bynum;
247 register struct graphsym_pindef *pd;
248 register char *pinid;
249
250 if (matchkey[0] == '#') {
251 bynum = 1;
252 matchkey++;
253 } else
254 bynum = 0;
255 for (pd = gs->gs_pins; pd; pd = pd->gspd_next) {
256 pinid = bynum ? pd->gspd_pinnumber : pd->gspd_pinname;
257 if (pinid && !strcmp(pinid, matchkey))
258 return(1);
259 }
260 return(0);
261 }
262
263 check_symonpin(obj, symdec)
264 struct schemobj *obj;
265 struct decoration *symdec;
266 {
267 struct graphsym *gs;
268 struct graphsym_pindef *pindef;
269 register struct decoration *ndec;
270
271 gs = symdec->decorpinsym_gs;
272 if (gs->gs_npins > 1) {
273 fprintf(stderr,
274 "%s: line %d: SymOnPin symbols may not have more than 1 pin\n",
275 schem->orig_filename, symdec->decor_lineno);
276 return;
277 }
278 pindef = gs->gs_pins;
279 if (!pindef->gspd_forcenet)
280 return;
281 /* look for matching PinToNet */
282 for (ndec = obj->obj_decorations; ndec; ndec = ndec->decor_next)
283 if (ndec->decor_type == DECOR_TYPE_PINTONET &&
284 !strcmp(ndec->decorpincon_pin, symdec->decorpinsym_pin))
285 break;
286 if (!ndec) {
287 fprintf(stderr,
288 "%s: line %d: SymOnPin implies connection to %s, but no matching PinToNet\n",
289 schem->orig_filename, symdec->decor_lineno,
290 pindef->gspd_forcenet);
291 return;
292 }
293 if (strcmp(ndec->decorpincon_netname, pindef->gspd_forcenet))
294 fprintf(stderr,
295 "%s: SymOnPin (line %d) and PinToNet (line %d) call for different nets!\n",
296 schem->orig_filename, symdec->decor_lineno,
297 ndec->decor_lineno);
298 }