comparison ueda/sverp-bind/readunet.c @ 19:1d4c693b8f35

unet-bind: sverp netlist reading implemented
author Space Falcon <falcon@ivan.Harhan.ORG>
date Sun, 02 Aug 2015 03:09:15 +0000
parents
children dcdf606dfaaa
comparison
equal deleted inserted replaced
18:52000ae7a6cf 19:1d4c693b8f35
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->conn_array[pinidx]) {
120 fprintf(stderr,
121 "error: multiple connections to %s pin %s (input lines %d and %d)\n",
122 oc->name, pinnumstr,
123 oc->conn_array[pinidx]->input_lineno, rdstate.lineno);
124 exit(1);
125 }
126 oc->conn_array[pinidx] = create_pinconn();
127 }
128
129 static void
130 process_pinmap(inst)
131 struct instance *inst;
132 {
133 register struct outcomp *oc = inst->outcomp;
134 register char *pinnum;
135
136 if (!oc->mclcomp) {
137 fprintf(stderr,
138 "%s line %d: PINMAP is meaningless for starpoints\n",
139 input_filename, rdstate.lineno);
140 exit(1);
141 }
142 pinnum = pinname_to_pinnumber(oc->mclcomp, rdout.objname, inst->slot);
143 if (!pinnum) {
144 fprintf(stderr, "PINMAP error on %s line %d\n",
145 input_filename, rdstate.lineno);
146 exit(1);
147 }
148 connect_pin(oc, pinnum);
149 }
150
151 static void
152 process_component()
153 {
154 struct instance *inst;
155
156 inst = find_instance(rdout.objname);
157 if (!inst) {
158 fprintf(stderr, "%s line %d: instance %s not bound in MCL\n",
159 input_filename, rdstate.lineno, rdout.objname);
160 unbound_instances++;
161 } else {
162 if (inst->claimed) {
163 fprintf(stderr,
164 "%s line %d: instance %s appears more than once\n",
165 input_filename, rdstate.lineno, inst->name);
166 exit(1);
167 }
168 inst->claimed = 1;
169 }
170 for (;;) {
171 if (!read_unet_line(&rdstate, &rdout)) {
172 fprintf(stderr, "%s error: EOF in component block\n",
173 input_filename);
174 exit(1);
175 }
176 if (rdout.typecode == UNETOBJ_CLOSINGBRACE)
177 break;
178 switch(rdout.typecode) {
179 case UNETOBJ_PRIMITIVE:
180 case UNETOBJ_ALTNAME:
181 continue;
182 case UNETOBJ_PIN:
183 if (inst)
184 connect_pin(inst->outcomp, rdout.objname);
185 continue;
186 case UNETOBJ_PINMAP:
187 if (inst)
188 process_pinmap(inst);
189 continue;
190 default:
191 fprintf(stderr,
192 "%s line %d: object type %s unexpected in component block\n",
193 input_filename, rdstate.lineno, rdout.keyword);
194 exit(1);
195 }
196 }
197 }
198
199 process_input_unet()
200 {
201 open_unet_input_file(input_filename, &rdstate);
202 while (read_unet_line(&rdstate, &rdout)) {
203 switch(rdout.typecode) {
204 case UNETOBJ_CLOSINGBRACE:
205 fprintf(stderr,
206 "%s line %d: unexpected '}' outside of component block\n",
207 input_filename, rdstate.lineno);
208 exit(1);
209 case UNETOBJ_NET:
210 enter_net_object(rdout.objname, 0);
211 continue;
212 case UNETOBJ_COMPONENT:
213 process_component();
214 continue;
215 case UNETOBJ_STARPOINT:
216 fprintf(stderr,
217 "error: STARPOINT objects not expected in unet-bind input (%s line %d)\n",
218 input_filename, rdstate.lineno);
219 exit(1);
220 default:
221 fprintf(stderr,
222 "%s line %d: unexpected object type %s\n",
223 input_filename, rdstate.lineno, rdout.keyword);
224 exit(1);
225 }
226 }
227 }