1 import com.atmel.fpslic.*;
2 import byucc.edif.tools.merge.*;
6 import edu.berkeley.slipway.*;
7 import com.atmel.fpslic.*;
8 import static com.atmel.fpslic.FpslicConstants.*;
10 public class MPARDemo {
12 public static final double alphaParameter = 00.9;
13 public static final double betaParameter = 20.0;
14 public static final double gammaParameter = 1.0;
16 public static class FlatNetlist {
18 private HashMap<String,Integer> ids = new HashMap<String,Integer>();
20 public HashSet<Node> nodes = new HashSet<Node>();
21 public HashSet<Net> nets = new HashSet<Net>();
23 /** a node is some primitive element; a potential configuration of a CLB */
25 public PhysicalDevice.PhysicalCell physicalCell = null;
26 private final String type;
32 private HashMap<String,Port> ports = new HashMap<String,Port>();
34 public Node(String type) {
36 this.type = type.toLowerCase();
37 Integer num = ids.get(type);
38 this.id = num == null ? 0 : num.intValue();
39 ids.put(type, this.id+1);
41 public String getType() { return type; }
42 public String toString() {
44 return type + "["+id+"]";
45 return type + "@("+x+","+y+")";
47 public Port getPort(String name, boolean driver) {
48 Port p = ports.get(name);
49 if (p==null) ports.put(name, p = new Port(name, driver));
53 public Fpslic.Cell getPlacement(Fpslic fpslic) { return fpslic.cell(x, y); }
54 public void place(Fpslic fpslic) {
55 Fpslic.Cell cell = fpslic.cell(x,y);
61 if (type.equals("and2")) cell.xlut(LUT_SELF & LUT_OTHER);
62 else if (type.equals("or2")) cell.xlut(LUT_SELF | LUT_OTHER);
63 else if (type.equals("xor2")) cell.xlut(LUT_SELF ^ LUT_OTHER);
64 else if (type.equals("buf")) cell.xlut(LUT_SELF);
65 else if (type.equals("inv")) cell.xlut(~LUT_SELF);
66 else if (type.equals("cell0")) return;
69 private int portIndex = 0;
71 /** a port is an input or output to a Node */
73 private final String name;
74 private final boolean driver;
76 public final int index;
77 public Port(String name, boolean driver) {
80 this.index = driver ? 0 : portIndex++;
82 public String toString() { return Node.this + "." + name; }
83 public Node getNode() { return Node.this; }
84 public void connect(Port p) {
85 if (net != null) { net.add(p);
86 } else if (p.net != null) { p.net.add(this);
92 public void route(Fpslic fpslic, Port[] dests, PhysicalDevice pd) {
93 PhysicalDevice.PhysicalNet[] destsp = new PhysicalDevice.PhysicalNet[dests.length];
94 for(int i=0; i<dests.length; i++) {
97 case 0: destsp[i] = dest.getNode().physicalCell.getNet("xi"); break;
98 case 1: destsp[i] = dest.getNode().physicalCell.getNet("yi"); break;
99 default: throw new Error();
102 //System.out.println(physicalCell.getNet("out"));
103 //System.out.println(destsp[0]);
104 pd.route(physicalCell.getNet("out"), destsp);
107 Fpslic.Cell driverCell = fpslic.cell(getNode().x,getNode().y);
108 Fpslic.Cell destCell = fpslic.cell(dest.getNode().x,dest.getNode().y);
109 boolean[] hblocked = new boolean[5];
110 boolean[] vblocked = new boolean[5];
113 int minx = Math.min(getNode().x, dest.getNode().x);
114 int miny = Math.min(getNode().y, dest.getNode().y);
115 int maxx = Math.max(getNode().x, dest.getNode().x);
116 int maxy = Math.max(getNode().y, dest.getNode().y);
117 for(int cx = 0; cx <= 3; cx++) {
118 Fpslic.Cell c = fpslic.cell(cx, getNode().y);
119 for(int i=0; i<5; i++)
120 hblocked[i] |= (c.hx(i) && !c.equals(driverCell));
122 for(int cy = 0; cy <= 3; cy++) {
123 Fpslic.Cell c = fpslic.cell(dest.getNode().x, cy);
124 for(int i=0; i<5; i++)
125 vblocked[i] |= (c.vx(i) && !c.equals(driverCell));
128 for(; free < 5; free++) if (!hblocked[free]) break;
129 for(; free < 5; free++) if (!vblocked[free]) break;
130 if (free >= 5) throw new RuntimeException("unroutable!");
131 Fpslic.Cell turnCell = fpslic.cell(dest.getNode().x, getNode().y);
132 driverCell.out(free, true);
133 driverCell.h(free, true);
134 turnCell.h(free, true);
135 turnCell.v(free, true);
137 case 0: destCell.xi(L0 + free); break;
138 case 1: destCell.yi(L0 + free); break;
139 case 2: destCell.wi(L0 + free); break;
140 case 3: destCell.zi(L0 + free); break;
141 default: throw new RuntimeException("error");
143 destCell.v(free, true);
144 System.out.println("route " + this + " -> " + dest + " on planes " + free);
150 /** a Net is a collection of ports which are wired together */
151 public class Net implements Iterable<Node.Port> {
152 private Node.Port driver = null;
153 private HashSet<Node.Port> ports = new HashSet<Node.Port>();
154 public Net() { nets.add(this); }
155 public Iterator<Node.Port> iterator() { return ports.iterator(); }
156 public int getSize() { return ports.size(); }
157 public void route(Fpslic fpslic, PhysicalDevice pd) {
158 if (driver == null) return;
159 //System.out.println();
160 //System.out.println("routing " + this);
161 Node.Port[] dests = new Node.Port[ports.size() - (ports.contains(driver) ? 1 : 0)];
163 for(Node.Port p : ports)
166 driver.route(fpslic, dests, pd);
168 public void add(Node.Port p) {
170 if (driver != null && driver != p)
171 throw new RuntimeException("two drivers on a port!\n "+driver+"\n "+p);
174 if (p.net==this || ports.contains(p)) return;
179 public void add(Net n) {
180 if (n==this || n==null) return;
181 for(Node.Port p : n) add(p);
184 public String toString() {
185 StringBuffer ret = new StringBuffer();
186 ret.append(driver==null ? "()" : driver.toString());
188 for(Node.Port p : this)
191 return ret.toString();
196 public HashMap<EdifCellInstance,FlatNetlist.Node> cache =
197 new HashMap<EdifCellInstance,FlatNetlist.Node>();
198 public HashMap<String,FlatNetlist.Node> top =
199 new HashMap<String,FlatNetlist.Node>();
201 public FlatNetlist.Node createNode(EdifCellInstance eci, String portName) {
202 FlatNetlist.Node n = eci==null ? top.get(portName) : cache.get(eci);
203 if (n != null) return n;
205 n = new FlatNetlist.Node("top_"+portName);
206 top.put(portName, n);
209 n = new FlatNetlist.Node(eci.getType());
212 for(EdifPortRef epr : eci.getAllEPRs()) {
213 EdifPort ep = epr.getPort();
214 EdifNet en = epr.getNet();
215 String name = ep.getOldName();
216 boolean driver = ep.getDirection()==ep.OUT;
217 if (eci==null) driver = !driver;
218 if (eci==null) name = driver ? "out" : "xi";
219 FlatNetlist.Node.Port p = n.getPort(name, driver);
220 for(EdifPortRef epr2 : en.getConnectedPortRefs()) {
221 EdifCellInstance eci2 = epr2.getCellInstance();
222 EdifPort ep2 = epr2.getPort();
223 Node n2 = createNode(eci2, ep2.getOldName());
224 driver = ep2.getDirection()==ep.OUT;
225 name = ep2.getOldName();
226 if (eci2==null) driver = !driver;
227 if (eci2==null) name = driver ? "out" : "xi";
228 FlatNetlist.Node.Port p2 = n2.getPort(name, driver);
237 test code for inter-sector switchboxes
238 public static void main2() throws Exception {
239 Fpslic fpslic = new FtdiBoard();
241 fpslic.cell(23,15).h(3, true);
242 fpslic.cell(23,15).yi(L3);
243 fpslic.cell(23,15).ylut(0xAA);
244 fpslic.iob_right(15, true).enableOutput(WEST);
245 fpslic.cell(23,0).ylut(0x00);
246 fpslic.iob_right(0, true).enableOutput(WEST);
248 for(int x=0; x<20; x++) {
249 for(int y=0; y<20; y++) {
250 for(int l=0; l<5; l++) {
251 for(int v = 0; v <= 1; v++) {
253 int newx = vert ? x : x-1;
254 int newy = vert ? y-1 : y;
255 if (newx<0 || newy<0) continue;
256 if (vert && (y%4) != 0) continue;
257 if (!vert && (x%4) != 0) continue;
260 if (layer==3) continue;
261 Fpslic.Cell c = fpslic.cell(x, y);
262 Fpslic.Cell c2 = fpslic.cell(newx, newy);
263 Fpslic.SectorWire sw1 = vert ? c.vwire(layer) : c.hwire(layer);
264 Fpslic.SectorWire sw2 = vert ? c2.vwire(layer) : c2.hwire(layer);
265 sw1.drives(sw2, true);
268 if (vert) c.v(L0 + layer, true);
269 else c.h(L0 + layer, true);
270 c.out(L0 + layer, true);
274 if (vert) c2.v(L0 + layer, true);
275 else c2.h(L0 + layer, true);
280 System.out.print(x+","+y+","+l+","+(vert?"v":"h")+": ");
283 boolean good = scan(fpslic, c2)==0;
285 System.out.print(good ? "ok " : "bad ");
288 good = scan(fpslic, c2)!=0;
290 System.out.print(good ? "ok " : "bad ");
291 System.out.println();
292 sw1.drives(sw2, false);
293 if (vert) c.v(layer, false);
294 else c.h(layer, false);
300 System.out.println("fails = " + fails);
303 public static int fails = 0;
306 public static void main(String[] s) throws Exception {
307 EdifEnvironment topEnv = new EdifEnvironment("top");
308 EdifLibraryManager elm = new EdifLibraryManager(topEnv);
309 EdifLibrary initLib = new EdifLibrary(elm, "initLib");
310 EdifEnvironment env = EdifMergeParser.parseAndMerge(s, initLib);
311 System.out.println("top is " + env.getTopCell());
312 FlatNetlist fnl = new FlatNetlist();
314 for(Iterator<EdifCellInstance> it = (Iterator<EdifCellInstance>)env.getTopCell().cellInstanceIterator();
317 FlatNetlist.Node n = fnl.createNode(it.next(), null);
320 Fpslic fpslic = new FtdiBoard();
321 PhysicalDevice pd = new PhysicalDevice(fpslic, 20, 20);
327 Random rand = new Random();
328 boolean[][] used = new boolean[pd.width][pd.height];
329 for(FlatNetlist.Node n : fnl.nodes) {
331 px = Math.abs(rand.nextInt()) % pd.width;
332 py = Math.abs(rand.nextInt()) % pd.height;
337 n.physicalCell = pd.getCell(px, py);
338 System.out.println("placed " + n + " at ("+px+","+py+")");
347 System.out.println();
348 System.out.println("routing trial " + (++trial));
349 for(FlatNetlist.Net net : fnl.nets) {
350 if (net.getSize() <= 1) continue;
351 net.route(fpslic, pd);
353 double congestion = 0;
355 for(PhysicalDevice.PhysicalNet pn : pd.allPhysicalNets) {
357 //System.out.println("overrouted: " + pn + ", congestion="+pn.congestion);
359 congestion += pn.congestion;
361 pn.congestion = pn.congestion * alphaParameter;
363 pn.congestion += betaParameter;
367 System.out.println(" overrouted="+overrouted+", congestion="+congestion);
368 if (overrouted <= 0) break;
369 for(PhysicalDevice.PhysicalNet pn : pd.allPhysicalNets)
370 for(PhysicalDevice.PhysicalPip pip : pn) {
376 fpslic.cell(23,15).h(3, true);
377 fpslic.cell(23,15).yi(L3);
378 fpslic.cell(23,15).ylut(0xAA);
379 fpslic.iob_right(15, true).enableOutput(WEST);
380 fpslic.cell(23,0).ylut(0x00);
381 fpslic.iob_right(0, true).enableOutput(WEST);
386 int a = Math.abs(rand.nextInt()) % (1 << width);
387 int b = Math.abs(rand.nextInt()) % (1 << width);
388 setInput(fnl, fpslic, "a", a);
389 setInput(fnl, fpslic, "b", b);
390 setInput(fnl, fpslic, "ci", 0);
391 int result = getOutput(fnl, fpslic, "out");
392 System.out.println(Integer.toString(a,16) + " + " +
393 Integer.toString(b,16) + " = " +
394 Integer.toString(result,16) +
395 " [ " + (a+b==result ? "ok" : "bad" ) + " ] ");
399 public static class PhysicalDevice {
400 private final Fpslic fpslic;
402 public final int width;
403 public final int height;
404 private final PhysicalNet[][][][] sectorWires;
405 private final PhysicalCell[][] cells;
407 public PhysicalCell getCell(int col, int row) {
408 if (col<0) return null;
409 if (row<0) return null;
410 if (col>=width) return null;
411 if (row>=height) return null;
412 return cells[col][row];
415 public PhysicalDevice(final Fpslic fpslic, int width, int height) {
416 this.fpslic = fpslic;
418 this.height = height;
419 sectorWires = new PhysicalNet[width][height][5][2];
420 for(int x=0; x<width; x+=4)
421 for(int y=0; y<height; y+=4)
422 for(int p=0; p<5; p++) {
423 for(int xc=x; xc<x+4; xc++) {
424 PhysicalNet vwire = new PhysicalNet("("+xc+","+y+"-"+(y+3)+")");
425 for(int yc=y; yc<y+4; yc++)
426 sectorWires[xc][yc][p][0] = vwire;
428 for(int yc=y; yc<y+4; yc++) {
429 PhysicalNet hwire = new PhysicalNet("("+x+"-"+(x+3)+","+yc+")");
430 for(int xc=x; xc<x+4; xc++)
431 sectorWires[xc][yc][p][1] = hwire;
435 for(int x=4; x<width; x+=4) {
436 for(int y=0; y<height; y++) {
437 for(int p=0; p<5; p++) {
441 new PhysicalPip("xxx",
442 sectorWires[x-1][y][p][1],
443 new PhysicalNet[] { sectorWires[x][y][p][1] },
445 public void set(boolean connected) {
446 fpslic.cell(xc-1, yc).hwire(pc).drives(fpslic.cell(xc, yc).hwire(pc), connected);
449 new PhysicalPip("xxx",
450 sectorWires[x][y][p][1],
451 new PhysicalNet[] { sectorWires[x-1][y][p][1] },
453 public void set(boolean connected) {
454 fpslic.cell(xc, yc).hwire(pc).drives(fpslic.cell(xc-1, yc).hwire(pc), connected);
461 for(int x=0; x<width; x++) {
462 for(int y=4; y<height; y+=4) {
463 for(int p=0; p<5; p++) {
467 new PhysicalPip("xxx",
468 sectorWires[x][y-1][p][0],
469 new PhysicalNet[] { sectorWires[x][y][p][0] },
471 public void set(boolean connected) {
472 fpslic.cell(xc, yc-1).vwire(pc).drives(fpslic.cell(xc, yc).vwire(pc), connected);
475 new PhysicalPip("xxx",
476 sectorWires[x][y][p][0],
477 new PhysicalNet[] { sectorWires[x][y-1][p][0] },
479 public void set(boolean connected) {
480 fpslic.cell(xc, yc).vwire(pc).drives(fpslic.cell(xc, yc-1).vwire(pc), connected);
487 cells = new PhysicalCell[width][height];
488 for(int x=0; x<width; x++)
489 for(int y=0; y<height; y++) {
490 cells[x][y] = new PhysicalCell(x, y);
492 for(int x=0; x<width; x++)
493 for(int y=0; y<height; y++)
497 private PhysicalNet getSectorWire(int col, int row, int plane, boolean horizontal) {
498 return sectorWires[col][row][plane][horizontal ? 1 : 0];
501 public class PhysicalCell {
503 public PhysicalNet getNet(String name) {
504 if (name.equals("out")) return outputNet;
505 if (name.equals("xi")) return xin;
506 if (name.equals("yi")) return yin;
507 throw new RuntimeException("unknown");
512 private PhysicalNet outputNet;
513 private PhysicalNet xin;
514 private PhysicalNet yin;
515 private PhysicalNet[] local = new PhysicalNet[5];
517 private Fpslic.Cell cell() { return fpslic.cell(col, row); }
519 public void setFunction(String type) {
520 Fpslic.Cell cell = cell();
525 if (type.equals("and2")) cell.xlut(LUT_SELF & LUT_OTHER);
526 else if (type.equals("or2")) cell.xlut(LUT_SELF | LUT_OTHER);
527 else if (type.equals("xor2")) cell.xlut(LUT_SELF ^ LUT_OTHER);
528 else if (type.equals("buf")) cell.xlut(LUT_SELF);
529 else if (type.equals("inv")) cell.xlut(~LUT_SELF);
533 // FIXME wow, this is a horrendous hack!
534 if (getCell(col-1, row+1) != null)
535 new PhysicalPip(this+".xiNW", getCell(col-1, row+1).getNet("out"), new PhysicalNet[] { xin }, 5) {
536 public void set(boolean connected) { cell().xi(connected ? NW : NONE); }
538 if (getCell(col-1, row-1) != null)
539 new PhysicalPip(this+".xiSW", getCell(col-1, row-1).getNet("out"), new PhysicalNet[] { xin }, 5) {
540 public void set(boolean connected) { cell().xi(connected ? SW : NONE); }
542 if (getCell(col+1, row+1) != null)
543 new PhysicalPip(this+".xiNE", getCell(col+1, row+1).getNet("out"), new PhysicalNet[] { xin }, 5) {
544 public void set(boolean connected) { cell().xi(connected ? NE : NONE); }
546 if (getCell(col+1, row-1) != null)
547 new PhysicalPip(this+".xiSE", getCell(col+1, row-1).getNet("out"), new PhysicalNet[] { xin }, 5) {
548 public void set(boolean connected) { cell().xi(connected ? SE : NONE); }
552 private PhysicalCell(int col, int row) {
555 outputNet = new PhysicalNet(this.toString()+".out");
556 xin = new PhysicalNet(this.toString()+".xi");
557 yin = new PhysicalNet(this.toString()+".yi");
558 for(int j=0; j<5; j++) {
560 // plane 3 is reserved for debugging
564 local[i] = new PhysicalNet(this.toString()+".L"+i);
565 new PhysicalPip(this+".h"+i, null, new PhysicalNet[] { local[i], getSectorWire(col, row, i, true) }) {
566 public void set(boolean connected) { cell().h(i, connected); }
568 new PhysicalPip(this+".v"+i, null, new PhysicalNet[] { local[i], getSectorWire(col, row, i, false) }) {
569 public void set(boolean connected) { cell().v(i, connected); }
571 new PhysicalPip(this+".xi"+i, local[i], new PhysicalNet[] { xin }) {
572 public void set(boolean connected) { cell().xi(connected ? i : NONE); }
574 new PhysicalPip(this+".yi"+i, local[i], new PhysicalNet[] { yin }) {
575 public void set(boolean connected) { cell().yi(connected ? i : NONE); }
577 new PhysicalPip(this+".o"+i, outputNet, new PhysicalNet[] { local[i] }) {
578 public void set(boolean connected) { cell().out(i, connected); }
582 public String toString() { return "cell@("+col+","+row+")"; }
586 public void route(PhysicalNet source, PhysicalNet[] dests) {
587 HashSet<PhysicalNet> remainingDests = new HashSet<PhysicalNet>();
588 for(PhysicalNet dest : dests) remainingDests.add(dest);
590 HashSet<PhysicalNet> needsReset = new HashSet<PhysicalNet>();
591 PriorityQueue<PhysicalNet> pq = new PriorityQueue<PhysicalNet>();
592 needsReset.add(source);
597 PhysicalNet pn = pq.poll();
598 if (pn==null) throw new Error("unroutable! " + source + " -> " + dests[0]);
599 double frontier = pn.distance;
600 for(PhysicalPip pip : pn)
601 for(PhysicalNet net : pip.getDrivenNets()) {
602 double newfrontier = frontier + (1/*pip.getCost(pn, net)*/ * (1.0+net.congestion));
604 if (net.load >= 1) newfrontier = newfrontier + 200;
606 if (net.distance <= newfrontier) continue;
607 pq.remove(net); // if already in there
608 net.distance = newfrontier;
611 net.backpointer = pn;
612 if (remainingDests.contains(net)) {
613 remainingDests.remove(net);
614 if (remainingDests.size()==0) break OUTER;
619 for(PhysicalNet dest : dests) {
620 PhysicalNet pn = dest;
621 while(pn != null && pn.backpointer != null) {
622 if (pn.distance != Double.MAX_VALUE) {
623 pn.distance = Double.MAX_VALUE;
626 PhysicalPip pip = pn.getPipFrom(pn.backpointer);
630 // FIXME: check pn==source at this point
633 for(PhysicalNet pn : needsReset) {
634 pn.distance = Double.MAX_VALUE;
635 pn.backpointer = null;
638 public HashSet<PhysicalNet> allPhysicalNets = new HashSet<PhysicalNet>();
639 public class PhysicalNet implements Iterable<PhysicalPip>, Comparable<PhysicalNet> {
640 public double congestion = 0;
642 public double distance = Double.MAX_VALUE;
643 public PhysicalNet backpointer = null;
645 public int compareTo(PhysicalNet pn) {
646 double x = distance - pn.distance;
647 return distance > pn.distance
649 : distance < pn.distance
654 private final HashSet<PhysicalPip> pips = new HashSet<PhysicalPip>();
655 public Iterator<PhysicalPip> iterator() { return pips.iterator(); }
657 public PhysicalNet(String name) {
659 allPhysicalNets.add(this);
661 public String toString() { return name; }
662 private void addPip(PhysicalPip pip) { pips.add(pip); }
663 public PhysicalPip getPipFrom(PhysicalNet pn) {
664 for(PhysicalPip pip : pn)
665 for(PhysicalNet pn2 : pip.getDrivenNets())
672 public abstract class PhysicalPip {
673 private PhysicalNet driver;
674 private PhysicalNet[] driven;
676 private int defaultCost;
677 public String toString() { return name; }
678 public PhysicalNet getDriverNet() { return driver; }
679 public PhysicalNet[] getDrivenNets() { return driven; }
680 public int getCost(PhysicalNet in, PhysicalNet out) { return defaultCost; }
681 public PhysicalPip(String name, PhysicalNet driver, PhysicalNet[] driven) { this(name, driver, driven, 100); }
682 public PhysicalPip(String name, PhysicalNet driver, PhysicalNet[] driven, int defaultCost) {
684 this.driver = driver;
685 this.driven = driven;
686 this.defaultCost = defaultCost;
687 if (driver != null) driver.addPip(this);
688 for(PhysicalNet pn : driven) pn.addPip(this);
690 public abstract void set(boolean connected);
695 private static int ret;
696 public static synchronized int scan(final Fpslic device, final Fpslic.Cell cell) {
698 scan(device, cell, YLUT, true);
699 ((FtdiBoard)device).readBus(new FtdiBoard.ByteCallback() {
700 public void call(byte b) throws Exception {
702 synchronized(device) {
707 synchronized(device) {
710 } catch (Exception e) { throw new RuntimeException(e); }
712 scan(device, cell, YLUT, false);
714 } catch (Exception e) { throw new RuntimeException(e); }
717 public static void scan(Fpslic dev, Fpslic.Cell cell, int source, boolean setup) {
719 //if (source != NONE) cell.c(source);
720 if (cell.b()) cell.b(false);
721 if (cell.f()) cell.f(false);
723 if (cell.out(L3)!=setup) cell.out(L3, setup);
724 if (cell.vx(L3)!=setup) cell.v(L3, setup);
726 Fpslic.SectorWire sw = cell.vwire(L3);
727 //System.out.println("wire is: " + sw);
729 if (sw.row > (12 & ~0x3) && sw.north()!=null && sw.north().drives(sw))
730 sw.north().drives(sw, false);
731 while(sw.row > (12 & ~0x3) && sw.south() != null) {
732 //System.out.println(sw + " -> " + sw.south());
733 if (sw.drives(sw.south())!=setup) sw.drives(sw.south(), setup);
736 if (sw.row < (12 & ~0x3) && sw.south() != null && sw.south().drives(sw))
737 sw.north().drives(sw, false);
738 while(sw.row < (12 & ~0x3) && sw.north() != null) {
739 //System.out.println(sw + " -> " + sw.north());
740 if (sw.drives(sw.north())!=setup) sw.drives(sw.north(), setup);
744 //cell = dev.cell(19, 15);
745 cell = dev.cell(cell.col, 15);
747 System.out.println("cell is " + cell);
756 if (cell.hx(L3) != setup) cell.h(L3, setup);
757 if (cell.vx(L3) != setup) cell.v(L3, setup);
760 if (sw.west()!=null && sw.west().drives(sw)) { sw.west().drives(sw, false); }
761 while(sw.east() != null) {
762 //System.out.println(sw + " -> " + sw.east());
763 if (sw.drives(sw.east())!=setup) sw.drives(sw.east(), setup);
769 public static void setInput(FlatNetlist fnl, Fpslic fpslic, String prefix, int val) {
770 for(int i=0; ; i++) {
771 FlatNetlist.Node n = fnl.top.get(prefix + "["+i+"]");
772 if (n==null && i==0) n = fnl.top.get(prefix);
774 Fpslic.Cell c = n.getPlacement(fpslic);
777 c.xlut((val & 0x1)==0 ? 0x00 : 0xff);
781 public static int getOutput(FlatNetlist fnl, Fpslic fpslic, String prefix) {
783 for(int i=0; ; i++) {
784 FlatNetlist.Node n = fnl.top.get(prefix+"["+i+"]");
785 if (n==null && i==0) n = fnl.top.get(prefix);
786 if (n==null) return val;
787 Fpslic.Cell c = n.getPlacement(fpslic);
792 int scan = scan(fpslic, c);
793 val |= ((scan==0 ? 0 : 1) << i);