FreeCalypso > hg > ueda-linux
comparison ueda/unet-bind/readunet.c @ 101:ffab0a4424ad
ueda: unet-bind program moved into sensibly named unet-bind subdir
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 29 Sep 2019 22:42:41 +0000 |
parents | ueda/sverp-bind/readunet.c@ce887659d12e |
children |
comparison
equal
deleted
inserted
replaced
100:071b24bca546 | 101:ffab0a4424ad |
---|---|
1 #include <stdio.h> | |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <strings.h> | |
5 #include "../libueda/xga.h" | |
6 #include "../libunet/unetrd.h" | |
7 #include "struct.h" | |
8 | |
9 extern char *pinname_to_pinnumber(); | |
10 extern struct net *find_net_by_name(); | |
11 extern struct instance *find_instance(); | |
12 | |
13 extern char *input_filename; | |
14 extern int unbound_instances; | |
15 | |
16 static struct unetrd_state rdstate; | |
17 static struct unetrd_out rdout; | |
18 | |
19 static int | |
20 resolve_pinnum_numeric(oc, pinnumstr) | |
21 struct outcomp *oc; | |
22 register char *pinnumstr; | |
23 { | |
24 register int num; | |
25 | |
26 if (!string_is_valid_decnum(pinnumstr)) { | |
27 invnum: fprintf(stderr, | |
28 "%s line %d: component %s has numeric pins and \"%s\" is not a valid pin number\n", | |
29 input_filename, rdstate.lineno, oc->name, pinnumstr); | |
30 exit(1); | |
31 } | |
32 num = atoi(pinnumstr); | |
33 if (num < 1) | |
34 goto invnum; | |
35 if (num > oc->npins) { | |
36 fprintf(stderr, | |
37 "%s line %d: attempting connection to pin %d on component %s that only has %d pins\n", | |
38 input_filename, rdstate.lineno, num, oc->name, | |
39 oc->npins); | |
40 exit(1); | |
41 } | |
42 return(num - 1); | |
43 } | |
44 | |
45 static int | |
46 resolve_pinnum_grid(oc, pinnumstr) | |
47 struct outcomp *oc; | |
48 char *pinnumstr; | |
49 { | |
50 register struct grid_pkg_desc *xga = oc->grid_pkg; | |
51 struct xga_parsed_pinnum rowcol; | |
52 register int idx; | |
53 | |
54 if (parse_xga_pinnumber(xga, pinnumstr, &rowcol) < 0) { | |
55 fprintf(stderr, | |
56 "%s line %d: \"%s\" is not a valid pin number for grid package %s\n", | |
57 input_filename, rdstate.lineno, pinnumstr, oc->name); | |
58 exit(1); | |
59 } | |
60 idx = rowcol.row_0based * xga->ncolumns + rowcol.col_0based; | |
61 if (xga->holes_array[idx]) { | |
62 fprintf(stderr, | |
63 "%s line %d: pin position %s is a hole in the grid package for %s\n", | |
64 input_filename, rdstate.lineno, pinnumstr, oc->name); | |
65 exit(1); | |
66 } | |
67 return(idx); | |
68 } | |
69 | |
70 static int | |
71 resolve_pinnum(oc, pinnumstr) | |
72 register struct outcomp *oc; | |
73 char *pinnumstr; | |
74 { | |
75 if (oc->grid_pkg) | |
76 return resolve_pinnum_grid(oc, pinnumstr); | |
77 else | |
78 return resolve_pinnum_numeric(oc, pinnumstr); | |
79 } | |
80 | |
81 static struct pinconn * | |
82 create_pinconn() | |
83 { | |
84 register struct pinconn *conn; | |
85 register struct net *net; | |
86 | |
87 if (rdout.connect_to_net) { | |
88 net = find_net_by_name(rdout.connect_to_net); | |
89 conn = (struct pinconn *) malloc(sizeof(struct pinconn)); | |
90 if (!conn) { | |
91 perror("malloc"); | |
92 exit(1); | |
93 } | |
94 conn->net = net; | |
95 conn->nc_comment = 0; | |
96 } else { | |
97 conn = (struct pinconn *) malloc(sizeof(struct pinconn) + | |
98 strlen(rdout.nc_comment) + 1); | |
99 if (!conn) { | |
100 perror("malloc"); | |
101 exit(1); | |
102 } | |
103 conn->net = 0; | |
104 conn->nc_comment = (char *)(conn + 1); | |
105 strcpy(conn->nc_comment, rdout.nc_comment); | |
106 } | |
107 conn->input_lineno = rdstate.lineno; | |
108 return conn; | |
109 } | |
110 | |
111 static void | |
112 connect_pin(oc, pinnumstr) | |
113 register struct outcomp *oc; | |
114 char *pinnumstr; | |
115 { | |
116 register int pinidx; | |
117 | |
118 pinidx = resolve_pinnum(oc, pinnumstr); | |
119 if (oc->reverse_2pin) | |
120 pinidx = !pinidx; | |
121 if (oc->conn_array[pinidx]) { | |
122 fprintf(stderr, | |
123 "error: multiple connections to %s pin %s (input lines %d and %d)\n", | |
124 oc->name, pinnumstr, | |
125 oc->conn_array[pinidx]->input_lineno, rdstate.lineno); | |
126 exit(1); | |
127 } | |
128 oc->conn_array[pinidx] = create_pinconn(); | |
129 } | |
130 | |
131 static void | |
132 process_pinmap(inst) | |
133 struct instance *inst; | |
134 { | |
135 register struct outcomp *oc = inst->outcomp; | |
136 register char *pinnum; | |
137 | |
138 if (!oc->mclcomp) { | |
139 fprintf(stderr, | |
140 "%s line %d: PINMAP is meaningless for starpoints\n", | |
141 input_filename, rdstate.lineno); | |
142 exit(1); | |
143 } | |
144 pinnum = pinname_to_pinnumber(oc->mclcomp, rdout.objname, inst->slot); | |
145 if (!pinnum) { | |
146 fprintf(stderr, "PINMAP error on %s line %d\n", | |
147 input_filename, rdstate.lineno); | |
148 exit(1); | |
149 } | |
150 connect_pin(oc, pinnum); | |
151 } | |
152 | |
153 static void | |
154 process_component() | |
155 { | |
156 struct instance *inst; | |
157 | |
158 inst = find_instance(rdout.objname); | |
159 if (!inst) { | |
160 fprintf(stderr, "%s line %d: instance %s not bound in MCL\n", | |
161 input_filename, rdstate.lineno, rdout.objname); | |
162 unbound_instances++; | |
163 } else { | |
164 if (inst->claimed) { | |
165 fprintf(stderr, | |
166 "%s line %d: instance %s appears more than once\n", | |
167 input_filename, rdstate.lineno, inst->name); | |
168 exit(1); | |
169 } | |
170 inst->claimed = 1; | |
171 } | |
172 for (;;) { | |
173 if (!read_unet_line(&rdstate, &rdout)) { | |
174 fprintf(stderr, "%s error: EOF in component block\n", | |
175 input_filename); | |
176 exit(1); | |
177 } | |
178 if (rdout.typecode == UNETOBJ_CLOSINGBRACE) | |
179 break; | |
180 switch(rdout.typecode) { | |
181 case UNETOBJ_PRIMITIVE: | |
182 case UNETOBJ_ALTNAME: | |
183 case UNETOBJ_ATTR: | |
184 continue; | |
185 case UNETOBJ_PIN: | |
186 if (inst) | |
187 connect_pin(inst->outcomp, rdout.objname); | |
188 continue; | |
189 case UNETOBJ_PINMAP: | |
190 if (inst) | |
191 process_pinmap(inst); | |
192 continue; | |
193 default: | |
194 fprintf(stderr, | |
195 "%s line %d: object type %s unexpected in component block\n", | |
196 input_filename, rdstate.lineno, rdout.keyword); | |
197 exit(1); | |
198 } | |
199 } | |
200 } | |
201 | |
202 process_input_unet() | |
203 { | |
204 open_unet_input_file(input_filename, &rdstate); | |
205 while (read_unet_line(&rdstate, &rdout)) { | |
206 switch(rdout.typecode) { | |
207 case UNETOBJ_CLOSINGBRACE: | |
208 fprintf(stderr, | |
209 "%s line %d: unexpected '}' outside of component block\n", | |
210 input_filename, rdstate.lineno); | |
211 exit(1); | |
212 case UNETOBJ_NET: | |
213 enter_net_object(rdout.objname, 0); | |
214 continue; | |
215 case UNETOBJ_COMPONENT: | |
216 process_component(); | |
217 continue; | |
218 case UNETOBJ_STARPOINT: | |
219 fprintf(stderr, | |
220 "error: STARPOINT objects not expected in unet-bind input (%s line %d)\n", | |
221 input_filename, rdstate.lineno); | |
222 exit(1); | |
223 default: | |
224 fprintf(stderr, | |
225 "%s line %d: unexpected object type %s\n", | |
226 input_filename, rdstate.lineno, rdout.keyword); | |
227 exit(1); | |
228 } | |
229 } | |
230 } |