FreeCalypso > hg > ueda-linux
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 } |