1 /*
2 * Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
3 *
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 # include "edif.h"
21 # include <stdlib.h>
22 # include <string.h>
23 # include <assert.h>
24 # include "ivl_alloc.h"
25
26 typedef enum property_e {
27 PRP_NONE = 0,
28 PRP_STRING,
29 PRP_INTEGER
30 } property_t;
31
32 struct cellref_property_ {
33 const char*name;
34 property_t ptype;
35 union {
36 const char*str;
37 long num;
38 } value_;
39 struct cellref_property_*next;
40 };
41
42 struct edif_s {
43 const char*name;
44 /* List the ports of the design. */
45 unsigned nports;
46 struct __cell_port*ports;
47 /* All the external libraries attached to me. */
48 edif_xlibrary_t xlibs;
49 /* list the cellref instances. */
50 edif_cellref_t celref;
51 /* The root instance has cellref properties as well. */
52 struct cellref_property_*property;
53 /* Keep a list of all the nexa */
54 struct edif_joint_s*nexa;
55 };
56
57 struct edif_xlibrary_s {
58 /* Name of this library. */
59 const char*name;
60 /* The cells that are contained in this library. */
61 struct edif_cell_s*cells;
62 /* point to the optional celltable. */
63 const struct edif_xlib_celltable*celltable;
64 /* used to list libraries in an edif_t. */
65 struct edif_xlibrary_s*next;
66 };
67
68
69 struct __cell_port {
70 const char*name;
71 const char*ename;
72 struct cellref_property_*property;
73 ivl_signal_port_t dir;
74 };
75
76 struct edif_cell_s {
77 const char*name;
78 edif_xlibrary_t xlib;
79
80 unsigned nports;
81 struct __cell_port*ports;
82
83 struct cellref_property_*property;
84 struct edif_cell_s*next;
85 };
86
87 struct edif_cellref_s {
88 struct edif_cell_s* cell;
89 unsigned u;
90 struct cellref_property_*property;
91 struct edif_cellref_s* next;
92 };
93
94 struct joint_cell_ {
95 struct edif_cellref_s*cell;
96 unsigned port;
97 struct joint_cell_*next;
98 };
99
100 struct edif_joint_s {
101 const char*name;
102 struct joint_cell_*links;
103 struct edif_joint_s*next;
104 };
105
106
is_edif_name(const char * text)107 static int is_edif_name(const char*text)
108 {
109 static const char*edif_name_chars = "abcdefghijklmnopqrstuvwxyz"
110 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
111 "0123456789";
112 return (strspn(text, edif_name_chars) == strlen(text));
113 }
114
edif_create(const char * design_name,unsigned nports)115 edif_t edif_create(const char*design_name, unsigned nports)
116 {
117 edif_t edf = malloc(sizeof(struct edif_s));
118
119 edf->name = design_name;
120 edf->nports= nports;
121 edf->ports = nports? calloc(nports, sizeof(struct __cell_port)) : 0;
122 edf->celref= 0;
123 edf->xlibs = 0;
124 edf->property = 0;
125 edf->nexa = 0;
126
127 return edf;
128 }
129
edif_portconfig(edif_t edf,unsigned idx,const char * name,ivl_signal_port_t dir)130 void edif_portconfig(edif_t edf, unsigned idx,
131 const char*name, ivl_signal_port_t dir)
132 {
133 assert(idx < edf->nports);
134
135 edf->ports[idx].name = name;
136 if (is_edif_name(name)) {
137 edf->ports[idx].ename = 0;
138
139 } else {
140 char buf[16];
141 sprintf(buf, "PORT%u", idx);
142 edf->ports[idx].ename = strdup(buf);
143 }
144
145 edf->ports[idx].dir = dir;
146 }
147
edif_port_to_joint(edif_joint_t jnt,edif_t edf,unsigned port)148 void edif_port_to_joint(edif_joint_t jnt, edif_t edf, unsigned port)
149 {
150 struct joint_cell_* jc = malloc(sizeof(struct joint_cell_));
151
152 jc->cell = 0;
153 jc->port = port;
154 jc->next = jnt->links;
155 jnt->links = jc;
156 }
157
edif_pstring(edif_t edf,const char * name,const char * value)158 void edif_pstring(edif_t edf, const char*name, const char*value)
159 {
160 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
161 prp->name = name;
162 prp->ptype = PRP_STRING;
163 prp->value_.str = value;
164 prp->next = edf->property;
165 edf->property = prp;
166 }
167
edif_xlibrary_create(edif_t edf,const char * name)168 edif_xlibrary_t edif_xlibrary_create(edif_t edf, const char*name)
169 {
170 edif_xlibrary_t xlib = malloc(sizeof(struct edif_xlibrary_s));
171
172 xlib->name = name;
173 xlib->cells = 0;
174 xlib->celltable = 0;
175 xlib->next = edf->xlibs;
176 edf->xlibs = xlib;
177
178 return xlib;
179 }
180
edif_xlibrary_set_celltable(edif_xlibrary_t xlib,const struct edif_xlib_celltable * tab)181 void edif_xlibrary_set_celltable(edif_xlibrary_t xlib,
182 const struct edif_xlib_celltable*tab)
183 {
184 assert(xlib->celltable == 0);
185 xlib->celltable = tab;
186 }
187
edif_xlibrary_findcell(edif_xlibrary_t xlib,const char * cell_name)188 edif_cell_t edif_xlibrary_findcell(edif_xlibrary_t xlib,
189 const char*cell_name)
190 {
191 const struct edif_xlib_celltable*tcur;
192 edif_cell_t cur;
193
194 for (cur = xlib->cells ; cur ; cur = cur->next) {
195 if (strcmp(cell_name, cur->name) == 0)
196 return cur;
197 }
198
199 if (xlib->celltable == 0)
200 return 0;
201
202 for (tcur = xlib->celltable ; tcur->cell_name ; tcur += 1)
203 if (strcmp(cell_name, tcur->cell_name) == 0) {
204 return (tcur->cell_func)(xlib);
205 }
206
207 return 0;
208 }
209
edif_xlibrary_scope_cell(edif_xlibrary_t xlib,ivl_scope_t scope)210 edif_cell_t edif_xlibrary_scope_cell(edif_xlibrary_t xlib,
211 ivl_scope_t scope)
212 {
213 unsigned port_count, idx;
214 edif_cell_t cur;
215
216 /* Check to see if the cell is already somehow defined. */
217 cur = edif_xlibrary_findcell(xlib, ivl_scope_tname(scope));
218 if (cur) return cur;
219
220 /* Count the ports of the scope. */
221 port_count = 0;
222 for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) {
223 ivl_signal_t sig = ivl_scope_sig(scope, idx);
224
225 if (ivl_signal_port(sig) == IVL_SIP_NONE)
226 continue;
227
228 port_count += 1;
229 }
230
231 cur = edif_xcell_create(xlib, ivl_scope_tname(scope), port_count);
232
233 port_count = 0;
234 for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) {
235 ivl_signal_t sig = ivl_scope_sig(scope, idx);
236
237 if (ivl_signal_port(sig) == IVL_SIP_NONE)
238 continue;
239
240 edif_cell_portconfig(cur, port_count,
241 ivl_signal_basename(sig),
242 ivl_signal_port(sig));
243 port_count += 1;
244 }
245
246 return cur;
247 }
248
edif_xcell_create(edif_xlibrary_t xlib,const char * name,unsigned nports)249 edif_cell_t edif_xcell_create(edif_xlibrary_t xlib, const char*name,
250 unsigned nports)
251 {
252 unsigned idx;
253 edif_cell_t cell = malloc(sizeof(struct edif_cell_s));
254
255 cell->name = name;
256 cell->xlib = xlib;
257 cell->nports = nports;
258 cell->ports = calloc(nports, sizeof(struct __cell_port));
259 cell->property = 0;
260
261 for (idx = 0 ; idx < nports ; idx += 1) {
262 cell->ports[idx].name = "?";
263 cell->ports[idx].dir = IVL_SIP_NONE;
264 cell->ports[idx].property = 0;
265 }
266
267 cell->next = xlib->cells;
268 xlib->cells = cell;
269
270 return cell;
271 }
272
edif_cell_portconfig(edif_cell_t cell,unsigned idx,const char * name,ivl_signal_port_t dir)273 void edif_cell_portconfig(edif_cell_t cell, unsigned idx,
274 const char*name, ivl_signal_port_t dir)
275 {
276 assert(idx < cell->nports);
277
278 cell->ports[idx].name = name;
279 cell->ports[idx].dir = dir;
280 }
281
edif_cell_port_pstring(edif_cell_t cell,unsigned idx,const char * name,const char * value)282 void edif_cell_port_pstring(edif_cell_t cell, unsigned idx,
283 const char*name, const char*value)
284 {
285 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
286 prp->name = name;
287 prp->ptype = PRP_STRING;
288 prp->value_.str = value;
289 prp->next = cell->ports[idx].property;
290 cell->ports[idx].property = prp;
291 }
292
edif_cell_port_byname(edif_cell_t cell,const char * name)293 unsigned edif_cell_port_byname(edif_cell_t cell, const char*name)
294 {
295 unsigned idx = 0;
296 for (idx = 0 ; idx < cell->nports ; idx += 1)
297 if (strcmp(name, cell->ports[idx].name) == 0)
298 break;
299
300 return idx;
301 }
302
edif_cell_pstring(edif_cell_t cell,const char * name,const char * value)303 void edif_cell_pstring(edif_cell_t cell, const char*name,
304 const char*value)
305 {
306 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
307 prp->name = name;
308 prp->ptype = PRP_STRING;
309 prp->value_.str = value;
310 prp->next = cell->property;
311 cell->property = prp;
312 }
313
edif_cell_pinteger(edif_cell_t cell,const char * name,int value)314 void edif_cell_pinteger(edif_cell_t cell, const char*name,
315 int value)
316 {
317 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
318 prp->name = name;
319 prp->ptype = PRP_INTEGER;
320 prp->value_.num = value;
321 prp->next = cell->property;
322 cell->property = prp;
323 }
324
edif_cellref_create(edif_t edf,edif_cell_t cell)325 edif_cellref_t edif_cellref_create(edif_t edf, edif_cell_t cell)
326 {
327 static unsigned u_number = 0;
328 edif_cellref_t ref = malloc(sizeof(struct edif_cellref_s));
329
330 u_number += 1;
331
332 assert(cell);
333 assert(edf);
334
335 ref->u = u_number;
336 ref->cell = cell;
337 ref->property = 0;
338 ref->next = edf->celref;
339 edf->celref = ref;
340
341 return ref;
342 }
343
edif_cellref_pstring(edif_cellref_t ref,const char * name,const char * value)344 void edif_cellref_pstring(edif_cellref_t ref, const char*name,
345 const char*value)
346 {
347 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
348 prp->name = name;
349 prp->ptype = PRP_STRING;
350 prp->value_.str = value;
351 prp->next = ref->property;
352 ref->property = prp;
353 }
354
edif_cellref_pinteger(edif_cellref_t ref,const char * name,int value)355 void edif_cellref_pinteger(edif_cellref_t ref, const char*name, int value)
356 {
357 struct cellref_property_*prp = malloc(sizeof(struct cellref_property_));
358 prp->name = name;
359 prp->ptype = PRP_INTEGER;
360 prp->value_.num = value;
361 prp->next = ref->property;
362 ref->property = prp;
363 }
364
edif_joint_create(edif_t edf)365 edif_joint_t edif_joint_create(edif_t edf)
366 {
367 edif_joint_t jnt = malloc(sizeof(struct edif_joint_s));
368
369 jnt->name = 0;
370 jnt->links = 0;
371 jnt->next = edf->nexa;
372 edf->nexa = jnt;
373 return jnt;
374 }
375
edif_joint_of_nexus(edif_t edf,ivl_nexus_t nex)376 edif_joint_t edif_joint_of_nexus(edif_t edf, ivl_nexus_t nex)
377 {
378 void*tmp = ivl_nexus_get_private(nex);
379 edif_joint_t jnt;
380
381 if (tmp == 0) {
382 jnt = edif_joint_create(edf);
383 ivl_nexus_set_private(nex, jnt);
384 return jnt;
385 }
386
387 jnt = (edif_joint_t) tmp;
388 return jnt;
389 }
390
edif_joint_rename(edif_joint_t jnt,const char * name)391 void edif_joint_rename(edif_joint_t jnt, const char*name)
392 {
393 assert(jnt->name == 0);
394 jnt->name = name;
395 }
396
edif_add_to_joint(edif_joint_t jnt,edif_cellref_t cell,unsigned port)397 void edif_add_to_joint(edif_joint_t jnt, edif_cellref_t cell, unsigned port)
398 {
399 struct joint_cell_* jc = malloc(sizeof(struct joint_cell_));
400
401 jc->cell = cell;
402 jc->port = port;
403 jc->next = jnt->links;
404 jnt->links = jc;
405 }
406
fprint_property(FILE * fd,const struct cellref_property_ * prp)407 static void fprint_property(FILE*fd, const struct cellref_property_*prp)
408 {
409 fprintf(fd, "(property %s ", prp->name);
410 switch (prp->ptype) {
411 case PRP_NONE:
412 break;
413 case PRP_STRING:
414 fprintf(fd, "(string \"%s\")", prp->value_.str);
415 break;
416 case PRP_INTEGER:
417 fprintf(fd, "(integer %ld)", prp->value_.num);
418 break;
419 }
420 fprintf(fd, ")");
421 }
422
423 /*
424 * This function takes all the data structures that have been
425 * assembled by the code generator, and writes them into an EDIF
426 * formatted file.
427 */
edif_print(FILE * fd,edif_t edf)428 void edif_print(FILE*fd, edif_t edf)
429 {
430 edif_xlibrary_t xlib;
431 edif_cell_t cell;
432 edif_cellref_t ref;
433 edif_joint_t jnt;
434 struct cellref_property_*prp;
435 unsigned idx;
436
437 fprintf(fd, "(edif %s\n", edf->name);
438 fprintf(fd, " (edifVersion 2 0 0)\n");
439 fprintf(fd, " (edifLevel 0)\n");
440 fprintf(fd, " (keywordMap (keywordLevel 0))\n");
441 fprintf(fd, " (status\n");
442 fprintf(fd, " (written\n");
443 fprintf(fd, " (timeStamp 0 0 0 0 0 0)\n");
444 fprintf(fd, " (author \"unknown\")\n");
445 fprintf(fd, " (program \"Icarus Verilog/fpga.tgt\")))\n");
446 fflush(fd);
447
448 for (xlib = edf->xlibs ; xlib ; xlib = xlib->next) {
449
450 fprintf(fd, " (external %s "
451 "(edifLevel 0) "
452 "(technology (numberDefinition))\n",
453 xlib->name);
454
455 for (cell = xlib->cells ; cell ; cell = cell->next) {
456 fprintf(fd, " (cell %s (cellType GENERIC)\n",
457 cell->name);
458 fprintf(fd, " (view net\n"
459 " (viewType NETLIST)\n"
460 " (interface");
461
462 for (idx = 0 ; idx < cell->nports ; idx += 1) {
463 struct __cell_port*pp = cell->ports + idx;
464 fprintf(fd, "\n (port %s", pp->name);
465 switch (pp->dir) {
466 case IVL_SIP_INPUT:
467 fprintf(fd, " (direction INPUT)");
468 break;
469 case IVL_SIP_OUTPUT:
470 fprintf(fd, " (direction OUTPUT)");
471 break;
472 case IVL_SIP_INOUT:
473 fprintf(fd, " (direction INOUT)");
474 break;
475 default:
476 break;
477 }
478
479 for (prp = pp->property ; prp ; prp=prp->next) {
480 fprintf(fd, " ");
481 fprint_property(fd, prp);
482 }
483
484 fprintf(fd, ")");
485 }
486
487 for (prp = cell->property ; prp ; prp = prp->next) {
488 fprintf(fd, "\n ");
489 fprint_property(fd, prp);
490 }
491 fprintf(fd, ")))\n");
492 }
493
494 fprintf(fd, " )\n"); /* terminate (external ...) sexp */
495 }
496 fflush(fd);
497
498 /* Write out the library header */
499 fprintf(fd, " (library DESIGN\n");
500 fprintf(fd, " (edifLevel 0)\n");
501 fprintf(fd, " (technology (numberDefinition))\n");
502
503 /* The root module is a cell in the library. */
504 fprintf(fd, " (cell %s\n", edf->name);
505 fprintf(fd, " (cellType GENERIC)\n");
506 fprintf(fd, " (view net\n");
507 fprintf(fd, " (viewType NETLIST)\n");
508 fprintf(fd, " (interface\n");
509
510 for (idx = 0 ; idx < edf->nports ; idx += 1) {
511 fprintf(fd, " (port ");
512 if (edf->ports[idx].ename == 0)
513 fprintf(fd, "%s ", edf->ports[idx].name);
514 else
515 fprintf(fd, "(rename %s \"%s\") ",
516 edf->ports[idx].ename,
517 edf->ports[idx].name);
518
519 switch (edf->ports[idx].dir) {
520 case IVL_SIP_INPUT:
521 fprintf(fd, "(direction INPUT)");
522 break;
523 case IVL_SIP_OUTPUT:
524 fprintf(fd, "(direction OUTPUT)");
525 break;
526 case IVL_SIP_INOUT:
527 fprintf(fd, "(direction INOUT)");
528 break;
529 default:
530 break;
531 }
532 fprintf(fd, ")\n");
533 }
534
535 fprintf(fd, " )\n"); /* end the (interface ) sexp */
536 fflush(fd);
537
538 fprintf(fd, " (contents\n");
539
540 /* Display all the instances. */
541 for (ref = edf->celref ; ref ; ref = ref->next) {
542
543 assert(ref->cell);
544
545 fprintf(fd, "(instance U%u (viewRef net "
546 "(cellRef %s (libraryRef %s)))",
547 ref->u, ref->cell->name, ref->cell->xlib->name);
548
549 for (prp = ref->property ; prp ; prp = prp->next) {
550 fprintf(fd, " ");
551 fprint_property(fd, prp);
552 }
553
554 fprintf(fd, ")\n");
555 }
556
557 fflush(fd);
558
559 /* Display all the joints. */
560 idx = 0;
561 for (jnt = edf->nexa ; jnt ; jnt = jnt->next, idx += 1) {
562 struct joint_cell_*jc;
563
564 fprintf(fd, "(net ");
565 if (jnt->name != 0)
566 fprintf(fd, "(rename N%u \"%s\")", idx, jnt->name);
567 else
568 fprintf(fd, "N%u", idx);
569 fprintf(fd, " (joined");
570
571 for (jc = jnt->links ; jc ; jc = jc->next) {
572 if (jc->cell) {
573 fprintf(fd, " (portRef %s (instanceRef U%u))",
574 jc->cell->cell->ports[jc->port].name,
575 jc->cell->u);
576 } else {
577 /* Reference to a port of the main cell. */
578 if (edf->ports[jc->port].ename)
579 fprintf(fd, " (portRef %s)",
580 edf->ports[jc->port].ename);
581 else
582 fprintf(fd, " (portRef %s)",
583 edf->ports[jc->port].name);
584 }
585 }
586 fprintf(fd, "))\n");
587 }
588
589 fprintf(fd, " )\n"); /* end the (contents...) sexp */
590
591 fprintf(fd, " )\n"); /* end the (view ) sexp */
592 fprintf(fd, " )\n"); /* end the (cell ) sexp */
593 fprintf(fd, " )\n"); /* end the (library DESIGN) sexp */
594
595 /* Make an instance of the defined object */
596 fprintf(fd, " (design %s\n", edf->name);
597 fprintf(fd, " (cellRef %s (libraryRef DESIGN))\n", edf->name);
598
599 for (prp = edf->property ; prp ; prp = prp->next) {
600 fprintf(fd, " ");
601 fprint_property(fd, prp);
602 fprintf(fd, "\n");
603 }
604
605 fprintf(fd, " )\n");
606
607
608
609 fprintf(fd, ")\n");
610 fflush(fd);
611 }
612