2 * Copyright (c) 2003 Stephen Williams (steve@icarus.com)
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)
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 #ident "$Id: d-lpm.c,v 1.12 2004/10/04 01:10:56 steve Exp $"
24 * This is the driver for a purely generic LPM module writer. This
25 * uses LPM version 2 1 0 devices, without particularly considering
26 * the target technology.
28 * The LPM standard is EIA-IS/103-A October 1996
29 * The output is EDIF 2 0 0 format.
33 # include "fpga_priv.h"
39 static edif_cell_t
lpm_cell_buf(void)
41 static edif_cell_t tmp
= 0;
46 tmp
= edif_xcell_create(xlib
, "BUF", 2);
47 edif_cell_portconfig(tmp
, 0, "Result", IVL_SIP_OUTPUT
);
48 edif_cell_portconfig(tmp
, 1, "Data", IVL_SIP_INPUT
);
50 /* A buffer is an inverted inverter. */
51 edif_cell_port_pstring(tmp
, 0, "LPM_Polarity", "INVERT");
53 edif_cell_pstring(tmp
, "LPM_TYPE", "LPM_INV");
54 edif_cell_pinteger(tmp
, "LPM_Width", 1);
55 edif_cell_pinteger(tmp
, "LPM_Size", 1);
59 static edif_cell_t
lpm_cell_inv(void)
61 static edif_cell_t tmp
= 0;
66 tmp
= edif_xcell_create(xlib
, "INV", 2);
67 edif_cell_portconfig(tmp
, 0, "Result", IVL_SIP_OUTPUT
);
68 edif_cell_portconfig(tmp
, 1, "Data", IVL_SIP_INPUT
);
70 edif_cell_pstring(tmp
, "LPM_TYPE", "LPM_INV");
71 edif_cell_pinteger(tmp
, "LPM_Width", 1);
72 edif_cell_pinteger(tmp
, "LPM_Size", 1);
76 static edif_cell_t
lpm_cell_bufif0(void)
78 static edif_cell_t tmp
= 0;
83 tmp
= edif_xcell_create(xlib
, "BUFIF1", 3);
84 edif_cell_portconfig(tmp
, 0, "TriData", IVL_SIP_OUTPUT
);
85 edif_cell_portconfig(tmp
, 1, "Data", IVL_SIP_INPUT
);
86 edif_cell_portconfig(tmp
, 2, "EnableDT", IVL_SIP_INPUT
);
88 edif_cell_port_pstring(tmp
, 2, "LPM_Polarity", "INVERT");
90 edif_cell_pstring(tmp
, "LPM_TYPE", "LPM_BUSTRI");
91 edif_cell_pinteger(tmp
, "LPM_Width", 1);
95 static edif_cell_t
lpm_cell_bufif1(void)
97 static edif_cell_t tmp
= 0;
102 tmp
= edif_xcell_create(xlib
, "BUFIF1", 3);
103 edif_cell_portconfig(tmp
, 0, "TriData", IVL_SIP_OUTPUT
);
104 edif_cell_portconfig(tmp
, 1, "Data", IVL_SIP_INPUT
);
105 edif_cell_portconfig(tmp
, 2, "EnableDT", IVL_SIP_INPUT
);
107 edif_cell_pstring(tmp
, "LPM_TYPE", "LPM_BUSTRI");
108 edif_cell_pinteger(tmp
, "LPM_Width", 1);
112 static edif_cell_t
lpm_cell_or(unsigned siz
)
118 sprintf(name
, "or%u", siz
);
120 cell
= edif_xlibrary_findcell(xlib
, name
);
124 cell
= edif_xcell_create(xlib
, strdup(name
), siz
+1);
126 edif_cell_portconfig(cell
, 0, "Result0", IVL_SIP_OUTPUT
);
128 for (idx
= 0 ; idx
< siz
; idx
+= 1) {
129 sprintf(name
, "Data%ux0", idx
);
130 edif_cell_portconfig(cell
, idx
+1, strdup(name
), IVL_SIP_INPUT
);
133 edif_cell_pstring(cell
, "LPM_TYPE", "LPM_OR");
134 edif_cell_pinteger(cell
, "LPM_Width", 1);
135 edif_cell_pinteger(cell
, "LPM_Size", siz
);
140 static edif_cell_t
lpm_cell_and(unsigned siz
)
146 sprintf(name
, "and%u", siz
);
148 cell
= edif_xlibrary_findcell(xlib
, name
);
152 cell
= edif_xcell_create(xlib
, strdup(name
), siz
+1);
154 edif_cell_portconfig(cell
, 0, "Result0", IVL_SIP_OUTPUT
);
156 for (idx
= 0 ; idx
< siz
; idx
+= 1) {
157 sprintf(name
, "Data%ux0", idx
);
158 edif_cell_portconfig(cell
, idx
+1, strdup(name
), IVL_SIP_INPUT
);
161 edif_cell_pstring(cell
, "LPM_TYPE", "LPM_AND");
162 edif_cell_pinteger(cell
, "LPM_Width", 1);
163 edif_cell_pinteger(cell
, "LPM_Size", siz
);
168 static edif_cell_t
lpm_cell_xor(unsigned siz
)
174 sprintf(name
, "xor%u", siz
);
176 cell
= edif_xlibrary_findcell(xlib
, name
);
180 cell
= edif_xcell_create(xlib
, strdup(name
), siz
+1);
182 edif_cell_portconfig(cell
, 0, "Result0", IVL_SIP_OUTPUT
);
184 for (idx
= 0 ; idx
< siz
; idx
+= 1) {
185 sprintf(name
, "Data%ux0", idx
);
186 edif_cell_portconfig(cell
, idx
+1, strdup(name
), IVL_SIP_INPUT
);
189 edif_cell_pstring(cell
, "LPM_TYPE", "LPM_XOR");
190 edif_cell_pinteger(cell
, "LPM_Width", 1);
191 edif_cell_pinteger(cell
, "LPM_Size", siz
);
196 static edif_cell_t
lpm_cell_nor(unsigned siz
)
202 sprintf(name
, "nor%u", siz
);
204 cell
= edif_xlibrary_findcell(xlib
, name
);
208 cell
= edif_xcell_create(xlib
, strdup(name
), siz
+1);
210 edif_cell_portconfig(cell
, 0, "Result0", IVL_SIP_OUTPUT
);
211 edif_cell_port_pstring(cell
, 0, "LPM_Polarity", "INVERT");
213 for (idx
= 0 ; idx
< siz
; idx
+= 1) {
214 sprintf(name
, "Data%ux0", idx
);
215 edif_cell_portconfig(cell
, idx
+1, strdup(name
), IVL_SIP_INPUT
);
218 edif_cell_pstring(cell
, "LPM_TYPE", "LPM_OR");
219 edif_cell_pinteger(cell
, "LPM_Width", 1);
220 edif_cell_pinteger(cell
, "LPM_Size", siz
);
225 static void lpm_show_header(ivl_design_t des
)
228 ivl_scope_t root
= ivl_design_root(des
);
229 unsigned sig_cnt
= ivl_scope_sigs(root
);
230 unsigned nports
= 0, pidx
;
232 /* Count the ports I'm going to use. */
233 for (idx
= 0 ; idx
< sig_cnt
; idx
+= 1) {
234 ivl_signal_t sig
= ivl_scope_sig(root
, idx
);
236 if (ivl_signal_port(sig
) == IVL_SIP_NONE
)
239 if (ivl_signal_attr(sig
, "PAD") != 0)
242 nports
+= ivl_signal_pins(sig
);
245 /* Create the base edf object. */
246 edf
= edif_create(ivl_scope_basename(root
), nports
);
250 for (idx
= 0 ; idx
< sig_cnt
; idx
+= 1) {
252 ivl_signal_t sig
= ivl_scope_sig(root
, idx
);
254 if (ivl_signal_port(sig
) == IVL_SIP_NONE
)
257 if (ivl_signal_attr(sig
, "PAD") != 0)
260 if (ivl_signal_pins(sig
) == 1) {
261 edif_portconfig(edf
, pidx
, ivl_signal_basename(sig
),
262 ivl_signal_port(sig
));
264 assert(ivl_signal_pins(sig
) == 1);
265 jnt
= edif_joint_of_nexus(edf
, ivl_signal_pin(sig
, 0));
266 edif_port_to_joint(jnt
, edf
, pidx
);
269 const char*name
= ivl_signal_basename(sig
);
270 ivl_signal_port_t dir
= ivl_signal_port(sig
);
273 for (bit
= 0 ; bit
< ivl_signal_pins(sig
) ; bit
+= 1) {
275 sprintf(buf
, "%s[%u]", name
, bit
);
277 edif_portconfig(edf
, pidx
+bit
, tmp
, dir
);
279 jnt
= edif_joint_of_nexus(edf
,ivl_signal_pin(sig
,bit
));
280 edif_port_to_joint(jnt
, edf
, pidx
+bit
);
284 pidx
+= ivl_signal_pins(sig
);
287 assert(pidx
== nports
);
289 xlib
= edif_xlibrary_create(edf
, "LPM_LIBRARY");
292 static void lpm_show_footer(ivl_design_t des
)
294 edif_print(xnf
, edf
);
297 static void hookup_logic_gate(ivl_net_logic_t net
, edif_cell_t cell
)
302 edif_cellref_t ref
= edif_cellref_create(edf
, cell
);
304 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 0));
305 pin
= edif_cell_port_byname(cell
, "Result0");
306 edif_add_to_joint(jnt
, ref
, pin
);
308 for (idx
= 1 ; idx
< ivl_logic_pins(net
) ; idx
+= 1) {
311 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, idx
));
312 sprintf(name
, "Data%ux0", idx
-1);
313 pin
= edif_cell_port_byname(cell
, name
);
314 edif_add_to_joint(jnt
, ref
, pin
);
318 static void lpm_logic(ivl_net_logic_t net
)
324 switch (ivl_logic_type(net
)) {
328 assert(ivl_logic_pins(net
) == 2);
329 cell
= lpm_cell_buf();
330 ref
= edif_cellref_create(edf
, cell
);
332 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 0));
333 edif_add_to_joint(jnt
, ref
, 0);
335 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 1));
336 edif_add_to_joint(jnt
, ref
, 1);
340 assert(ivl_logic_pins(net
) == 3);
341 cell
= lpm_cell_bufif0();
342 ref
= edif_cellref_create(edf
, cell
);
344 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 0));
345 edif_add_to_joint(jnt
, ref
, 0);
347 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 1));
348 edif_add_to_joint(jnt
, ref
, 1);
350 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 2));
351 edif_add_to_joint(jnt
, ref
, 2);
355 assert(ivl_logic_pins(net
) == 3);
356 cell
= lpm_cell_bufif1();
357 ref
= edif_cellref_create(edf
, cell
);
359 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 0));
360 edif_add_to_joint(jnt
, ref
, 0);
362 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 1));
363 edif_add_to_joint(jnt
, ref
, 1);
365 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 2));
366 edif_add_to_joint(jnt
, ref
, 2);
370 assert(ivl_logic_pins(net
) == 2);
371 cell
= lpm_cell_inv();
372 ref
= edif_cellref_create(edf
, cell
);
374 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 0));
375 edif_add_to_joint(jnt
, ref
, 0);
377 jnt
= edif_joint_of_nexus(edf
, ivl_logic_pin(net
, 1));
378 edif_add_to_joint(jnt
, ref
, 1);
382 cell
= lpm_cell_or(ivl_logic_pins(net
)-1);
383 hookup_logic_gate(net
, cell
);
387 cell
= lpm_cell_nor(ivl_logic_pins(net
)-1);
388 hookup_logic_gate(net
, cell
);
392 cell
= lpm_cell_and(ivl_logic_pins(net
)-1);
393 hookup_logic_gate( net
, cell
);
397 cell
= lpm_cell_xor(ivl_logic_pins(net
)-1);
398 hookup_logic_gate( net
, cell
);
402 fprintf(stderr
, "UNSUPPORTED LOGIC TYPE: %u\n",
403 ivl_logic_type(net
));
409 static void lpm_show_dff(ivl_lpm_t net
)
417 unsigned pin
, wid
= ivl_lpm_width(net
);
419 sprintf(name
, "fd%s%s%s%s%s%u",
420 ivl_lpm_enable(net
)? "ce" : "",
421 ivl_lpm_async_clr(net
)? "cl" : "",
422 ivl_lpm_sync_clr(net
)? "sc" : "",
423 ivl_lpm_async_set(net
)? "se" : "",
424 ivl_lpm_sync_set(net
)? "ss" : "",
427 cell
= edif_xlibrary_findcell(xlib
, name
);
430 unsigned nports
= 2 * wid
+ 1;
432 if (ivl_lpm_enable(net
))
434 if (ivl_lpm_async_clr(net
))
436 if (ivl_lpm_sync_clr(net
))
438 if (ivl_lpm_async_set(net
))
440 if (ivl_lpm_sync_set(net
))
443 cell
= edif_xcell_create(xlib
, strdup(name
), nports
);
444 edif_cell_pstring(cell
, "LPM_Type", "LPM_FF");
445 edif_cell_pinteger(cell
, "LPM_Width", wid
);
447 for (idx
= 0 ; idx
< wid
; idx
+= 1) {
449 sprintf(name
, "Q%u", idx
);
450 edif_cell_portconfig(cell
, idx
*2+0, strdup(name
),
453 sprintf(name
, "Data%u", idx
);
454 edif_cell_portconfig(cell
, idx
*2+1, strdup(name
),
460 if (ivl_lpm_enable(net
)) {
461 edif_cell_portconfig(cell
, pin
, "Enable", IVL_SIP_INPUT
);
465 if (ivl_lpm_async_clr(net
)) {
466 edif_cell_portconfig(cell
, pin
, "Aclr", IVL_SIP_INPUT
);
470 if (ivl_lpm_sync_clr(net
)) {
471 edif_cell_portconfig(cell
, pin
, "Sclr", IVL_SIP_INPUT
);
475 if (ivl_lpm_async_set(net
)) {
476 edif_cell_portconfig(cell
, pin
, "Aset", IVL_SIP_INPUT
);
480 if (ivl_lpm_sync_set(net
)) {
481 edif_cell_portconfig(cell
, pin
, "Sset", IVL_SIP_INPUT
);
485 edif_cell_portconfig(cell
, pin
, "Clock", IVL_SIP_INPUT
);
488 assert(pin
== nports
);
491 ref
= edif_cellref_create(edf
, cell
);
493 pin
= edif_cell_port_byname(cell
, "Clock");
495 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_clk(net
));
496 edif_add_to_joint(jnt
, ref
, pin
);
498 if (ivl_lpm_enable(net
)) {
499 pin
= edif_cell_port_byname(cell
, "Enable");
501 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_enable(net
));
502 edif_add_to_joint(jnt
, ref
, pin
);
505 if (ivl_lpm_async_clr(net
)) {
506 pin
= edif_cell_port_byname(cell
, "Aclr");
508 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_async_clr(net
));
509 edif_add_to_joint(jnt
, ref
, pin
);
512 if (ivl_lpm_sync_clr(net
)) {
513 pin
= edif_cell_port_byname(cell
, "Sclr");
515 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_sync_clr(net
));
516 edif_add_to_joint(jnt
, ref
, pin
);
519 if (ivl_lpm_async_set(net
)) {
520 pin
= edif_cell_port_byname(cell
, "Aset");
522 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_async_set(net
));
523 edif_add_to_joint(jnt
, ref
, pin
);
526 if (ivl_lpm_sync_set(net
)) {
527 ivl_expr_t svalue
= ivl_lpm_sset_value(net
);
529 pin
= edif_cell_port_byname(cell
, "Sset");
531 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_sync_set(net
));
532 edif_add_to_joint(jnt
, ref
, pin
);
534 edif_cellref_pinteger(ref
, "LPM_Svalue", ivl_expr_uvalue(svalue
));
537 for (idx
= 0 ; idx
< wid
; idx
+= 1) {
539 sprintf(name
, "Q%u", idx
);
540 pin
= edif_cell_port_byname(cell
, name
);
542 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_q(net
, idx
));
543 edif_add_to_joint(jnt
, ref
, pin
);
545 sprintf(name
, "Data%u", idx
);
546 pin
= edif_cell_port_byname(cell
, name
);
548 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_data(net
, idx
));
549 edif_add_to_joint(jnt
, ref
, pin
);
553 static void lpm_show_mux(ivl_lpm_t net
)
563 unsigned wid_r
= ivl_lpm_width(net
);
564 unsigned wid_s
= ivl_lpm_selects(net
);
565 unsigned wid_z
= ivl_lpm_size(net
);
567 sprintf(cellname
, "mux%u_%u_%u", wid_r
, wid_s
, wid_z
);
568 cell
= edif_xlibrary_findcell(xlib
, cellname
);
571 unsigned pins
= wid_r
+ wid_s
+ wid_r
*wid_z
;
573 cell
= edif_xcell_create(xlib
, strdup(cellname
), pins
);
575 /* Make the output ports. */
576 for (idx
= 0 ; idx
< wid_r
; idx
+= 1) {
577 sprintf(cellname
, "Result%u", idx
);
578 edif_cell_portconfig(cell
, idx
, strdup(cellname
),
582 /* Make the select ports. */
583 for (idx
= 0 ; idx
< wid_s
; idx
+= 1) {
584 sprintf(cellname
, "Sel%u", idx
);
585 edif_cell_portconfig(cell
, wid_r
+idx
, strdup(cellname
),
589 for (idx
= 0 ; idx
< wid_z
; idx
+= 1) {
590 unsigned base
= wid_r
+ wid_s
+ wid_r
* idx
;
593 for (rdx
= 0 ; rdx
< wid_r
; rdx
+= 1) {
594 sprintf(cellname
, "Data%ux%u", idx
, rdx
);
595 edif_cell_portconfig(cell
, base
+rdx
, strdup(cellname
),
600 edif_cell_pstring(cell
, "LPM_Type", "LPM_MUX");
601 edif_cell_pinteger(cell
, "LPM_Width", wid_r
);
602 edif_cell_pinteger(cell
, "LPM_WidthS", wid_s
);
603 edif_cell_pinteger(cell
, "LPM_Size", wid_z
);
607 ref
= edif_cellref_create(edf
, cell
);
609 /* Connect the pins of the instance to the nexa. Access the
610 cell pins by name. */
611 for (idx
= 0 ; idx
< wid_r
; idx
+= 1) {
614 sprintf(cellname
, "Result%u", idx
);
615 pin
= edif_cell_port_byname(cell
, cellname
);
617 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_q(net
, idx
));
618 edif_add_to_joint(jnt
, ref
, pin
);
621 for (idx
= 0 ; idx
< wid_s
; idx
+= 1) {
624 sprintf(cellname
, "Sel%u", idx
);
625 pin
= edif_cell_port_byname(cell
, cellname
);
627 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_select(net
, idx
));
628 edif_add_to_joint(jnt
, ref
, pin
);
631 for (idx
= 0 ; idx
< wid_z
; idx
+= 1) {
632 for (rdx
= 0 ; rdx
< wid_r
; rdx
+= 1) {
635 sprintf(cellname
, "Data%ux%u", idx
, rdx
);
636 pin
= edif_cell_port_byname(cell
, cellname
);
638 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_data2(net
, idx
, rdx
));
639 edif_add_to_joint(jnt
, ref
, pin
);
644 static void lpm_show_add(ivl_lpm_t net
)
653 const char*type
= "ADD";
655 if (ivl_lpm_type(net
) == IVL_LPM_SUB
)
658 /* Figure out the width of the cell. Normally, it is the LPM
659 width known by IVL. But if the top data input bits are
660 unconnected, then we really have a width one less, and we
661 can use the cout to fill out the output width. */
662 cell_width
= ivl_lpm_width(net
);
663 if ( (ivl_lpm_data(net
,cell_width
-1) == 0)
664 && (ivl_lpm_datab(net
,cell_width
-1) == 0) )
667 /* Find the correct ADD/SUB device in the library, search by
668 name. If the device is not there, then create it and put it
670 sprintf(cellname
, "%s%u", type
, cell_width
);
671 cell
= edif_xlibrary_findcell(xlib
, cellname
);
674 unsigned pins
= cell_width
* 3 + 1;
676 cell
= edif_xcell_create(xlib
, strdup(cellname
), pins
);
678 for (idx
= 0 ; idx
< cell_width
; idx
+= 1) {
680 sprintf(cellname
, "Result%u", idx
);
681 edif_cell_portconfig(cell
, idx
*3+0, strdup(cellname
),
684 sprintf(cellname
, "DataA%u", idx
);
685 edif_cell_portconfig(cell
, idx
*3+1, strdup(cellname
),
688 sprintf(cellname
, "DataB%u", idx
);
689 edif_cell_portconfig(cell
, idx
*3+2, strdup(cellname
),
693 edif_cell_portconfig(cell
, pins
-1, "Cout", IVL_SIP_OUTPUT
);
695 edif_cell_pstring(cell
, "LPM_Type", "LPM_ADD_SUB");
696 edif_cell_pstring(cell
, "LPM_Direction", type
);
697 edif_cell_pinteger(cell
, "LPM_Width", ivl_lpm_width(net
));
700 ref
= edif_cellref_create(edf
, cell
);
702 /* Connect the pins of the instance to the nexa. Access the
703 cell pins by name. */
704 for (idx
= 0 ; idx
< cell_width
; idx
+= 1) {
707 sprintf(cellname
, "Result%u", idx
);
708 pin
= edif_cell_port_byname(cell
, cellname
);
710 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_q(net
, idx
));
711 edif_add_to_joint(jnt
, ref
, pin
);
713 sprintf(cellname
, "DataA%u", idx
);
714 pin
= edif_cell_port_byname(cell
, cellname
);
716 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_data(net
, idx
));
717 edif_add_to_joint(jnt
, ref
, pin
);
719 sprintf(cellname
, "DataB%u", idx
);
720 pin
= edif_cell_port_byname(cell
, cellname
);
722 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_datab(net
, idx
));
723 edif_add_to_joint(jnt
, ref
, pin
);
726 if (cell_width
< ivl_lpm_width(net
)) {
727 unsigned pin
= edif_cell_port_byname(cell
, "Cout");
729 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_q(net
, cell_width
));
730 edif_add_to_joint(jnt
, ref
, pin
);
734 static void lpm_show_mult(ivl_lpm_t net
)
743 sprintf(name
, "mult%u", ivl_lpm_width(net
));
744 cell
= edif_xlibrary_findcell(xlib
, name
);
747 cell
= edif_xcell_create(xlib
, strdup(name
),
748 3 * ivl_lpm_width(net
));
750 for (idx
= 0 ; idx
< ivl_lpm_width(net
) ; idx
+= 1) {
752 sprintf(name
, "Result%u", idx
);
753 edif_cell_portconfig(cell
, idx
*3+0,
757 sprintf(name
, "DataA%u", idx
);
758 edif_cell_portconfig(cell
, idx
*3+1,
762 sprintf(name
, "DataB%u", idx
);
763 edif_cell_portconfig(cell
, idx
*3+2,
768 edif_cell_pstring(cell
, "LPM_Type", "LPM_MULT");
769 edif_cell_pinteger(cell
, "LPM_WidthP", ivl_lpm_width(net
));
770 edif_cell_pinteger(cell
, "LPM_WidthA", ivl_lpm_width(net
));
771 edif_cell_pinteger(cell
, "LPM_WidthB", ivl_lpm_width(net
));
774 ref
= edif_cellref_create(edf
, cell
);
776 for (idx
= 0 ; idx
< ivl_lpm_width(net
) ; idx
+= 1) {
780 sprintf(name
, "Result%u", idx
);
781 pin
= edif_cell_port_byname(cell
, name
);
783 jnt
= edif_joint_of_nexus(edf
, ivl_lpm_q(net
, idx
));
784 edif_add_to_joint(jnt
, ref
, pin
);
786 if ( (nex
= ivl_lpm_data(net
, idx
)) ) {
787 sprintf(name
, "DataA%u", idx
);
788 pin
= edif_cell_port_byname(cell
, name
);
790 jnt
= edif_joint_of_nexus(edf
, nex
);
791 edif_add_to_joint(jnt
, ref
, pin
);
794 if ( (nex
= ivl_lpm_datab(net
, idx
)) ) {
795 sprintf(name
, "DataB%u", idx
);
796 pin
= edif_cell_port_byname(cell
, name
);
798 jnt
= edif_joint_of_nexus(edf
, nex
);
799 edif_add_to_joint(jnt
, ref
, pin
);
805 static void lpm_show_constant(ivl_net_const_t net
)
807 edif_cell_t cell0
= edif_xlibrary_findcell(xlib
, "cell0");
808 edif_cell_t cell1
= edif_xlibrary_findcell(xlib
, "cell1");
809 edif_cellref_t ref0
= 0, ref1
= 0;
815 cell0
= edif_xcell_create(xlib
, "cell0", 1);
816 edif_cell_portconfig(cell0
, 0, "Result0", IVL_SIP_OUTPUT
);
818 edif_cell_pstring(cell0
, "LPM_Type", "LPM_CONSTANT");
819 edif_cell_pinteger(cell0
, "LPM_Width", 1);
820 edif_cell_pinteger(cell0
, "LPM_CValue", 0);
824 cell1
= edif_xcell_create(xlib
, "cell1", 1);
825 edif_cell_portconfig(cell1
, 0, "Result0", IVL_SIP_OUTPUT
);
827 edif_cell_pstring(cell1
, "LPM_Type", "LPM_CONSTANT");
828 edif_cell_pinteger(cell1
, "LPM_Width", 1);
829 edif_cell_pinteger(cell1
, "LPM_CValue", 1);
832 bits
= ivl_const_bits(net
);
833 for (idx
= 0 ; idx
< ivl_const_pins(net
) ; idx
+= 1) {
834 if (bits
[idx
] == '1') {
836 ref1
= edif_cellref_create(edf
, cell1
);
840 ref0
= edif_cellref_create(edf
, cell0
);
844 for (idx
= 0 ; idx
< ivl_const_pins(net
) ; idx
+= 1) {
847 jnt
= edif_joint_of_nexus(edf
, ivl_const_pin(net
,idx
));
848 if (bits
[idx
] == '1')
849 edif_add_to_joint(jnt
, ref1
, 0);
851 edif_add_to_joint(jnt
, ref0
, 0);
857 const struct device_s d_lpm_edif
= {
863 lpm_show_dff
, /* show_dff */
868 lpm_show_mux
, /* show_mux */
869 lpm_show_add
, /* show_add */
870 lpm_show_add
, /* show_sub */
873 lpm_show_mult
, /* show_mult */
874 lpm_show_constant
/* show_constant */
879 * Revision 1.12 2004/10/04 01:10:56 steve
880 * Clean up spurious trailing white space.
882 * Revision 1.11 2003/11/12 03:20:14 steve
883 * devices need show_cmp_gt
885 * Revision 1.10 2003/10/31 03:45:50 steve
886 * Handle adders that use Cout for the top bit.
888 * Revision 1.9 2003/10/27 02:18:27 steve
889 * Emit constants for LPM device.
891 * Revision 1.8 2003/09/03 23:34:09 steve
892 * Support synchronous set of LPM_FF devices.
894 * Revision 1.7 2003/08/26 04:45:47 steve
895 * iverilog-vpi support --cflags a la gtk.
897 * Revision 1.6 2003/08/15 02:23:53 steve
898 * Add synthesis support for synchronous reset.
900 * Revision 1.5 2003/08/10 16:42:23 steve
901 * Add async clear to LPM_FF devices.
903 * Revision 1.4 2003/08/09 03:23:03 steve
904 * Add support for IVL_LPM_MULT device.
906 * Revision 1.3 2003/08/09 02:40:50 steve
907 * Generate LPM_FF devices.
909 * Revision 1.2 2003/08/07 05:18:04 steve
910 * Add support for OR/NOR/bufif0/bufif1.
912 * Revision 1.1 2003/08/07 04:04:01 steve
913 * Add an LPM device type.