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 }