1 /* -*- tab-width: 4 -*-
2 *
3 * Electric(tm) VLSI Design System
4 *
5 * File: tecschem.c
6 * Schematic technology
7 * Written by: Steven M. Rubin, Static Free Software
8 * Inspired by Erwin S. K. Liu, University of Calgary
9 *
10 * Copyright (c) 2000 Static Free Software.
11 *
12 * Electric(tm) is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * Electric(tm) is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with Electric(tm); see the file COPYING. If not, write to
24 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
25 * Boston, Mass 02111-1307, USA.
26 *
27 * Static Free Software
28 * 4119 Alpine Road
29 * Portola Valley, California 94028
30 * info@staticfreesoft.com
31 */
32
33 /*
34 * The primitives of this technology can be parameterized as follows:
35 *
36 * "TRANSISTOR" uses "ATTR_width", "ATTR_length", and "ATTR_area" for size
37 * "RESISTOR" uses "SCHEM_resistance" for ohms
38 * "CAPACITOR" uses "SCHEM_capacitance" for capacitance
39 * "DIODE" uses "SCHEM_diode" for area
40 * "INDUCTOR" uses "SCHEM_inductance" for Henrys
41 * "BBOX" uses "SCHEM_function" for function
42 * "SOURCE" uses "SIM_spice_model" for the SPICE card
43 * "METER" uses "SCHEM_meter_type" for SPICE range
44 * "TWOPORT" uses "SIM_spice_model" for the SPICE card
45 */
46
47 #include "global.h"
48 #include "database.h"
49 #include "egraphics.h"
50 #include "tech.h"
51 #include "tecschem.h"
52 #include "efunction.h"
53 #include "usr.h"
54 #include "network.h"
55
56 #define SCALABLEGATES 1 /* uncomment for experimental scalable gate code */
57
58 /* twentieths of a unit fractions */
59 #define D1 (WHOLE/20) /* 0.05 */
60 #define FO (WHOLE/40) /* 0.025 */
61 #define D2 (WHOLE/10) /* 0.10 */
62 #define D3 (WHOLE/20 * 3) /* 0.15 */
63 #define D4 (WHOLE/5) /* 0.20 */
64 #define D5 (WHOLE/4) /* 0.25 */
65 #define D6 (WHOLE/10 * 3) /* 0.30 */
66 #define D7 (WHOLE/20 * 7) /* 0.35 */
67 #define D8 (WHOLE/5 * 2) /* 0.40 */
68 #define D9 (WHOLE/20 * 9) /* 0.45 */
69 #define D12 (WHOLE/5 * 3) /* 0.60 */
70 #define D13 (WHOLE/20 * 13) /* 0.65 */
71 #define D14 (WHOLE/10 * 7) /* 0.70 */
72 #define D16 (WHOLE/5 * 4) /* 0.80 */
73
74 /* right of center by this amount */
75 #define CENTERR0Q 0,Q0 /* 0.25 */
76 #define CENTERR0T 0,T0 /* 0.75 */
77 #define CENTERR1Q 0,Q1 /* 1.25 */
78 #define CENTERR1T 0,T1 /* 1.75 */
79 #define CENTERR2Q 0,Q2 /* 2.25 */
80 #define CENTERR2T 0,T2 /* 2.75 */
81 #define CENTERR3Q 0,Q3 /* 3.25 */
82 #define CENTERR3T 0,T3 /* 3.75 */
83
84 /* left of center by this amount */
85 #define CENTERL0Q 0,-Q0 /* 0.25 */
86 #define CENTERL0T 0,-T0 /* 0.75 */
87 #define CENTERL1Q 0,-Q1 /* 1.25 */
88 #define CENTERL1T 0,-T1 /* 1.75 */
89 #define CENTERL2Q 0,-Q2 /* 2.25 */
90 #define CENTERL2T 0,-T2 /* 2.75 */
91 #define CENTERL3Q 0,-Q3 /* 3.25 */
92 #define CENTERL3T 0,-T3 /* 3.75 */
93 #define CENTERL4Q 0,-Q4 /* 4.25 */
94 #define CENTERL9 0,-K9 /* 9.00 */
95 #define CENTERL10 0,-K10 /* 10.00 */
96
97 /* up from center by this amount */
98 #define CENTERU0Q 0,Q0 /* 0.25 */
99 #define CENTERU0T 0,T0 /* 0.75 */
100 #define CENTERU1Q 0,Q1 /* 1.25 */
101 #define CENTERU1T 0,T1 /* 1.75 */
102 #define CENTERU2Q 0,Q2 /* 2.25 */
103 #define CENTERU2T 0,T2 /* 2.75 */
104 #define CENTERU3Q 0,Q3 /* 3.25 */
105 #define CENTERU3T 0,T3 /* 3.75 */
106
107 /* down from center by this amount */
108 #define CENTERD0Q 0,-Q0 /* 0.25 */
109 #define CENTERD0T 0,-T0 /* 0.75 */
110 #define CENTERD1Q 0,-Q1 /* 1.25 */
111 #define CENTERD1T 0,-T1 /* 1.75 */
112 #define CENTERD2Q 0,-Q2 /* 2.25 */
113 #define CENTERD2T 0,-T2 /* 2.75 */
114 #define CENTERD3Q 0,-Q3 /* 3.25 */
115 #define CENTERD3T 0,-T3 /* 3.75 */
116
117 /* this much from the center to the left edge */
118 #define LEFTBYP1 -D1,0 /* 0.1 */
119 #define LEFTBYP125 (-K1/15),0 /* 0.13333... */ /* wanted 0.125 but can't */
120 #define LEFTBYP166 (-K1/12),0 /* 0.16666... */
121 #define LEFTBYP2 -D2,0 /* 0.2 */
122 #define LEFTBYP25 (-D2-FO),0 /* 0.25 */
123 #define LEFTBYP3 -D3,0 /* 0.3 */
124 #define LEFTBYP33 (-K1/6),0 /* 0.3333... */
125 #define LEFTBYP35 -(D3+FO),0 /* 0.35 (21/60) */
126 #define LEFTBYP3666 -22,0 /* 0.3666... (22/60) */
127 #define LEFTBYP4 -D4,0 /* 0.4 */
128 #define LEFTBYP45 -(D4+FO),0 /* 0.45 (27/60) */
129 #define LEFTBYP5 -D5,0 /* 0.5 */
130 #define LEFTBYP6 -D6,0 /* 0.6 */
131 #define LEFTBYP6333 -38,0 /* 0.6333... (38/60) */
132 #define LEFTBYP66 (-K1/3),0 /* 0.6666... */
133 #define LEFTBYP7 -D7,0 /* 0.7 */
134 #define LEFTBYP75 (-D7-FO),0 /* 0.75 */
135 #define LEFTBYP8 -D8,0 /* 0.8 */
136 #define LEFTBYP875 -D9,0 /* 0.9 */ /* wanted 0.875 but can't */
137 #define LEFTBYP9 -D9,0 /* 0.9 */
138 #define LEFTBYP12 -D12,0 /* 1.2 */
139 #define LEFTBYP14 -D14,0 /* 1.4 */
140 #define LEFTBY1P6 -H0-D6,0 /* 1.6 */
141
142 /* this much from the center to the right edge */
143 #define RIGHTBYP1 D1,0 /* 0.1 (6/60) */
144 #define RIGHTBYP125 (K1/15),0 /* 0.133... (8/60) */ /* not precise */
145 #define RIGHTBYP166 (K1/12),0 /* 0.166... (10/60) */
146 #define RIGHTBYP2 D2,0 /* 0.2 (12/60) */
147 #define RIGHTBYP25 (D2+FO),0 /* 0.25 (15/60) */
148 #define RIGHTBYP3 D3,0 /* 0.3 (18/60) */
149 #define RIGHTBYP33 (K1/6),0 /* 0.33... (20/60) */
150 #define RIGHTBYP35 (D3+FO),0 /* 0.35 (21/60) */
151 #define RIGHTBYP3666 22,0 /* 0.3666... (22/60) */
152 #define RIGHTBYP3833 23,0 /* 0.3833... (23/60) */
153 #define RIGHTBYP4 D4,0 /* 0.4 (24/60) */
154 #define RIGHTBYP433 26,0 /* 0.433... (26/60) */
155 #define RIGHTBYP45 (D4+FO),0 /* 0.45 (27/60) */
156 #define RIGHTBYP5 D5,0 /* 0.5 (30/60) */
157 #define RIGHTBYP5166 31,0 /* 0.5166... (31/60) */
158 #define RIGHTBYP55 (D5+FO),0 /* 0.55 (33/60) */
159 #define RIGHTBYP566 34,0 /* 0.566... (34/60) */
160 #define RIGHTBYP6 D6,0 /* 0.6 (36/60) */
161 #define RIGHTBYP6166 37,0 /* 0.6166... (37/60) */
162 #define RIGHTBYP6333 38,0 /* 0.6333... (38/60) */
163 #define RIGHTBYP66 (K1/3),0 /* 0.66... (40/60) */
164 #define RIGHTBYP7 D7,0 /* 0.7 (42/60) */
165 #define RIGHTBYP75 (D7+FO),0 /* 0.75 (45/60) */
166 #define RIGHTBYP8 D8,0 /* 0.8 (48/60) */
167 #define RIGHTBYP875 D9,0 /* 0.9 (54/60) */ /* not precise */
168 #define RIGHTBYP9 D9,0 /* 0.9 (54/60) */
169
170 /* this much from the center to the bottom edge */
171 #define BOTBYP1 -D1,0 /* 0.1 */
172 #define BOTBYP125 (-K1/15),0 /* 0.133... (8/60) */ /* not precise */
173 #define BOTBYP166 (-K1/12),0 /* 0.166... (10/60) */
174 #define BOTBYP2 -D2,0 /* 0.2 */
175 #define BOTBYP25 (-D2-FO),0 /* 0.25 */
176 #define BOTBYP3 -D3,0 /* 0.3 */
177 #define BOTBYP33 (-K1/6),0 /* 0.3333... */
178 #define BOTBYP375 -D4,0 /* 0.4 */
179 #define BOTBYP4 -D4,0 /* 0.4 */
180 #define BOTBYP5 -D5,0 /* 0.5 */
181 #define BOTBYP6 -D6,0 /* 0.6 */
182 #define BOTBYP66 (-K1/3),0 /* 0.6666... */
183 #define BOTBYP7 -D7,0 /* 0.7 */
184 #define BOTBYP75 (-D7-FO),0 /* 0.75 */
185 #define BOTBYP8 -D8,0 /* 0.8 */
186 #define BOTBYP875 -D9,0 /* 0.9 */ /* wanted 0.875 but can't */
187 #define BOTBYP9 -D9,0 /* 0.9 */
188
189 /* this much from the center to the top edge */
190 #define TOPBYP1 D1,0 /* 0.1 */
191 #define TOPBYP2 D2,0 /* 0.2 */
192 #define TOPBYP25 (D2+FO),0 /* 0.25 */
193 #define TOPBYP3 D3,0 /* 0.3 */
194 #define TOPBYP33 (K1/6),0 /* 0.3333... */
195 #define TOPBYP4 D4,0 /* 0.4 */
196 #define TOPBYP5 D5,0 /* 0.5 */
197 #define TOPBYP5833 35,0 /* 0.58333... (35/60) */
198 #define TOPBYP6 D6,0 /* 0.6 */
199 #define TOPBYP66 (K1/3),0 /* 0.6666... */
200 #define TOPBYP7 D7,0 /* 0.7 */
201 #define TOPBYP75 45,0 /* 0.75 (45/60) */
202 #define TOPBYP8 D8,0 /* 0.8 */
203 #define TOPBYP866 (K1/12*5),0 /* 0.8666... */
204 #define TOPBYP875 D9,0 /* 0.9 */ /* wanted 0.875 but can't */
205 #define TOPBYP9 D9,0 /* 0.9 */
206
207 /* the options table */
208 static COMCOMP schnegp = {NOKEYWORD, NOTOPLIST, NONEXTLIST, NOPARAMS,
209 0, x_(" \t"), M_("size of negating bubble"), M_("show current size")};
210 static KEYWORD schopt[] =
211 {
212 {x_("negating-bubble-diameter"), 1,{&schnegp,NOKEY,NOKEY,NOKEY,NOKEY}},
213 {x_("disable-differential-ports"), 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
214 {x_("enable-differential-ports"), 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
215 TERMKEY
216 };
217 COMCOMP sch_parse = {schopt, NOTOPLIST, NONEXTLIST, NOPARAMS,
218 0, x_(" \t"), M_("Schematic option"), M_("show current options")};
219
220 TECHNOLOGY *sch_tech;
221 INTBIG sch_meterkey; /* key for "SCHEM_meter_type" */
222 INTBIG sch_diodekey; /* key for "SCHEM_diode" */
223 INTBIG sch_capacitancekey; /* key for "SCHEM_capacitance" */
224 INTBIG sch_resistancekey; /* key for "SCHEM_resistance" */
225 INTBIG sch_inductancekey; /* key for "SCHEM_inductance" */
226 INTBIG sch_functionkey; /* key for "SCHEM_function" */
227 INTBIG sch_spicemodelkey; /* key for "SIM_spice_model" */
228 INTBIG sch_globalnamekey; /* key for "SCHEM_global_name" */
229 NODEPROTO *sch_wirepinprim, *sch_buspinprim, *sch_wireconprim, *sch_bufprim,
230 *sch_andprim, *sch_orprim, *sch_xorprim, *sch_ffprim, *sch_muxprim,
231 *sch_bboxprim, *sch_switchprim, *sch_offpageprim, *sch_pwrprim,
232 *sch_gndprim, *sch_sourceprim, *sch_transistorprim, *sch_resistorprim,
233 *sch_capacitorprim, *sch_diodeprim, *sch_inductorprim, *sch_meterprim,
234 *sch_wellprim, *sch_substrateprim, *sch_twoportprim, *sch_transistor4prim,
235 *sch_globalprim;
236 ARCPROTO *sch_wirearc, *sch_busarc;
237 static INTBIG sch_bubblediameter = K1+D4;
238
239 typedef struct
240 {
241 /* for arc drawing */
242 INTBIG bubblebox, arrowbox;
243
244 /* for node drawing */
245 TECH_POLYGON *layerlist;
246
247 /* control of the bar in a switch node */
248 INTBIG switchbarvalue;
249
250 /* control of the bus pin node */
251 INTBIG buspinlayer;
252 INTBIG buspinsize;
253 INTBIG *buspinpoints;
254
255 /* for extra steiner points on nodes */
256 INTBIG extrasteinerpoint;
257 TECH_PORTS *extrasteinerport[10];
258 } SCHPOLYLOOP;
259 static SCHPOLYLOOP sch_oneprocpolyloop;
260
261 static PORTPROTO *sch_anddiffports, *sch_ordiffports, *sch_xordiffports;
262 INTBIG sch_wirepinsizex; /* X size if wire-pin primitives */
263 INTBIG sch_wirepinsizey; /* Y size if wire-pin primitives */
264
265 INTBIG sch_intnodepolys(NODEINST *ni, INTBIG *reasonable, WINDOWPART *win, POLYLOOP *pl, SCHPOLYLOOP *schpl);
266 void sch_intshapenodepoly(NODEINST *ni, INTBIG box, POLYGON *poly, POLYLOOP *pl, SCHPOLYLOOP *schpl);
267 INTBIG sch_intarcpolys(ARCINST *ai, WINDOWPART *win, POLYLOOP *pl, SCHPOLYLOOP *schpl);
268 void sch_intshapearcpoly(ARCINST *ai, INTBIG box, POLYGON *poly, POLYLOOP *pl, SCHPOLYLOOP *schpl);
269
270 /******************** LAYERS ********************/
271
272 #define MAXLAYERS 4 /* total layers below */
273
274 #define LARC 0 /* wire */
275 #define LBUS 1 /* bus */
276 #define LNODE 2 /* schematic block and pin */
277 #define LTEXT 3 /* documentation */
278
279 static GRAPHICS sch_a_lay = {LAYERO,BLUE, SOLIDC, SOLIDC,
280 {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
281 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF}, NOVARIABLE, 0};
282 static GRAPHICS sch_b_lay = {LAYERT3,COLORT3, SOLIDC, PATTERNED,
283 /* bus layer */ {0x2222, /* X X X X */
284 0x0000, /* */
285 0x8888, /* X X X X */
286 0x0000, /* */
287 0x2222, /* X X X X */
288 0x0000, /* */
289 0x8888, /* X X X X */
290 0x0000, /* */
291 0x2222, /* X X X X */
292 0x0000, /* */
293 0x8888, /* X X X X */
294 0x0000, /* */
295 0x2222, /* X X X X */
296 0x0000, /* */
297 0x8888, /* X X X X */
298 0x0000}, /* */
299 NOVARIABLE, 0};
300 static GRAPHICS sch_n_lay = {LAYERO, RED, SOLIDC, SOLIDC,
301 {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
302 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF}, NOVARIABLE, 0};
303 static GRAPHICS sch_t_lay = {LAYERO, CELLTXT, SOLIDC, SOLIDC,
304 {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
305 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF}, NOVARIABLE, 0};
306
307 /* these tables must be updated together */
308 GRAPHICS *sch_layers[MAXLAYERS+1] = {&sch_a_lay, &sch_b_lay, &sch_n_lay,
309 &sch_t_lay, NOGRAPHICS};
310 static CHAR *sch_layer_names[MAXLAYERS] = {x_("Arc"), x_("Bus"), x_("Node"), x_("Text")};
311 static INTBIG sch_layer_function[MAXLAYERS] = {LFMETAL1, LFBUS, LFART, LFART};
312 static CHAR *sch_layer_letters[MAXLAYERS] = {x_("a"), x_("b"), x_("n"), x_("t")};
313
314 /******************** ARCS ********************/
315
316 #define ARCPROTOCOUNT 2
317
318 #define AWIRE 0 /* wire */
319 #define ABUS 1 /* bus */
320
321 /* wire arc */
322 static TECH_ARCLAY sch_al_w[] = { {LARC,0,FILLED}, {LARC,0,CIRCLE}, {LARC,0,VECTORS}};
323 static TECH_ARCS sch_a_w = {
324 x_("wire"),0,AWIRE,NOARCPROTO, /* name */
325 1,sch_al_w, /* layers */
326 (APMETAL1<<AFUNCTIONSH)|WANTFIXANG|WANTCANTSLIDE|(45<<AANGLEINCSH)}; /* userbits */
327
328 /* bus arc */
329 static TECH_ARCLAY sch_al_b[] = { {LBUS,0,FILLED}, {LBUS,0,CIRCLE}, {LARC,0,VECTORS}};
330 static TECH_ARCS sch_a_b = {
331 x_("bus"),K1,ABUS,NOARCPROTO, /* name */
332 1,sch_al_b, /* layers */
333 (APBUS<<AFUNCTIONSH)|WANTFIXANG|WANTCANTSLIDE|WANTNOEXTEND|(45<<AANGLEINCSH)}; /* userbits */
334
335 TECH_ARCS *sch_arcprotos[ARCPROTOCOUNT+1] = {&sch_a_w, &sch_a_b, ((TECH_ARCS *)-1)};
336
337 /******************** PORTINST CONNECTIONS ********************/
338
339 /* these values are replaced with actual arcproto addresses */
340 static INTBIG sch_pc_wire[] = {-1, AWIRE, ALLGEN, -1};
341 static INTBIG sch_pc_bus[] = {-1, ABUS, ALLGEN, -1};
342 static INTBIG sch_pc_either[] = {-1, AWIRE, ABUS, ALLGEN, -1};
343
344 /******************** NODES ********************/
345
346 #define NODEPROTOCOUNT 26
347
348 #define NWIREPIN 1 /* wire pin */
349 #define NBUSPIN 2 /* bus pin */
350 #define NWIRECON 3 /* wire connector */
351 #define NBUF 4 /* general BUFFER */
352 #define NAND 5 /* general AND */
353 #define NOR 6 /* general OR */
354 #define NXOR 7 /* general XOR */
355 #define NFF 8 /* general FLIP FLOP */
356 #define NMUX 9 /* general MUX */
357 #define NBBOX 10 /* black box */
358 #define NSWITCH 11 /* switch */
359 #define NOFFPAGE 12 /* off page connector */
360 #define NPWR 13 /* power */
361 #define NGND 14 /* ground */
362 #define NSOURCE 15 /* source (voltage, current) */
363 #define NTRANSISTOR 16 /* transistor */
364 #define NRESISTOR 17 /* resistor */
365 #define NCAPACITOR 18 /* capacitor */
366 #define NDIODE 19 /* diode */
367 #define NINDUCTOR 20 /* inductor */
368 #define NMETER 21 /* meter */
369 #define NWELL 22 /* well connection */
370 #define NSUBSTRATE 23 /* substrate connection */
371 #define NTWOPORT 24 /* generic two-port block */
372 #define NTRANSISTOR4 25 /* four-port transistor */
373 #define NGLOBALSIG 26 /* global signal */
374
375 /******************** POLYGONS ********************/
376
377 static CHAR sch_NULLSTR[] = {x_("")};
378 static CHAR sch_D[] = {x_("D")};
379 static CHAR sch_E[] = {x_("E")};
380 static CHAR sch_J[] = {x_("J")};
381 static CHAR sch_K[] = {x_("K")};
382 static CHAR sch_Q[] = {x_("Q")};
383 static CHAR sch_R[] = {x_("R")};
384 static CHAR sch_S[] = {x_("S")};
385 static CHAR sch_T[] = {x_("T")};
386 static CHAR sch_V[] = {x_("V")};
387 static CHAR sch_PR[] = {x_("PR")};
388 static CHAR sch_QB[] = {x_("QB")};
389
390 static INTBIG sch_g_pindisc[] = {CENTER, CENTER, RIGHTEDGE, CENTER};
391 static INTBIG sch_g_buspindisc[] = {CENTER, CENTER, RIGHTBYP5, CENTER};
392 static INTBIG sch_g_bustapdisc[] = {CENTER, CENTER, RIGHTBYP25,CENTER};
393 static CHAR *sch_g_wireconj[] = {0, 0, 0, 0, sch_J};
394 static INTBIG sch_g_inv[] = {RIGHTBYP66,CENTER, LEFTEDGE, TOPBYP875,
395 LEFTEDGE, BOTBYP875};
396 static INTBIG sch_g_and[] = {CENTERR0H, CENTER, CENTERR0H, CENTERU3,
397 CENTERR0H, CENTERD3};
398 static INTBIG sch_g_andbox[] = {CENTERR0H, CENTERU3, CENTERL4, CENTERU3,
399 CENTERL4, TOPEDGE, CENTERL4, BOTEDGE,
400 CENTERL4, CENTERD3, CENTERR0H, CENTERD3};
401 static INTBIG sch_g_or[] = {CENTERL4, TOPEDGE, CENTERL4, CENTERU3,
402 CENTERL4, CENTERU3, CENTERL0T, CENTERU3,
403 CENTERL4, BOTEDGE, CENTERL4, CENTERD3,
404 CENTERL4, CENTERD3, CENTERL0T, CENTERD3};
405 static INTBIG sch_g_ort[] = {CENTERL0T, CENTERD3, CENTERL0T, CENTERU3,
406 CENTERR4H, CENTER};
407 static INTBIG sch_g_orb[] = {CENTERL0T, CENTERU3, CENTERR4H, CENTER,
408 CENTERL0T, CENTERD3};
409 static INTBIG sch_g_orl[] = {CENTERL9, CENTER, CENTERL4, CENTERU3,
410 CENTERL4, CENTERD3};
411 static INTBIG sch_g_xor[] = {CENTERL10, CENTER, CENTERL5, CENTERU3,
412 CENTERL5, CENTERD3};
413 static INTBIG sch_g_ffbox[] = {LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE};
414 static INTBIG sch_g_ffarrow[] = {LEFTEDGE, BOTBYP2, LEFTBYP7, CENTER,
415 LEFTEDGE, TOPBYP2};
416 static CHAR *sch_g_fftextd[] = {(CHAR *)-H0, 0, (CHAR *)D4,0, (CHAR *)-H0, 0, (CHAR *)D8,0,
417 (CHAR *)-D4,0, (CHAR *)D8,0, (CHAR *)-D4,0, (CHAR *)D4,0,
418 sch_D};
419 static CHAR *sch_g_fftexte[] = {(CHAR *)-H0, 0, (CHAR *)-D4,0, (CHAR *)-H0, 0, (CHAR *)-D8,0,
420 (CHAR *)-D4,0, (CHAR *)-D8,0, (CHAR *)-D4,0, (CHAR *)-D4,0,
421 sch_E};
422 static CHAR *sch_g_fftextq[] = {(CHAR *)H0, 0, (CHAR *)D4,0, (CHAR *)H0, 0, (CHAR *)D8,0,
423 (CHAR *)D4,0, (CHAR *)D8,0, (CHAR *)D4,0, (CHAR *)D4,0,
424 sch_Q};
425 static CHAR *sch_g_fftextqb[] = {(CHAR *)H0, 0, (CHAR *)-D4,0, (CHAR *)H0, 0, (CHAR *)-D8,0,
426 (CHAR *)D4,0, (CHAR *)-D8,0, (CHAR *)D4,0, (CHAR *)-D4,0,
427 sch_QB};
428 static CHAR *sch_g_fftextpr[] = {(CHAR *)-D6,0, (CHAR *)D6,0, (CHAR *)-D6,0, (CHAR *)H0, 0,
429 (CHAR *)D6,0, (CHAR *)H0, 0, (CHAR *)D6,0, (CHAR *)D6,0,
430 sch_PR};
431 static CHAR *sch_g_fftextclr[] = {(CHAR *)-D6,0, (CHAR *)-D6,0, (CHAR *)-D6,0, (CHAR *)-H0, 0,
432 (CHAR *)D6,0, (CHAR *)-H0, 0, (CHAR *)D6,0, (CHAR *)-D6,0,
433 0 /* "CLR" */};
434 static CHAR *sch_g_meterv[] = {(CHAR *)-H0, 0, (CHAR *)-H0, 0, (CHAR *)H0, 0, (CHAR *)H0, 0,
435 sch_V};
436 static INTBIG sch_g_ffn[] = {LEFTBYP6, TOPBYP2, LEFTBYP4, TOPBYP2,
437 LEFTBYP4, BOTBYP2, LEFTBYP2, BOTBYP2};
438 static INTBIG sch_g_ffp[] = {LEFTBYP6, BOTBYP2, LEFTBYP4, BOTBYP2,
439 LEFTBYP4, TOPBYP2, LEFTBYP2, TOPBYP2};
440 static INTBIG sch_g_ffms[] = {LEFTBYP6, BOTBYP2, LEFTBYP4, BOTBYP2,
441 LEFTBYP4, TOPBYP2, LEFTBYP2, TOPBYP2,
442 LEFTBYP2, BOTBYP2, CENTER, BOTBYP2};
443 static INTBIG sch_g_mux[] = {RIGHTBYP8, TOPBYP75, RIGHTBYP8, BOTBYP75,
444 LEFTBYP8, BOTEDGE, LEFTBYP8, TOPEDGE};
445 static INTBIG sch_g_bbox[] = {LEFTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE};
446 static INTBIG sch_g_switchin[] = {RIGHTIN1, CENTER, RIGHTIN1Q, CENTER};
447 static INTBIG sch_g_switchbar[] = {RIGHTIN1, CENTER, LEFTIN1, CENTER};
448 static INTBIG sch_g_switchout[] = {LEFTIN1, BOTIN0H, LEFTIN0T, BOTIN0H};
449 static INTBIG sch_g_offpage[] = {LEFTEDGE, BOTEDGE, LEFTEDGE, TOPEDGE,
450 RIGHTBYP5, TOPEDGE, RIGHTEDGE, CENTER,
451 RIGHTBYP5, BOTEDGE};
452 static INTBIG sch_g_pwr1[] = {CENTER, CENTER, CENTER, TOPEDGE};
453 static INTBIG sch_g_pwr2[] = {CENTER, CENTER, CENTER, TOPBYP75};
454 static INTBIG sch_g_gnd[] = {CENTER, CENTER, CENTER, TOPEDGE,
455 LEFTEDGE, CENTER, RIGHTEDGE, CENTER,
456 LEFTBYP75, BOTBYP25, RIGHTBYP75,BOTBYP25,
457 LEFTBYP5, BOTBYP5, RIGHTBYP5, BOTBYP5,
458 LEFTBYP25, BOTBYP75, RIGHTBYP25,BOTBYP75,
459 CENTER, BOTEDGE, CENTER, BOTEDGE};
460 static INTBIG sch_g_resist[] = {LEFTBYP66, CENTER, LEFTBYP6, CENTER,
461 LEFTBYP5, TOPEDGE, LEFTBYP3, BOTEDGE,
462 LEFTBYP1, TOPEDGE, RIGHTBYP1, BOTEDGE,
463 RIGHTBYP3, TOPEDGE, RIGHTBYP5, BOTEDGE,
464 RIGHTBYP6, CENTER, RIGHTBYP66,CENTER};
465 static INTBIG sch_g_capac[] = {LEFTEDGE, TOPBYP2, RIGHTEDGE, TOPBYP2,
466 LEFTEDGE, BOTBYP2, RIGHTEDGE, BOTBYP2,
467 CENTER, TOPBYP2, CENTER, TOPEDGE,
468 CENTER, BOTBYP2, CENTER, BOTEDGE};
469 static INTBIG sch_g_capace[] = {RIGHTBYP2, BOTBYP6, RIGHTBYP6, BOTBYP6,
470 RIGHTBYP4, BOTBYP4, RIGHTBYP4, BOTBYP8};
471 static INTBIG sch_g_source[] = {CENTER, CENTER, RIGHTEDGE, CENTER};
472 static INTBIG sch_g_sourcepl[] = {LEFTBYP3, TOPBYP6, RIGHTBYP3, TOPBYP6,
473 CENTER, TOPBYP3, CENTER, TOPBYP9};
474 static INTBIG sch_g_mos[] = {LEFTEDGE, BOTEDGE, LEFTBYP75, BOTEDGE,
475 LEFTBYP75, BOTBYP5, RIGHTBYP75,BOTBYP5,
476 RIGHTBYP75,BOTEDGE, RIGHTEDGE, BOTEDGE};
477 static INTBIG sch_g_trantop[] = {LEFTBYP75, BOTBYP25, RIGHTBYP75,BOTBYP25};
478 static INTBIG sch_g_nmos[] = {CENTER, BOTBYP25, CENTER, TOPIN1};
479 static INTBIG sch_g_nmos4[] = {LEFTBYP5, BOTBYP5, LEFTBYP5, BOTEDGE,
480 LEFTBYP5, BOTBYP5, LEFTBYP35, BOTBYP75,
481 LEFTBYP5, BOTBYP5, LEFTBYP66, BOTBYP75};
482 static INTBIG sch_g_dmos4[] = {LEFTBYP5, BOTBYP75, LEFTBYP5, BOTEDGE,
483 LEFTBYP5, BOTBYP75, LEFTBYP35, BOTBYP9,
484 LEFTBYP5, BOTBYP75, LEFTBYP66, BOTBYP9};
485 static INTBIG sch_g_pmos4[] = {LEFTBYP5, BOTBYP5, LEFTBYP5, BOTEDGE,
486 LEFTBYP5, BOTEDGE, LEFTBYP35, BOTBYP75,
487 LEFTBYP5, BOTEDGE, LEFTBYP66, BOTBYP75};
488 static INTBIG sch_g_bip4[] = {LEFTBYP5, BOTEDGE, CENTER, BOTBYP25};
489 static INTBIG sch_g_nmes4[] = {LEFTBYP5, BOTBYP25, LEFTBYP5, BOTEDGE,
490 LEFTBYP5, BOTBYP25, LEFTBYP35, BOTBYP5,
491 LEFTBYP5, BOTBYP25, LEFTBYP66, BOTBYP5};
492 static INTBIG sch_g_pmes4[] = {LEFTBYP5, BOTBYP25, LEFTBYP5, BOTEDGE,
493 LEFTBYP5, BOTEDGE, LEFTBYP35, BOTBYP75,
494 LEFTBYP5, BOTEDGE, LEFTBYP66, BOTBYP75};
495 static INTBIG sch_g_pmos[] = {CENTER, TOPBYP25, CENTER, TOPIN1};
496 static INTBIG sch_g_pmoscir[] = {CENTER, CENTER, CENTER, BOTBYP25};
497 static INTBIG sch_g_dmos[] = {LEFTBYP75, BOTBYP75, RIGHTBYP75,BOTBYP5};
498 static INTBIG sch_g_btran1[] = {LEFTEDGE, BOTEDGE, LEFTBYP75, BOTEDGE,
499 LEFTBYP25, BOTBYP25, RIGHTBYP25,BOTBYP25,
500 RIGHTBYP75,BOTEDGE, RIGHTEDGE, BOTEDGE};
501 static INTBIG sch_g_btran2[] = {LEFTBYP75, BOTBYP75, LEFTBYP75, BOTEDGE,
502 LEFTBYP5, BOTBYP875};
503 static INTBIG sch_g_btran3[] = {LEFTBYP5, BOTBYP375, LEFTBYP25, BOTBYP25,
504 LEFTBYP25, BOTBYP5};
505 static INTBIG sch_g_btran4[] = {LEFTEDGE, BOTEDGE, LEFTBYP75, BOTEDGE,
506 LEFTBYP75, BOTEDGE, LEFTBYP75, BOTBYP25,
507 LEFTBYP875,BOTBYP25, RIGHTBYP875,BOTBYP25,
508 RIGHTBYP75,BOTBYP25, RIGHTBYP75,BOTEDGE,
509 RIGHTBYP75,BOTEDGE, RIGHTEDGE, BOTEDGE};
510 static INTBIG sch_g_btran5[] = {LEFTBYP125,CENTER, CENTER, BOTBYP25,
511 RIGHTBYP125,CENTER};
512 static INTBIG sch_g_btran6[] = {LEFTBYP125,CENTER, CENTER, TOPBYP25,
513 RIGHTBYP125,CENTER};
514 static INTBIG sch_g_btran7[] = {LEFTEDGE, BOTEDGE, LEFTBYP75, BOTEDGE,
515 LEFTBYP75, BOTEDGE, LEFTBYP75, BOTBYP25,
516 LEFTBYP875,BOTBYP25, LEFTBYP5, BOTBYP25,
517 LEFTBYP25, BOTBYP25, RIGHTBYP25,BOTBYP25,
518 RIGHTBYP5, BOTBYP25, RIGHTBYP875,BOTBYP25,
519 RIGHTBYP75,BOTBYP25, RIGHTBYP75,BOTEDGE,
520 RIGHTBYP75,BOTEDGE, RIGHTEDGE, BOTEDGE};
521 static INTBIG sch_g_diode1[] = {LEFTEDGE, TOPBYP5, RIGHTEDGE, TOPBYP5,
522 CENTER, TOPBYP5, CENTER, TOPEDGE,
523 CENTER, BOTBYP5, CENTER, BOTEDGE};
524 static INTBIG sch_g_diode2[] = {LEFTEDGE, BOTBYP5, RIGHTEDGE, BOTBYP5,
525 CENTER, TOPBYP5};
526 static INTBIG sch_g_diode3[] = {LEFTEDGE, TOPBYP75, LEFTEDGE, TOPBYP5,
527 LEFTEDGE, TOPBYP5, RIGHTEDGE, TOPBYP5,
528 RIGHTEDGE, TOPBYP5, RIGHTEDGE, TOPBYP25,
529 CENTER, TOPBYP5, CENTER, TOPEDGE,
530 CENTER, BOTBYP5, CENTER, BOTEDGE};
531 static INTBIG sch_g_induct1[] = {CENTER, TOPEDGE, CENTER, BOTEDGE};
532 static INTBIG sch_g_induct2[] = {LEFTBYP5, TOPBYP33, CENTER, TOPBYP33};
533 static INTBIG sch_g_induct3[] = {LEFTBYP5, CENTER, CENTER, CENTER};
534 static INTBIG sch_g_induct4[] = {LEFTBYP5, BOTBYP33, CENTER, BOTBYP33};
535 static INTBIG sch_g_meter[] = {CENTER, CENTER, RIGHTEDGE, CENTER};
536 static INTBIG sch_g_well[] = {LEFTEDGE, BOTEDGE, RIGHTEDGE, BOTEDGE,
537 CENTER, TOPEDGE, CENTER, BOTEDGE};
538 static INTBIG sch_g_global1[] = {LEFTEDGE, CENTER, CENTER, TOPEDGE,
539 RIGHTEDGE, CENTER, CENTER, BOTEDGE};
540 static INTBIG sch_g_global2[] = {LEFTBYP9, CENTER, CENTER, TOPBYP9,
541 RIGHTBYP9, CENTER, CENTER, BOTBYP9};
542 static INTBIG sch_g_substrate[] = {CENTER, CENTER, CENTER, TOPEDGE,
543 LEFTEDGE, CENTER, RIGHTEDGE, CENTER,
544 LEFTEDGE, CENTER, CENTER, BOTEDGE,
545 RIGHTEDGE, CENTER, CENTER, BOTEDGE};
546
547 static INTBIG sch_g_twocsarr[] = {RIGHTBYP3833,TOPBYP33,RIGHTBYP3833,BOTBYP33,
548 RIGHTBYP3833,BOTBYP33,RIGHTBYP33,BOTBYP166,
549 RIGHTBYP3833,BOTBYP33,RIGHTBYP433,BOTBYP166};
550 static INTBIG sch_g_twoulpl[] = {LEFTBYP35, TOPBYP66, LEFTBYP45, TOPBYP66,
551 LEFTBYP4, TOPBYP5833,LEFTBYP4, TOPBYP75};
552 static INTBIG sch_g_twourpl[] = {RIGHTBYP35,TOPBYP66, RIGHTBYP45,TOPBYP66,
553 RIGHTBYP4, TOPBYP5833,RIGHTBYP4, TOPBYP75};
554 static INTBIG sch_g_twourrpl[] = {RIGHTBYP5166,TOPBYP66,RIGHTBYP6166,TOPBYP66,
555 RIGHTBYP566,TOPBYP5833,RIGHTBYP566,TOPBYP75};
556 static INTBIG sch_g_twobox[] = {LEFTBYP8, BOTEDGE, RIGHTBYP8, TOPEDGE};
557 static INTBIG sch_g_twogwire[] = {LEFTEDGE, TOPBYP66, LEFTBYP8, TOPBYP66,
558 LEFTEDGE, BOTBYP66, LEFTBYP8, BOTBYP66,
559 RIGHTEDGE, TOPBYP66, RIGHTBYP8, TOPBYP66,
560 RIGHTEDGE, BOTBYP66, RIGHTBYP8, BOTBYP66};
561 static INTBIG sch_g_twonormwire[]= {LEFTEDGE, TOPBYP66, LEFTBYP6, TOPBYP66,
562 LEFTEDGE, BOTBYP66, LEFTBYP6, BOTBYP66,
563 RIGHTEDGE, TOPBYP66, RIGHTBYP6, TOPBYP66,
564 RIGHTBYP6, TOPBYP66, RIGHTBYP6, TOPBYP3,
565 RIGHTEDGE, BOTBYP66, RIGHTBYP6, BOTBYP66,
566 RIGHTBYP6, BOTBYP66, RIGHTBYP6, BOTBYP3};
567 static INTBIG sch_g_twoccwire[] = {LEFTBYP6, TOPBYP66, LEFTBYP6, BOTBYP66};
568 static INTBIG sch_g_twocswire[] = {RIGHTBYP6, TOPBYP3, RIGHTBYP45,CENTER,
569 RIGHTBYP45,CENTER, RIGHTBYP6, BOTBYP3,
570 RIGHTBYP6, BOTBYP3, RIGHTBYP75,CENTER,
571 RIGHTBYP75,CENTER, RIGHTBYP6, TOPBYP3};
572 static INTBIG sch_g_twovsc[] = {RIGHTBYP6, CENTER, RIGHTBYP6, TOPBYP3};
573 static INTBIG sch_g_twotr1[] = {CENTER, CENTER, LEFTBYP8, BOTEDGE,
574 LEFTBYP8, TOPEDGE};
575 static INTBIG sch_g_twotr2[] = {LEFTBY1P6, CENTER, LEFTBYP8, TOPEDGE,
576 LEFTBYP8, BOTEDGE};
577 static INTBIG sch_g_twotr3[] = {CENTER, CENTER, RIGHTBYP8, TOPEDGE,
578 RIGHTBYP8, BOTEDGE};
579 static INTBIG sch_g_twotrbox[] = {LEFTBYP8, TOPEDGE, RIGHTBYP8, TOPEDGE,
580 LEFTBYP8, BOTEDGE, RIGHTBYP8, BOTEDGE};
581 static INTBIG sch_g_twotrwire[] = {LEFTEDGE, TOPBYP66, LEFTBYP8, TOPBYP66,
582 LEFTEDGE, BOTBYP66, LEFTBYP8, BOTBYP66,
583 RIGHTEDGE, TOPBYP66, RIGHTBYP9, TOPBYP66,
584 RIGHTEDGE, BOTBYP66, RIGHTBYP9, BOTBYP66};
585
586 /******************** NODES ********************/
587
588 /* wire-pin */
589 static TECH_PORTS sch_wirepin_p[] = { /* ports */
590 {sch_pc_wire, x_("wire"), NOPORTPROTO, (180<<PORTARANGESH),
591 CENTER, CENTER, CENTER, CENTER}};
592 static TECH_POLYGON sch_wirepin_l[] = { /* layers */
593 {LARC, 0, 2, DISC, POINTS, sch_g_pindisc}};
594 static TECH_NODES sch_wirepin = {
595 x_("Wire_Pin"),NWIREPIN,NONODEPROTO, /* name */
596 H0,H0, /* size */
597 1,sch_wirepin_p, /* ports */
598 1,sch_wirepin_l, /* layers */
599 (NPPIN<<NFUNCTIONSH)|NSQUARE|WIPEON1OR2, /* userbits */
600 0,0,0,0,0,0,0,0,0}; /* characteristics */
601
602 /* bus-pin */
603 static TECH_PORTS sch_buspin_p[] = { /* ports */
604 {sch_pc_either, x_("bus"), NOPORTPROTO, (180<<PORTARANGESH),
605 CENTER, CENTER, CENTER, CENTER}};
606 static TECH_POLYGON sch_buspin_l[] = { /* layers */
607 {LBUS, 0, 2, DISC, POINTS, sch_g_buspindisc},
608 {LARC, 0, 2, DISC, POINTS, sch_g_bustapdisc}};
609 static TECH_NODES sch_buspin = {
610 x_("Bus_Pin"),NBUSPIN,NONODEPROTO, /* name */
611 K2,K2, /* size */
612 1,sch_buspin_p, /* ports */
613 2,sch_buspin_l, /* layers */
614 (NPPIN<<NFUNCTIONSH)|NSQUARE|WIPEON1OR2|NHASOPA|(1<<NFIRSTOPASH), /* userbits */
615 0,0,0,0,0,0,0,0,0}; /* characteristics */
616
617 /* wire-con */
618 static TECH_PORTS sch_wirecon_p[] = { /* ports */
619 {sch_pc_either, x_("wire"), NOPORTPROTO, (180<<PORTARANGESH)|PORTISOLATED,
620 LEFTIN0H, BOTIN0H, RIGHTIN0H, TOPIN0H}};
621 static TECH_POLYGON sch_wirecon_l[] = { /* layers */
622 {LNODE, 0, 4, CLOSEDRECT, BOX, sch_g_bbox},
623 {LTEXT, TXTSETQLAMBDA(8), 1, TEXTCENT, POINTS, (INTBIG *)sch_g_wireconj}};
624 static TECH_NODES sch_wirecon = {
625 x_("Wire_Con"),NWIRECON,NONODEPROTO, /* name */
626 K2,K2, /* size */
627 1,sch_wirecon_p, /* ports */
628 2,sch_wirecon_l, /* layers */
629 (NPCONNECT<<NFUNCTIONSH), /* userbits */
630 0,0,0,0,0,0,0,0,0}; /* characteristics */
631
632 /* general buffer */
633 static TECH_PORTS sch_buf_p[] = { /* ports */
634 {sch_pc_either, x_("a"), NOPORTPROTO, (180<<PORTANGLESH)|(0<<PORTARANGESH)|
635 (0<<PORTNETSH)|INPORT, LEFTEDGE, CENTER, LEFTEDGE, CENTER},
636 {sch_pc_wire, x_("c"), NOPORTPROTO, (270<<PORTANGLESH)|(0<<PORTARANGESH)|
637 (1<<PORTNETSH)|INPORT, CENTER, BOTBYP33, CENTER, BOTBYP33},
638 {sch_pc_either, x_("y"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
639 (2<<PORTNETSH)|OUTPORT, RIGHTBYP66, CENTER, RIGHTBYP66, CENTER}};
640 static TECH_POLYGON sch_buf_l[] = { /* layers */
641 {LNODE, 0, 3, CLOSED, POINTS, sch_g_inv}};
642 static TECH_NODES sch_buf = {
643 x_("Buffer"), NBUF, NONODEPROTO, /* name */
644 K6,K6, /* size */
645 3,sch_buf_p, /* ports */
646 1,sch_buf_l, /* layers */
647 (NPBUFFER<<NFUNCTIONSH), /* userbits */
648 0,0,0,0,0,0,0,0,0}; /* characteristics */
649
650 /* general and */
651 static TECH_PORTS sch_and_p[] = { /* ports */
652 {sch_pc_either, x_("a"), NOPORTPROTO, (180<<PORTANGLESH)|(0<<PORTARANGESH)|
653 (0<<PORTNETSH)|INPORT|PORTISOLATED, CENTERL4,BOTEDGE,CENTERL4,TOPEDGE},
654 {sch_pc_either, x_("y"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
655 (1<<PORTNETSH)|OUTPORT, CENTERR3H, CENTER, CENTERR3H, CENTER},
656 {sch_pc_either, x_("yt"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
657 (2<<PORTNETSH)|OUTPORT, CENTERR2T, CENTERU2, CENTERR2T, CENTERU2},
658 {sch_pc_either, x_("yc"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
659 (3<<PORTNETSH)|OUTPORT, CENTERR2T, CENTERD2, CENTERR2T, CENTERD2}};
660 static TECH_POLYGON sch_and_l[] = { /* layers */
661 {LNODE, 0, 3, CIRCLEARC, POINTS, sch_g_and},
662 {LNODE, 0, 6, OPENED, POINTS, sch_g_andbox}};
663 static TECH_NODES sch_and = {
664 x_("And"), NAND, NONODEPROTO, /* name */
665 K8,K6, /* size */
666 4,sch_and_p, /* ports */
667 2,sch_and_l, /* layers */
668 (NPGATEAND<<NFUNCTIONSH), /* userbits */
669 0,0,0,0,0,0,0,0,0}; /* characteristics */
670
671 /* general or */
672 static TECH_PORTS sch_or_p[] = { /* ports */
673 {sch_pc_either, x_("a"), NOPORTPROTO, (180<<PORTANGLESH)|(0<<PORTARANGESH)|
674 (0<<PORTNETSH)|INPORT|PORTISOLATED, CENTERL4,BOTEDGE, CENTERL3,TOPEDGE},
675 {sch_pc_either, x_("y"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
676 (1<<PORTNETSH)|OUTPORT, CENTERR4H, CENTER, CENTERR4H, CENTER},
677 {sch_pc_either, x_("yt"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
678 (2<<PORTNETSH)|OUTPORT, CENTERR2+D13, CENTERU2, CENTERR2+D13, CENTERU2},
679 {sch_pc_either, x_("yc"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
680 (3<<PORTNETSH)|OUTPORT, CENTERR2+D13, CENTERD2, CENTERR2+D13, CENTERD2}};
681 static TECH_POLYGON sch_or_l[] = { /* layers */
682 {LNODE, 0, 3, CIRCLEARC, POINTS, sch_g_orl},
683 {LNODE, 0, 3, CIRCLEARC, POINTS, sch_g_ort},
684 {LNODE, 0, 3, CIRCLEARC, POINTS, sch_g_orb},
685 {LNODE, 0, 8, VECTORS, POINTS, sch_g_or}};
686 static TECH_NODES sch_or = {
687 x_("Or"), NOR, NONODEPROTO, /* name */
688 K10,K6, /* size */
689 4,sch_or_p, /* ports */
690 4,sch_or_l, /* layers */
691 (NPGATEOR<<NFUNCTIONSH), /* userbits */
692 0,0,0,0,0,0,0,0,0}; /* characteristics */
693
694 /* general xor */
695 static TECH_PORTS sch_xor_p[] = { /* ports */
696 {sch_pc_either, x_("a"), NOPORTPROTO, (180<<PORTANGLESH)|(0<<PORTARANGESH)|
697 (0<<PORTNETSH)|INPORT|PORTISOLATED, CENTERL4,BOTEDGE, CENTERL3,TOPEDGE},
698 {sch_pc_either, x_("y"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
699 (1<<PORTNETSH)|OUTPORT, CENTERR4H, CENTER, CENTERR4H, CENTER},
700 {sch_pc_either, x_("yt"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
701 (2<<PORTNETSH)|OUTPORT, CENTERR2+D13, CENTERU2, CENTERR2+D13, CENTERU2},
702 {sch_pc_either, x_("yc"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
703 (3<<PORTNETSH)|OUTPORT, CENTERR2+D13, CENTERD2, CENTERR2+D13, CENTERD2}};
704 static TECH_POLYGON sch_xor_l[] = { /* layers */
705 {LNODE, 0, 3, CIRCLEARC, POINTS, sch_g_orl},
706 {LNODE, 0, 3, CIRCLEARC, POINTS, sch_g_ort},
707 {LNODE, 0, 3, CIRCLEARC, POINTS, sch_g_orb},
708 {LNODE, 0, 3, CIRCLEARC, POINTS, sch_g_xor},
709 {LNODE, 0, 8, VECTORS, POINTS, sch_g_or}};
710 static TECH_NODES sch_xor = {
711 x_("Xor"), NXOR, NONODEPROTO, /* name */
712 K10,K6, /* size */
713 4,sch_xor_p, /* ports */
714 5,sch_xor_l, /* layers */
715 (NPGATEXOR<<NFUNCTIONSH), /* userbits */
716 0,0,0,0,0,0,0,0,0}; /* characteristics */
717
718 /* general flip flop */
719 static TECH_PORTS sch_ff_p[] = { /* ports */
720 {sch_pc_wire, x_("i1"), NOPORTPROTO, (180<<PORTANGLESH)|(45<<PORTARANGESH)|
721 (0<<PORTNETSH)|INPORT, LEFTEDGE, TOPBYP6, LEFTEDGE, TOPBYP6},
722 {sch_pc_wire, x_("i2"), NOPORTPROTO, (180<<PORTANGLESH)|(45<<PORTARANGESH)|
723 (1<<PORTNETSH)|INPORT, LEFTEDGE, BOTBYP6, LEFTEDGE, BOTBYP6},
724 {sch_pc_wire, x_("q"), NOPORTPROTO, (0<<PORTANGLESH)|(45<<PORTARANGESH)|
725 (2<<PORTNETSH)|OUTPORT, RIGHTEDGE, TOPBYP6, RIGHTEDGE, TOPBYP6},
726 {sch_pc_wire, x_("qb"), NOPORTPROTO, (0<<PORTANGLESH)|(45<<PORTARANGESH)|
727 (3<<PORTNETSH)|OUTPORT, RIGHTEDGE, BOTBYP6, RIGHTEDGE, BOTBYP6},
728 {sch_pc_wire, x_("ck"), NOPORTPROTO, (180<<PORTANGLESH)|(45<<PORTARANGESH)|
729 (4<<PORTNETSH)|INPORT, LEFTEDGE, CENTER, LEFTEDGE, CENTER},
730 {sch_pc_wire, x_("preset"), NOPORTPROTO, (90<<PORTANGLESH)|(45<<PORTARANGESH)|
731 (5<<PORTNETSH)|INPORT, CENTER, TOPEDGE, CENTER, TOPEDGE},
732 {sch_pc_wire, x_("clear"), NOPORTPROTO,(270<<PORTANGLESH)|(45<<PORTARANGESH)|
733 (6<<PORTNETSH)|INPORT, CENTER, BOTEDGE, CENTER, BOTEDGE}};
734 static TECH_POLYGON sch_ffp_l[] = { /* layers */
735 {LNODE, 0, 4, CLOSEDRECT, BOX, sch_g_ffbox},
736 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextd},
737 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftexte},
738 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextq},
739 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextqb},
740 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextpr},
741 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextclr},
742 {LNODE, 0, 3, OPENED, POINTS, sch_g_ffarrow},
743 {LNODE, 0, 4, OPENED, POINTS, sch_g_ffp}};
744 static TECH_POLYGON sch_ffn_l[] = { /* layers */
745 {LNODE, 0, 4, CLOSEDRECT, BOX, sch_g_ffbox},
746 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextd},
747 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftexte},
748 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextq},
749 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextqb},
750 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextpr},
751 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextclr},
752 {LNODE, 0, 3, OPENED, POINTS, sch_g_ffarrow},
753 {LNODE, 0, 4, OPENED, POINTS, sch_g_ffn}};
754 static TECH_POLYGON sch_ffms_l[] = { /* layers */
755 {LNODE, 0, 4, CLOSEDRECT, BOX, sch_g_ffbox},
756 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextd},
757 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftexte},
758 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextq},
759 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextqb},
760 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextpr},
761 {LTEXT, TXTSETQLAMBDA(4), 4, TEXTBOX, POINTS, (INTBIG *)sch_g_fftextclr},
762 {LNODE, 0, 3, OPENED, POINTS, sch_g_ffarrow},
763 {LNODE, 0, 6, OPENED, POINTS, sch_g_ffms}};
764 static TECH_NODES sch_ff = {
765 x_("Flip-Flop"), NFF, NONODEPROTO, /* name */
766 K6,K10, /* size */
767 7,sch_ff_p, /* ports */
768 9,sch_ffp_l, /* layers */
769 (NPFLIPFLOP<<NFUNCTIONSH), /* userbits */
770 0,0,0,0,0,0,0,0,0}; /* characteristics */
771
772 /* general MUX */
773 static TECH_PORTS sch_mux_p[] = { /* ports */
774 {sch_pc_either, x_("a"), NOPORTPROTO, (180<<PORTANGLESH)|(0<<PORTARANGESH)|
775 (0<<PORTNETSH)|INPORT|PORTISOLATED, LEFTBYP8,BOTEDGE,LEFTBYP8,TOPEDGE},
776 {sch_pc_bus, x_("s"), NOPORTPROTO, (270<<PORTANGLESH)|(0<<PORTARANGESH)|
777 (2<<PORTNETSH)|INPORT, CENTER, BOTBYP875, CENTER, BOTBYP875},
778 {sch_pc_either, x_("y"), NOPORTPROTO, (0<<PORTANGLESH)|(0<<PORTARANGESH)|
779 (1<<PORTNETSH)|OUTPORT, RIGHTBYP8, CENTER, RIGHTBYP8, CENTER}};
780 static TECH_POLYGON sch_mux_l[] = { /* layers */
781 {LNODE, 0, 4, CLOSED, POINTS, sch_g_mux}};
782 static TECH_NODES sch_mux = {
783 x_("Mux"), NMUX, NONODEPROTO, /* name */
784 K8,K10, /* size */
785 3,sch_mux_p, /* ports */
786 1,sch_mux_l, /* layers */
787 (NPMUX<<NFUNCTIONSH), /* userbits */
788 0,0,0,0,0,0,0,0,0}; /* characteristics */
789
790 /* black box */
791 static TECH_PORTS sch_bbox_p[] = { /* ports */
792 {sch_pc_either, x_("a"), NOPORTPROTO, (0<<PORTANGLESH)|(45<<PORTARANGESH)|
793 (0<<PORTNETSH)|PORTISOLATED, RIGHTEDGE, BOTEDGE, RIGHTEDGE, TOPEDGE},
794 {sch_pc_either, x_("b"), NOPORTPROTO, (90<<PORTANGLESH)|(45<<PORTARANGESH)|
795 (1<<PORTNETSH)|PORTISOLATED, LEFTEDGE, TOPEDGE, RIGHTEDGE, TOPEDGE},
796 {sch_pc_either, x_("c"), NOPORTPROTO, (180<<PORTANGLESH)|(45<<PORTARANGESH)|
797 (2<<PORTNETSH)|PORTISOLATED, LEFTEDGE, BOTEDGE, LEFTEDGE, TOPEDGE},
798 {sch_pc_either, x_("d"), NOPORTPROTO, (270<<PORTANGLESH)|(45<<PORTARANGESH)|
799 (3<<PORTNETSH)|PORTISOLATED, LEFTEDGE, BOTEDGE, RIGHTEDGE, BOTEDGE}};
800 static TECH_POLYGON sch_bbox_l[] = { /* layers */
801 {LNODE, 0, 4, CLOSEDRECT, BOX, sch_g_bbox}};
802 static TECH_NODES sch_bbox = {
803 x_("Bbox"), NBBOX, NONODEPROTO, /* name */
804 K10,K10, /* size */
805 4,sch_bbox_p, /* ports */
806 1,sch_bbox_l, /* layers */
807 (NPUNKNOWN<<NFUNCTIONSH), /* userbits */
808 0,0,0,0,0,0,0,0,0}; /* characteristics */
809
810 /* switch */
811 static TECH_PORTS sch_switch_p[] = { /* ports */
812 {sch_pc_either, x_("a"), NOPORTPROTO, (180<<PORTANGLESH)|(90<<PORTARANGESH)|
813 (0<<PORTNETSH)|PORTISOLATED, LEFTIN1, BOTIN1, LEFTIN1, TOPIN1},
814 {sch_pc_either, x_("y"), NOPORTPROTO, (0<<PORTANGLESH)|(90<<PORTARANGESH)|
815 (1<<PORTNETSH), RIGHTIN1, CENTER, RIGHTIN1, CENTER}};
816 static TECH_POLYGON sch_switch_l[] = { /* layers */
817 {LNODE, 0, 2, DISC, POINTS, sch_g_switchin},
818 {LNODE, 0, 2, OPENED, POINTS, sch_g_switchbar},
819 {LNODE, 0, 2, DISC, POINTS, sch_g_switchout}};
820 static TECH_NODES sch_switch = {
821 x_("Switch"),NSWITCH,NONODEPROTO, /* name */
822 K6,K2, /* size */
823 2,sch_switch_p, /* ports */
824 3,sch_switch_l, /* layers */
825 (NPUNKNOWN<<NFUNCTIONSH), /* userbits */
826 0,0,0,0,0,0,0,0,0}; /* characteristics */
827
828 /* off page connector */
829 static TECH_PORTS sch_offpage_p[] = { /* ports */
830 {sch_pc_either, x_("a"), NOPORTPROTO, (180<<PORTANGLESH)|(45<<PORTARANGESH),
831 LEFTEDGE, CENTER, LEFTEDGE, CENTER},
832 {sch_pc_either, x_("y"), NOPORTPROTO, (0<<PORTANGLESH)|(45<<PORTARANGESH),
833 RIGHTEDGE, CENTER, RIGHTEDGE, CENTER}};
834 static TECH_POLYGON sch_offpage_l[] = { /* layers */
835 {LNODE, 0, 5, CLOSED, POINTS, sch_g_offpage}};
836 static TECH_NODES sch_offpage = {
837 x_("Off-Page"), NOFFPAGE, NONODEPROTO, /* name */
838 K4,K2, /* size */
839 2,sch_offpage_p, /* ports */
840 1,sch_offpage_l, /* layers */
841 (NPCONNECT<<NFUNCTIONSH), /* userbits */
842 0,0,0,0,0,0,0,0,0}; /* characteristics */
843
844 /* power */
845 static TECH_PORTS sch_pwr_p[] = { /* ports */
846 {sch_pc_wire, x_("pwr"), NOPORTPROTO, (180<<PORTARANGESH)|PWRPORT,
847 CENTER, CENTER, CENTER, CENTER}};
848 static TECH_POLYGON sch_pwr_l[] = { /* layers */
849 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_pwr1},
850 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_pwr2}};
851 static TECH_NODES sch_pwr = {
852 x_("Power"), NPWR, NONODEPROTO, /* name */
853 K3,K3, /* size */
854 1,sch_pwr_p, /* ports */
855 2,sch_pwr_l, /* layers */
856 (NPCONPOWER<<NFUNCTIONSH)|NSQUARE, /* userbits */
857 0,0,0,0,0,0,0,0,0}; /* characteristics */
858
859 /* ground */
860 static TECH_PORTS sch_gnd_p[] = { /* ports */
861 {sch_pc_wire, x_("gnd"), NOPORTPROTO, (90<<PORTANGLESH)|(90<<PORTARANGESH)|
862 GNDPORT, CENTER, TOPEDGE, CENTER, TOPEDGE}};
863 static TECH_POLYGON sch_gnd_l[] = { /* layers */
864 {LNODE, 0, 12, VECTORS, POINTS, sch_g_gnd}};
865 static TECH_NODES sch_gnd = {
866 x_("Ground"), NGND, NONODEPROTO, /* name */
867 K3,K4, /* size */
868 1,sch_gnd_p, /* ports */
869 1,sch_gnd_l, /* layers */
870 (NPCONGROUND<<NFUNCTIONSH), /* userbits */
871 0,0,0,0,0,0,0,0,0}; /* characteristics */
872
873 /* source */
874 static TECH_PORTS sch_source_p[] = { /* ports */
875 {sch_pc_wire, x_("plus"), NOPORTPROTO, (90<<PORTANGLESH)|(0<<PORTARANGESH)|
876 (0<<PORTNETSH), CENTER, TOPEDGE, CENTER, TOPEDGE},
877 {sch_pc_wire, x_("minus"), NOPORTPROTO, (270<<PORTANGLESH)|(0<<PORTARANGESH)|
878 (1<<PORTNETSH), CENTER, BOTEDGE, CENTER, BOTEDGE}};
879 static TECH_POLYGON sch_sourcev_l[] = { /* layers */
880 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_source},
881 {LNODE, 0, 4, VECTORS, POINTS, sch_g_sourcepl}};
882 static TECH_NODES sch_source = {
883 x_("Source"), NSOURCE, NONODEPROTO, /* name */
884 K6,K6, /* size */
885 2,sch_source_p, /* ports */
886 2,sch_sourcev_l, /* layers */
887 (NPSOURCE<<NFUNCTIONSH)|NSQUARE, /* userbits */
888 0,0,0,0,0,0,0,0,0}; /* characteristics */
889
890 /* transistor */
891 static TECH_PORTS sch_trans_p[] = { /* ports */
892 {sch_pc_wire, x_("g"), NOPORTPROTO, (180<<PORTARANGESH)|
893 (0<<PORTNETSH)|INPORT, CENTER, TOPIN1, CENTER, TOPIN1},
894 {sch_pc_wire, x_("s"), NOPORTPROTO, (180<<PORTANGLESH)|(90<<PORTARANGESH)|
895 (1<<PORTNETSH)|BIDIRPORT, LEFTEDGE, BOTEDGE, LEFTEDGE, BOTEDGE},
896 {sch_pc_wire, x_("d"), NOPORTPROTO, (0<<PORTANGLESH)|(90<<PORTARANGESH)|
897 (2<<PORTNETSH)|BIDIRPORT, RIGHTEDGE, BOTEDGE, RIGHTEDGE, BOTEDGE}};
898 static TECH_POLYGON sch_nmos_l[] = { /* layers */
899 {LNODE, 0, 6, OPENED, POINTS, sch_g_mos},
900 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
901 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos}};
902 static TECH_POLYGON sch_pmos_l[] = { /* layers */
903 {LNODE, 0, 6, OPENED, POINTS, sch_g_mos},
904 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
905 {LNODE, 0, 2, OPENED, POINTS, sch_g_pmos},
906 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_pmoscir}};
907 static TECH_POLYGON sch_dmos_l[] = { /* layers */
908 {LNODE, 0, 6, OPENED, POINTS, sch_g_mos},
909 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
910 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
911 {LNODE, 0, 4, FILLEDRECT, BOX, sch_g_dmos}};
912 static TECH_POLYGON sch_npn_l[] = { /* layers */
913 {LNODE, 0, 6, OPENED, POINTS, sch_g_btran1},
914 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
915 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
916 {LNODE, 0, 3, OPENED, POINTS, sch_g_btran2}};
917 static TECH_POLYGON sch_pnp_l[] = { /* layers */
918 {LNODE, 0, 6, OPENED, POINTS, sch_g_btran1},
919 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
920 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
921 {LNODE, 0, 3, OPENED, POINTS, sch_g_btran3}};
922 static TECH_POLYGON sch_njfet_l[] = { /* layers */
923 {LNODE, 0, 10, VECTORS, POINTS, sch_g_btran4},
924 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
925 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
926 {LNODE, 0, 3, OPENED, POINTS, sch_g_btran5}};
927 static TECH_POLYGON sch_pjfet_l[] = { /* layers */
928 {LNODE, 0, 10, VECTORS, POINTS, sch_g_btran4},
929 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
930 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
931 {LNODE, 0, 3, OPENED, POINTS, sch_g_btran6}};
932 static TECH_POLYGON sch_dmes_l[] = { /* layers */
933 {LNODE, 0, 10, VECTORS, POINTS, sch_g_btran4},
934 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
935 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos}};
936 static TECH_POLYGON sch_emes_l[] = { /* layers */
937 {LNODE, 0, 14, VECTORS, POINTS, sch_g_btran7},
938 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos}};
939 static TECH_NODES sch_trans = {
940 x_("Transistor"), NTRANSISTOR, NONODEPROTO, /* name */
941 K4,K4, /* size */
942 3,sch_trans_p, /* ports */
943 3,sch_nmos_l, /* layers */
944 (NPTRANS<<NFUNCTIONSH), /* userbits */
945 0,0,0,0,0,0,0,0,0}; /* characteristics */
946
947 /* resistor */
948 static TECH_PORTS sch_resist_p[] = { /* ports */
949 {sch_pc_wire, x_("a"), NOPORTPROTO, (180<<PORTANGLESH)|(90<<PORTARANGESH)|
950 (0<<PORTNETSH), LEFTBYP66, CENTER, LEFTBYP66, CENTER},
951 {sch_pc_wire, x_("b"), NOPORTPROTO, (0<<PORTANGLESH)|(90<<PORTARANGESH)|
952 (1<<PORTNETSH), RIGHTBYP66, CENTER, RIGHTBYP66, CENTER}};
953 static TECH_POLYGON sch_resist_l[] = { /* layers */
954 {LNODE, 0, 10, OPENED, POINTS, sch_g_resist}};
955 static TECH_NODES sch_resist = {
956 x_("Resistor"), NRESISTOR, NONODEPROTO, /* name */
957 K6,K1, /* size */
958 2,sch_resist_p, /* ports */
959 1,sch_resist_l, /* layers */
960 (NPRESIST<<NFUNCTIONSH), /* userbits */
961 0,0,0,0,0,0,0,0,0}; /* characteristics */
962
963 /* capacitor */
964 static TECH_PORTS sch_capac_p[] = { /* ports */
965 {sch_pc_wire, x_("a"), NOPORTPROTO, (90<<PORTANGLESH)|(90<<PORTARANGESH)|
966 (0<<PORTNETSH), CENTER, TOPEDGE, CENTER, TOPEDGE},
967 {sch_pc_wire, x_("b"), NOPORTPROTO, (270<<PORTANGLESH)|(90<<PORTARANGESH)|
968 (1<<PORTNETSH), CENTER, BOTEDGE, CENTER, BOTEDGE}};
969 static TECH_POLYGON sch_capac_l[] = { /* layers */
970 {LNODE, 0, 8, VECTORS, POINTS, sch_g_capac},
971 {LNODE, 0, 4, VECTORS, POINTS, sch_g_capace}};
972 static TECH_NODES sch_capac = {
973 x_("Capacitor"), NCAPACITOR, NONODEPROTO, /* name */
974 K3,K4, /* size */
975 2,sch_capac_p, /* ports */
976 1,sch_capac_l, /* layers */
977 (NPCAPAC<<NFUNCTIONSH), /* userbits */
978 0,0,0,0,0,0,0,0,0}; /* characteristics */
979
980 /* diode */
981 static TECH_PORTS sch_diode_p[] = { /* ports */
982 {sch_pc_wire, x_("a"), NOPORTPROTO, (90<<PORTANGLESH)|(90<<PORTARANGESH)|
983 (0<<PORTNETSH), CENTER, TOPEDGE, CENTER, TOPEDGE},
984 {sch_pc_wire, x_("b"), NOPORTPROTO, (270<<PORTANGLESH)|(90<<PORTARANGESH)|
985 (1<<PORTNETSH), CENTER, BOTEDGE, CENTER, BOTEDGE}};
986 static TECH_POLYGON sch_diode_l[] = { /* layers */
987 {LNODE, 0, 6, VECTORS, POINTS, sch_g_diode1},
988 {LNODE, 0, 3, FILLED, POINTS, sch_g_diode2}};
989 static TECH_NODES sch_diode = {
990 x_("Diode"), NDIODE, NONODEPROTO, /* name */
991 K2,K4, /* size */
992 2,sch_diode_p, /* ports */
993 2,sch_diode_l, /* layers */
994 (NPDIODE<<NFUNCTIONSH), /* userbits */
995 0,0,0,0,0,0,0,0,0}; /* characteristics */
996
997 /* inductor */
998 static TECH_PORTS sch_induct_p[] = { /* ports */
999 {sch_pc_wire, x_("a"), NOPORTPROTO, (90<<PORTANGLESH)|(90<<PORTARANGESH)|
1000 (0<<PORTNETSH), CENTER, TOPEDGE, CENTER, TOPEDGE},
1001 {sch_pc_wire, x_("b"), NOPORTPROTO, (270<<PORTANGLESH)|(90<<PORTARANGESH)|
1002 (1<<PORTNETSH), CENTER, BOTEDGE, CENTER, BOTEDGE}};
1003 static TECH_POLYGON sch_induct_l[] = { /* layers */
1004 {LNODE, 0, 2, OPENED, POINTS, sch_g_induct1},
1005 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_induct2},
1006 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_induct3},
1007 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_induct4}};
1008 static TECH_NODES sch_induct = {
1009 x_("Inductor"), NINDUCTOR, NONODEPROTO, /* name */
1010 K2,K4, /* size */
1011 2,sch_induct_p, /* ports */
1012 4,sch_induct_l, /* layers */
1013 (NPINDUCT<<NFUNCTIONSH), /* userbits */
1014 0,0,0,0,0,0,0,0,0}; /* characteristics */
1015
1016 /* meter */
1017 static TECH_PORTS sch_meter_p[] = { /* ports */
1018 {sch_pc_wire, x_("a"), NOPORTPROTO, (90<<PORTANGLESH)|(0<<PORTARANGESH)|
1019 (0<<PORTNETSH), CENTER, TOPEDGE, CENTER, TOPEDGE},
1020 {sch_pc_wire, x_("b"), NOPORTPROTO, (270<<PORTANGLESH)|(0<<PORTARANGESH)|
1021 (1<<PORTNETSH), CENTER, BOTEDGE, CENTER, BOTEDGE}};
1022 static TECH_POLYGON sch_meterv_l[] = { /* layers */
1023 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_meter},
1024 {LTEXT, TXTSETQLAMBDA(8), 4, TEXTBOX, BOX, (INTBIG *)sch_g_meterv}};
1025 static TECH_NODES sch_meter = {
1026 x_("Meter"), NMETER, NONODEPROTO, /* name */
1027 K6,K6, /* size */
1028 2,sch_meter_p, /* ports */
1029 2,sch_meterv_l, /* layers */
1030 (NPMETER<<NFUNCTIONSH)|NSQUARE, /* userbits */
1031 0,0,0,0,0,0,0,0,0}; /* characteristics */
1032
1033 /* well contact */
1034 static TECH_PORTS sch_well_p[] = { /* ports */
1035 {sch_pc_wire, x_("well"), NOPORTPROTO, (90<<PORTANGLESH)|(90<<PORTARANGESH),
1036 CENTER, TOPEDGE, CENTER, TOPEDGE}};
1037 static TECH_POLYGON sch_well_l[] = { /* layers */
1038 {LNODE, 0, 4, VECTORS, POINTS, sch_g_well}};
1039 static TECH_NODES sch_well = {
1040 x_("Well"), NWELL, NONODEPROTO, /* name */
1041 K4,K2, /* size */
1042 1,sch_well_p, /* ports */
1043 1,sch_well_l, /* layers */
1044 (NPWELL<<NFUNCTIONSH), /* userbits */
1045 0,0,0,0,0,0,0,0,0}; /* characteristics */
1046
1047 /* substrate contact */
1048 static TECH_PORTS sch_substrate_p[] = { /* ports */
1049 {sch_pc_wire, x_("substrate"), NOPORTPROTO, (90<<PORTANGLESH)|(90<<PORTARANGESH),
1050 CENTER, TOPEDGE, CENTER, TOPEDGE}};
1051 static TECH_POLYGON sch_substrate_l[] = { /* layers */
1052 {LNODE, 0, 8, VECTORS, POINTS, sch_g_substrate}};
1053 static TECH_NODES sch_substrate = {
1054 x_("Substrate"), NSUBSTRATE, NONODEPROTO, /* name */
1055 K3,K3, /* size */
1056 1,sch_substrate_p, /* ports */
1057 1,sch_substrate_l, /* layers */
1058 (NPSUBSTRATE<<NFUNCTIONSH), /* userbits */
1059 0,0,0,0,0,0,0,0,0}; /* characteristics */
1060
1061 /* two-port */
1062 static TECH_PORTS sch_twoport_p[] = { /* ports */
1063 {sch_pc_wire, x_("a"), NOPORTPROTO, (180<<PORTANGLESH)|(90<<PORTARANGESH)|
1064 (0<<PORTNETSH), LEFTEDGE, TOPBYP66, LEFTEDGE, TOPBYP66},
1065 {sch_pc_wire, x_("b"), NOPORTPROTO, (180<<PORTANGLESH)|(90<<PORTARANGESH)|
1066 (1<<PORTNETSH), LEFTEDGE, BOTBYP66, LEFTEDGE, BOTBYP66},
1067 {sch_pc_wire, x_("x"), NOPORTPROTO, (0<<PORTANGLESH)|(90<<PORTARANGESH)|
1068 (2<<PORTNETSH), RIGHTEDGE, TOPBYP66, RIGHTEDGE, TOPBYP66},
1069 {sch_pc_wire, x_("y"), NOPORTPROTO, (0<<PORTANGLESH)|(90<<PORTARANGESH)|
1070 (3<<PORTNETSH), RIGHTEDGE, BOTBYP66, RIGHTEDGE, BOTBYP66}};
1071 static TECH_POLYGON sch_twoportg_l[] = { /* layers */
1072 {LNODE, 0, 4, CLOSEDRECT, BOX, sch_g_twobox},
1073 {LNODE, 0, 8, VECTORS, POINTS, sch_g_twogwire},
1074 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twoulpl},
1075 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twourpl}};
1076 static TECH_POLYGON sch_twoportvcvs_l[] = { /* layers */
1077 {LNODE, 0, 4, CLOSEDRECT, BOX, sch_g_twobox},
1078 {LNODE, 0, 12, VECTORS, POINTS, sch_g_twonormwire},
1079 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_twovsc},
1080 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twourpl},
1081 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twoulpl}};
1082 static TECH_POLYGON sch_twoportvccs_l[] = { /* layers */
1083 {LNODE, 0, 4, CLOSEDRECT, BOX, sch_g_twobox},
1084 {LNODE, 0, 12, VECTORS, POINTS, sch_g_twonormwire},
1085 {LNODE, 0, 8, VECTORS, POINTS, sch_g_twocswire},
1086 {LNODE, 0, 6, VECTORS, POINTS, sch_g_twocsarr},
1087 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twoulpl}};
1088 static TECH_POLYGON sch_twoportccvs_l[] = { /* layers */
1089 {LNODE, 0, 4, CLOSEDRECT, BOX, sch_g_twobox},
1090 {LNODE, 0, 2, /*VECTORS*/OPENEDT1, POINTS, sch_g_twoccwire},
1091 {LNODE, 0, 12, VECTORS, POINTS, sch_g_twonormwire},
1092 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_twovsc},
1093 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twourpl},
1094 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twoulpl}};
1095 static TECH_POLYGON sch_twoportcccs_l[] = { /* layers */
1096 {LNODE, 0, 4, CLOSEDRECT, BOX, sch_g_twobox},
1097 {LNODE, 0, 2, /*VECTORS*/OPENEDT1, POINTS, sch_g_twoccwire},
1098 {LNODE, 0, 12, VECTORS, POINTS, sch_g_twonormwire},
1099 {LNODE, 0, 8, VECTORS, POINTS, sch_g_twocswire},
1100 {LNODE, 0, 6, VECTORS, POINTS, sch_g_twocsarr},
1101 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twoulpl}};
1102 static TECH_POLYGON sch_twoporttran_l[] = { /* layers */
1103 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twotrbox},
1104 {LNODE, 0, 3, CIRCLEARC,POINTS, sch_g_twotr1},
1105 {LNODE, 0, 3, CIRCLEARC,POINTS, sch_g_twotr2},
1106 {LNODE, 0, 3, CIRCLEARC,POINTS, sch_g_twotr3},
1107 {LNODE, 0, 8, VECTORS, POINTS, sch_g_twotrwire},
1108 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twoulpl},
1109 {LNODE, 0, 4, VECTORS, POINTS, sch_g_twourrpl}};
1110 static TECH_NODES sch_twoport = {
1111 x_("Two-Port"), NTWOPORT, NONODEPROTO, /* name */
1112 K10,K6, /* size */
1113 4,sch_twoport_p, /* ports */
1114 4,sch_twoportg_l, /* layers */
1115 (NPTLINE<<NFUNCTIONSH), /* userbits */
1116 0,0,0,0,0,0,0,0,0}; /* characteristics */
1117
1118 /* 4-port transistor */
1119 static TECH_PORTS sch_trans4_p[] = { /* ports */
1120 {sch_pc_wire, x_("g"), NOPORTPROTO, (180<<PORTARANGESH)|
1121 (0<<PORTNETSH)|INPORT, CENTER, TOPIN1, CENTER, TOPIN1},
1122 {sch_pc_wire, x_("s"), NOPORTPROTO, (180<<PORTANGLESH)|(90<<PORTARANGESH)|
1123 (1<<PORTNETSH)|BIDIRPORT, LEFTEDGE, BOTEDGE, LEFTEDGE, BOTEDGE},
1124 {sch_pc_wire, x_("d"), NOPORTPROTO, (0<<PORTANGLESH)|(90<<PORTARANGESH)|
1125 (2<<PORTNETSH)|BIDIRPORT, RIGHTEDGE, BOTEDGE, RIGHTEDGE, BOTEDGE},
1126 {sch_pc_wire, x_("b"), NOPORTPROTO, (270<<PORTANGLESH)|(90<<PORTARANGESH)|
1127 (3<<PORTNETSH)|BIDIRPORT, LEFTBYP5, BOTEDGE, LEFTBYP5, BOTEDGE}};
1128 static TECH_POLYGON sch_nmos4_l[] = { /* layers */
1129 {LNODE, 0, 6, OPENED, POINTS, sch_g_mos},
1130 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
1131 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
1132 {LNODE, 0, 6, VECTORS, POINTS, sch_g_nmos4}};
1133 static TECH_POLYGON sch_pmos4_l[] = { /* layers */
1134 {LNODE, 0, 6, OPENED, POINTS, sch_g_mos},
1135 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
1136 {LNODE, 0, 2, OPENED, POINTS, sch_g_pmos},
1137 {LNODE, 0, 2, CIRCLE, POINTS, sch_g_pmoscir},
1138 {LNODE, 0, 6, VECTORS, POINTS, sch_g_pmos4}};
1139 static TECH_POLYGON sch_dmos4_l[] = { /* layers */
1140 {LNODE, 0, 6, OPENED, POINTS, sch_g_mos},
1141 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
1142 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
1143 {LNODE, 0, 4, FILLEDRECT, BOX, sch_g_dmos},
1144 {LNODE, 0, 6, VECTORS, POINTS, sch_g_dmos4}};
1145 static TECH_POLYGON sch_npn4_l[] = { /* layers */
1146 {LNODE, 0, 6, OPENED, POINTS, sch_g_btran1},
1147 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
1148 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
1149 {LNODE, 0, 3, OPENED, POINTS, sch_g_btran2},
1150 {LNODE, 0, 2, OPENED, POINTS, sch_g_bip4}};
1151 static TECH_POLYGON sch_pnp4_l[] = { /* layers */
1152 {LNODE, 0, 6, OPENED, POINTS, sch_g_btran1},
1153 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
1154 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
1155 {LNODE, 0, 3, OPENED, POINTS, sch_g_btran3},
1156 {LNODE, 0, 2, OPENED, POINTS, sch_g_bip4}};
1157 static TECH_POLYGON sch_njfet4_l[] = { /* layers */
1158 {LNODE, 0, 10, VECTORS, POINTS, sch_g_btran4},
1159 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
1160 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
1161 {LNODE, 0, 3, OPENED, POINTS, sch_g_btran5},
1162 {LNODE, 0, 6, VECTORS, POINTS, sch_g_pmes4}};
1163 static TECH_POLYGON sch_pjfet4_l[] = { /* layers */
1164 {LNODE, 0, 10, VECTORS, POINTS, sch_g_btran4},
1165 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
1166 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
1167 {LNODE, 0, 3, OPENED, POINTS, sch_g_btran6},
1168 {LNODE, 0, 6, VECTORS, POINTS, sch_g_nmes4}};
1169 static TECH_POLYGON sch_dmes4_l[] = { /* layers */
1170 {LNODE, 0, 10, VECTORS, POINTS, sch_g_btran4},
1171 {LNODE, 0, 2, OPENED, POINTS, sch_g_trantop},
1172 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
1173 {LNODE, 0, 6, VECTORS, POINTS, sch_g_nmes4}};
1174 static TECH_POLYGON sch_emes4_l[] = { /* layers */
1175 {LNODE, 0, 14, VECTORS, POINTS, sch_g_btran7},
1176 {LNODE, 0, 2, OPENED, POINTS, sch_g_nmos},
1177 {LNODE, 0, 6, VECTORS, POINTS, sch_g_nmes4}};
1178 static TECH_NODES sch_trans4 = {
1179 x_("4-Port-Transistor"), NTRANSISTOR4, NONODEPROTO, /* name */
1180 K4,K4, /* size */
1181 4,sch_trans4_p, /* ports */
1182 3,sch_nmos4_l, /* layers */
1183 (NPTRANS4<<NFUNCTIONSH), /* userbits */
1184 0,0,0,0,0,0,0,0,0}; /* characteristics */
1185
1186 /* global signal */
1187 static TECH_PORTS sch_globalsig_p[] = { /* ports */
1188 {sch_pc_wire, x_("global"), NOPORTPROTO, (270<<PORTANGLESH)|(90<<PORTARANGESH),
1189 CENTER, BOTEDGE, CENTER, BOTEDGE}};
1190 static TECH_POLYGON sch_globalsig_l[] = { /* layers */
1191 {LNODE, 0, 4, CLOSED, POINTS, sch_g_global1},
1192 {LNODE, 0, 4, CLOSED, POINTS, sch_g_global2}};
1193 static TECH_NODES sch_globalsig = {
1194 x_("Global-Signal"), NGLOBALSIG, NONODEPROTO, /* name */
1195 K3,K3, /* size */
1196 1,sch_globalsig_p, /* ports */
1197 2,sch_globalsig_l, /* layers */
1198 (NPCONNECT<<NFUNCTIONSH), /* userbits */
1199 0,0,0,0,0,0,0,0,0}; /* characteristics */
1200
1201 TECH_NODES *sch_nodeprotos[NODEPROTOCOUNT+1] = {
1202 &sch_wirepin, &sch_buspin, &sch_wirecon, /* pins */
1203 &sch_buf, &sch_and, &sch_or, &sch_xor, /* gates: buffer, and, or, xor */
1204 &sch_ff, &sch_mux, /* flipflop, mux */
1205 &sch_bbox, &sch_switch, /* box/switch */
1206 &sch_offpage, /* offpage */
1207 &sch_pwr, &sch_gnd, &sch_source, /* pwr/gnd/source */
1208 &sch_trans, &sch_resist, &sch_capac, /* trans/resist/capac */
1209 &sch_diode, &sch_induct, /* diode/inductor */
1210 &sch_meter, /* meter */
1211 &sch_well, &sch_substrate, /* well/substrate */
1212 &sch_twoport, &sch_trans4, &sch_globalsig, /* twoport/4-port/global */
1213 ((TECH_NODES *)-1)
1214 };
1215
1216 static INTBIG sch_node_widoff[NODEPROTOCOUNT*4] = {
1217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* pins */
1218 0,K1, 0, 0, 0,H0, 0, 0, K1,H0, 0, 0, 0,H0, 0, 0, /* gates: buffer, and, or, xor */
1219 0, 0, 0, 0, 0, 0, 0, 0, /* flipflop, mux */
1220 0, 0, 0, 0, 0, 0, 0, 0, /* box/switch */
1221 0, 0, 0, 0, /* offpage */
1222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* pwr/gnd/source */
1223 0, 0, 0,K1, 0, 0, 0, 0, 0, 0, 0, 0, /* trans/resist/capac */
1224 0, 0, 0, 0, 0, 0, 0, 0, /* diode/inductor */
1225 0, 0, 0, 0, /* meter */
1226 0, 0, 0, 0, 0, 0, 0, 0, /* well/substrate */
1227 0, 0, 0, 0, 0, 0, 0,K1, 0, 0, 0, 0 /* twoport/4-port/global */
1228 };
1229
1230 static CHAR *sch_node_vhdlstring[NODEPROTOCOUNT] = {
1231 x_(""), x_(""), x_(""), /* pins */
1232 x_("buffer/inverter"), x_("and%ld/nand%ld"), x_("or%ld/nor%ld"), x_("xor%ld/xnor%ld"), /* gates */
1233 x_("ff"), x_("mux%ld"), /* flipflop, mux */
1234 x_(""), x_(""), /* box/switch */
1235 x_(""), /* offpage */
1236 x_(""), x_(""), x_(""), /* pwr/gnd/source */
1237 x_(""), x_(""), x_(""), /* trans/resist/capac */
1238 x_(""), x_(""), /* diode/inductor */
1239 x_(""), /* meter */
1240 x_(""), x_(""), /* well/substrate */
1241 x_(""), x_(""), x_("") /* twoport/4-port/global */
1242 };
1243
1244 /******************** VARIABLE AGGREGATION ********************/
1245
1246 TECH_VARIABLES sch_variables[] =
1247 {
1248 /* set general information about the technology */
1249 {x_("TECH_layer_names"), (CHAR *)sch_layer_names, 0.0,
1250 VSTRING|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},
1251 {x_("TECH_layer_function"), (CHAR *)sch_layer_function, 0.0,
1252 VINTEGER|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},
1253 {x_("TECH_node_width_offset"), (CHAR *)sch_node_widoff, 0.0,
1254 VFRACT|VDONTSAVE|VISARRAY|((NODEPROTOCOUNT*4)<<VLENGTHSH)},
1255 {x_("TECH_vhdl_names"), (CHAR *)sch_node_vhdlstring, 0.0,
1256 VSTRING|VDONTSAVE|VISARRAY|(NODEPROTOCOUNT<<VLENGTHSH)},
1257
1258 /* set information for the USER analysis tool */
1259 {x_("USER_layer_letters"), (CHAR *)sch_layer_letters, 0.0,
1260 VSTRING|VDONTSAVE|VISARRAY|(MAXLAYERS<<VLENGTHSH)},
1261 {NULL, NULL, 0.0, 0}
1262 };
1263
1264 /******************** ROUTINES ********************/
1265
sch_initprocess(TECHNOLOGY * tech,INTBIG pass)1266 BOOLEAN sch_initprocess(TECHNOLOGY *tech, INTBIG pass)
1267 {
1268 switch (pass)
1269 {
1270 case 0:
1271 /* initialize the technology variable */
1272 sch_tech = tech;
1273 break;
1274
1275 case 1:
1276 /* cache pointers to the primitives */
1277 sch_wirepinprim = getnodeproto(x_("schematic:Wire_Pin"));
1278 sch_buspinprim = getnodeproto(x_("schematic:Bus_Pin"));
1279 sch_wireconprim = getnodeproto(x_("schematic:Wire_Con"));
1280 sch_bufprim = getnodeproto(x_("schematic:Buffer"));
1281 sch_andprim = getnodeproto(x_("schematic:And"));
1282 sch_orprim = getnodeproto(x_("schematic:Or"));
1283 sch_xorprim = getnodeproto(x_("schematic:Xor"));
1284 sch_ffprim = getnodeproto(x_("schematic:Flip-Flop"));
1285 sch_muxprim = getnodeproto(x_("schematic:Mux"));
1286 sch_bboxprim = getnodeproto(x_("schematic:Bbox"));
1287 sch_switchprim = getnodeproto(x_("schematic:Switch"));
1288 sch_offpageprim = getnodeproto(x_("schematic:Off-Page"));
1289 sch_pwrprim = getnodeproto(x_("schematic:Power"));
1290 sch_gndprim = getnodeproto(x_("schematic:Ground"));
1291 sch_sourceprim = getnodeproto(x_("schematic:Source"));
1292 sch_transistorprim = getnodeproto(x_("schematic:Transistor"));
1293 sch_resistorprim = getnodeproto(x_("schematic:Resistor"));
1294 sch_capacitorprim = getnodeproto(x_("schematic:Capacitor"));
1295 sch_diodeprim = getnodeproto(x_("schematic:Diode"));
1296 sch_inductorprim = getnodeproto(x_("schematic:Inductor"));
1297 sch_meterprim = getnodeproto(x_("schematic:Meter"));
1298 sch_wellprim = getnodeproto(x_("schematic:Well"));
1299 sch_substrateprim = getnodeproto(x_("schematic:Substrate"));
1300 sch_twoportprim = getnodeproto(x_("schematic:Two-Port"));
1301 sch_transistor4prim = getnodeproto(x_("schematic:4-Port-Transistor"));
1302 sch_globalprim = getnodeproto(x_("schematic:Global-Signal"));
1303
1304 sch_wirearc = getarcproto(x_("schematic:wire"));
1305 sch_busarc = getarcproto(x_("schematic:bus"));
1306
1307 sch_meterkey = makekey(x_("SCHEM_meter_type"));
1308 sch_diodekey = makekey(x_("SCHEM_diode"));
1309 sch_capacitancekey = makekey(x_("SCHEM_capacitance"));
1310 sch_resistancekey = makekey(x_("SCHEM_resistance"));
1311 sch_inductancekey = makekey(x_("SCHEM_inductance"));
1312 sch_functionkey = makekey(x_("SCHEM_function"));
1313 sch_spicemodelkey = makekey(x_("SIM_spice_model"));
1314 sch_globalnamekey = makekey(x_("SCHEM_global_name"));
1315
1316 /* differential ports are enabled */
1317 sch_anddiffports = sch_ordiffports = sch_xordiffports = NOPORTPROTO;
1318
1319 /* translate strings on schematic nodes */
1320 sch_g_fftextclr[16] = _("CLR");
1321 sch_wirepinsizex = sch_wirepinprim->highx - sch_wirepinprim->lowx;
1322 sch_wirepinsizey = sch_wirepinprim->highy - sch_wirepinprim->lowy;
1323 break;
1324
1325 case 2:
1326 /* set the default transistor placement to be rotated */
1327 nextchangequiet();
1328 setvalkey((INTBIG)sch_transistorprim, VNODEPROTO, us_placement_angle_key, 900, VINTEGER|VDONTSAVE);
1329 nextchangequiet();
1330 setvalkey((INTBIG)sch_transistor4prim, VNODEPROTO, us_placement_angle_key, 900, VINTEGER|VDONTSAVE);
1331 break;
1332 }
1333 return(FALSE);
1334 }
1335
sch_termprocess(void)1336 void sch_termprocess(void)
1337 {
1338 /* put all ports into play so that deallocation will be complete */
1339 if (sch_anddiffports == NOPORTPROTO) return;
1340 sch_andprim->firstportproto->nextportproto->nextportproto = sch_anddiffports;
1341 sch_orprim->firstportproto->nextportproto->nextportproto = sch_ordiffports;
1342 sch_xorprim->firstportproto->nextportproto->nextportproto = sch_xordiffports;
1343 sch_anddiffports = sch_ordiffports = sch_xordiffports = NOPORTPROTO;
1344 }
1345
sch_setmode(INTBIG count,CHAR * par[])1346 void sch_setmode(INTBIG count, CHAR *par[])
1347 {
1348 REGISTER CHAR *pp;
1349 REGISTER INTBIG l;
1350
1351 if (count == 0)
1352 {
1353 /* report size of negating bubbles */
1354 ttyputmsg(M_("Diameter of negating bubbles is %s"), frtoa(sch_bubblediameter));
1355 return;
1356 }
1357
1358 l = estrlen(pp = par[0]);
1359 if (namesamen(pp, x_("negating-bubble-diameter"), l) == 0)
1360 {
1361 /* get new negating bubble diameter */
1362 if (count <= 1)
1363 {
1364 ttyputmsg(M_("Diameter of negating bubbles is %s"), frtoa(sch_bubblediameter));
1365 return;
1366 }
1367 l = atofr(par[1]);
1368 if (l > 0) sch_bubblediameter = l; else
1369 ttyputerr(M_("Bubble diameter must be positive and nonzero"));
1370 return;
1371 }
1372 if (namesamen(pp, x_("disable-differential-ports"), l) == 0)
1373 {
1374 if (sch_anddiffports != NOPORTPROTO)
1375 {
1376 ttyputerr(M_("Differential ports are already disabled"));
1377 return;
1378 }
1379 sch_anddiffports = sch_andprim->firstportproto->nextportproto->nextportproto;
1380 sch_andprim->firstportproto->nextportproto->nextportproto = NOPORTPROTO;
1381
1382 sch_ordiffports = sch_orprim->firstportproto->nextportproto->nextportproto;
1383 sch_orprim->firstportproto->nextportproto->nextportproto = NOPORTPROTO;
1384
1385 sch_xordiffports = sch_xorprim->firstportproto->nextportproto->nextportproto;
1386 sch_xorprim->firstportproto->nextportproto->nextportproto = NOPORTPROTO;
1387 net_redoprim();
1388 return;
1389 }
1390 if (namesamen(pp, x_("enable-differential-ports"), l) == 0)
1391 {
1392 if (sch_anddiffports == NOPORTPROTO)
1393 {
1394 ttyputerr(M_("Differential ports are already enabled"));
1395 return;
1396 }
1397 sch_andprim->firstportproto->nextportproto->nextportproto = sch_anddiffports;
1398 sch_orprim->firstportproto->nextportproto->nextportproto = sch_ordiffports;
1399 sch_xorprim->firstportproto->nextportproto->nextportproto = sch_xordiffports;
1400 sch_anddiffports = sch_ordiffports = sch_xordiffports = NOPORTPROTO;
1401 net_redoprim();
1402 return;
1403 }
1404 ttyputbadusage(x_("technology tell schematic"));
1405 }
1406
sch_request(CHAR * command,va_list ap)1407 INTBIG sch_request(CHAR *command, va_list ap)
1408 {
1409 REGISTER PORTPROTO *pp;
1410
1411 if (namesame(command, x_("ignoring-resistor-topology")) == 0)
1412 {
1413 pp = sch_resistorprim->firstportproto->nextportproto;
1414 if ((pp->userbits&PORTNET) == 0) return(1);
1415 return(0);
1416 }
1417 if (namesame(command, x_("ignore-resistor-topology")) == 0)
1418 {
1419 pp = sch_resistorprim->firstportproto->nextportproto;
1420 pp->userbits = (pp->userbits & ~PORTNET);
1421 net_redoprim();
1422 return(0);
1423 }
1424 if (namesame(command, x_("include-resistor-topology")) == 0)
1425 {
1426 pp = sch_resistorprim->firstportproto->nextportproto;
1427 pp->userbits = (pp->userbits & ~PORTNET) | (1 << PORTNETSH);
1428 net_redoprim();
1429 return(0);
1430 }
1431
1432 if (namesame(command, x_("get-bubble-size")) == 0)
1433 {
1434 return(sch_bubblediameter);
1435 }
1436 if (namesame(command, x_("set-bubble-size")) == 0)
1437 {
1438 sch_bubblediameter = va_arg(ap, INTBIG);
1439 return(0);
1440 }
1441 return(0);
1442 }
1443
sch_nodepolys(NODEINST * ni,INTBIG * reasonable,WINDOWPART * win)1444 INTBIG sch_nodepolys(NODEINST *ni, INTBIG *reasonable, WINDOWPART *win)
1445 {
1446 return(sch_intnodepolys(ni, reasonable, win, &tech_oneprocpolyloop, &sch_oneprocpolyloop));
1447 }
1448
sch_intnodepolys(NODEINST * ni,INTBIG * reasonable,WINDOWPART * win,POLYLOOP * pl,SCHPOLYLOOP * schpl)1449 INTBIG sch_intnodepolys(NODEINST *ni, INTBIG *reasonable, WINDOWPART *win, POLYLOOP *pl, SCHPOLYLOOP *schpl)
1450 {
1451 REGISTER INTBIG total, pindex, buscon, nonbuscon, hei, arcs, i, implicitcon;
1452 INTBIG depth;
1453 NODEINST **nilist, *upni;
1454 REGISTER PORTARCINST *pi;
1455 REGISTER PORTEXPINST *pe;
1456 REGISTER PORTPROTO *pp;
1457
1458 /* get the default number of polygons and list of layers */
1459 pindex = ni->proto->primindex;
1460 total = sch_nodeprotos[pindex-1]->layercount;
1461 schpl->layerlist = sch_nodeprotos[pindex-1]->layerlist;
1462
1463 /* special cases for special primitives */
1464 switch (pindex)
1465 {
1466 case NWIREPIN: /* wire pins disappear with one or two wires */
1467 if (tech_pinusecount(ni, win)) total = 0;
1468 break;
1469
1470 case NBUSPIN: /* bus pins get bigger in "T" configurations, disappear when alone and exported */
1471 buscon = nonbuscon = 0;
1472 for (pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1473 {
1474 if (pi->conarcinst->proto == sch_busarc) buscon++; else
1475 nonbuscon++;
1476 }
1477 if (buscon == 0 && nonbuscon == 0) implicitcon = 1; else
1478 implicitcon = 0;
1479
1480 /* if the next level up the hierarchy is visible, consider arcs connected there */
1481 if (win != NOWINDOWPART && ni->firstportexpinst != NOPORTEXPINST)
1482 {
1483 db_gettraversalpath(ni->parent, NOWINDOWPART, &nilist, &depth);
1484 if (depth == 1)
1485 {
1486 upni = nilist[0];
1487 if (upni->proto == ni->parent && upni->parent == win->curnodeproto)
1488 {
1489 for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
1490 {
1491 for (pi = upni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1492 {
1493 if (pi->proto != pe->exportproto) continue;
1494 if (pi->conarcinst->proto == sch_busarc) buscon++; else
1495 nonbuscon++;
1496 }
1497 }
1498 }
1499 }
1500 }
1501
1502 /* bus pins don't show wire pin in center if not tapped */
1503 if (nonbuscon == 0) total--;
1504
1505 schpl->buspinlayer = LBUS;
1506 schpl->buspinpoints = sch_g_buspindisc;
1507 if (buscon+implicitcon > 2)
1508 {
1509 /* larger pin because it is connected to 3 or more bus arcs */
1510 schpl->buspinsize = H0;
1511 } else
1512 {
1513 /* smaller pin because it has 0, 1, or 2 connections */
1514 schpl->buspinsize = Q0;
1515 if (buscon == 0)
1516 {
1517 if (nonbuscon+implicitcon > 2)
1518 {
1519 schpl->buspinlayer = LARC;
1520 schpl->buspinpoints = sch_g_bustapdisc;
1521 total--;
1522 } else
1523 {
1524 if (ni->firstportexpinst != NOPORTEXPINST)
1525 total = 0;
1526 }
1527 }
1528 }
1529 break;
1530
1531 case NFF: /* determine graphics to use for FlipFlops */
1532 switch (ni->userbits&FFCLOCK)
1533 {
1534 case FFCLOCKMS: /* FlipFlop is Master/slave */
1535 schpl->layerlist = sch_ffms_l;
1536 break;
1537 case FFCLOCKP: /* FlipFlop is Positive clock */
1538 schpl->layerlist = sch_ffp_l;
1539 break;
1540 case FFCLOCKN: /* FlipFlop is Negative clock */
1541 schpl->layerlist = sch_ffn_l;
1542 break;
1543 }
1544 break;
1545
1546 case NSWITCH: /* add in multiple connection sites for switch */
1547 hei = (ni->highy - ni->lowy) / lambdaofnode(ni);
1548 if (hei >= 4) total += (hei/2)-1;
1549 if (((hei/2)&1) == 0) schpl->switchbarvalue = 0; else
1550 schpl->switchbarvalue = K1;
1551 break;
1552
1553 case NTRANSISTOR: /* determine graphics to use for transistors */
1554 switch (ni->userbits&NTECHBITS)
1555 {
1556 case TRANNMOS: /* Transistor is N channel MOS */
1557 schpl->layerlist = sch_nmos_l;
1558 total = 3;
1559 break;
1560 case TRANDMOS: /* Transistor is Depletion MOS */
1561 schpl->layerlist = sch_dmos_l;
1562 total = 4;
1563 break;
1564 case TRANPMOS: /* Transistor is P channel MOS */
1565 schpl->layerlist = sch_pmos_l;
1566 total = 4;
1567 break;
1568 case TRANNPN: /* Transistor is NPN Junction */
1569 schpl->layerlist = sch_npn_l;
1570 total = 4;
1571 break;
1572 case TRANPNP: /* Transistor is PNP Junction */
1573 schpl->layerlist = sch_pnp_l;
1574 total = 4;
1575 break;
1576 case TRANNJFET: /* Transistor is N Channel Junction FET */
1577 schpl->layerlist = sch_njfet_l;
1578 total = 4;
1579 break;
1580 case TRANPJFET: /* Transistor is P Channel Junction FET */
1581 schpl->layerlist = sch_pjfet_l;
1582 total = 4;
1583 break;
1584 case TRANDMES: /* Transistor is Depletion MESFET */
1585 schpl->layerlist = sch_dmes_l;
1586 total = 3;
1587 break;
1588 case TRANEMES: /* Transistor is Enhancement MESFET */
1589 schpl->layerlist = sch_emes_l;
1590 total = 2;
1591 break;
1592 }
1593 break;
1594
1595 case NCAPACITOR: /* determine graphics to use for capacitors */
1596 if ((ni->userbits&NTECHBITS) == CAPACELEC)
1597 total++;
1598 break;
1599
1600 case NTWOPORT: /* determine graphics to use for Two-Ports */
1601 switch (ni->userbits&NTECHBITS)
1602 {
1603 case TWOPVCCS: /* Two-port is Transconductance (VCCS) */
1604 schpl->layerlist = sch_twoportvccs_l;
1605 total = 5;
1606 break;
1607 case TWOPCCVS: /* Two-port is Transresistance (CCVS) */
1608 schpl->layerlist = sch_twoportccvs_l;
1609 total = 6;
1610 break;
1611 case TWOPVCVS: /* Two-port is Voltage gain (VCVS) */
1612 schpl->layerlist = sch_twoportvcvs_l;
1613 total = 5;
1614 break;
1615 case TWOPCCCS: /* Two-port is Current gain (CCCS) */
1616 schpl->layerlist = sch_twoportcccs_l;
1617 total = 6;
1618 break;
1619 case TWOPTLINE: /* Two-port is Transmission Line */
1620 schpl->layerlist = sch_twoporttran_l;
1621 total = 7;
1622 break;
1623 }
1624 break;
1625 case NTRANSISTOR4: /* determine graphics to use for 4-port transistors */
1626 switch (ni->userbits&NTECHBITS)
1627 {
1628 case TRANNMOS: /* Transistor is N channel MOS */
1629 schpl->layerlist = sch_nmos4_l;
1630 total = 4;
1631 break;
1632 case TRANDMOS: /* Transistor is Depletion MOS */
1633 schpl->layerlist = sch_dmos4_l;
1634 total = 5;
1635 break;
1636 case TRANPMOS: /* Transistor is P channel MOS */
1637 schpl->layerlist = sch_pmos4_l;
1638 total = 5;
1639 break;
1640 case TRANNPN: /* Transistor is NPN Junction */
1641 schpl->layerlist = sch_npn4_l;
1642 total = 5;
1643 break;
1644 case TRANPNP: /* Transistor is PNP Junction */
1645 schpl->layerlist = sch_pnp4_l;
1646 total = 5;
1647 break;
1648 case TRANNJFET: /* Transistor is N Channel Junction FET */
1649 schpl->layerlist = sch_njfet4_l;
1650 total = 5;
1651 break;
1652 case TRANPJFET: /* Transistor is P Channel Junction FET */
1653 schpl->layerlist = sch_pjfet4_l;
1654 total = 5;
1655 break;
1656 case TRANDMES: /* Transistor is Depletion MESFET */
1657 schpl->layerlist = sch_dmes4_l;
1658 total = 4;
1659 break;
1660 case TRANEMES: /* Transistor is Enhancement MESFET */
1661 schpl->layerlist = sch_emes4_l;
1662 total = 3;
1663 break;
1664 }
1665 break;
1666 }
1667
1668 schpl->extrasteinerpoint = total;
1669 switch (pindex)
1670 {
1671 case NSWITCH:
1672 case NOFFPAGE:
1673 case NPWR:
1674 case NGND:
1675 case NSOURCE:
1676 case NTRANSISTOR:
1677 case NRESISTOR:
1678 case NCAPACITOR:
1679 case NDIODE:
1680 case NINDUCTOR:
1681 case NMETER:
1682 case NWELL:
1683 case NSUBSTRATE:
1684 case NTWOPORT:
1685 case NTRANSISTOR4:
1686 for(i=0; i<sch_nodeprotos[pindex-1]->portcount; i++)
1687 {
1688 pp = sch_nodeprotos[pindex-1]->portlist[i].addr;
1689 arcs = 0;
1690 for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1691 if (pi->proto == pp) arcs++;
1692 if (arcs > 1)
1693 {
1694 schpl->extrasteinerport[total - schpl->extrasteinerpoint] = &sch_nodeprotos[pindex-1]->portlist[i];
1695 total++;
1696 }
1697 }
1698 break;
1699 }
1700
1701 /* add in displayable variables */
1702 pl->realpolys = total;
1703 total += tech_displayablenvars(ni, pl->curwindowpart, pl);
1704 if (reasonable != 0) *reasonable = total;
1705 return(total);
1706 }
1707
sch_shapenodepoly(NODEINST * ni,INTBIG box,POLYGON * poly)1708 void sch_shapenodepoly(NODEINST *ni, INTBIG box, POLYGON *poly)
1709 {
1710 sch_intshapenodepoly(ni, box, poly, &tech_oneprocpolyloop, &sch_oneprocpolyloop);
1711 }
1712
sch_intshapenodepoly(NODEINST * ni,INTBIG box,POLYGON * poly,POLYLOOP * pl,SCHPOLYLOOP * schpl)1713 void sch_intshapenodepoly(NODEINST *ni, INTBIG box, POLYGON *poly, POLYLOOP *pl, SCHPOLYLOOP *schpl)
1714 {
1715 REGISTER INTBIG lambda, width, height;
1716 REGISTER VARIABLE *var;
1717 REGISTER TECH_PORTS *tp;
1718 REGISTER TECH_POLYGON *lay;
1719
1720 /* handle displayable variables */
1721 if (box >= pl->realpolys)
1722 {
1723 var = tech_filldisplayablenvar(ni, poly, pl->curwindowpart, 0, pl);
1724 return;
1725 }
1726
1727 /* get the unit size (lambda) */
1728 switch (ni->proto->primindex)
1729 {
1730 #ifdef SCALABLEGATES
1731 case NAND:
1732 width = ni->highx - ni->lowx;
1733 height = ni->highy - ni->lowy;
1734 lambda = width / 8;
1735 if (height < lambda * 6) lambda = height / 6;
1736 break;
1737 case NOR:
1738 case NXOR:
1739 width = ni->highx - ni->lowx;
1740 height = ni->highy - ni->lowy;
1741 lambda = width / 10;
1742 if (height < lambda * 6) lambda = height / 6;
1743 break;
1744 #endif
1745 default:
1746 lambda = lambdaofnode(ni);
1747 break;
1748 }
1749
1750 if (box >= schpl->extrasteinerpoint)
1751 {
1752 /* handle extra steiner points */
1753 tp = schpl->extrasteinerport[box - schpl->extrasteinerpoint];
1754 if (poly->limit < 2) (void)extendpolygon(poly, 2);
1755 poly->xv[0] = (getrange(ni->lowx, ni->highx, tp->lowxmul, tp->lowxsum, lambda) +
1756 getrange(ni->lowx, ni->highx, tp->highxmul, tp->highxsum, lambda)) / 2;
1757 poly->yv[0] = (getrange(ni->lowy, ni->highy, tp->lowymul, tp->lowysum, lambda) +
1758 getrange(ni->lowy, ni->highy, tp->highymul, tp->highysum, lambda)) / 2;
1759 poly->xv[1] = poly->xv[0] + sch_wirepinsizex/2;
1760 poly->yv[1] = poly->yv[0];
1761 poly->count = 2;
1762 poly->style = DISC;
1763 poly->layer = LARC;
1764 poly->tech = sch_tech;
1765 poly->desc = sch_layers[poly->layer];
1766 return;
1767 }
1768
1769 /* handle extra blobs on tall switches */
1770 lay = &schpl->layerlist[box];
1771 switch (ni->proto->primindex)
1772 {
1773 case NBUSPIN:
1774 if (box == 0)
1775 {
1776 sch_buspin_l[0].layernum = (INTSML)schpl->buspinlayer;
1777 sch_buspin_l[0].points = schpl->buspinpoints;
1778 sch_g_buspindisc[4] = schpl->buspinsize;
1779 }
1780 break;
1781 case NSWITCH:
1782 if (box >= 2)
1783 {
1784 sch_g_switchout[3] = sch_g_switchout[7] = WHOLE*2*(box-1) - WHOLE;
1785 box = 2;
1786 lay = &schpl->layerlist[box];
1787 }
1788 if (lay->points == sch_g_switchbar)
1789 sch_g_switchbar[7] = schpl->switchbarvalue;
1790 break;
1791 case NFF:
1792 if (lay->points == (INTBIG *)sch_g_fftextd)
1793 {
1794 switch (ni->userbits&FFTYPE)
1795 {
1796 case FFTYPERS: sch_g_fftextd[16] = sch_R; break;
1797 case FFTYPEJK: sch_g_fftextd[16] = sch_J; break;
1798 case FFTYPED: sch_g_fftextd[16] = sch_D; break;
1799 case FFTYPET: sch_g_fftextd[16] = sch_T; break;
1800 }
1801 } else if (lay->points == (INTBIG *)sch_g_fftexte)
1802 {
1803 switch (ni->userbits&FFTYPE)
1804 {
1805 case FFTYPERS: sch_g_fftexte[16] = sch_S; break;
1806 case FFTYPEJK: sch_g_fftexte[16] = sch_K; break;
1807 case FFTYPED: sch_g_fftexte[16] = sch_E; break;
1808 case FFTYPET: sch_g_fftexte[16] = sch_NULLSTR; break;
1809 }
1810 }
1811 break;
1812 case NDIODE: /* determine graphics to use for diodes */
1813 if (box == 0)
1814 {
1815 switch (ni->userbits&NTECHBITS)
1816 {
1817 case DIODENORM: /* Diode is normal */
1818 lay->points = sch_g_diode1;
1819 lay->count = 6;
1820 break;
1821 case DIODEZENER: /* Diode is Zener */
1822 lay->points = sch_g_diode3;
1823 lay->count = 10;
1824 break;
1825 }
1826 }
1827 break;
1828 }
1829
1830 tech_fillpoly(poly, lay, ni, lambda, FILLED);
1831 TDCLEAR(poly->textdescript);
1832 TDSETSIZE(poly->textdescript, lay->portnum);
1833 poly->tech = sch_tech;
1834 poly->desc = sch_layers[poly->layer];
1835 }
1836
sch_allnodepolys(NODEINST * ni,POLYLIST * plist,WINDOWPART * win,BOOLEAN onlyreasonable)1837 INTBIG sch_allnodepolys(NODEINST *ni, POLYLIST *plist, WINDOWPART *win, BOOLEAN onlyreasonable)
1838 {
1839 REGISTER INTBIG tot, j;
1840 INTBIG reasonable;
1841 REGISTER NODEPROTO *np;
1842 REGISTER POLYGON *poly;
1843 POLYLOOP mypl;
1844 SCHPOLYLOOP myschpl;
1845
1846 np = ni->proto;
1847 mypl.curwindowpart = win;
1848 tot = sch_intnodepolys(ni, &reasonable, win, &mypl, &myschpl);
1849 if (onlyreasonable) tot = reasonable;
1850 if (mypl.realpolys < tot) tot = mypl.realpolys;
1851 if (ensurepolylist(plist, tot, db_cluster)) return(-1);
1852 for(j = 0; j < tot; j++)
1853 {
1854 poly = plist->polygons[j];
1855 poly->tech = sch_tech;
1856 sch_intshapenodepoly(ni, j, poly, &mypl, &myschpl);
1857 }
1858 return(tot);
1859 }
1860
sch_nodeEpolys(NODEINST * ni,INTBIG * reasonable,WINDOWPART * win)1861 INTBIG sch_nodeEpolys(NODEINST *ni, INTBIG *reasonable, WINDOWPART *win)
1862 {
1863 Q_UNUSED( ni );
1864 Q_UNUSED( win );
1865
1866 if (reasonable != 0) *reasonable = 0;
1867 return(0);
1868 }
1869
sch_shapeEnodepoly(NODEINST * ni,INTBIG box,POLYGON * poly)1870 void sch_shapeEnodepoly(NODEINST *ni, INTBIG box, POLYGON *poly)
1871 {
1872 Q_UNUSED( ni );
1873 Q_UNUSED( box );
1874 Q_UNUSED( poly );
1875 }
1876
sch_allnodeEpolys(NODEINST * ni,POLYLIST * plist,WINDOWPART * win,BOOLEAN onlyreasonable)1877 INTBIG sch_allnodeEpolys(NODEINST *ni, POLYLIST *plist, WINDOWPART *win, BOOLEAN onlyreasonable)
1878 {
1879 Q_UNUSED( ni );
1880 Q_UNUSED( plist );
1881 Q_UNUSED( win );
1882 Q_UNUSED( onlyreasonable );
1883 return(0);
1884 }
1885
sch_nodesizeoffset(NODEINST * ni,INTBIG * lx,INTBIG * ly,INTBIG * hx,INTBIG * hy)1886 void sch_nodesizeoffset(NODEINST *ni, INTBIG *lx, INTBIG *ly, INTBIG *hx, INTBIG *hy)
1887 {
1888 REGISTER INTBIG index, width, height, unitsize;
1889
1890 index = ni->proto->primindex;
1891 switch (index)
1892 {
1893 #ifdef SCALABLEGATES
1894 case NAND:
1895 width = ni->highx - ni->lowx;
1896 height = ni->highy - ni->lowy;
1897 unitsize = width / 8;
1898 if (height < unitsize * 6) unitsize = height / 6;
1899 *lx = 0;
1900 *hx = unitsize/2;
1901 *ly = *hy = 0;
1902 break;
1903 case NOR:
1904 width = ni->highx - ni->lowx;
1905 height = ni->highy - ni->lowy;
1906 unitsize = width / 10;
1907 if (height < unitsize * 6) unitsize = height / 6;
1908 *lx = unitsize;
1909 *hx = unitsize/2;
1910 *ly = *hy = 0;
1911 break;
1912 case NXOR:
1913 width = ni->highx - ni->lowx;
1914 height = ni->highy - ni->lowy;
1915 unitsize = width / 10;
1916 if (height < unitsize * 6) unitsize = height / 6;
1917 *lx = 0;
1918 *hx = unitsize/2;
1919 *ly = *hy = 0;
1920 break;
1921 #endif
1922 default:
1923 tech_nodeprotosizeoffset(ni->proto, lx, ly, hx, hy, lambdaofnode(ni));
1924 break;
1925 }
1926 }
1927
sch_shapeportpoly(NODEINST * ni,PORTPROTO * pp,POLYGON * poly,XARRAY trans,BOOLEAN purpose)1928 void sch_shapeportpoly(NODEINST *ni, PORTPROTO *pp, POLYGON *poly, XARRAY trans,
1929 BOOLEAN purpose)
1930 {
1931 REGISTER INTBIG pindex, i, e, total, besti, xposition, yposition, x, y, lambda,
1932 wantx, wanty, bestdist, bestx, besty, dist, width, height;
1933 REGISTER PORTARCINST *pi;
1934 REGISTER ARCINST *ai;
1935 REGISTER WINDOWPART *w;
1936
1937 pindex = ni->proto->primindex;
1938
1939 switch (ni->proto->primindex)
1940 {
1941 #ifdef SCALABLEGATES
1942 case NAND:
1943 width = ni->highx - ni->lowx;
1944 height = ni->highy - ni->lowy;
1945 lambda = width / 8;
1946 if (height < lambda * 6) lambda = height / 6;
1947 break;
1948 case NOR:
1949 case NXOR:
1950 width = ni->highx - ni->lowx;
1951 height = ni->highy - ni->lowy;
1952 lambda = width / 10;
1953 if (height < lambda * 6) lambda = height / 6;
1954 break;
1955 #endif
1956 default:
1957 lambda = lambdaofnode(ni);
1958 break;
1959 }
1960
1961 /* special case for extendible primitives */
1962 if (purpose && sch_nodeprotos[pindex-1]->portlist[0].addr == pp)
1963 {
1964 /* initialize */
1965 wantx = poly->xv[0]; wanty = poly->yv[0];
1966 poly->count = 1;
1967 poly->style = FILLED;
1968 bestdist = MAXINTBIG;
1969 besti = bestx = besty = 0;
1970
1971 /* schematic gates must keep connections discrete and separate */
1972 if (pindex == NAND || pindex == NOR || pindex == NXOR || pindex == NMUX)
1973 {
1974 /* determine total number of arcs already on this port */
1975 for(total=0, pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1976 if (pi->proto == pp) total++;
1977
1978 /* cycle through the arc positions */
1979 total = maxi(total+2, 3);
1980 for(i=0; i<total; i++)
1981 {
1982 /* compute the position along the left edge */
1983 yposition = (i+1)/2 * WHOLE * 2;
1984 if ((i&1) != 0) yposition = -yposition;
1985
1986 /* compute indentation (for OR and XOR) */
1987 if (pindex != NMUX) xposition = -K4; else
1988 xposition = -(ni->highx - ni->lowx) * 4 / 10 * WHOLE / lambda;
1989 if (pindex == NOR || pindex == NXOR) switch (i)
1990 {
1991 case 0: xposition += T0; break;
1992 case 1:
1993 case 2: xposition += H0; break;
1994 }
1995
1996 /* fill the polygon with that point */
1997 x = getrange(ni->lowx, ni->highx, 0, xposition, lambda);
1998 y = getrange(ni->lowy, ni->highy, 0, yposition, lambda);
1999 xform(x, y, &poly->xv[0], &poly->yv[0], trans);
2000 x = poly->xv[0]; y = poly->yv[0];
2001
2002 /* check for duplication */
2003 for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
2004 {
2005 ai = pi->conarcinst;
2006 if (ai->end[0].portarcinst == pi) e = 0; else e = 1;
2007 if (ai->end[e].xpos == x && ai->end[e].ypos == y) break;
2008 }
2009
2010 /* if there is no duplication, this is a possible position */
2011 if (pi == NOPORTARCINST)
2012 {
2013 dist = abs(wantx - x) + abs(wanty - y);
2014 if (dist < bestdist)
2015 {
2016 bestdist = dist; bestx = x; besty = y; besti = i;
2017 }
2018 }
2019 }
2020 if (bestdist == MAXINTBIG) ttyputerr(_("Warning: cannot find gate port"));
2021
2022 /* set the closest port */
2023 poly->xv[0] = bestx; poly->yv[0] = besty;
2024
2025 /* make sure the node is large enough */
2026 if (besti*lambda*2 >= ni->highy - ni->lowy)
2027 {
2028 startobjectchange((INTBIG)ni, VNODEINST);
2029 modifynodeinst(ni, 0, -lambda*2, 0, lambda*2, 0, 0);
2030 endobjectchange((INTBIG)ni, VNODEINST);
2031
2032 /* make this gate change visible if it is in a window */
2033 for(w = el_topwindowpart; w != NOWINDOWPART; w = w->nextwindowpart)
2034 if (w->curnodeproto == ni->parent) break;
2035 if (w != NOWINDOWPART) (void)asktool(us_tool, x_("flush-changes"));
2036 }
2037 return;
2038 }
2039
2040 /* switches must discretize the location of connections */
2041 if (pindex == NSWITCH)
2042 {
2043 /* cycle through the possible positions */
2044 total = (ni->highy - ni->lowy) / lambda / 2;
2045 for(i=0; i<total; i++)
2046 {
2047 yposition = i * 2 * WHOLE + K1;
2048 xposition = -K2;
2049 x = getrange(ni->lowx, ni->highx, 0, xposition, lambda);
2050 y = getrange(ni->lowy, ni->highy, -H0, yposition, lambda);
2051 xform(x, y, &poly->xv[0], &poly->yv[0], trans);
2052 x = poly->xv[0]; y = poly->yv[0];
2053 dist = abs(wantx - x) + abs(wanty - y);
2054 if (dist < bestdist)
2055 {
2056 bestdist = dist; bestx = x; besty = y; besti = i;
2057 }
2058 }
2059 if (bestdist == MAXINTBIG) ttyputerr(_("Warning: cannot find switch port"));
2060
2061 /* set the closest port */
2062 poly->xv[0] = bestx; poly->yv[0] = besty;
2063 return;
2064 }
2065 }
2066 tech_fillportpoly(ni, pp, poly, trans, sch_nodeprotos[pindex-1], CLOSED, lambda);
2067 }
2068
sch_arcpolys(ARCINST * ai,WINDOWPART * win)2069 INTBIG sch_arcpolys(ARCINST *ai, WINDOWPART *win)
2070 {
2071 return(sch_intarcpolys(ai, win, &tech_oneprocpolyloop, &sch_oneprocpolyloop));
2072 }
2073
sch_intarcpolys(ARCINST * ai,WINDOWPART * win,POLYLOOP * pl,SCHPOLYLOOP * schpl)2074 INTBIG sch_intarcpolys(ARCINST *ai, WINDOWPART *win, POLYLOOP *pl, SCHPOLYLOOP *schpl)
2075 {
2076 REGISTER INTBIG i;
2077
2078 i = sch_arcprotos[ai->proto->arcindex]->laycount;
2079 schpl->bubblebox = schpl->arrowbox = -1;
2080 if ((ai->userbits&(ISNEGATED|NOTEND0)) == ISNEGATED) schpl->bubblebox = i++;
2081 if ((ai->userbits&ISDIRECTIONAL) != 0) schpl->arrowbox = i++;
2082
2083 /* add in displayable variables */
2084 pl->realpolys = i;
2085 i += tech_displayableavars(ai, win, pl);
2086 return(i);
2087 }
2088
sch_shapearcpoly(ARCINST * ai,INTBIG box,POLYGON * poly)2089 void sch_shapearcpoly(ARCINST *ai, INTBIG box, POLYGON *poly)
2090 {
2091 sch_intshapearcpoly(ai, box, poly, &tech_oneprocpolyloop, &sch_oneprocpolyloop);
2092 }
2093
sch_intshapearcpoly(ARCINST * ai,INTBIG box,POLYGON * poly,POLYLOOP * pl,SCHPOLYLOOP * schpl)2094 void sch_intshapearcpoly(ARCINST *ai, INTBIG box, POLYGON *poly, POLYLOOP *pl, SCHPOLYLOOP *schpl)
2095 {
2096 REGISTER INTBIG aindex, bubbleend;
2097 REGISTER INTBIG angle;
2098 REGISTER INTBIG x1,y1, cosdist, sindist, x2,y2, lambda, i,
2099 saveendx, saveendy, bubblesize;
2100 REGISTER TECH_ARCLAY *thista;
2101
2102 /* handle displayable variables */
2103 if (box >= pl->realpolys)
2104 {
2105 (void)tech_filldisplayableavar(ai, poly, pl->curwindowpart, 0, pl);
2106 return;
2107 }
2108
2109 /* initialize for the arc */
2110 aindex = ai->proto->arcindex;
2111 thista = &sch_arcprotos[aindex]->list[box];
2112 poly->layer = thista->lay;
2113 poly->desc = sch_layers[poly->layer];
2114 lambda = lambdaofarc(ai);
2115 if (schpl->bubblebox < 0 && schpl->arrowbox < 0)
2116 {
2117 /* simple arc */
2118 makearcpoly(ai->length, ai->width-thista->off*lambda/WHOLE,
2119 ai, poly, thista->style);
2120 return;
2121 }
2122
2123 /* prepare special information for negated and/or directional arcs */
2124 bubbleend = 0;
2125 x1 = ai->end[0].xpos; y1 = ai->end[0].ypos;
2126 x2 = ai->end[1].xpos; y2 = ai->end[1].ypos;
2127 angle = ((ai->userbits&AANGLE) >> AANGLESH) * 10;
2128 if ((ai->userbits&REVERSEEND) != 0)
2129 {
2130 i = x1; x1 = x2; x2 = i;
2131 i = y1; y1 = y2; y2 = i;
2132 bubbleend = 1;
2133 angle = (angle+1800) % 3600;
2134 }
2135 bubblesize = sch_bubblediameter * lambda;
2136 cosdist = mult(cosine(angle), bubblesize) / WHOLE;
2137 sindist = mult(sine(angle), bubblesize) / WHOLE;
2138
2139 /* handle the main body of the arc */
2140 if (box == 0)
2141 {
2142 if (schpl->bubblebox >= 0)
2143 {
2144 /* draw the arc, shortened at the end for the negating bubble */
2145 saveendx = ai->end[bubbleend].xpos;
2146 saveendy = ai->end[bubbleend].ypos;
2147 ai->end[bubbleend].xpos = x1 + cosdist;
2148 ai->end[bubbleend].ypos = y1 + sindist;
2149 makearcpoly(ai->length-sch_bubblediameter,
2150 ai->width-thista->off*lambda/WHOLE, ai, poly, thista->style);
2151 ai->end[bubbleend].xpos = saveendx;
2152 ai->end[bubbleend].ypos = saveendy;
2153 } else
2154 {
2155 makearcpoly(ai->length, ai->width-thista->off*lambda/WHOLE,
2156 ai, poly, thista->style);
2157 }
2158 return;
2159 }
2160
2161 /* draw the negating bubble */
2162 if (box == schpl->bubblebox)
2163 {
2164 poly->count = 2;
2165 if (poly->limit < 2) (void)extendpolygon(poly, 2);
2166 poly->xv[0] = x1 + cosdist / 2;
2167 poly->yv[0] = y1 + sindist / 2;
2168 poly->xv[1] = x1; poly->yv[1] = y1;
2169 poly->style = CIRCLE;
2170 return;
2171 }
2172
2173 /* draw the directional arrow */
2174 if (box == schpl->arrowbox)
2175 {
2176 if ((ai->userbits&(ISNEGATED|NOTEND0)) == ISNEGATED)
2177 {
2178 x1 += cosdist;
2179 y1 += sindist;
2180 }
2181 poly->style = VECTORS;
2182 poly->layer = -1;
2183 if (aindex == ABUS)
2184 {
2185 poly->desc = &sch_t_lay;
2186 x2 -= cosdist / 2;
2187 y2 -= sindist / 2;
2188 }
2189 if (poly->limit < 2) (void)extendpolygon(poly, 2);
2190 poly->count = 2;
2191 poly->xv[0] = x1; poly->yv[0] = y1;
2192 poly->xv[1] = x2; poly->yv[1] = y2;
2193 if ((ai->userbits&NOTEND1) == 0)
2194 tech_addheadarrow(poly, angle, x2, y2, lambda);
2195 }
2196 }
2197
sch_allarcpolys(ARCINST * ai,POLYLIST * plist,WINDOWPART * win)2198 INTBIG sch_allarcpolys(ARCINST *ai, POLYLIST *plist, WINDOWPART *win)
2199 {
2200 REGISTER INTBIG tot, j;
2201 POLYLOOP mypl;
2202 SCHPOLYLOOP myschpl;
2203
2204 mypl.curwindowpart = win;
2205 tot = sch_intarcpolys(ai, win, &mypl, &myschpl);
2206 tot = mypl.realpolys;
2207 if (ensurepolylist(plist, tot, db_cluster)) return(-1);
2208 for(j = 0; j < tot; j++)
2209 {
2210 sch_intshapearcpoly(ai, j, plist->polygons[j], &mypl, &myschpl);
2211 }
2212 return(tot);
2213 }
2214